gsd-pi 2.74.0-dev.14c45ac → 2.74.0-dev.20f79a8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/resources/extensions/gsd/auto-post-unit.js +7 -3
- package/dist/resources/extensions/gsd/bootstrap/register-extension.js +10 -1
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +45 -4
- package/dist/resources/extensions/gsd/ecosystem/gsd-extension-api.js +144 -0
- package/dist/resources/extensions/gsd/ecosystem/loader.js +145 -0
- package/dist/tsconfig.extensions.tsbuildinfo +1 -1
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +16 -16
- package/dist/web/standalone/.next/build-manifest.json +2 -2
- package/dist/web/standalone/.next/prerender-manifest.json +3 -3
- package/dist/web/standalone/.next/required-server-files.json +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +1 -1
- package/dist/web/standalone/.next/server/app/index.html +1 -1
- package/dist/web/standalone/.next/server/app/index.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app-paths-manifest.json +16 -16
- package/dist/web/standalone/.next/server/chunks/6897.js +3 -3
- package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
- package/dist/web/standalone/.next/server/middleware-manifest.json +5 -5
- package/dist/web/standalone/.next/server/pages/404.html +1 -1
- package/dist/web/standalone/.next/server/pages/500.html +1 -1
- package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
- package/dist/web/standalone/server.js +1 -1
- package/package.json +1 -1
- package/packages/pi-agent-core/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-ai/dist/index.d.ts +1 -9
- package/packages/pi-ai/dist/index.d.ts.map +1 -1
- package/packages/pi-ai/dist/index.js +1 -9
- package/packages/pi-ai/dist/index.js.map +1 -1
- package/packages/pi-ai/dist/models/capability-patches.d.ts +19 -0
- package/packages/pi-ai/dist/models/capability-patches.d.ts.map +1 -0
- package/packages/pi-ai/dist/models/capability-patches.js +36 -0
- package/packages/pi-ai/dist/models/capability-patches.js.map +1 -0
- package/packages/pi-ai/dist/{models.custom.d.ts → models/custom.d.ts} +1 -1
- package/packages/pi-ai/dist/models/custom.d.ts.map +1 -0
- package/packages/pi-ai/dist/{models.custom.js → models/custom.js} +4 -4
- package/packages/pi-ai/dist/models/custom.js.map +1 -0
- package/packages/pi-ai/dist/models/generated/amazon-bedrock.d.ts +1482 -0
- package/packages/pi-ai/dist/models/generated/amazon-bedrock.d.ts.map +1 -0
- package/packages/pi-ai/dist/models/generated/amazon-bedrock.js +1484 -0
- package/packages/pi-ai/dist/models/generated/amazon-bedrock.js.map +1 -0
- package/packages/pi-ai/dist/models/generated/anthropic.d.ts +377 -0
- package/packages/pi-ai/dist/models/generated/anthropic.d.ts.map +1 -0
- package/packages/pi-ai/dist/models/generated/anthropic.js +379 -0
- package/packages/pi-ai/dist/models/generated/anthropic.js.map +1 -0
- package/packages/pi-ai/dist/models/generated/azure-openai-responses.d.ts +700 -0
- package/packages/pi-ai/dist/models/generated/azure-openai-responses.d.ts.map +1 -0
- package/packages/pi-ai/dist/models/generated/azure-openai-responses.js +702 -0
- package/packages/pi-ai/dist/models/generated/azure-openai-responses.js.map +1 -0
- package/packages/pi-ai/dist/models/generated/cerebras.d.ts +71 -0
- package/packages/pi-ai/dist/models/generated/cerebras.d.ts.map +1 -0
- package/packages/pi-ai/dist/models/generated/cerebras.js +73 -0
- package/packages/pi-ai/dist/models/generated/cerebras.js.map +1 -0
- package/packages/pi-ai/dist/models/generated/github-copilot.d.ts +590 -0
- package/packages/pi-ai/dist/models/generated/github-copilot.d.ts.map +1 -0
- package/packages/pi-ai/dist/models/generated/github-copilot.js +444 -0
- package/packages/pi-ai/dist/models/generated/github-copilot.js.map +1 -0
- package/packages/pi-ai/dist/models/generated/google-antigravity.d.ts +156 -0
- package/packages/pi-ai/dist/models/generated/google-antigravity.d.ts.map +1 -0
- package/packages/pi-ai/dist/models/generated/google-antigravity.js +158 -0
- package/packages/pi-ai/dist/models/generated/google-antigravity.js.map +1 -0
- package/packages/pi-ai/dist/models/generated/google-gemini-cli.d.ts +105 -0
- package/packages/pi-ai/dist/models/generated/google-gemini-cli.d.ts.map +1 -0
- package/packages/pi-ai/dist/models/generated/google-gemini-cli.js +107 -0
- package/packages/pi-ai/dist/models/generated/google-gemini-cli.js.map +1 -0
- package/packages/pi-ai/dist/models/generated/google-vertex.d.ts +207 -0
- package/packages/pi-ai/dist/models/generated/google-vertex.d.ts.map +1 -0
- package/packages/pi-ai/dist/models/generated/google-vertex.js +209 -0
- package/packages/pi-ai/dist/models/generated/google-vertex.js.map +1 -0
- package/packages/pi-ai/dist/models/generated/google.d.ts +462 -0
- package/packages/pi-ai/dist/models/generated/google.d.ts.map +1 -0
- package/packages/pi-ai/dist/models/generated/google.js +464 -0
- package/packages/pi-ai/dist/models/generated/google.js.map +1 -0
- package/packages/pi-ai/dist/models/generated/groq.d.ts +309 -0
- package/packages/pi-ai/dist/models/generated/groq.d.ts.map +1 -0
- package/packages/pi-ai/dist/models/generated/groq.js +311 -0
- package/packages/pi-ai/dist/models/generated/groq.js.map +1 -0
- package/packages/pi-ai/dist/models/generated/huggingface.d.ts +383 -0
- package/packages/pi-ai/dist/models/generated/huggingface.d.ts.map +1 -0
- package/packages/pi-ai/dist/models/generated/huggingface.js +347 -0
- package/packages/pi-ai/dist/models/generated/huggingface.js.map +1 -0
- package/packages/pi-ai/dist/{models.generated.d.ts → models/generated/index.d.ts} +1 -1
- package/packages/pi-ai/dist/{models.generated.d.ts.map → models/generated/index.d.ts.map} +1 -1
- package/packages/pi-ai/dist/models/generated/index.js +51 -0
- package/packages/pi-ai/dist/models/generated/index.js.map +1 -0
- package/packages/pi-ai/dist/models/generated/kimi-coding.d.ts +37 -0
- package/packages/pi-ai/dist/models/generated/kimi-coding.d.ts.map +1 -0
- package/packages/pi-ai/dist/models/generated/kimi-coding.js +39 -0
- package/packages/pi-ai/dist/models/generated/kimi-coding.js.map +1 -0
- package/packages/pi-ai/dist/models/generated/minimax-cn.d.ts +105 -0
- package/packages/pi-ai/dist/models/generated/minimax-cn.d.ts.map +1 -0
- package/packages/pi-ai/dist/models/generated/minimax-cn.js +107 -0
- package/packages/pi-ai/dist/models/generated/minimax-cn.js.map +1 -0
- package/packages/pi-ai/dist/models/generated/minimax.d.ts +105 -0
- package/packages/pi-ai/dist/models/generated/minimax.d.ts.map +1 -0
- package/packages/pi-ai/dist/models/generated/minimax.js +107 -0
- package/packages/pi-ai/dist/models/generated/minimax.js.map +1 -0
- package/packages/pi-ai/dist/models/generated/mistral.d.ts +445 -0
- package/packages/pi-ai/dist/models/generated/mistral.d.ts.map +1 -0
- package/packages/pi-ai/dist/models/generated/mistral.js +447 -0
- package/packages/pi-ai/dist/models/generated/mistral.js.map +1 -0
- package/packages/pi-ai/dist/models/generated/openai-codex.d.ts +139 -0
- package/packages/pi-ai/dist/models/generated/openai-codex.d.ts.map +1 -0
- package/packages/pi-ai/dist/models/generated/openai-codex.js +141 -0
- package/packages/pi-ai/dist/models/generated/openai-codex.js.map +1 -0
- package/packages/pi-ai/dist/models/generated/openai.d.ts +700 -0
- package/packages/pi-ai/dist/models/generated/openai.d.ts.map +1 -0
- package/packages/pi-ai/dist/models/generated/openai.js +702 -0
- package/packages/pi-ai/dist/models/generated/openai.js.map +1 -0
- package/packages/pi-ai/dist/models/generated/opencode-go.d.ts +122 -0
- package/packages/pi-ai/dist/models/generated/opencode-go.d.ts.map +1 -0
- package/packages/pi-ai/dist/models/generated/opencode-go.js +124 -0
- package/packages/pi-ai/dist/models/generated/opencode-go.js.map +1 -0
- package/packages/pi-ai/dist/models/generated/opencode.d.ts +530 -0
- package/packages/pi-ai/dist/models/generated/opencode.d.ts.map +1 -0
- package/packages/pi-ai/dist/models/generated/opencode.js +532 -0
- package/packages/pi-ai/dist/models/generated/opencode.js.map +1 -0
- package/packages/pi-ai/dist/models/generated/openrouter.d.ts +4270 -0
- package/packages/pi-ai/dist/models/generated/openrouter.d.ts.map +1 -0
- package/packages/pi-ai/dist/models/generated/openrouter.js +4272 -0
- package/packages/pi-ai/dist/models/generated/openrouter.js.map +1 -0
- package/packages/pi-ai/dist/models/generated/vercel-ai-gateway.d.ts +2604 -0
- package/packages/pi-ai/dist/models/generated/vercel-ai-gateway.d.ts.map +1 -0
- package/packages/pi-ai/dist/models/generated/vercel-ai-gateway.js +2606 -0
- package/packages/pi-ai/dist/models/generated/vercel-ai-gateway.js.map +1 -0
- package/packages/pi-ai/dist/models/generated/xai.d.ts +411 -0
- package/packages/pi-ai/dist/models/generated/xai.d.ts.map +1 -0
- package/packages/pi-ai/dist/models/generated/xai.js +413 -0
- package/packages/pi-ai/dist/models/generated/xai.js.map +1 -0
- package/packages/pi-ai/dist/models/generated/zai.d.ts +276 -0
- package/packages/pi-ai/dist/models/generated/zai.d.ts.map +1 -0
- package/packages/pi-ai/dist/models/generated/zai.js +239 -0
- package/packages/pi-ai/dist/models/generated/zai.js.map +1 -0
- package/packages/pi-ai/dist/models/index.d.ts +27 -0
- package/packages/pi-ai/dist/models/index.d.ts.map +1 -0
- package/packages/pi-ai/dist/models/index.js +80 -0
- package/packages/pi-ai/dist/models/index.js.map +1 -0
- package/packages/pi-ai/dist/models.d.ts +1 -36
- package/packages/pi-ai/dist/models.d.ts.map +1 -1
- package/packages/pi-ai/dist/models.generated.test.js +1 -2
- package/packages/pi-ai/dist/models.generated.test.js.map +1 -1
- package/packages/pi-ai/dist/models.js +3 -112
- package/packages/pi-ai/dist/models.js.map +1 -1
- package/packages/pi-ai/dist/models.test.js +6 -5
- package/packages/pi-ai/dist/models.test.js.map +1 -1
- package/packages/pi-ai/scripts/generate-models.ts +74 -40
- package/packages/pi-ai/src/index.ts +1 -9
- package/packages/pi-ai/src/models/capability-patches.ts +40 -0
- package/packages/pi-ai/src/{models.custom.ts → models/custom.ts} +4 -4
- package/packages/pi-ai/src/models/generated/amazon-bedrock.ts +1486 -0
- package/packages/pi-ai/src/models/generated/anthropic.ts +381 -0
- package/packages/pi-ai/src/models/generated/azure-openai-responses.ts +704 -0
- package/packages/pi-ai/src/models/generated/cerebras.ts +75 -0
- package/packages/pi-ai/src/models/generated/github-copilot.ts +446 -0
- package/packages/pi-ai/src/models/generated/google-antigravity.ts +160 -0
- package/packages/pi-ai/src/models/generated/google-gemini-cli.ts +109 -0
- package/packages/pi-ai/src/models/generated/google-vertex.ts +211 -0
- package/packages/pi-ai/src/models/generated/google.ts +466 -0
- package/packages/pi-ai/src/models/generated/groq.ts +313 -0
- package/packages/pi-ai/src/models/generated/huggingface.ts +349 -0
- package/packages/pi-ai/src/models/generated/index.ts +52 -0
- package/packages/pi-ai/src/models/generated/kimi-coding.ts +41 -0
- package/packages/pi-ai/src/models/generated/minimax-cn.ts +109 -0
- package/packages/pi-ai/src/models/generated/minimax.ts +109 -0
- package/packages/pi-ai/src/models/generated/mistral.ts +449 -0
- package/packages/pi-ai/src/models/generated/openai-codex.ts +143 -0
- package/packages/pi-ai/src/models/generated/openai.ts +704 -0
- package/packages/pi-ai/src/models/generated/opencode-go.ts +126 -0
- package/packages/pi-ai/src/models/generated/opencode.ts +534 -0
- package/packages/pi-ai/src/models/generated/openrouter.ts +4274 -0
- package/packages/pi-ai/src/models/generated/vercel-ai-gateway.ts +2608 -0
- package/packages/pi-ai/src/models/generated/xai.ts +415 -0
- package/packages/pi-ai/src/models/generated/zai.ts +241 -0
- package/packages/pi-ai/src/models/index.ts +106 -0
- package/packages/pi-ai/src/models.generated.test.ts +1 -2
- package/packages/pi-ai/src/models.test.ts +6 -5
- package/packages/pi-ai/src/models.ts +3 -153
- package/packages/pi-ai/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session.js +8 -2
- package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js +284 -10
- package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.d.ts +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.js +23 -9
- package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.d.ts +11 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.js +47 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.js.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/user-message.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/user-message.js +22 -22
- package/packages/pi-coding-agent/dist/modes/interactive/components/user-message.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +171 -24
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-ordering.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-ordering.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-ordering.test.js +38 -0
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-ordering.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts +13 -0
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +53 -6
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/packages/pi-coding-agent/src/core/agent-session.ts +12 -6
- package/packages/pi-coding-agent/src/core/chat-controller-ordering.test.ts +357 -10
- package/packages/pi-coding-agent/src/modes/interactive/components/assistant-message.ts +25 -10
- package/packages/pi-coding-agent/src/modes/interactive/components/chat-frame.ts +67 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/user-message.ts +23 -26
- package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +232 -47
- package/packages/pi-coding-agent/src/modes/interactive/interactive-mode-ordering.test.ts +44 -0
- package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +73 -6
- package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
- package/src/resources/extensions/gsd/auto-post-unit.ts +7 -3
- package/src/resources/extensions/gsd/bootstrap/register-extension.ts +15 -1
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +56 -3
- package/src/resources/extensions/gsd/ecosystem/gsd-extension-api.ts +228 -0
- package/src/resources/extensions/gsd/ecosystem/loader.ts +201 -0
- package/src/resources/extensions/gsd/tests/health-widget.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/register-hooks-depth-verification.test.ts +1 -1
- package/src/resources/extensions/gsd/types.ts +13 -0
- package/src/resources/extensions/gsd/workflow-logger.ts +2 -1
- package/packages/pi-ai/dist/models.custom.d.ts.map +0 -1
- package/packages/pi-ai/dist/models.custom.js.map +0 -1
- package/packages/pi-ai/dist/models.generated.js +0 -14343
- package/packages/pi-ai/dist/models.generated.js.map +0 -1
- package/packages/pi-ai/src/models.generated.ts +0 -14345
- /package/dist/web/standalone/.next/static/{ZMKM0OI0CrTgzKWbgfPOg → ZDXqgjuglsRoazETSKw1J}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{ZMKM0OI0CrTgzKWbgfPOg → ZDXqgjuglsRoazETSKw1J}/_ssgManifest.js +0 -0
|
@@ -199,7 +199,54 @@ test("chat-controller renders serverToolUse before trailing text matching conten
|
|
|
199
199
|
assert.equal(host.chatContainer.children[0]?.constructor?.name, "ToolExecutionComponent");
|
|
200
200
|
assert.equal(host.chatContainer.children[1]?.constructor?.name, "AssistantMessageComponent");
|
|
201
201
|
});
|
|
202
|
-
test("chat-controller
|
|
202
|
+
test("chat-controller replays final message_end content when result adds unstreamed trailing text", async () => {
|
|
203
|
+
globalThis[Symbol.for("@gsd/pi-coding-agent:theme")] = {
|
|
204
|
+
fg: (_key, text) => text,
|
|
205
|
+
bg: (_key, text) => text,
|
|
206
|
+
bold: (text) => text,
|
|
207
|
+
italic: (text) => text,
|
|
208
|
+
truncate: (text) => text,
|
|
209
|
+
};
|
|
210
|
+
const host = createHost();
|
|
211
|
+
host.getMarkdownThemeWithSettings = () => ({});
|
|
212
|
+
const tool = {
|
|
213
|
+
type: "toolCall",
|
|
214
|
+
id: "mcp-end-replay-1",
|
|
215
|
+
name: "read",
|
|
216
|
+
mcpServer: "filesystem",
|
|
217
|
+
arguments: { filePath: "/tmp/demo.txt" },
|
|
218
|
+
};
|
|
219
|
+
await handleAgentEvent(host, { type: "message_start", message: makeAssistant([]) });
|
|
220
|
+
const streamedContent = [
|
|
221
|
+
tool,
|
|
222
|
+
{ type: "thinking", thinking: "I am analyzing tool output..." },
|
|
223
|
+
];
|
|
224
|
+
await handleAgentEvent(host, {
|
|
225
|
+
type: "message_update",
|
|
226
|
+
message: makeAssistant(streamedContent),
|
|
227
|
+
assistantMessageEvent: {
|
|
228
|
+
type: "thinking_delta",
|
|
229
|
+
contentIndex: 1,
|
|
230
|
+
delta: "I am analyzing tool output...",
|
|
231
|
+
partial: makeAssistant(streamedContent),
|
|
232
|
+
},
|
|
233
|
+
});
|
|
234
|
+
assert.equal(host.chatContainer.children.length, 2, "streaming shows tool + thinking only");
|
|
235
|
+
assert.equal(host.chatContainer.children[0]?.constructor?.name, "ToolExecutionComponent");
|
|
236
|
+
assert.equal(host.chatContainer.children[1]?.constructor?.name, "AssistantMessageComponent");
|
|
237
|
+
// Final payload includes trailing text that never arrived as message_update.
|
|
238
|
+
const finalContent = [
|
|
239
|
+
tool,
|
|
240
|
+
{ type: "thinking", thinking: "I am analyzing tool output..." },
|
|
241
|
+
{ type: "text", text: "Correct anything important I missed?" },
|
|
242
|
+
];
|
|
243
|
+
await handleAgentEvent(host, { type: "message_end", message: makeAssistant(finalContent) });
|
|
244
|
+
assert.equal(host.chatContainer.children.length, 3, "message_end should replay and include trailing text segment");
|
|
245
|
+
assert.equal(host.chatContainer.children[0]?.constructor?.name, "ToolExecutionComponent");
|
|
246
|
+
assert.equal(host.chatContainer.children[1]?.constructor?.name, "AssistantMessageComponent");
|
|
247
|
+
assert.equal(host.chatContainer.children[2]?.constructor?.name, "AssistantMessageComponent");
|
|
248
|
+
});
|
|
249
|
+
test("chat-controller keeps pre-tool prose visible until post-tool prose arrives, then prunes it", async () => {
|
|
203
250
|
globalThis[Symbol.for("@gsd/pi-coding-agent:theme")] = {
|
|
204
251
|
fg: (_key, text) => text,
|
|
205
252
|
bg: (_key, text) => text,
|
|
@@ -230,7 +277,7 @@ test("chat-controller drops provisional pre-tool text for claude-code MCP turns"
|
|
|
230
277
|
});
|
|
231
278
|
assert.equal(host.chatContainer.children.length, 1);
|
|
232
279
|
assert.equal(host.chatContainer.children[0]?.constructor?.name, "AssistantMessageComponent");
|
|
233
|
-
// MCP tool appears; provisional text should
|
|
280
|
+
// MCP tool appears; provisional text should remain visible until post-tool prose exists.
|
|
234
281
|
await handleAgentEvent(host, {
|
|
235
282
|
type: "message_update",
|
|
236
283
|
message: makeAssistant([{ type: "text", text: "Let me inspect the workspace first." }, mcpTool]),
|
|
@@ -248,16 +295,21 @@ test("chat-controller drops provisional pre-tool text for claude-code MCP turns"
|
|
|
248
295
|
partial: makeAssistant([{ type: "text", text: "Let me inspect the workspace first." }, mcpTool]),
|
|
249
296
|
},
|
|
250
297
|
});
|
|
251
|
-
assert.equal(host.chatContainer.children.length,
|
|
252
|
-
assert.equal(host.chatContainer.children[0]?.constructor?.name, "
|
|
253
|
-
|
|
254
|
-
|
|
298
|
+
assert.equal(host.chatContainer.children.length, 2, "pre-tool prose should remain during tool-only window");
|
|
299
|
+
assert.equal(host.chatContainer.children[0]?.constructor?.name, "AssistantMessageComponent");
|
|
300
|
+
assert.equal(host.chatContainer.children[1]?.constructor?.name, "ToolExecutionComponent");
|
|
301
|
+
// Post-tool prose arrives: pre-tool prose should now be pruned.
|
|
302
|
+
const finalContent = [
|
|
303
|
+
{ type: "text", text: "Let me inspect the workspace first." },
|
|
304
|
+
mcpTool,
|
|
305
|
+
{ type: "text", text: "Which missing feature matters most to you?" },
|
|
306
|
+
];
|
|
255
307
|
await handleAgentEvent(host, {
|
|
256
308
|
type: "message_update",
|
|
257
309
|
message: makeAssistant(finalContent),
|
|
258
310
|
assistantMessageEvent: {
|
|
259
311
|
type: "text_delta",
|
|
260
|
-
contentIndex:
|
|
312
|
+
contentIndex: 2,
|
|
261
313
|
delta: "Which missing feature matters most to you?",
|
|
262
314
|
partial: makeAssistant(finalContent),
|
|
263
315
|
},
|
|
@@ -268,6 +320,123 @@ test("chat-controller drops provisional pre-tool text for claude-code MCP turns"
|
|
|
268
320
|
// Finalize to tear down any pinned spinner state.
|
|
269
321
|
await handleAgentEvent(host, { type: "message_end", message: makeAssistant(finalContent) });
|
|
270
322
|
});
|
|
323
|
+
test("chat-controller keeps pre-tool thinking visible for claude-code MCP turns without post-tool prose", async () => {
|
|
324
|
+
globalThis[Symbol.for("@gsd/pi-coding-agent:theme")] = {
|
|
325
|
+
fg: (_key, text) => text,
|
|
326
|
+
bg: (_key, text) => text,
|
|
327
|
+
bold: (text) => text,
|
|
328
|
+
italic: (text) => text,
|
|
329
|
+
truncate: (text) => text,
|
|
330
|
+
};
|
|
331
|
+
const host = createHost();
|
|
332
|
+
host.getMarkdownThemeWithSettings = () => ({});
|
|
333
|
+
const mcpTool = {
|
|
334
|
+
type: "toolCall",
|
|
335
|
+
id: "mcp-tool-thinking-1",
|
|
336
|
+
name: "read",
|
|
337
|
+
mcpServer: "filesystem",
|
|
338
|
+
arguments: { filePath: "/tmp/demo.txt" },
|
|
339
|
+
};
|
|
340
|
+
await handleAgentEvent(host, { type: "message_start", message: makeAssistant([]) });
|
|
341
|
+
const thinkingOnly = [{ type: "thinking", thinking: "I should inspect the workspace." }];
|
|
342
|
+
await handleAgentEvent(host, {
|
|
343
|
+
type: "message_update",
|
|
344
|
+
message: makeAssistant(thinkingOnly),
|
|
345
|
+
assistantMessageEvent: {
|
|
346
|
+
type: "thinking_delta",
|
|
347
|
+
contentIndex: 0,
|
|
348
|
+
delta: "I should inspect the workspace.",
|
|
349
|
+
partial: makeAssistant(thinkingOnly),
|
|
350
|
+
},
|
|
351
|
+
});
|
|
352
|
+
assert.equal(host.chatContainer.children.length, 1);
|
|
353
|
+
assert.equal(host.chatContainer.children[0]?.constructor?.name, "AssistantMessageComponent");
|
|
354
|
+
await handleAgentEvent(host, {
|
|
355
|
+
type: "message_update",
|
|
356
|
+
message: makeAssistant([thinkingOnly[0], mcpTool]),
|
|
357
|
+
assistantMessageEvent: {
|
|
358
|
+
type: "toolcall_end",
|
|
359
|
+
contentIndex: 1,
|
|
360
|
+
toolCall: {
|
|
361
|
+
...mcpTool,
|
|
362
|
+
externalResult: {
|
|
363
|
+
content: [{ type: "text", text: "file preview" }],
|
|
364
|
+
details: {},
|
|
365
|
+
isError: false,
|
|
366
|
+
},
|
|
367
|
+
},
|
|
368
|
+
partial: makeAssistant([thinkingOnly[0], mcpTool]),
|
|
369
|
+
},
|
|
370
|
+
});
|
|
371
|
+
assert.equal(host.chatContainer.children.length, 2, "thinking should remain visible while only tool output is present");
|
|
372
|
+
assert.equal(host.chatContainer.children[0]?.constructor?.name, "AssistantMessageComponent");
|
|
373
|
+
assert.equal(host.chatContainer.children[1]?.constructor?.name, "ToolExecutionComponent");
|
|
374
|
+
await handleAgentEvent(host, { type: "message_end", message: makeAssistant([thinkingOnly[0], mcpTool]) });
|
|
375
|
+
});
|
|
376
|
+
test("chat-controller keeps pre-tool question text for claude-code MCP when post-tool prose exists", async () => {
|
|
377
|
+
globalThis[Symbol.for("@gsd/pi-coding-agent:theme")] = {
|
|
378
|
+
fg: (_key, text) => text,
|
|
379
|
+
bg: (_key, text) => text,
|
|
380
|
+
bold: (text) => text,
|
|
381
|
+
italic: (text) => text,
|
|
382
|
+
truncate: (text) => text,
|
|
383
|
+
};
|
|
384
|
+
const host = createHost();
|
|
385
|
+
host.getMarkdownThemeWithSettings = () => ({});
|
|
386
|
+
const mcpTool = {
|
|
387
|
+
type: "toolCall",
|
|
388
|
+
id: "mcp-tool-question-1",
|
|
389
|
+
name: "glob",
|
|
390
|
+
mcpServer: "filesystem",
|
|
391
|
+
arguments: { pattern: "**/*" },
|
|
392
|
+
};
|
|
393
|
+
await handleAgentEvent(host, { type: "message_start", message: makeAssistant([]) });
|
|
394
|
+
const questionText = { type: "text", text: "Which file should I inspect?" };
|
|
395
|
+
await handleAgentEvent(host, {
|
|
396
|
+
type: "message_update",
|
|
397
|
+
message: makeAssistant([questionText]),
|
|
398
|
+
assistantMessageEvent: {
|
|
399
|
+
type: "text_delta",
|
|
400
|
+
contentIndex: 0,
|
|
401
|
+
delta: questionText.text,
|
|
402
|
+
partial: makeAssistant([questionText]),
|
|
403
|
+
},
|
|
404
|
+
});
|
|
405
|
+
await handleAgentEvent(host, {
|
|
406
|
+
type: "message_update",
|
|
407
|
+
message: makeAssistant([questionText, mcpTool]),
|
|
408
|
+
assistantMessageEvent: {
|
|
409
|
+
type: "toolcall_end",
|
|
410
|
+
contentIndex: 1,
|
|
411
|
+
toolCall: {
|
|
412
|
+
...mcpTool,
|
|
413
|
+
externalResult: {
|
|
414
|
+
content: [{ type: "text", text: "glob output" }],
|
|
415
|
+
details: {},
|
|
416
|
+
isError: false,
|
|
417
|
+
},
|
|
418
|
+
},
|
|
419
|
+
partial: makeAssistant([questionText, mcpTool]),
|
|
420
|
+
},
|
|
421
|
+
});
|
|
422
|
+
const postTool = { type: "text", text: "I'll review that next." };
|
|
423
|
+
const finalContent = [questionText, mcpTool, postTool];
|
|
424
|
+
await handleAgentEvent(host, {
|
|
425
|
+
type: "message_update",
|
|
426
|
+
message: makeAssistant(finalContent),
|
|
427
|
+
assistantMessageEvent: {
|
|
428
|
+
type: "text_delta",
|
|
429
|
+
contentIndex: 2,
|
|
430
|
+
delta: postTool.text,
|
|
431
|
+
partial: makeAssistant(finalContent),
|
|
432
|
+
},
|
|
433
|
+
});
|
|
434
|
+
assert.equal(host.chatContainer.children.length, 3, "question text should remain alongside MCP tool and post-tool prose");
|
|
435
|
+
assert.equal(host.chatContainer.children[0]?.constructor?.name, "AssistantMessageComponent", "pre-tool question stays visible");
|
|
436
|
+
assert.equal(host.chatContainer.children[1]?.constructor?.name, "ToolExecutionComponent", "tool renders in the middle");
|
|
437
|
+
assert.equal(host.chatContainer.children[2]?.constructor?.name, "AssistantMessageComponent", "post-tool prose renders last");
|
|
438
|
+
await handleAgentEvent(host, { type: "message_end", message: makeAssistant(finalContent) });
|
|
439
|
+
});
|
|
271
440
|
test("chat-controller prunes orphaned provisional text after claude-code sub-turn shrink when MCP tools appear", async () => {
|
|
272
441
|
globalThis[Symbol.for("@gsd/pi-coding-agent:theme")] = {
|
|
273
442
|
fg: (_key, text) => text,
|
|
@@ -310,7 +479,7 @@ test("chat-controller prunes orphaned provisional text after claude-code sub-tur
|
|
|
310
479
|
},
|
|
311
480
|
});
|
|
312
481
|
assert.equal(host.chatContainer.children.length, 2, "shrink keeps prior text until MCP tool context appears");
|
|
313
|
-
// MCP tool appears in sub-turn 2:
|
|
482
|
+
// MCP tool appears in sub-turn 2: tool-only windows keep provisional prose visible.
|
|
314
483
|
await handleAgentEvent(host, {
|
|
315
484
|
type: "message_update",
|
|
316
485
|
message: makeAssistant([{ type: "text", text: "New provisional text before tool." }, mcpTool]),
|
|
@@ -328,8 +497,10 @@ test("chat-controller prunes orphaned provisional text after claude-code sub-tur
|
|
|
328
497
|
partial: makeAssistant([{ type: "text", text: "New provisional text before tool." }, mcpTool]),
|
|
329
498
|
},
|
|
330
499
|
});
|
|
331
|
-
assert.equal(host.chatContainer.children.length,
|
|
332
|
-
assert.equal(host.chatContainer.children[0]?.constructor?.name, "
|
|
500
|
+
assert.equal(host.chatContainer.children.length, 3, "stale text runs are deferred until post-tool prose arrives");
|
|
501
|
+
assert.equal(host.chatContainer.children[0]?.constructor?.name, "AssistantMessageComponent");
|
|
502
|
+
assert.equal(host.chatContainer.children[1]?.constructor?.name, "AssistantMessageComponent");
|
|
503
|
+
assert.equal(host.chatContainer.children[2]?.constructor?.name, "ToolExecutionComponent");
|
|
333
504
|
const finalContent = [mcpTool, { type: "text", text: "Final visible question?" }];
|
|
334
505
|
await handleAgentEvent(host, {
|
|
335
506
|
type: "message_update",
|
|
@@ -346,6 +517,109 @@ test("chat-controller prunes orphaned provisional text after claude-code sub-tur
|
|
|
346
517
|
assert.equal(host.chatContainer.children[1]?.constructor?.name, "AssistantMessageComponent");
|
|
347
518
|
await handleAgentEvent(host, { type: "message_end", message: makeAssistant(finalContent) });
|
|
348
519
|
});
|
|
520
|
+
test("chat-controller prunes orphans from multiple sub-turn shrinks before MCP post-tool prose", async () => {
|
|
521
|
+
globalThis[Symbol.for("@gsd/pi-coding-agent:theme")] = {
|
|
522
|
+
fg: (_key, text) => text,
|
|
523
|
+
bg: (_key, text) => text,
|
|
524
|
+
bold: (text) => text,
|
|
525
|
+
italic: (text) => text,
|
|
526
|
+
truncate: (text) => text,
|
|
527
|
+
};
|
|
528
|
+
const host = createHost();
|
|
529
|
+
host.getMarkdownThemeWithSettings = () => ({});
|
|
530
|
+
const mcpTool = {
|
|
531
|
+
type: "toolCall",
|
|
532
|
+
id: "mcp-tool-multi-shrink-1",
|
|
533
|
+
name: "glob",
|
|
534
|
+
mcpServer: "filesystem",
|
|
535
|
+
arguments: { pattern: "**/*" },
|
|
536
|
+
};
|
|
537
|
+
await handleAgentEvent(host, { type: "message_start", message: makeAssistant([]) });
|
|
538
|
+
// Sub-turn 1: 3 text blocks (merged into one text-run).
|
|
539
|
+
const subTurn1 = [
|
|
540
|
+
{ type: "text", text: "First provisional A." },
|
|
541
|
+
{ type: "text", text: "First provisional B." },
|
|
542
|
+
{ type: "text", text: "First provisional C." },
|
|
543
|
+
];
|
|
544
|
+
await handleAgentEvent(host, {
|
|
545
|
+
type: "message_update",
|
|
546
|
+
message: makeAssistant(subTurn1),
|
|
547
|
+
assistantMessageEvent: {
|
|
548
|
+
type: "text_delta",
|
|
549
|
+
contentIndex: 2,
|
|
550
|
+
delta: "First provisional C.",
|
|
551
|
+
partial: makeAssistant(subTurn1),
|
|
552
|
+
},
|
|
553
|
+
});
|
|
554
|
+
assert.equal(host.chatContainer.children.length, 1, "first sub-turn renders 1 text-run");
|
|
555
|
+
// Sub-turn 2 (first shrink 3 → 2 blocks).
|
|
556
|
+
const subTurn2 = [
|
|
557
|
+
{ type: "text", text: "Second provisional A." },
|
|
558
|
+
{ type: "text", text: "Second provisional B." },
|
|
559
|
+
];
|
|
560
|
+
await handleAgentEvent(host, {
|
|
561
|
+
type: "message_update",
|
|
562
|
+
message: makeAssistant(subTurn2),
|
|
563
|
+
assistantMessageEvent: {
|
|
564
|
+
type: "text_delta",
|
|
565
|
+
contentIndex: 1,
|
|
566
|
+
delta: "Second provisional B.",
|
|
567
|
+
partial: makeAssistant(subTurn2),
|
|
568
|
+
},
|
|
569
|
+
});
|
|
570
|
+
assert.equal(host.chatContainer.children.length, 2, "first shrink appends, keeps prior text as frozen history");
|
|
571
|
+
// Sub-turn 3 (second shrink 2 → 1 block). This is the critical step —
|
|
572
|
+
// without orphan accumulation, sub-turn 1's orphaned segment would be
|
|
573
|
+
// dropped from tracking here and later strand in the container.
|
|
574
|
+
const subTurn3 = [{ type: "text", text: "Third provisional." }];
|
|
575
|
+
await handleAgentEvent(host, {
|
|
576
|
+
type: "message_update",
|
|
577
|
+
message: makeAssistant(subTurn3),
|
|
578
|
+
assistantMessageEvent: {
|
|
579
|
+
type: "text_delta",
|
|
580
|
+
contentIndex: 0,
|
|
581
|
+
delta: "Third provisional.",
|
|
582
|
+
partial: makeAssistant(subTurn3),
|
|
583
|
+
},
|
|
584
|
+
});
|
|
585
|
+
assert.equal(host.chatContainer.children.length, 3, "second shrink appends again, still no prune (no post-tool text)");
|
|
586
|
+
// MCP tool appears — tool-only window still keeps provisional prose visible.
|
|
587
|
+
await handleAgentEvent(host, {
|
|
588
|
+
type: "message_update",
|
|
589
|
+
message: makeAssistant([{ type: "text", text: "Third provisional." }, mcpTool]),
|
|
590
|
+
assistantMessageEvent: {
|
|
591
|
+
type: "toolcall_end",
|
|
592
|
+
contentIndex: 1,
|
|
593
|
+
toolCall: {
|
|
594
|
+
...mcpTool,
|
|
595
|
+
externalResult: {
|
|
596
|
+
content: [{ type: "text", text: "glob output" }],
|
|
597
|
+
details: {},
|
|
598
|
+
isError: false,
|
|
599
|
+
},
|
|
600
|
+
},
|
|
601
|
+
partial: makeAssistant([{ type: "text", text: "Third provisional." }, mcpTool]),
|
|
602
|
+
},
|
|
603
|
+
});
|
|
604
|
+
assert.equal(host.chatContainer.children.length, 4, "tool-only window keeps all three provisional text-runs");
|
|
605
|
+
// Final post-tool text arrives — prune must drop ALL three pre-tool
|
|
606
|
+
// provisional text-runs across both shrinks, leaving only tool + final text.
|
|
607
|
+
const finalContent = [mcpTool, { type: "text", text: "Final answer." }];
|
|
608
|
+
await handleAgentEvent(host, {
|
|
609
|
+
type: "message_update",
|
|
610
|
+
message: makeAssistant(finalContent),
|
|
611
|
+
assistantMessageEvent: {
|
|
612
|
+
type: "text_delta",
|
|
613
|
+
contentIndex: 1,
|
|
614
|
+
delta: "Final answer.",
|
|
615
|
+
partial: makeAssistant(finalContent),
|
|
616
|
+
},
|
|
617
|
+
});
|
|
618
|
+
assert.equal(host.chatContainer.children.length, 2, "all pre-tool provisional segments from every shrink must be pruned once post-tool prose arrives");
|
|
619
|
+
assert.equal(host.chatContainer.children[0]?.constructor?.name, "ToolExecutionComponent");
|
|
620
|
+
assert.equal(host.chatContainer.children[1]?.constructor?.name, "AssistantMessageComponent");
|
|
621
|
+
await handleAgentEvent(host, { type: "message_end", message: makeAssistant(finalContent) });
|
|
622
|
+
});
|
|
349
623
|
test("chat-controller pins latest assistant text above editor when tool calls are present", async () => {
|
|
350
624
|
globalThis[Symbol.for("@gsd/pi-coding-agent:theme")] = {
|
|
351
625
|
fg: (_key, text) => text,
|