@code-yeongyu/senpi 2026.7.16 → 2026.7.17-2
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/CHANGELOG.md +65 -0
- package/dist/core/dynamic-prompt/build.d.ts +7 -0
- package/dist/core/dynamic-prompt/build.d.ts.map +1 -1
- package/dist/core/dynamic-prompt/build.js +5 -0
- package/dist/core/dynamic-prompt/build.js.map +1 -1
- package/dist/core/dynamic-prompt/workstation.d.ts +35 -0
- package/dist/core/dynamic-prompt/workstation.d.ts.map +1 -0
- package/dist/core/dynamic-prompt/workstation.js +81 -0
- package/dist/core/dynamic-prompt/workstation.js.map +1 -0
- package/dist/core/extensions/builtin/anthropic-web-search/index.d.ts +6 -2
- package/dist/core/extensions/builtin/anthropic-web-search/index.d.ts.map +1 -1
- package/dist/core/extensions/builtin/anthropic-web-search/index.js +73 -5
- package/dist/core/extensions/builtin/anthropic-web-search/index.js.map +1 -1
- package/dist/core/extensions/builtin/goal/command-registration.d.ts +1 -0
- package/dist/core/extensions/builtin/goal/command-registration.d.ts.map +1 -1
- package/dist/core/extensions/builtin/goal/command-registration.js +4 -5
- package/dist/core/extensions/builtin/goal/command-registration.js.map +1 -1
- package/dist/core/extensions/builtin/goal/elapsed-ticker.d.ts +43 -0
- package/dist/core/extensions/builtin/goal/elapsed-ticker.d.ts.map +1 -0
- package/dist/core/extensions/builtin/goal/elapsed-ticker.js +58 -0
- package/dist/core/extensions/builtin/goal/elapsed-ticker.js.map +1 -0
- package/dist/core/extensions/builtin/goal/index.d.ts.map +1 -1
- package/dist/core/extensions/builtin/goal/index.js +39 -14
- package/dist/core/extensions/builtin/goal/index.js.map +1 -1
- package/dist/core/extensions/builtin/goal/tool-registration.d.ts +1 -0
- package/dist/core/extensions/builtin/goal/tool-registration.d.ts.map +1 -1
- package/dist/core/extensions/builtin/goal/tool-registration.js +3 -4
- package/dist/core/extensions/builtin/goal/tool-registration.js.map +1 -1
- package/dist/core/extensions/builtin/goal/ui.d.ts +2 -2
- package/dist/core/extensions/builtin/goal/ui.d.ts.map +1 -1
- package/dist/core/extensions/builtin/goal/ui.js +8 -4
- package/dist/core/extensions/builtin/goal/ui.js.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/claude-fable-5.d.ts.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/claude-fable-5.js +5 -1
- package/dist/core/extensions/builtin/prompt-preset/claude-fable-5.js.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/claude-opus-4-5.d.ts.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/claude-opus-4-5.js +5 -1
- package/dist/core/extensions/builtin/prompt-preset/claude-opus-4-5.js.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/claude-opus-4-6.d.ts.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/claude-opus-4-6.js +5 -1
- package/dist/core/extensions/builtin/prompt-preset/claude-opus-4-6.js.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/claude-opus-4-7.d.ts.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/claude-opus-4-7.js +5 -1
- package/dist/core/extensions/builtin/prompt-preset/claude-opus-4-7.js.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/claude-opus-4-8.d.ts.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/claude-opus-4-8.js +5 -1
- package/dist/core/extensions/builtin/prompt-preset/claude-opus-4-8.js.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/glm-5-2.js +1 -1
- package/dist/core/extensions/builtin/prompt-preset/glm-5-2.js.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/gpt-5.2.js +1 -1
- package/dist/core/extensions/builtin/prompt-preset/gpt-5.2.js.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/gpt-5.3-codex.js +1 -1
- package/dist/core/extensions/builtin/prompt-preset/gpt-5.3-codex.js.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/gpt-5.4.js +1 -1
- package/dist/core/extensions/builtin/prompt-preset/gpt-5.4.js.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/gpt-5.5.js +1 -1
- package/dist/core/extensions/builtin/prompt-preset/gpt-5.5.js.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/gpt-5.6.js +1 -1
- package/dist/core/extensions/builtin/prompt-preset/gpt-5.6.js.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/gpt-5.js +1 -1
- package/dist/core/extensions/builtin/prompt-preset/gpt-5.js.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/kimi-k2-6.js +1 -1
- package/dist/core/extensions/builtin/prompt-preset/kimi-k2-6.js.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/kimi-k2-7.js +1 -1
- package/dist/core/extensions/builtin/prompt-preset/kimi-k2-7.js.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/kimi-k3.d.ts +3 -0
- package/dist/core/extensions/builtin/prompt-preset/kimi-k3.d.ts.map +1 -0
- package/dist/core/extensions/builtin/prompt-preset/kimi-k3.js +14 -0
- package/dist/core/extensions/builtin/prompt-preset/kimi-k3.js.map +1 -0
- package/dist/core/extensions/builtin/prompt-preset/presets.d.ts.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/presets.js +13 -0
- package/dist/core/extensions/builtin/prompt-preset/presets.js.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/settings.d.ts +1 -1
- package/dist/core/extensions/builtin/prompt-preset/settings.d.ts.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/settings.js +1 -0
- package/dist/core/extensions/builtin/prompt-preset/settings.js.map +1 -1
- package/dist/core/extensions/builtin/webfetch/webfetch/renderers.d.ts.map +1 -1
- package/dist/core/extensions/builtin/webfetch/webfetch/renderers.js +2 -1
- package/dist/core/extensions/builtin/webfetch/webfetch/renderers.js.map +1 -1
- package/dist/core/extensions/builtin/webfetch/webfetch/tool.d.ts +27 -0
- package/dist/core/extensions/builtin/webfetch/webfetch/tool.d.ts.map +1 -1
- package/dist/core/extensions/builtin/webfetch/webfetch/tool.js +60 -1
- package/dist/core/extensions/builtin/webfetch/webfetch/tool.js.map +1 -1
- package/dist/core/extensions/types.d.ts +5 -0
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/model-config.d.ts +5 -0
- package/dist/core/model-config.d.ts.map +1 -1
- package/dist/core/model-config.js +1 -0
- package/dist/core/model-config.js.map +1 -1
- package/dist/modes/interactive/components/tool-execution-renderer.d.ts.map +1 -1
- package/dist/modes/interactive/components/tool-execution-renderer.js +1 -0
- package/dist/modes/interactive/components/tool-execution-renderer.js.map +1 -1
- package/docs/settings.md +1 -1
- package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
- package/examples/extensions/custom-provider-anthropic/package.json +1 -1
- package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
- package/examples/extensions/gondolin/package-lock.json +2 -2
- package/examples/extensions/gondolin/package.json +1 -1
- package/examples/extensions/sandbox/package-lock.json +2 -2
- package/examples/extensions/sandbox/package.json +1 -1
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +1 -1
- package/node_modules/@code-yeongyu/senpi-codemode/CHANGELOG.md +37 -0
- package/node_modules/@code-yeongyu/senpi-codemode/package.json +3 -3
- package/node_modules/@code-yeongyu/senpi-codemode/src/index.ts +59 -19
- package/node_modules/@code-yeongyu/senpi-codemode/src/prompt/eval-prompt.ts +68 -2
- package/node_modules/@code-yeongyu/senpi-codemode/src/tool/eval-tool.ts +6 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/tool/render.ts +6 -0
- package/node_modules/@earendil-works/pi-agent-core/package.json +2 -2
- package/node_modules/@earendil-works/pi-ai/README.md +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.js +58 -7
- package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-completions.d.ts +2 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-completions.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-completions.js +6 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-completions.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/models.generated.d.ts +70 -110
- package/node_modules/@earendil-works/pi-ai/dist/models.generated.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/kimi-coding.models.d.ts +26 -0
- package/node_modules/@earendil-works/pi-ai/dist/providers/kimi-coding.models.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/kimi-coding.models.js +6 -0
- package/node_modules/@earendil-works/pi-ai/dist/providers/kimi-coding.models.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/moonshotai-cn.models.js +3 -3
- package/node_modules/@earendil-works/pi-ai/dist/providers/moonshotai-cn.models.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/moonshotai.models.js +3 -3
- package/node_modules/@earendil-works/pi-ai/dist/providers/moonshotai.models.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/opencode-go.models.d.ts +44 -0
- package/node_modules/@earendil-works/pi-ai/dist/providers/opencode-go.models.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/opencode-go.models.js +36 -0
- package/node_modules/@earendil-works/pi-ai/dist/providers/opencode-go.models.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/openrouter.models.js +20 -20
- package/node_modules/@earendil-works/pi-ai/dist/providers/openrouter.models.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/xai.models.d.ts +0 -110
- package/node_modules/@earendil-works/pi-ai/dist/providers/xai.models.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/xai.models.js +0 -90
- package/node_modules/@earendil-works/pi-ai/dist/providers/xai.models.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/types.d.ts +14 -0
- package/node_modules/@earendil-works/pi-ai/dist/types.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/types.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/utils/tool-schema-compat.d.ts +19 -0
- package/node_modules/@earendil-works/pi-ai/dist/utils/tool-schema-compat.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/utils/tool-schema-compat.js +171 -0
- package/node_modules/@earendil-works/pi-ai/dist/utils/tool-schema-compat.js.map +1 -0
- package/node_modules/@earendil-works/pi-ai/package.json +1 -1
- package/node_modules/@earendil-works/pi-pty/package.json +1 -1
- package/node_modules/@earendil-works/pi-tui/package.json +1 -1
- package/package.json +6 -6
|
@@ -152,6 +152,12 @@ function getAnthropicCompat(model) {
|
|
|
152
152
|
supportsForcedToolChoice: model.compat?.supportsForcedToolChoice ?? !CLAUDE_FABLE_OR_MYTHOS_MODEL_ID.test(model.id),
|
|
153
153
|
allowEmptySignature: model.compat?.allowEmptySignature ?? false,
|
|
154
154
|
supportsToolReferences: model.compat?.supportsToolReferences ?? defaultSupportsToolReferences(model),
|
|
155
|
+
// Default: first-party Anthropic only. Anthropic-compatible providers
|
|
156
|
+
// (kimi-coding, fireworks, copilot, gateways) may execute the server-side
|
|
157
|
+
// search but reject the replayed server_tool_use / web_search_tool_result
|
|
158
|
+
// blocks on the next request (kimi-coding 400s with `tool_call_id is not
|
|
159
|
+
// found`).
|
|
160
|
+
supportsWebSearch: model.compat?.supportsWebSearch ?? isAnthropicApiBaseUrl(model.baseUrl),
|
|
155
161
|
};
|
|
156
162
|
}
|
|
157
163
|
/**
|
|
@@ -227,6 +233,23 @@ function lastAnthropicFallbackBoundary(content) {
|
|
|
227
233
|
function isAnthropicServerToolUseBlock(raw) {
|
|
228
234
|
return isRecord(raw) && raw.type === "server_tool_use" && typeof raw.id === "string";
|
|
229
235
|
}
|
|
236
|
+
// Only tool_use-shaped provider-native blocks (server_tool_use, mcp_tool_use)
|
|
237
|
+
// stream their input via input_json_delta. Result-shaped blocks must replay
|
|
238
|
+
// byte-for-byte (encrypted_content), so never merge an `input` into them.
|
|
239
|
+
function isProviderNativeToolUseBlock(raw) {
|
|
240
|
+
return isRecord(raw) && (raw.type === "server_tool_use" || raw.type === "mcp_tool_use");
|
|
241
|
+
}
|
|
242
|
+
// Endpoints without `supportsWebSearch` reject replayed web-search server-tool
|
|
243
|
+
// blocks (kimi-coding 400s with `tool_call_id is not found`), wedging every
|
|
244
|
+
// subsequent request of the session. Dropping the pair loses the searched
|
|
245
|
+
// context but keeps the conversation usable.
|
|
246
|
+
function isAnthropicWebSearchReplayBlock(raw) {
|
|
247
|
+
if (!isRecord(raw))
|
|
248
|
+
return false;
|
|
249
|
+
if (raw.type === "web_search_tool_result")
|
|
250
|
+
return true;
|
|
251
|
+
return raw.type === "server_tool_use" && raw.name === "web_search";
|
|
252
|
+
}
|
|
230
253
|
// tool_use ids referenced by server-tool result blocks in content[0, boundary).
|
|
231
254
|
// A pre-boundary `server_tool_use` whose id is absent here is unpaired — the
|
|
232
255
|
// fallback interrupted the declined attempt before its result arrived — so
|
|
@@ -339,27 +362,28 @@ function rejectsComputerUseBeta(model) {
|
|
|
339
362
|
return ((model.provider === "cloudflare-ai-gateway" && model.baseUrl.includes("anthropic")) ||
|
|
340
363
|
matchesModelMarker(model, UNSUPPORTED_NATIVE_COMPUTER_TOOL_MODEL_MARKERS));
|
|
341
364
|
}
|
|
365
|
+
function isAnthropicWebSearchToolType(toolType) {
|
|
366
|
+
return toolType.startsWith("web_search_");
|
|
367
|
+
}
|
|
342
368
|
function sanitizeUnsupportedNativeTools(model, params) {
|
|
343
369
|
const payload = params;
|
|
344
370
|
const headers = stringRecord(payload.headers);
|
|
345
371
|
const headerSanitization = rejectsComputerUseBeta(model)
|
|
346
372
|
? removeComputerUseBetaHeader(headers)
|
|
347
373
|
: { changed: false };
|
|
374
|
+
const rejectsNativeWebSearch = !getAnthropicCompat(model).supportsWebSearch;
|
|
348
375
|
const tools = payload.tools;
|
|
349
376
|
const sanitized = { ...payload };
|
|
350
377
|
let changed = false;
|
|
351
|
-
const removedToolNames = new Set();
|
|
352
378
|
if (Array.isArray(tools)) {
|
|
353
379
|
const supportedTools = [];
|
|
354
380
|
for (const tool of tools) {
|
|
355
381
|
const hookTool = tool;
|
|
356
382
|
if (isRecord(hookTool) &&
|
|
357
383
|
typeof hookTool.type === "string" &&
|
|
358
|
-
rejectsNativeComputerTool(model, hookTool.type)
|
|
384
|
+
(rejectsNativeComputerTool(model, hookTool.type) ||
|
|
385
|
+
(rejectsNativeWebSearch && isAnthropicWebSearchToolType(hookTool.type)))) {
|
|
359
386
|
changed = true;
|
|
360
|
-
if (typeof hookTool.name === "string") {
|
|
361
|
-
removedToolNames.add(hookTool.name);
|
|
362
|
-
}
|
|
363
387
|
continue;
|
|
364
388
|
}
|
|
365
389
|
supportedTools.push(tool);
|
|
@@ -384,7 +408,10 @@ function sanitizeUnsupportedNativeTools(model, params) {
|
|
|
384
408
|
}
|
|
385
409
|
if (changed && isRecord(sanitized.tool_choice)) {
|
|
386
410
|
const toolChoiceName = sanitized.tool_choice.name;
|
|
387
|
-
const
|
|
411
|
+
const hasSelectedTool = typeof toolChoiceName === "string" &&
|
|
412
|
+
Array.isArray(sanitized.tools) &&
|
|
413
|
+
sanitized.tools.some((tool) => isRecord(tool) && tool.name === toolChoiceName);
|
|
414
|
+
const shouldRemoveToolChoice = sanitized.tools === undefined || (typeof toolChoiceName === "string" && !hasSelectedTool);
|
|
388
415
|
if (shouldRemoveToolChoice) {
|
|
389
416
|
delete sanitized.tool_choice;
|
|
390
417
|
}
|
|
@@ -764,6 +791,12 @@ export const stream = (model, context, options) => {
|
|
|
764
791
|
partial: output,
|
|
765
792
|
});
|
|
766
793
|
}
|
|
794
|
+
else if (block && block.type === "providerNative" && isProviderNativeToolUseBlock(block.raw)) {
|
|
795
|
+
// Server-side tool blocks (server_tool_use) stream their input
|
|
796
|
+
// the same way tool_use does; the block captured at
|
|
797
|
+
// content_block_start still has `input: {}`.
|
|
798
|
+
block.partialJson = (block.partialJson ?? "") + event.delta.partial_json;
|
|
799
|
+
}
|
|
767
800
|
}
|
|
768
801
|
else if (event.delta.type === "signature_delta") {
|
|
769
802
|
const index = blocks.findIndex((b) => b.index === event.index);
|
|
@@ -807,6 +840,13 @@ export const stream = (model, context, options) => {
|
|
|
807
840
|
partial: output,
|
|
808
841
|
});
|
|
809
842
|
}
|
|
843
|
+
else if (block.type === "providerNative") {
|
|
844
|
+
const partialJson = block.partialJson;
|
|
845
|
+
delete block.partialJson;
|
|
846
|
+
if (partialJson !== undefined && isRecord(block.raw)) {
|
|
847
|
+
block.raw = { ...block.raw, input: parseStreamingJson(partialJson) };
|
|
848
|
+
}
|
|
849
|
+
}
|
|
810
850
|
}
|
|
811
851
|
}
|
|
812
852
|
else if (event.type === "message_delta") {
|
|
@@ -859,6 +899,13 @@ export const stream = (model, context, options) => {
|
|
|
859
899
|
catch (error) {
|
|
860
900
|
for (const block of output.content) {
|
|
861
901
|
delete block.index;
|
|
902
|
+
// An aborted stream never reaches content_block_stop; keep whatever
|
|
903
|
+
// provider-native input accumulated, mirroring toolCall's partial
|
|
904
|
+
// arguments.
|
|
905
|
+
const scratch = block.partialJson;
|
|
906
|
+
if (block.type === "providerNative" && scratch !== undefined && isRecord(block.raw)) {
|
|
907
|
+
block.raw = { ...block.raw, input: parseStreamingJson(scratch) };
|
|
908
|
+
}
|
|
862
909
|
// partialJson is only a streaming scratch buffer; never persist it.
|
|
863
910
|
delete block.partialJson;
|
|
864
911
|
}
|
|
@@ -1199,6 +1246,7 @@ function convertMessages(transformedMessages, model, isOAuthToken, cacheControl,
|
|
|
1199
1246
|
// Tool calls from a declined pre-fallback attempt are dropped from their
|
|
1200
1247
|
// assistant turn below; drop their tool_results in lockstep so none dangle.
|
|
1201
1248
|
const discardedFallbackToolCallIds = collectDiscardedFallbackToolCallIds(transformedMessages, model);
|
|
1249
|
+
const rejectsNativeWebSearchReplay = !getAnthropicCompat(model).supportsWebSearch;
|
|
1202
1250
|
for (let i = 0; i < transformedMessages.length; i++) {
|
|
1203
1251
|
const msg = transformedMessages[i];
|
|
1204
1252
|
if (msg.role === "user") {
|
|
@@ -1320,8 +1368,11 @@ function convertMessages(transformedMessages, model, isOAuthToken, cacheControl,
|
|
|
1320
1368
|
});
|
|
1321
1369
|
}
|
|
1322
1370
|
else if (block.type === "providerNative") {
|
|
1323
|
-
if (isSameModel &&
|
|
1371
|
+
if (isSameModel &&
|
|
1372
|
+
isReplayableAnthropicProviderNativeBlock(block.raw) &&
|
|
1373
|
+
!(rejectsNativeWebSearchReplay && isAnthropicWebSearchReplayBlock(block.raw))) {
|
|
1324
1374
|
blocks.push(block.raw);
|
|
1375
|
+
}
|
|
1325
1376
|
}
|
|
1326
1377
|
}
|
|
1327
1378
|
if (blocks.length === 0)
|