fix(app): finish tool call ID rename (#40539)
Co-authored-by: Aiden Cline <rekram1-node@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
53b8111121
commit
6d2eb2240a
@@ -53,7 +53,7 @@ describe("normalizePermissionRequest", () => {
|
||||
resources: ["README.md"],
|
||||
save: ["*.md"],
|
||||
metadata: { path: "README.md" },
|
||||
source: { type: "tool", messageID: "message-1", callID: "call-1" },
|
||||
source: { type: "tool", messageID: "message-1", id: "call-1" },
|
||||
}),
|
||||
).toEqual({
|
||||
id: "permission-1",
|
||||
|
||||
@@ -48,7 +48,7 @@ export function normalizePermissionRequest(input: PermissionRequest | LegacyPerm
|
||||
always: input.save ?? [],
|
||||
metadata: input.metadata ?? {},
|
||||
tool:
|
||||
input.source?.type === "tool" ? { messageID: input.source.messageID, callID: input.source.callID } : undefined,
|
||||
input.source?.type === "tool" ? { messageID: input.source.messageID, callID: input.source.id } : undefined,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -21,12 +21,24 @@ describe("adaptServerEvent", () => {
|
||||
id: "evt_1",
|
||||
created: 1,
|
||||
type: "permission.asked",
|
||||
data: { id: "perm_1", sessionID: "ses_1", action: "read", resources: ["src/**"] },
|
||||
data: {
|
||||
id: "perm_1",
|
||||
sessionID: "ses_1",
|
||||
action: "read",
|
||||
resources: ["src/**"],
|
||||
source: { type: "tool", messageID: "msg_1", id: "call_1" },
|
||||
},
|
||||
} as OpenCodeEvent
|
||||
|
||||
expect(adaptServerEvent(current)).toMatchObject({
|
||||
type: "permission.asked",
|
||||
properties: { id: "perm_1", sessionID: "ses_1", permission: "read", patterns: ["src/**"] },
|
||||
properties: {
|
||||
id: "perm_1",
|
||||
sessionID: "ses_1",
|
||||
permission: "read",
|
||||
patterns: ["src/**"],
|
||||
tool: { messageID: "msg_1", callID: "call_1" },
|
||||
},
|
||||
current,
|
||||
})
|
||||
})
|
||||
@@ -70,6 +82,26 @@ describe("coalesceServerEvents", () => {
|
||||
expect(result[0]?.payload.current).toMatchObject({ id: "evt_2", data: { delta: "hello world" } })
|
||||
})
|
||||
|
||||
test("coalesces current tool input deltas by tool ID", () => {
|
||||
const current = (eventID: string, id: string, delta: string) =>
|
||||
adaptServerEvent({
|
||||
id: eventID,
|
||||
created: 1,
|
||||
type: "session.tool.input.delta",
|
||||
location: { directory: "/repo" },
|
||||
data: { sessionID: "ses", assistantMessageID: "msg", id, delta },
|
||||
} as OpenCodeEvent)
|
||||
const result = coalesceServerEvents([
|
||||
{ directory: "/repo", payload: current("evt_1", "call_1", "{") },
|
||||
{ directory: "/repo", payload: current("evt_2", "call_1", "}") },
|
||||
{ directory: "/repo", payload: current("evt_3", "call_2", "[]") },
|
||||
])
|
||||
|
||||
expect(result).toHaveLength(2)
|
||||
expect(result[0]?.payload.current).toMatchObject({ id: "evt_2", data: { id: "call_1", delta: "{}" } })
|
||||
expect(result[1]?.payload.current).toMatchObject({ id: "evt_3", data: { id: "call_2", delta: "[]" } })
|
||||
})
|
||||
|
||||
test("preserves event boundaries and distinct fields", () => {
|
||||
const status = {
|
||||
directory: "/repo",
|
||||
|
||||
@@ -39,7 +39,7 @@ export function adaptServerEvent(event: OpenCodeEvent): ServerEvent {
|
||||
metadata: event.data.metadata ?? {},
|
||||
tool:
|
||||
event.data.source?.type === "tool"
|
||||
? { messageID: event.data.source.messageID, callID: event.data.source.callID }
|
||||
? { messageID: event.data.source.messageID, callID: event.data.source.id }
|
||||
: undefined,
|
||||
},
|
||||
current: event,
|
||||
@@ -142,7 +142,7 @@ function currentDelta(event: OpenCodeEvent | undefined): CurrentDelta | undefine
|
||||
|
||||
function currentDeltaKey(event: CurrentDelta) {
|
||||
if (event.type === "session.tool.input.delta")
|
||||
return `${event.type}:${event.data.sessionID}:${event.data.assistantMessageID}:${event.data.callID}`
|
||||
return `${event.type}:${event.data.sessionID}:${event.data.assistantMessageID}:${event.data.id}`
|
||||
if (event.type === "session.compaction.delta") return `${event.type}:${event.data.sessionID}`
|
||||
return `${event.type}:${event.data.sessionID}:${event.data.assistantMessageID}:${event.data.ordinal}`
|
||||
}
|
||||
|
||||
@@ -92,19 +92,19 @@ describe("v2 session reducer", () => {
|
||||
...base,
|
||||
id: "evt_tool_start",
|
||||
type: "session.tool.input.started",
|
||||
data: { sessionID: "ses_1", assistantMessageID: "msg_assistant", callID: "call_1", name: "bash" },
|
||||
data: { sessionID: "ses_1", assistantMessageID: "msg_assistant", id: "call_1", name: "bash" },
|
||||
})
|
||||
apply({
|
||||
...base,
|
||||
id: "evt_tool_delta",
|
||||
type: "session.tool.input.delta",
|
||||
data: { sessionID: "ses_1", assistantMessageID: "msg_assistant", callID: "call_1", delta: "{}" },
|
||||
data: { sessionID: "ses_1", assistantMessageID: "msg_assistant", id: "call_1", delta: "{}" },
|
||||
})
|
||||
apply({
|
||||
...base,
|
||||
id: "evt_tool_called",
|
||||
type: "session.tool.called",
|
||||
data: { sessionID: "ses_1", assistantMessageID: "msg_assistant", callID: "call_1", input: {}, executed: true },
|
||||
data: { sessionID: "ses_1", assistantMessageID: "msg_assistant", id: "call_1", input: {}, executed: true },
|
||||
})
|
||||
apply({
|
||||
...base,
|
||||
@@ -113,7 +113,7 @@ describe("v2 session reducer", () => {
|
||||
data: {
|
||||
sessionID: "ses_1",
|
||||
assistantMessageID: "msg_assistant",
|
||||
callID: "call_1",
|
||||
id: "call_1",
|
||||
metadata: {},
|
||||
content: [{ type: "text", text: "done" }],
|
||||
executed: true,
|
||||
|
||||
@@ -241,13 +241,13 @@ export function createV2SessionReducer() {
|
||||
case "session.tool.input.started":
|
||||
return updateAssistant(source, event.data.assistantMessageID, sessionID, (item) => ({
|
||||
...item,
|
||||
content: item.content.some((content) => content.type === "tool" && content.id === event.data.callID)
|
||||
content: item.content.some((content) => content.type === "tool" && content.id === event.data.id)
|
||||
? item.content
|
||||
: [
|
||||
...item.content,
|
||||
{
|
||||
type: "tool",
|
||||
id: event.data.callID,
|
||||
id: event.data.id,
|
||||
name: event.data.name,
|
||||
state: { status: "streaming", input: "" },
|
||||
time: { created: event.created },
|
||||
@@ -255,17 +255,17 @@ export function createV2SessionReducer() {
|
||||
],
|
||||
}))
|
||||
case "session.tool.input.delta":
|
||||
return updateTool(source, event.data.assistantMessageID, event.data.callID, sessionID, (tool) =>
|
||||
return updateTool(source, event.data.assistantMessageID, event.data.id, sessionID, (tool) =>
|
||||
tool.state.status === "streaming"
|
||||
? { ...tool, state: { ...tool.state, input: tool.state.input + event.data.delta } }
|
||||
: tool,
|
||||
)
|
||||
case "session.tool.input.ended":
|
||||
return updateTool(source, event.data.assistantMessageID, event.data.callID, sessionID, (tool) =>
|
||||
return updateTool(source, event.data.assistantMessageID, event.data.id, sessionID, (tool) =>
|
||||
tool.state.status === "streaming" ? { ...tool, state: { ...tool.state, input: event.data.text } } : tool,
|
||||
)
|
||||
case "session.tool.called":
|
||||
return updateTool(source, event.data.assistantMessageID, event.data.callID, sessionID, (tool) => ({
|
||||
return updateTool(source, event.data.assistantMessageID, event.data.id, sessionID, (tool) => ({
|
||||
...tool,
|
||||
executed: event.data.executed,
|
||||
providerState: event.data.state,
|
||||
@@ -274,7 +274,7 @@ export function createV2SessionReducer() {
|
||||
time: { ...tool.time, ran: event.created },
|
||||
}))
|
||||
case "session.tool.progress":
|
||||
return updateTool(source, event.data.assistantMessageID, event.data.callID, sessionID, (tool) =>
|
||||
return updateTool(source, event.data.assistantMessageID, event.data.id, sessionID, (tool) =>
|
||||
tool.state.status === "running"
|
||||
? {
|
||||
...tool,
|
||||
@@ -284,7 +284,7 @@ export function createV2SessionReducer() {
|
||||
: tool,
|
||||
)
|
||||
case "session.tool.success":
|
||||
return updateTool(source, event.data.assistantMessageID, event.data.callID, sessionID, (tool) => {
|
||||
return updateTool(source, event.data.assistantMessageID, event.data.id, sessionID, (tool) => {
|
||||
if (tool.state.status !== "running") return tool
|
||||
return {
|
||||
...tool,
|
||||
@@ -302,7 +302,7 @@ export function createV2SessionReducer() {
|
||||
}
|
||||
})
|
||||
case "session.tool.failed":
|
||||
return updateTool(source, event.data.assistantMessageID, event.data.callID, sessionID, (tool) => {
|
||||
return updateTool(source, event.data.assistantMessageID, event.data.id, sessionID, (tool) => {
|
||||
if (tool.state.status !== "streaming" && tool.state.status !== "running") return tool
|
||||
return {
|
||||
...tool,
|
||||
|
||||
Reference in New Issue
Block a user