fix: [app-server] Schema mismatch prevents thread resume

This commit is contained in:
Leo Shimonaka
2026-02-20 15:30:36 -08:00
parent 4ebdddaa34
commit 2e5c52e6da
21 changed files with 58 additions and 63 deletions

View File

@@ -1551,7 +1551,7 @@
"phase": {
"anyOf": [
{
"$ref": "#/definitions/MessagePhase2"
"$ref": "#/definitions/MessagePhase"
},
{
"type": "null"
@@ -4593,13 +4593,6 @@
"type": "string"
},
"MessagePhase": {
"enum": [
"commentary",
"finalAnswer"
],
"type": "string"
},
"MessagePhase2": {
"description": "Classifies an assistant message as interim commentary or final answer text.\n\nProviders do not emit this consistently, so callers must treat `None` as \"phase unknown\" and keep compatibility behavior for legacy models.",
"oneOf": [
{
@@ -4618,6 +4611,13 @@
}
]
},
"MessagePhaseV2": {
"enum": [
"commentary",
"finalAnswer"
],
"type": "string"
},
"ModeKind": {
"description": "Initial collaboration mode to use when the TUI starts.",
"enum": [
@@ -5551,7 +5551,7 @@
"phase": {
"anyOf": [
{
"$ref": "#/definitions/MessagePhase2"
"$ref": "#/definitions/MessagePhase"
},
{
"type": "null"
@@ -6848,7 +6848,7 @@
"phase": {
"anyOf": [
{
"$ref": "#/definitions/MessagePhase"
"$ref": "#/definitions/MessagePhaseV2"
},
{
"type": "null"
@@ -7735,7 +7735,7 @@
"phase": {
"anyOf": [
{
"$ref": "#/definitions/MessagePhase2"
"$ref": "#/definitions/MessagePhase"
},
{
"type": "null"

View File

@@ -13361,6 +13361,13 @@
}
]
},
"MessagePhaseV2": {
"enum": [
"commentary",
"finalAnswer"
],
"type": "string"
},
"ModeKind": {
"description": "Initial collaboration mode to use when the TUI starts.",
"enum": [
@@ -15818,7 +15825,7 @@
"phase": {
"anyOf": [
{
"$ref": "#/definitions/v2/MessagePhase"
"$ref": "#/definitions/v2/MessagePhaseV2"
},
{
"type": "null"

View File

@@ -236,7 +236,7 @@
],
"type": "string"
},
"MessagePhase": {
"MessagePhaseV2": {
"enum": [
"commentary",
"finalAnswer"
@@ -370,7 +370,7 @@
"phase": {
"anyOf": [
{
"$ref": "#/definitions/MessagePhase"
"$ref": "#/definitions/MessagePhaseV2"
},
{
"type": "null"

View File

@@ -236,7 +236,7 @@
],
"type": "string"
},
"MessagePhase": {
"MessagePhaseV2": {
"enum": [
"commentary",
"finalAnswer"
@@ -370,7 +370,7 @@
"phase": {
"anyOf": [
{
"$ref": "#/definitions/MessagePhase"
"$ref": "#/definitions/MessagePhaseV2"
},
{
"type": "null"

View File

@@ -350,7 +350,7 @@
],
"type": "string"
},
"MessagePhase": {
"MessagePhaseV2": {
"enum": [
"commentary",
"finalAnswer"
@@ -484,7 +484,7 @@
"phase": {
"anyOf": [
{
"$ref": "#/definitions/MessagePhase"
"$ref": "#/definitions/MessagePhaseV2"
},
{
"type": "null"

View File

@@ -419,7 +419,7 @@
],
"type": "string"
},
"MessagePhase": {
"MessagePhaseV2": {
"enum": [
"commentary",
"finalAnswer"
@@ -937,7 +937,7 @@
"phase": {
"anyOf": [
{
"$ref": "#/definitions/MessagePhase"
"$ref": "#/definitions/MessagePhaseV2"
},
{
"type": "null"

View File

@@ -373,7 +373,7 @@
],
"type": "string"
},
"MessagePhase": {
"MessagePhaseV2": {
"enum": [
"commentary",
"finalAnswer"
@@ -710,7 +710,7 @@
"phase": {
"anyOf": [
{
"$ref": "#/definitions/MessagePhase"
"$ref": "#/definitions/MessagePhaseV2"
},
{
"type": "null"

View File

@@ -373,7 +373,7 @@
],
"type": "string"
},
"MessagePhase": {
"MessagePhaseV2": {
"enum": [
"commentary",
"finalAnswer"
@@ -710,7 +710,7 @@
"phase": {
"anyOf": [
{
"$ref": "#/definitions/MessagePhase"
"$ref": "#/definitions/MessagePhaseV2"
},
{
"type": "null"

View File

@@ -419,7 +419,7 @@
],
"type": "string"
},
"MessagePhase": {
"MessagePhaseV2": {
"enum": [
"commentary",
"finalAnswer"
@@ -937,7 +937,7 @@
"phase": {
"anyOf": [
{
"$ref": "#/definitions/MessagePhase"
"$ref": "#/definitions/MessagePhaseV2"
},
{
"type": "null"

View File

@@ -373,7 +373,7 @@
],
"type": "string"
},
"MessagePhase": {
"MessagePhaseV2": {
"enum": [
"commentary",
"finalAnswer"
@@ -710,7 +710,7 @@
"phase": {
"anyOf": [
{
"$ref": "#/definitions/MessagePhase"
"$ref": "#/definitions/MessagePhaseV2"
},
{
"type": "null"

View File

@@ -419,7 +419,7 @@
],
"type": "string"
},
"MessagePhase": {
"MessagePhaseV2": {
"enum": [
"commentary",
"finalAnswer"
@@ -937,7 +937,7 @@
"phase": {
"anyOf": [
{
"$ref": "#/definitions/MessagePhase"
"$ref": "#/definitions/MessagePhaseV2"
},
{
"type": "null"

View File

@@ -373,7 +373,7 @@
],
"type": "string"
},
"MessagePhase": {
"MessagePhaseV2": {
"enum": [
"commentary",
"finalAnswer"
@@ -710,7 +710,7 @@
"phase": {
"anyOf": [
{
"$ref": "#/definitions/MessagePhase"
"$ref": "#/definitions/MessagePhaseV2"
},
{
"type": "null"

View File

@@ -373,7 +373,7 @@
],
"type": "string"
},
"MessagePhase": {
"MessagePhaseV2": {
"enum": [
"commentary",
"finalAnswer"
@@ -710,7 +710,7 @@
"phase": {
"anyOf": [
{
"$ref": "#/definitions/MessagePhase"
"$ref": "#/definitions/MessagePhaseV2"
},
{
"type": "null"

View File

@@ -350,7 +350,7 @@
],
"type": "string"
},
"MessagePhase": {
"MessagePhaseV2": {
"enum": [
"commentary",
"finalAnswer"
@@ -484,7 +484,7 @@
"phase": {
"anyOf": [
{
"$ref": "#/definitions/MessagePhase"
"$ref": "#/definitions/MessagePhaseV2"
},
{
"type": "null"

View File

@@ -350,7 +350,7 @@
],
"type": "string"
},
"MessagePhase": {
"MessagePhaseV2": {
"enum": [
"commentary",
"finalAnswer"
@@ -484,7 +484,7 @@
"phase": {
"anyOf": [
{
"$ref": "#/definitions/MessagePhase"
"$ref": "#/definitions/MessagePhaseV2"
},
{
"type": "null"

View File

@@ -350,7 +350,7 @@
],
"type": "string"
},
"MessagePhase": {
"MessagePhaseV2": {
"enum": [
"commentary",
"finalAnswer"
@@ -484,7 +484,7 @@
"phase": {
"anyOf": [
{
"$ref": "#/definitions/MessagePhase"
"$ref": "#/definitions/MessagePhaseV2"
},
{
"type": "null"

View File

@@ -2,4 +2,4 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
export type MessagePhase = "commentary" | "finalAnswer";
export type MessagePhaseV2 = "commentary" | "finalAnswer";

View File

@@ -11,12 +11,12 @@ import type { FileUpdateChange } from "./FileUpdateChange";
import type { McpToolCallError } from "./McpToolCallError";
import type { McpToolCallResult } from "./McpToolCallResult";
import type { McpToolCallStatus } from "./McpToolCallStatus";
import type { MessagePhase } from "./MessagePhase";
import type { MessagePhaseV2 } from "./MessagePhaseV2";
import type { PatchApplyStatus } from "./PatchApplyStatus";
import type { UserInput } from "./UserInput";
import type { WebSearchAction } from "./WebSearchAction";
export type ThreadItem = { "type": "userMessage", id: string, content: Array<UserInput>, } | { "type": "agentMessage", id: string, text: string, phase: MessagePhase | null, } | { "type": "plan", id: string, text: string, } | { "type": "reasoning", id: string, summary: Array<string>, content: Array<string>, } | { "type": "commandExecution", id: string,
export type ThreadItem = { "type": "userMessage", id: string, content: Array<UserInput>, } | { "type": "agentMessage", id: string, text: string, phase: MessagePhaseV2 | null, } | { "type": "plan", id: string, text: string, } | { "type": "reasoning", id: string, summary: Array<string>, content: Array<string>, } | { "type": "commandExecution", id: string,
/**
* The command to be executed.
*/

View File

@@ -95,7 +95,7 @@ export type { McpToolCallProgressNotification } from "./McpToolCallProgressNotif
export type { McpToolCallResult } from "./McpToolCallResult";
export type { McpToolCallStatus } from "./McpToolCallStatus";
export type { MergeStrategy } from "./MergeStrategy";
export type { MessagePhase } from "./MessagePhase";
export type { MessagePhaseV2 } from "./MessagePhaseV2";
export type { Model } from "./Model";
export type { ModelListParams } from "./ModelListParams";
export type { ModelListResponse } from "./ModelListResponse";

View File

@@ -1196,7 +1196,7 @@ mod tests {
ThreadItem::AgentMessage {
id: "item-1".into(),
text: "Final reply".into(),
phase: Some(crate::protocol::v2::MessagePhase::FinalAnswer),
phase: Some(crate::protocol::v2::MessagePhaseV2::FinalAnswer),
}
);
}

View File

@@ -2664,23 +2664,11 @@ impl From<CoreUserInput> for UserInput {
}
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
#[serde(rename_all = "camelCase")]
#[ts(rename_all = "camelCase")]
#[ts(export_to = "v2/")]
pub enum MessagePhase {
Commentary,
FinalAnswer,
}
impl From<CoreMessagePhase> for MessagePhase {
fn from(value: CoreMessagePhase) -> Self {
match value {
CoreMessagePhase::Commentary => Self::Commentary,
CoreMessagePhase::FinalAnswer => Self::FinalAnswer,
}
v2_enum_from_core!(
pub enum MessagePhaseV2 from CoreMessagePhase {
Commentary, FinalAnswer
}
}
);
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
#[serde(tag = "type", rename_all = "camelCase")]
@@ -2696,7 +2684,7 @@ pub enum ThreadItem {
id: String,
text: String,
#[serde(default)]
phase: Option<MessagePhase>,
phase: Option<MessagePhaseV2>,
},
#[serde(rename_all = "camelCase")]
#[ts(rename_all = "camelCase")]
@@ -3908,7 +3896,7 @@ mod tests {
ThreadItem::AgentMessage {
id: "agent-2".to_string(),
text: "final".to_string(),
phase: Some(MessagePhase::FinalAnswer),
phase: Some(MessagePhaseV2::FinalAnswer),
}
);