gsd-pi 2.23.0 → 2.25.0
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/README.md +2 -1
- package/dist/cli.js +12 -3
- package/dist/headless.d.ts +4 -0
- package/dist/headless.js +118 -10
- package/dist/help-text.js +22 -7
- package/dist/models-resolver.d.ts +0 -11
- package/dist/models-resolver.js +0 -15
- package/dist/resource-loader.d.ts +0 -1
- package/dist/resource-loader.js +64 -18
- package/dist/resources/GSD-WORKFLOW.md +12 -9
- package/dist/resources/extensions/bg-shell/overlay.ts +18 -17
- package/dist/resources/extensions/get-secrets-from-user.ts +5 -23
- package/dist/resources/extensions/gsd/activity-log.ts +5 -3
- package/dist/resources/extensions/gsd/auto-dispatch.ts +51 -2
- package/dist/resources/extensions/gsd/auto-prompts.ts +87 -0
- package/dist/resources/extensions/gsd/auto-recovery.ts +41 -2
- package/dist/resources/extensions/gsd/auto-worktree.ts +134 -4
- package/dist/resources/extensions/gsd/auto.ts +307 -77
- package/dist/resources/extensions/gsd/cache.ts +3 -1
- package/dist/resources/extensions/gsd/commands.ts +176 -10
- package/dist/resources/extensions/gsd/complexity.ts +1 -0
- package/dist/resources/extensions/gsd/dashboard-overlay.ts +38 -0
- package/dist/resources/extensions/gsd/doctor.ts +58 -11
- package/dist/resources/extensions/gsd/exit-command.ts +2 -2
- package/dist/resources/extensions/gsd/git-service.ts +74 -14
- package/dist/resources/extensions/gsd/gitignore.ts +1 -0
- package/dist/resources/extensions/gsd/gsd-db.ts +78 -1
- package/dist/resources/extensions/gsd/guided-flow.ts +109 -12
- package/dist/resources/extensions/gsd/index.ts +48 -2
- package/dist/resources/extensions/gsd/memory-extractor.ts +352 -0
- package/dist/resources/extensions/gsd/memory-store.ts +441 -0
- package/dist/resources/extensions/gsd/migrate/command.ts +2 -2
- package/dist/resources/extensions/gsd/parallel-eligibility.ts +233 -0
- package/dist/resources/extensions/gsd/parallel-merge.ts +156 -0
- package/dist/resources/extensions/gsd/parallel-orchestrator.ts +496 -0
- package/dist/resources/extensions/gsd/preferences.ts +65 -1
- package/dist/resources/extensions/gsd/prompts/complete-slice.md +1 -1
- package/dist/resources/extensions/gsd/prompts/discuss-headless.md +86 -0
- package/dist/resources/extensions/gsd/prompts/discuss.md +4 -4
- package/dist/resources/extensions/gsd/prompts/execute-task.md +1 -1
- package/dist/resources/extensions/gsd/prompts/guided-discuss-milestone.md +1 -1
- package/dist/resources/extensions/gsd/prompts/guided-discuss-slice.md +1 -1
- package/dist/resources/extensions/gsd/prompts/plan-slice.md +1 -1
- package/dist/resources/extensions/gsd/prompts/queue.md +1 -1
- package/dist/resources/extensions/gsd/prompts/reassess-roadmap.md +1 -1
- package/dist/resources/extensions/gsd/prompts/research-slice.md +1 -1
- package/dist/resources/extensions/gsd/prompts/validate-milestone.md +40 -61
- package/dist/resources/extensions/gsd/provider-error-pause.ts +29 -2
- package/dist/resources/extensions/gsd/session-status-io.ts +197 -0
- package/dist/resources/extensions/gsd/state.ts +72 -30
- package/dist/resources/extensions/gsd/tests/agent-end-provider-error.test.ts +81 -0
- package/dist/resources/extensions/gsd/tests/auto-budget-alerts.test.ts +20 -3
- package/dist/resources/extensions/gsd/tests/auto-preflight.test.ts +1 -0
- package/dist/resources/extensions/gsd/tests/auto-recovery.test.ts +256 -2
- package/dist/resources/extensions/gsd/tests/auto-worktree-milestone-merge.test.ts +34 -0
- package/dist/resources/extensions/gsd/tests/auto-worktree.test.ts +58 -0
- package/dist/resources/extensions/gsd/tests/complete-milestone.test.ts +8 -1
- package/dist/resources/extensions/gsd/tests/derive-state-db.test.ts +9 -15
- package/dist/resources/extensions/gsd/tests/derive-state-deps.test.ts +9 -0
- package/dist/resources/extensions/gsd/tests/derive-state-draft.test.ts +8 -0
- package/dist/resources/extensions/gsd/tests/derive-state.test.ts +14 -0
- package/dist/resources/extensions/gsd/tests/git-service.test.ts +70 -4
- package/dist/resources/extensions/gsd/tests/gsd-db.test.ts +2 -2
- package/dist/resources/extensions/gsd/tests/integration-mixed-milestones.test.ts +8 -0
- package/dist/resources/extensions/gsd/tests/md-importer.test.ts +2 -3
- package/dist/resources/extensions/gsd/tests/memory-extractor.test.ts +180 -0
- package/dist/resources/extensions/gsd/tests/memory-store.test.ts +345 -0
- package/dist/resources/extensions/gsd/tests/migrate-writer-integration.test.ts +5 -5
- package/dist/resources/extensions/gsd/tests/parallel-orchestration.test.ts +656 -0
- package/dist/resources/extensions/gsd/tests/parallel-workers-multi-milestone-e2e.test.ts +354 -0
- package/dist/resources/extensions/gsd/tests/queue-reorder-e2e.test.ts +1 -0
- package/dist/resources/extensions/gsd/tests/smart-entry-draft.test.ts +1 -1
- package/dist/resources/extensions/gsd/tests/validate-milestone.test.ts +316 -0
- package/dist/resources/extensions/gsd/tests/visualizer-data.test.ts +147 -2
- package/dist/resources/extensions/gsd/tests/visualizer-overlay.test.ts +88 -10
- package/dist/resources/extensions/gsd/tests/visualizer-views.test.ts +314 -87
- package/dist/resources/extensions/gsd/tests/worker-registry.test.ts +148 -0
- package/dist/resources/extensions/gsd/triage-ui.ts +1 -1
- package/dist/resources/extensions/gsd/types.ts +15 -1
- package/dist/resources/extensions/gsd/visualizer-data.ts +291 -10
- package/dist/resources/extensions/gsd/visualizer-overlay.ts +237 -28
- package/dist/resources/extensions/gsd/visualizer-views.ts +462 -48
- package/dist/resources/extensions/gsd/worktree.ts +9 -2
- package/dist/resources/extensions/search-the-web/native-search.ts +15 -5
- package/dist/resources/extensions/subagent/index.ts +5 -0
- package/dist/resources/extensions/subagent/worker-registry.ts +99 -0
- package/dist/update-check.d.ts +9 -0
- package/dist/update-check.js +97 -0
- package/package.json +6 -1
- package/packages/pi-agent-core/dist/agent-loop.js +2 -0
- package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
- package/packages/pi-agent-core/src/agent-loop.ts +2 -0
- package/packages/pi-ai/dist/providers/anthropic.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic.js +55 -7
- package/packages/pi-ai/dist/providers/anthropic.js.map +1 -1
- package/packages/pi-ai/dist/providers/azure-openai-responses.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/azure-openai-responses.js +12 -4
- package/packages/pi-ai/dist/providers/azure-openai-responses.js.map +1 -1
- package/packages/pi-ai/dist/providers/google-vertex.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/google-vertex.js +21 -9
- package/packages/pi-ai/dist/providers/google-vertex.js.map +1 -1
- package/packages/pi-ai/dist/providers/mistral.js +3 -0
- package/packages/pi-ai/dist/providers/mistral.js.map +1 -1
- package/packages/pi-ai/dist/providers/openai-completions.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/openai-completions.js +12 -4
- package/packages/pi-ai/dist/providers/openai-completions.js.map +1 -1
- package/packages/pi-ai/dist/providers/openai-responses.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/openai-responses.js +12 -4
- package/packages/pi-ai/dist/providers/openai-responses.js.map +1 -1
- package/packages/pi-ai/dist/types.d.ts +23 -1
- package/packages/pi-ai/dist/types.d.ts.map +1 -1
- package/packages/pi-ai/dist/types.js.map +1 -1
- package/packages/pi-ai/src/providers/anthropic.ts +59 -9
- package/packages/pi-ai/src/providers/azure-openai-responses.ts +16 -4
- package/packages/pi-ai/src/providers/google-vertex.ts +32 -17
- package/packages/pi-ai/src/providers/mistral.ts +3 -0
- package/packages/pi-ai/src/providers/openai-completions.ts +16 -4
- package/packages/pi-ai/src/providers/openai-responses.ts +16 -4
- package/packages/pi-ai/src/types.ts +19 -1
- package/packages/pi-coding-agent/dist/core/agent-session.js +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/settings-manager.js +1 -1
- package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js +17 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts +4 -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 +72 -0
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/packages/pi-coding-agent/src/core/agent-session.ts +1 -1
- package/packages/pi-coding-agent/src/core/settings-manager.ts +2 -2
- package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +18 -0
- package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +84 -0
- package/scripts/postinstall.js +7 -109
- package/src/resources/GSD-WORKFLOW.md +12 -9
- package/src/resources/extensions/bg-shell/overlay.ts +18 -17
- package/src/resources/extensions/get-secrets-from-user.ts +5 -23
- package/src/resources/extensions/gsd/activity-log.ts +5 -3
- package/src/resources/extensions/gsd/auto-dispatch.ts +51 -2
- package/src/resources/extensions/gsd/auto-prompts.ts +87 -0
- package/src/resources/extensions/gsd/auto-recovery.ts +41 -2
- package/src/resources/extensions/gsd/auto-worktree.ts +134 -4
- package/src/resources/extensions/gsd/auto.ts +307 -77
- package/src/resources/extensions/gsd/cache.ts +3 -1
- package/src/resources/extensions/gsd/commands.ts +176 -10
- package/src/resources/extensions/gsd/complexity.ts +1 -0
- package/src/resources/extensions/gsd/dashboard-overlay.ts +38 -0
- package/src/resources/extensions/gsd/doctor.ts +58 -11
- package/src/resources/extensions/gsd/exit-command.ts +2 -2
- package/src/resources/extensions/gsd/git-service.ts +74 -14
- package/src/resources/extensions/gsd/gitignore.ts +1 -0
- package/src/resources/extensions/gsd/gsd-db.ts +78 -1
- package/src/resources/extensions/gsd/guided-flow.ts +109 -12
- package/src/resources/extensions/gsd/index.ts +48 -2
- package/src/resources/extensions/gsd/memory-extractor.ts +352 -0
- package/src/resources/extensions/gsd/memory-store.ts +441 -0
- package/src/resources/extensions/gsd/migrate/command.ts +2 -2
- package/src/resources/extensions/gsd/parallel-eligibility.ts +233 -0
- package/src/resources/extensions/gsd/parallel-merge.ts +156 -0
- package/src/resources/extensions/gsd/parallel-orchestrator.ts +496 -0
- package/src/resources/extensions/gsd/preferences.ts +65 -1
- package/src/resources/extensions/gsd/prompts/complete-slice.md +1 -1
- package/src/resources/extensions/gsd/prompts/discuss-headless.md +86 -0
- package/src/resources/extensions/gsd/prompts/discuss.md +4 -4
- package/src/resources/extensions/gsd/prompts/execute-task.md +1 -1
- package/src/resources/extensions/gsd/prompts/guided-discuss-milestone.md +1 -1
- package/src/resources/extensions/gsd/prompts/guided-discuss-slice.md +1 -1
- package/src/resources/extensions/gsd/prompts/plan-slice.md +1 -1
- package/src/resources/extensions/gsd/prompts/queue.md +1 -1
- package/src/resources/extensions/gsd/prompts/reassess-roadmap.md +1 -1
- package/src/resources/extensions/gsd/prompts/research-slice.md +1 -1
- package/src/resources/extensions/gsd/prompts/validate-milestone.md +40 -61
- package/src/resources/extensions/gsd/provider-error-pause.ts +29 -2
- package/src/resources/extensions/gsd/session-status-io.ts +197 -0
- package/src/resources/extensions/gsd/state.ts +72 -30
- package/src/resources/extensions/gsd/tests/agent-end-provider-error.test.ts +81 -0
- package/src/resources/extensions/gsd/tests/auto-budget-alerts.test.ts +20 -3
- package/src/resources/extensions/gsd/tests/auto-preflight.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +256 -2
- package/src/resources/extensions/gsd/tests/auto-worktree-milestone-merge.test.ts +34 -0
- package/src/resources/extensions/gsd/tests/auto-worktree.test.ts +58 -0
- package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +8 -1
- package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +9 -15
- package/src/resources/extensions/gsd/tests/derive-state-deps.test.ts +9 -0
- package/src/resources/extensions/gsd/tests/derive-state-draft.test.ts +8 -0
- package/src/resources/extensions/gsd/tests/derive-state.test.ts +14 -0
- package/src/resources/extensions/gsd/tests/git-service.test.ts +70 -4
- package/src/resources/extensions/gsd/tests/gsd-db.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/integration-mixed-milestones.test.ts +8 -0
- package/src/resources/extensions/gsd/tests/md-importer.test.ts +2 -3
- package/src/resources/extensions/gsd/tests/memory-extractor.test.ts +180 -0
- package/src/resources/extensions/gsd/tests/memory-store.test.ts +345 -0
- package/src/resources/extensions/gsd/tests/migrate-writer-integration.test.ts +5 -5
- package/src/resources/extensions/gsd/tests/parallel-orchestration.test.ts +656 -0
- package/src/resources/extensions/gsd/tests/parallel-workers-multi-milestone-e2e.test.ts +354 -0
- package/src/resources/extensions/gsd/tests/queue-reorder-e2e.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/smart-entry-draft.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/validate-milestone.test.ts +316 -0
- package/src/resources/extensions/gsd/tests/visualizer-data.test.ts +147 -2
- package/src/resources/extensions/gsd/tests/visualizer-overlay.test.ts +88 -10
- package/src/resources/extensions/gsd/tests/visualizer-views.test.ts +314 -87
- package/src/resources/extensions/gsd/tests/worker-registry.test.ts +148 -0
- package/src/resources/extensions/gsd/triage-ui.ts +1 -1
- package/src/resources/extensions/gsd/types.ts +15 -1
- package/src/resources/extensions/gsd/visualizer-data.ts +291 -10
- package/src/resources/extensions/gsd/visualizer-overlay.ts +237 -28
- package/src/resources/extensions/gsd/visualizer-views.ts +462 -48
- package/src/resources/extensions/gsd/worktree.ts +9 -2
- package/src/resources/extensions/search-the-web/native-search.ts +15 -5
- package/src/resources/extensions/subagent/index.ts +5 -0
- package/src/resources/extensions/subagent/worker-registry.ts +99 -0
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
// Lazy-loaded: Anthropic SDK (~500ms) is imported on first use, not at startup.
|
|
2
|
+
// This avoids penalizing users who don't use Anthropic models.
|
|
3
|
+
import type Anthropic from "@anthropic-ai/sdk";
|
|
2
4
|
import type {
|
|
3
5
|
ContentBlockParam,
|
|
4
6
|
MessageCreateParamsStreaming,
|
|
@@ -14,6 +16,7 @@ import type {
|
|
|
14
16
|
ImageContent,
|
|
15
17
|
Message,
|
|
16
18
|
Model,
|
|
19
|
+
ServerToolUseContent,
|
|
17
20
|
SimpleStreamOptions,
|
|
18
21
|
StopReason,
|
|
19
22
|
StreamFunction,
|
|
@@ -23,6 +26,7 @@ import type {
|
|
|
23
26
|
Tool,
|
|
24
27
|
ToolCall,
|
|
25
28
|
ToolResultMessage,
|
|
29
|
+
WebSearchResultContent,
|
|
26
30
|
} from "../types.js";
|
|
27
31
|
import { AssistantMessageEventStream } from "../utils/event-stream.js";
|
|
28
32
|
import { parseStreamingJson } from "../utils/json-parse.js";
|
|
@@ -32,6 +36,15 @@ import { buildCopilotDynamicHeaders, hasCopilotVisionInput } from "./github-copi
|
|
|
32
36
|
import { adjustMaxTokensForThinking, buildBaseOptions } from "./simple-options.js";
|
|
33
37
|
import { transformMessages } from "./transform-messages.js";
|
|
34
38
|
|
|
39
|
+
let _AnthropicClass: typeof Anthropic | undefined;
|
|
40
|
+
async function getAnthropicClass(): Promise<typeof Anthropic> {
|
|
41
|
+
if (!_AnthropicClass) {
|
|
42
|
+
const mod = await import("@anthropic-ai/sdk");
|
|
43
|
+
_AnthropicClass = mod.default;
|
|
44
|
+
}
|
|
45
|
+
return _AnthropicClass;
|
|
46
|
+
}
|
|
47
|
+
|
|
35
48
|
/**
|
|
36
49
|
* Resolve cache retention preference.
|
|
37
50
|
* Defaults to "short" and uses PI_CACHE_RETENTION for backward compatibility.
|
|
@@ -265,7 +278,7 @@ export const streamAnthropic: StreamFunction<"anthropic-messages", AnthropicOpti
|
|
|
265
278
|
});
|
|
266
279
|
}
|
|
267
280
|
|
|
268
|
-
const { client, isOAuthToken } = createClient(
|
|
281
|
+
const { client, isOAuthToken } = await createClient(
|
|
269
282
|
model,
|
|
270
283
|
apiKey,
|
|
271
284
|
options?.interleavedThinking ?? true,
|
|
@@ -280,7 +293,7 @@ export const streamAnthropic: StreamFunction<"anthropic-messages", AnthropicOpti
|
|
|
280
293
|
const anthropicStream = client.messages.stream({ ...params, stream: true }, { signal: options?.signal });
|
|
281
294
|
stream.push({ type: "start", partial: output });
|
|
282
295
|
|
|
283
|
-
type Block = (ThinkingContent | TextContent | (ToolCall & { partialJson: string })) & { index: number };
|
|
296
|
+
type Block = (ThinkingContent | TextContent | (ToolCall & { partialJson: string }) | ServerToolUseContent | WebSearchResultContent) & { index: number };
|
|
284
297
|
const blocks = output.content as Block[];
|
|
285
298
|
|
|
286
299
|
for await (const event of anthropicStream) {
|
|
@@ -336,6 +349,27 @@ export const streamAnthropic: StreamFunction<"anthropic-messages", AnthropicOpti
|
|
|
336
349
|
};
|
|
337
350
|
output.content.push(block);
|
|
338
351
|
stream.push({ type: "toolcall_start", contentIndex: output.content.length - 1, partial: output });
|
|
352
|
+
} else if ((event.content_block as any).type === "server_tool_use") {
|
|
353
|
+
const serverBlock = event.content_block as any;
|
|
354
|
+
const block: Block = {
|
|
355
|
+
type: "serverToolUse",
|
|
356
|
+
id: serverBlock.id,
|
|
357
|
+
name: serverBlock.name,
|
|
358
|
+
input: serverBlock.input,
|
|
359
|
+
index: event.index,
|
|
360
|
+
};
|
|
361
|
+
output.content.push(block);
|
|
362
|
+
stream.push({ type: "server_tool_use", contentIndex: output.content.length - 1, partial: output });
|
|
363
|
+
} else if ((event.content_block as any).type === "web_search_tool_result") {
|
|
364
|
+
const resultBlock = event.content_block as any;
|
|
365
|
+
const block: Block = {
|
|
366
|
+
type: "webSearchResult",
|
|
367
|
+
toolUseId: resultBlock.tool_use_id,
|
|
368
|
+
content: resultBlock.content,
|
|
369
|
+
index: event.index,
|
|
370
|
+
};
|
|
371
|
+
output.content.push(block);
|
|
372
|
+
stream.push({ type: "web_search_result", contentIndex: output.content.length - 1, partial: output });
|
|
339
373
|
}
|
|
340
374
|
} else if (event.type === "content_block_delta") {
|
|
341
375
|
if (event.delta.type === "text_delta") {
|
|
@@ -412,6 +446,7 @@ export const streamAnthropic: StreamFunction<"anthropic-messages", AnthropicOpti
|
|
|
412
446
|
partial: output,
|
|
413
447
|
});
|
|
414
448
|
}
|
|
449
|
+
// serverToolUse and webSearchResult blocks just need index cleanup (already emitted on start)
|
|
415
450
|
}
|
|
416
451
|
} else if (event.type === "message_delta") {
|
|
417
452
|
if (event.delta.stop_reason) {
|
|
@@ -455,7 +490,8 @@ export const streamAnthropic: StreamFunction<"anthropic-messages", AnthropicOpti
|
|
|
455
490
|
if (model.provider === "alibaba-coding-plan") {
|
|
456
491
|
output.errorMessage = `[alibaba-coding-plan] ${output.errorMessage}`;
|
|
457
492
|
}
|
|
458
|
-
|
|
493
|
+
const AnthropicSdk = _AnthropicClass;
|
|
494
|
+
if (AnthropicSdk && error instanceof AnthropicSdk.APIError && error.headers) {
|
|
459
495
|
const retryAfterMs = extractRetryAfterMs(error.headers, error.message);
|
|
460
496
|
if (retryAfterMs !== undefined) {
|
|
461
497
|
output.retryAfterMs = retryAfterMs;
|
|
@@ -548,13 +584,14 @@ function isOAuthToken(apiKey: string): boolean {
|
|
|
548
584
|
return apiKey.includes("sk-ant-oat");
|
|
549
585
|
}
|
|
550
586
|
|
|
551
|
-
function createClient(
|
|
587
|
+
async function createClient(
|
|
552
588
|
model: Model<"anthropic-messages">,
|
|
553
589
|
apiKey: string,
|
|
554
590
|
interleavedThinking: boolean,
|
|
555
591
|
optionsHeaders?: Record<string, string>,
|
|
556
592
|
dynamicHeaders?: Record<string, string>,
|
|
557
|
-
): { client: Anthropic; isOAuthToken: boolean } {
|
|
593
|
+
): Promise<{ client: Anthropic; isOAuthToken: boolean }> {
|
|
594
|
+
const AnthropicClass = await getAnthropicClass();
|
|
558
595
|
// Adaptive thinking models (Opus 4.6, Sonnet 4.6) have interleaved thinking built-in.
|
|
559
596
|
// The beta header is deprecated on Opus 4.6 and redundant on Sonnet 4.6, so skip it.
|
|
560
597
|
const needsInterleavedBeta = interleavedThinking && !supportsAdaptiveThinking(model.id);
|
|
@@ -566,7 +603,7 @@ function createClient(
|
|
|
566
603
|
betaFeatures.push("interleaved-thinking-2025-05-14");
|
|
567
604
|
}
|
|
568
605
|
|
|
569
|
-
const client = new
|
|
606
|
+
const client = new AnthropicClass({
|
|
570
607
|
apiKey: null,
|
|
571
608
|
authToken: apiKey,
|
|
572
609
|
baseURL: model.baseUrl,
|
|
@@ -595,7 +632,7 @@ function createClient(
|
|
|
595
632
|
|
|
596
633
|
// OAuth: Bearer auth, Claude Code identity headers
|
|
597
634
|
if (isOAuthToken(apiKey)) {
|
|
598
|
-
const client = new
|
|
635
|
+
const client = new AnthropicClass({
|
|
599
636
|
apiKey: null,
|
|
600
637
|
authToken: apiKey,
|
|
601
638
|
baseURL: model.baseUrl,
|
|
@@ -619,7 +656,7 @@ function createClient(
|
|
|
619
656
|
// API key auth
|
|
620
657
|
// Alibaba Coding Plan uses Bearer token auth instead of x-api-key
|
|
621
658
|
const isAlibabaProvider = model.provider === "alibaba-coding-plan";
|
|
622
|
-
const client = new
|
|
659
|
+
const client = new AnthropicClass({
|
|
623
660
|
apiKey: isAlibabaProvider ? null : apiKey,
|
|
624
661
|
authToken: isAlibabaProvider ? apiKey : undefined,
|
|
625
662
|
baseURL: model.baseUrl,
|
|
@@ -827,6 +864,19 @@ function convertMessages(
|
|
|
827
864
|
name: isOAuthToken ? toClaudeCodeName(block.name) : block.name,
|
|
828
865
|
input: block.arguments ?? {},
|
|
829
866
|
});
|
|
867
|
+
} else if (block.type === "serverToolUse") {
|
|
868
|
+
blocks.push({
|
|
869
|
+
type: "server_tool_use",
|
|
870
|
+
id: block.id,
|
|
871
|
+
name: block.name,
|
|
872
|
+
input: block.input ?? {},
|
|
873
|
+
} as any);
|
|
874
|
+
} else if (block.type === "webSearchResult") {
|
|
875
|
+
blocks.push({
|
|
876
|
+
type: "web_search_tool_result",
|
|
877
|
+
tool_use_id: block.toolUseId,
|
|
878
|
+
content: block.content,
|
|
879
|
+
} as any);
|
|
830
880
|
}
|
|
831
881
|
}
|
|
832
882
|
if (blocks.length === 0) continue;
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
// Lazy-loaded: OpenAI SDK (AzureOpenAI) is imported on first use, not at startup.
|
|
2
|
+
// This avoids penalizing users who don't use Azure OpenAI models.
|
|
3
|
+
import type { AzureOpenAI } from "openai";
|
|
2
4
|
import type { ResponseCreateParamsStreaming } from "openai/resources/responses/responses.js";
|
|
3
5
|
import { getEnvApiKey } from "../env-api-keys.js";
|
|
4
6
|
import { supportsXhigh } from "../models.js";
|
|
@@ -15,6 +17,15 @@ import { AssistantMessageEventStream } from "../utils/event-stream.js";
|
|
|
15
17
|
import { convertResponsesMessages, convertResponsesTools, processResponsesStream } from "./openai-responses-shared.js";
|
|
16
18
|
import { buildBaseOptions, clampReasoning } from "./simple-options.js";
|
|
17
19
|
|
|
20
|
+
let _AzureOpenAIClass: typeof AzureOpenAI | undefined;
|
|
21
|
+
async function getAzureOpenAIClass(): Promise<typeof AzureOpenAI> {
|
|
22
|
+
if (!_AzureOpenAIClass) {
|
|
23
|
+
const mod = await import("openai");
|
|
24
|
+
_AzureOpenAIClass = mod.AzureOpenAI;
|
|
25
|
+
}
|
|
26
|
+
return _AzureOpenAIClass;
|
|
27
|
+
}
|
|
28
|
+
|
|
18
29
|
/**
|
|
19
30
|
* Clamp reasoning effort for models that don't support all levels.
|
|
20
31
|
* gpt-5.x models don't support "minimal" — map to "low".
|
|
@@ -94,7 +105,7 @@ export const streamAzureOpenAIResponses: StreamFunction<"azure-openai-responses"
|
|
|
94
105
|
try {
|
|
95
106
|
// Create Azure OpenAI client
|
|
96
107
|
const apiKey = options?.apiKey || getEnvApiKey(model.provider) || "";
|
|
97
|
-
const client = createClient(model, apiKey, options);
|
|
108
|
+
const client = await createClient(model, apiKey, options);
|
|
98
109
|
let params = buildParams(model, context, options, deploymentName);
|
|
99
110
|
const nextParams = await options?.onPayload?.(params, model);
|
|
100
111
|
if (nextParams !== undefined) {
|
|
@@ -188,7 +199,7 @@ function resolveAzureConfig(
|
|
|
188
199
|
};
|
|
189
200
|
}
|
|
190
201
|
|
|
191
|
-
function createClient(model: Model<"azure-openai-responses">, apiKey: string, options?: AzureOpenAIResponsesOptions) {
|
|
202
|
+
async function createClient(model: Model<"azure-openai-responses">, apiKey: string, options?: AzureOpenAIResponsesOptions) {
|
|
192
203
|
if (!apiKey) {
|
|
193
204
|
if (!process.env.AZURE_OPENAI_API_KEY) {
|
|
194
205
|
throw new Error(
|
|
@@ -205,8 +216,9 @@ function createClient(model: Model<"azure-openai-responses">, apiKey: string, op
|
|
|
205
216
|
}
|
|
206
217
|
|
|
207
218
|
const { baseUrl, apiVersion } = resolveAzureConfig(model, options);
|
|
219
|
+
const AzureOpenAIClass = await getAzureOpenAIClass();
|
|
208
220
|
|
|
209
|
-
return new
|
|
221
|
+
return new AzureOpenAIClass({
|
|
210
222
|
apiKey,
|
|
211
223
|
apiVersion,
|
|
212
224
|
dangerouslyAllowBrowser: true,
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
1
|
+
// Lazy-loaded: Google GenAI SDK is imported on first use, not at startup.
|
|
2
|
+
// This avoids penalizing users who don't use Google Vertex models.
|
|
3
|
+
import type { GoogleGenAI } from "@google/genai";
|
|
4
|
+
import type {
|
|
5
|
+
GenerateContentConfig,
|
|
6
|
+
GenerateContentParameters,
|
|
7
|
+
ThinkingConfig,
|
|
7
8
|
} from "@google/genai";
|
|
8
9
|
import { calculateCost } from "../models.js";
|
|
9
10
|
import type {
|
|
@@ -33,6 +34,15 @@ import {
|
|
|
33
34
|
} from "./google-shared.js";
|
|
34
35
|
import { buildBaseOptions, clampReasoning } from "./simple-options.js";
|
|
35
36
|
|
|
37
|
+
let _GoogleVertexClass: typeof GoogleGenAI | undefined;
|
|
38
|
+
async function getGoogleVertexClass(): Promise<typeof GoogleGenAI> {
|
|
39
|
+
if (!_GoogleVertexClass) {
|
|
40
|
+
const mod = await import("@google/genai");
|
|
41
|
+
_GoogleVertexClass = mod.GoogleGenAI;
|
|
42
|
+
}
|
|
43
|
+
return _GoogleVertexClass;
|
|
44
|
+
}
|
|
45
|
+
|
|
36
46
|
export interface GoogleVertexOptions extends StreamOptions {
|
|
37
47
|
toolChoice?: "auto" | "none" | "any";
|
|
38
48
|
thinking?: {
|
|
@@ -46,12 +56,14 @@ export interface GoogleVertexOptions extends StreamOptions {
|
|
|
46
56
|
|
|
47
57
|
const API_VERSION = "v1";
|
|
48
58
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
59
|
+
// ThinkingLevel is a string enum where each value equals its key name.
|
|
60
|
+
// Using string literals avoids importing the SDK at module load time.
|
|
61
|
+
const THINKING_LEVEL_MAP: Record<GoogleThinkingLevel, string> = {
|
|
62
|
+
THINKING_LEVEL_UNSPECIFIED: "THINKING_LEVEL_UNSPECIFIED",
|
|
63
|
+
MINIMAL: "MINIMAL",
|
|
64
|
+
LOW: "LOW",
|
|
65
|
+
MEDIUM: "MEDIUM",
|
|
66
|
+
HIGH: "HIGH",
|
|
55
67
|
};
|
|
56
68
|
|
|
57
69
|
// Counter for generating unique tool call IDs
|
|
@@ -86,7 +98,7 @@ export const streamGoogleVertex: StreamFunction<"google-vertex", GoogleVertexOpt
|
|
|
86
98
|
try {
|
|
87
99
|
const project = resolveProject(options);
|
|
88
100
|
const location = resolveLocation(options);
|
|
89
|
-
const client = createClient(model, project, location, options?.headers);
|
|
101
|
+
const client = await createClient(model, project, location, options?.headers);
|
|
90
102
|
let params = buildParams(model, context, options);
|
|
91
103
|
const nextParams = await options?.onPayload?.(params, model);
|
|
92
104
|
if (nextParams !== undefined) {
|
|
@@ -318,12 +330,12 @@ export const streamSimpleGoogleVertex: StreamFunction<"google-vertex", SimpleStr
|
|
|
318
330
|
} satisfies GoogleVertexOptions);
|
|
319
331
|
};
|
|
320
332
|
|
|
321
|
-
function createClient(
|
|
333
|
+
async function createClient(
|
|
322
334
|
model: Model<"google-vertex">,
|
|
323
335
|
project: string,
|
|
324
336
|
location: string,
|
|
325
337
|
optionsHeaders?: Record<string, string>,
|
|
326
|
-
): GoogleGenAI {
|
|
338
|
+
): Promise<GoogleGenAI> {
|
|
327
339
|
const httpOptions: { headers?: Record<string, string> } = {};
|
|
328
340
|
|
|
329
341
|
if (model.headers || optionsHeaders) {
|
|
@@ -331,8 +343,9 @@ function createClient(
|
|
|
331
343
|
}
|
|
332
344
|
|
|
333
345
|
const hasHttpOptions = Object.values(httpOptions).some(Boolean);
|
|
346
|
+
const GoogleGenAIClass = await getGoogleVertexClass();
|
|
334
347
|
|
|
335
|
-
return new
|
|
348
|
+
return new GoogleGenAIClass({
|
|
336
349
|
vertexai: true,
|
|
337
350
|
project,
|
|
338
351
|
location,
|
|
@@ -393,7 +406,9 @@ function buildParams(
|
|
|
393
406
|
if (options.thinking?.enabled && model.reasoning) {
|
|
394
407
|
const thinkingConfig: ThinkingConfig = { includeThoughts: true };
|
|
395
408
|
if (options.thinking.level !== undefined) {
|
|
396
|
-
|
|
409
|
+
// Cast safe: string values match ThinkingLevel enum values exactly
|
|
410
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
411
|
+
thinkingConfig.thinkingLevel = THINKING_LEVEL_MAP[options.thinking.level] as any;
|
|
397
412
|
} else if (options.thinking.budgetTokens !== undefined) {
|
|
398
413
|
thinkingConfig.thinkingBudget = options.thinking.budgetTokens;
|
|
399
414
|
}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
// Lazy-loaded: OpenAI SDK is imported on first use, not at startup.
|
|
2
|
+
// This avoids penalizing users who don't use OpenAI models.
|
|
3
|
+
import type OpenAI from "openai";
|
|
2
4
|
import type {
|
|
3
5
|
ChatCompletionAssistantMessageParam,
|
|
4
6
|
ChatCompletionChunk,
|
|
@@ -33,6 +35,15 @@ import { buildCopilotDynamicHeaders, hasCopilotVisionInput } from "./github-copi
|
|
|
33
35
|
import { buildBaseOptions, clampReasoning } from "./simple-options.js";
|
|
34
36
|
import { transformMessages } from "./transform-messages.js";
|
|
35
37
|
|
|
38
|
+
let _OpenAICompletionsClass: typeof OpenAI | undefined;
|
|
39
|
+
async function getOpenAICompletionsClass(): Promise<typeof OpenAI> {
|
|
40
|
+
if (!_OpenAICompletionsClass) {
|
|
41
|
+
const mod = await import("openai");
|
|
42
|
+
_OpenAICompletionsClass = mod.default;
|
|
43
|
+
}
|
|
44
|
+
return _OpenAICompletionsClass;
|
|
45
|
+
}
|
|
46
|
+
|
|
36
47
|
/**
|
|
37
48
|
* Check if conversation messages contain tool calls or tool results.
|
|
38
49
|
* This is needed because Anthropic (via proxy) requires the tools param
|
|
@@ -85,7 +96,7 @@ export const streamOpenAICompletions: StreamFunction<"openai-completions", OpenA
|
|
|
85
96
|
|
|
86
97
|
try {
|
|
87
98
|
const apiKey = options?.apiKey || getEnvApiKey(model.provider) || "";
|
|
88
|
-
const client = createClient(model, context, apiKey, options?.headers);
|
|
99
|
+
const client = await createClient(model, context, apiKey, options?.headers);
|
|
89
100
|
let params = buildParams(model, context, options);
|
|
90
101
|
const nextParams = await options?.onPayload?.(params, model);
|
|
91
102
|
if (nextParams !== undefined) {
|
|
@@ -327,7 +338,7 @@ export const streamSimpleOpenAICompletions: StreamFunction<"openai-completions",
|
|
|
327
338
|
} satisfies OpenAICompletionsOptions);
|
|
328
339
|
};
|
|
329
340
|
|
|
330
|
-
function createClient(
|
|
341
|
+
async function createClient(
|
|
331
342
|
model: Model<"openai-completions">,
|
|
332
343
|
context: Context,
|
|
333
344
|
apiKey?: string,
|
|
@@ -358,8 +369,9 @@ function createClient(
|
|
|
358
369
|
}
|
|
359
370
|
|
|
360
371
|
const isZai = model.provider === "zai" || model.baseUrl.includes("api.z.ai");
|
|
372
|
+
const OpenAIClass = await getOpenAICompletionsClass();
|
|
361
373
|
|
|
362
|
-
return new
|
|
374
|
+
return new OpenAIClass({
|
|
363
375
|
apiKey,
|
|
364
376
|
baseURL: model.baseUrl,
|
|
365
377
|
dangerouslyAllowBrowser: true,
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
// Lazy-loaded: OpenAI SDK is imported on first use, not at startup.
|
|
2
|
+
// This avoids penalizing users who don't use OpenAI models.
|
|
3
|
+
import type OpenAI from "openai";
|
|
2
4
|
import type { ResponseCreateParamsStreaming } from "openai/resources/responses/responses.js";
|
|
3
5
|
import { getEnvApiKey } from "../env-api-keys.js";
|
|
4
6
|
import { supportsXhigh } from "../models.js";
|
|
@@ -18,6 +20,15 @@ import { buildCopilotDynamicHeaders, hasCopilotVisionInput } from "./github-copi
|
|
|
18
20
|
import { convertResponsesMessages, convertResponsesTools, processResponsesStream } from "./openai-responses-shared.js";
|
|
19
21
|
import { buildBaseOptions, clampReasoning } from "./simple-options.js";
|
|
20
22
|
|
|
23
|
+
let _OpenAIResponsesClass: typeof OpenAI | undefined;
|
|
24
|
+
async function getOpenAIResponsesClass(): Promise<typeof OpenAI> {
|
|
25
|
+
if (!_OpenAIResponsesClass) {
|
|
26
|
+
const mod = await import("openai");
|
|
27
|
+
_OpenAIResponsesClass = mod.default;
|
|
28
|
+
}
|
|
29
|
+
return _OpenAIResponsesClass;
|
|
30
|
+
}
|
|
31
|
+
|
|
21
32
|
/**
|
|
22
33
|
* Clamp reasoning effort for models that don't support all levels.
|
|
23
34
|
* gpt-5.x models don't support "minimal" — map to "low".
|
|
@@ -98,7 +109,7 @@ export const streamOpenAIResponses: StreamFunction<"openai-responses", OpenAIRes
|
|
|
98
109
|
try {
|
|
99
110
|
// Create OpenAI client
|
|
100
111
|
const apiKey = options?.apiKey || getEnvApiKey(model.provider) || "";
|
|
101
|
-
const client = createClient(model, context, apiKey, options?.headers);
|
|
112
|
+
const client = await createClient(model, context, apiKey, options?.headers);
|
|
102
113
|
let params = buildParams(model, context, options);
|
|
103
114
|
const nextParams = await options?.onPayload?.(params, model);
|
|
104
115
|
if (nextParams !== undefined) {
|
|
@@ -156,7 +167,7 @@ export const streamSimpleOpenAIResponses: StreamFunction<"openai-responses", Sim
|
|
|
156
167
|
} satisfies OpenAIResponsesOptions);
|
|
157
168
|
};
|
|
158
169
|
|
|
159
|
-
function createClient(
|
|
170
|
+
async function createClient(
|
|
160
171
|
model: Model<"openai-responses">,
|
|
161
172
|
context: Context,
|
|
162
173
|
apiKey?: string,
|
|
@@ -186,7 +197,8 @@ function createClient(
|
|
|
186
197
|
Object.assign(headers, optionsHeaders);
|
|
187
198
|
}
|
|
188
199
|
|
|
189
|
-
|
|
200
|
+
const OpenAIClass = await getOpenAIResponsesClass();
|
|
201
|
+
return new OpenAIClass({
|
|
190
202
|
apiKey,
|
|
191
203
|
baseURL: model.baseUrl,
|
|
192
204
|
dangerouslyAllowBrowser: true,
|
|
@@ -159,6 +159,22 @@ export interface ToolCall {
|
|
|
159
159
|
thoughtSignature?: string; // Google-specific: opaque signature for reusing thought context
|
|
160
160
|
}
|
|
161
161
|
|
|
162
|
+
/** Server-side tool use (e.g., Anthropic native web search). Executed by the API, not the client. */
|
|
163
|
+
export interface ServerToolUseContent {
|
|
164
|
+
type: "serverToolUse";
|
|
165
|
+
id: string;
|
|
166
|
+
name: string; // e.g., "web_search"
|
|
167
|
+
input: unknown;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/** Result of a server-side tool execution, paired with a ServerToolUseContent by toolUseId. */
|
|
171
|
+
export interface WebSearchResultContent {
|
|
172
|
+
type: "webSearchResult";
|
|
173
|
+
toolUseId: string;
|
|
174
|
+
/** Search results or error from the server. Opaque — stored for API replay. */
|
|
175
|
+
content: unknown;
|
|
176
|
+
}
|
|
177
|
+
|
|
162
178
|
export interface Usage {
|
|
163
179
|
input: number;
|
|
164
180
|
output: number;
|
|
@@ -184,7 +200,7 @@ export interface UserMessage {
|
|
|
184
200
|
|
|
185
201
|
export interface AssistantMessage {
|
|
186
202
|
role: "assistant";
|
|
187
|
-
content: (TextContent | ThinkingContent | ToolCall)[];
|
|
203
|
+
content: (TextContent | ThinkingContent | ToolCall | ServerToolUseContent | WebSearchResultContent)[];
|
|
188
204
|
api: Api;
|
|
189
205
|
provider: Provider;
|
|
190
206
|
model: string;
|
|
@@ -233,6 +249,8 @@ export type AssistantMessageEvent =
|
|
|
233
249
|
| { type: "toolcall_start"; contentIndex: number; partial: AssistantMessage }
|
|
234
250
|
| { type: "toolcall_delta"; contentIndex: number; delta: string; partial: AssistantMessage }
|
|
235
251
|
| { type: "toolcall_end"; contentIndex: number; toolCall: ToolCall; partial: AssistantMessage }
|
|
252
|
+
| { type: "server_tool_use"; contentIndex: number; partial: AssistantMessage }
|
|
253
|
+
| { type: "web_search_result"; contentIndex: number; partial: AssistantMessage }
|
|
236
254
|
| { type: "done"; reason: Extract<StopReason, "stop" | "length" | "toolUse">; message: AssistantMessage }
|
|
237
255
|
| { type: "error"; reason: Extract<StopReason, "aborted" | "error">; error: AssistantMessage };
|
|
238
256
|
|
|
@@ -2041,7 +2041,7 @@ export class AgentSession {
|
|
|
2041
2041
|
if (message.retryAfterMs !== undefined) {
|
|
2042
2042
|
const cap = settings.maxDelayMs > 0 ? settings.maxDelayMs : Infinity;
|
|
2043
2043
|
if (message.retryAfterMs > cap) {
|
|
2044
|
-
// Server wants us to wait longer than
|
|
2044
|
+
// Server wants us to wait longer than maxDelayMs — give up to let auto-mode handle recovery
|
|
2045
2045
|
this._emit({
|
|
2046
2046
|
type: "auto_retry_end",
|
|
2047
2047
|
success: false,
|