gsd-pi 2.37.0 → 2.37.1-dev.3bbb0a9

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.
Files changed (103) hide show
  1. package/README.md +21 -20
  2. package/dist/onboarding.js +1 -0
  3. package/dist/resources/extensions/cmux/package.json +7 -0
  4. package/dist/resources/extensions/gsd/auto-dispatch.js +67 -1
  5. package/dist/resources/extensions/gsd/auto-loop.js +18 -4
  6. package/dist/resources/extensions/gsd/auto-post-unit.js +14 -0
  7. package/dist/resources/extensions/gsd/auto-prompts.js +91 -2
  8. package/dist/resources/extensions/gsd/auto-recovery.js +37 -1
  9. package/dist/resources/extensions/gsd/auto.js +42 -5
  10. package/dist/resources/extensions/gsd/commands.js +80 -33
  11. package/dist/resources/extensions/gsd/doctor-providers.js +35 -1
  12. package/dist/resources/extensions/gsd/files.js +41 -0
  13. package/dist/resources/extensions/gsd/git-service.js +9 -1
  14. package/dist/resources/extensions/gsd/history.js +2 -1
  15. package/dist/resources/extensions/gsd/metrics.js +4 -2
  16. package/dist/resources/extensions/gsd/observability-validator.js +24 -0
  17. package/dist/resources/extensions/gsd/preferences-types.js +2 -1
  18. package/dist/resources/extensions/gsd/preferences-validation.js +42 -0
  19. package/dist/resources/extensions/gsd/prompts/plan-slice.md +2 -1
  20. package/dist/resources/extensions/gsd/prompts/reactive-execute.md +41 -0
  21. package/dist/resources/extensions/gsd/reactive-graph.js +227 -0
  22. package/dist/resources/extensions/gsd/session-lock.js +26 -6
  23. package/dist/resources/extensions/gsd/templates/task-plan.md +11 -3
  24. package/dist/resources/extensions/shared/format-utils.js +5 -41
  25. package/dist/resources/extensions/shared/layout-utils.js +46 -0
  26. package/dist/resources/extensions/shared/mod.js +2 -1
  27. package/package.json +2 -1
  28. package/packages/pi-ai/dist/env-api-keys.js +13 -0
  29. package/packages/pi-ai/dist/env-api-keys.js.map +1 -1
  30. package/packages/pi-ai/dist/models.generated.d.ts +172 -0
  31. package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
  32. package/packages/pi-ai/dist/models.generated.js +172 -0
  33. package/packages/pi-ai/dist/models.generated.js.map +1 -1
  34. package/packages/pi-ai/dist/providers/anthropic-shared.d.ts +64 -0
  35. package/packages/pi-ai/dist/providers/anthropic-shared.d.ts.map +1 -0
  36. package/packages/pi-ai/dist/providers/anthropic-shared.js +668 -0
  37. package/packages/pi-ai/dist/providers/anthropic-shared.js.map +1 -0
  38. package/packages/pi-ai/dist/providers/anthropic-vertex.d.ts +5 -0
  39. package/packages/pi-ai/dist/providers/anthropic-vertex.d.ts.map +1 -0
  40. package/packages/pi-ai/dist/providers/anthropic-vertex.js +85 -0
  41. package/packages/pi-ai/dist/providers/anthropic-vertex.js.map +1 -0
  42. package/packages/pi-ai/dist/providers/anthropic.d.ts +4 -30
  43. package/packages/pi-ai/dist/providers/anthropic.d.ts.map +1 -1
  44. package/packages/pi-ai/dist/providers/anthropic.js +47 -764
  45. package/packages/pi-ai/dist/providers/anthropic.js.map +1 -1
  46. package/packages/pi-ai/dist/providers/register-builtins.d.ts.map +1 -1
  47. package/packages/pi-ai/dist/providers/register-builtins.js +6 -0
  48. package/packages/pi-ai/dist/providers/register-builtins.js.map +1 -1
  49. package/packages/pi-ai/dist/types.d.ts +2 -2
  50. package/packages/pi-ai/dist/types.d.ts.map +1 -1
  51. package/packages/pi-ai/dist/types.js.map +1 -1
  52. package/packages/pi-ai/package.json +1 -0
  53. package/packages/pi-ai/src/env-api-keys.ts +14 -0
  54. package/packages/pi-ai/src/models.generated.ts +172 -0
  55. package/packages/pi-ai/src/providers/anthropic-shared.ts +761 -0
  56. package/packages/pi-ai/src/providers/anthropic-vertex.ts +130 -0
  57. package/packages/pi-ai/src/providers/anthropic.ts +76 -868
  58. package/packages/pi-ai/src/providers/register-builtins.ts +7 -0
  59. package/packages/pi-ai/src/types.ts +2 -0
  60. package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts.map +1 -1
  61. package/packages/pi-coding-agent/dist/core/extensions/loader.js +8 -4
  62. package/packages/pi-coding-agent/dist/core/extensions/loader.js.map +1 -1
  63. package/packages/pi-coding-agent/dist/core/model-resolver.d.ts.map +1 -1
  64. package/packages/pi-coding-agent/dist/core/model-resolver.js +1 -0
  65. package/packages/pi-coding-agent/dist/core/model-resolver.js.map +1 -1
  66. package/packages/pi-coding-agent/package.json +1 -1
  67. package/packages/pi-coding-agent/src/core/extensions/loader.ts +8 -4
  68. package/packages/pi-coding-agent/src/core/model-resolver.ts +1 -0
  69. package/pkg/package.json +1 -1
  70. package/src/resources/extensions/cmux/package.json +7 -0
  71. package/src/resources/extensions/gsd/auto-dispatch.ts +93 -0
  72. package/src/resources/extensions/gsd/auto-loop.ts +24 -6
  73. package/src/resources/extensions/gsd/auto-post-unit.ts +14 -0
  74. package/src/resources/extensions/gsd/auto-prompts.ts +125 -3
  75. package/src/resources/extensions/gsd/auto-recovery.ts +42 -0
  76. package/src/resources/extensions/gsd/auto.ts +56 -5
  77. package/src/resources/extensions/gsd/commands.ts +85 -31
  78. package/src/resources/extensions/gsd/doctor-providers.ts +38 -1
  79. package/src/resources/extensions/gsd/files.ts +45 -0
  80. package/src/resources/extensions/gsd/git-service.ts +12 -1
  81. package/src/resources/extensions/gsd/history.ts +2 -1
  82. package/src/resources/extensions/gsd/metrics.ts +4 -2
  83. package/src/resources/extensions/gsd/observability-validator.ts +27 -0
  84. package/src/resources/extensions/gsd/preferences-types.ts +5 -1
  85. package/src/resources/extensions/gsd/preferences-validation.ts +41 -0
  86. package/src/resources/extensions/gsd/prompts/plan-slice.md +2 -1
  87. package/src/resources/extensions/gsd/prompts/reactive-execute.md +41 -0
  88. package/src/resources/extensions/gsd/reactive-graph.ts +289 -0
  89. package/src/resources/extensions/gsd/session-lock.ts +41 -6
  90. package/src/resources/extensions/gsd/templates/task-plan.md +11 -3
  91. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +37 -1
  92. package/src/resources/extensions/gsd/tests/auto-worktree.test.ts +19 -0
  93. package/src/resources/extensions/gsd/tests/cmux.test.ts +25 -1
  94. package/src/resources/extensions/gsd/tests/doctor-providers.test.ts +108 -3
  95. package/src/resources/extensions/gsd/tests/plan-quality-validator.test.ts +111 -0
  96. package/src/resources/extensions/gsd/tests/reactive-executor.test.ts +511 -0
  97. package/src/resources/extensions/gsd/tests/reactive-graph.test.ts +299 -0
  98. package/src/resources/extensions/gsd/tests/session-lock-regression.test.ts +45 -0
  99. package/src/resources/extensions/gsd/types.ts +43 -0
  100. package/src/resources/extensions/shared/format-utils.ts +5 -44
  101. package/src/resources/extensions/shared/layout-utils.ts +49 -0
  102. package/src/resources/extensions/shared/mod.ts +7 -4
  103. package/src/resources/extensions/shared/tests/format-utils.test.ts +5 -3
@@ -0,0 +1,668 @@
1
+ import { calculateCost } from "../models.js";
2
+ import { parseStreamingJson } from "../utils/json-parse.js";
3
+ import { sanitizeSurrogates } from "../utils/sanitize-unicode.js";
4
+ import { transformMessages } from "./transform-messages.js";
5
+ const claudeCodeTools = [
6
+ "Read",
7
+ "Write",
8
+ "Edit",
9
+ "Bash",
10
+ "Grep",
11
+ "Glob",
12
+ "AskUserQuestion",
13
+ "EnterPlanMode",
14
+ "ExitPlanMode",
15
+ "KillShell",
16
+ "NotebookEdit",
17
+ "Skill",
18
+ "Task",
19
+ "TaskOutput",
20
+ "TodoWrite",
21
+ "WebFetch",
22
+ "WebSearch",
23
+ ];
24
+ const ccToolLookup = new Map(claudeCodeTools.map((t) => [t.toLowerCase(), t]));
25
+ export const toClaudeCodeName = (name) => ccToolLookup.get(name.toLowerCase()) ?? name;
26
+ export const fromClaudeCodeName = (name, tools) => {
27
+ if (tools && tools.length > 0) {
28
+ const lowerName = name.toLowerCase();
29
+ const matchedTool = tools.find((tool) => tool.name.toLowerCase() === lowerName);
30
+ if (matchedTool)
31
+ return matchedTool.name;
32
+ }
33
+ return name;
34
+ };
35
+ function resolveCacheRetention(cacheRetention) {
36
+ if (cacheRetention) {
37
+ return cacheRetention;
38
+ }
39
+ if (typeof process !== "undefined" && process.env.PI_CACHE_RETENTION === "long") {
40
+ return "long";
41
+ }
42
+ return "short";
43
+ }
44
+ export function getCacheControl(baseUrl, cacheRetention) {
45
+ const retention = resolveCacheRetention(cacheRetention);
46
+ if (retention === "none") {
47
+ return { retention };
48
+ }
49
+ const ttl = retention === "long" && baseUrl.includes("api.anthropic.com") ? "1h" : undefined;
50
+ return {
51
+ retention,
52
+ cacheControl: { type: "ephemeral", ...(ttl && { ttl }) },
53
+ };
54
+ }
55
+ export function convertContentBlocks(content) {
56
+ const hasImages = content.some((c) => c.type === "image");
57
+ if (!hasImages) {
58
+ return sanitizeSurrogates(content.map((c) => c.text).join("\n"));
59
+ }
60
+ const blocks = content.map((block) => {
61
+ if (block.type === "text") {
62
+ return {
63
+ type: "text",
64
+ text: sanitizeSurrogates(block.text),
65
+ };
66
+ }
67
+ return {
68
+ type: "image",
69
+ source: {
70
+ type: "base64",
71
+ media_type: block.mimeType,
72
+ data: block.data,
73
+ },
74
+ };
75
+ });
76
+ const hasText = blocks.some((b) => b.type === "text");
77
+ if (!hasText) {
78
+ blocks.unshift({
79
+ type: "text",
80
+ text: "(see attached image)",
81
+ });
82
+ }
83
+ return blocks;
84
+ }
85
+ export function supportsAdaptiveThinking(modelId) {
86
+ return (modelId.includes("opus-4-6") ||
87
+ modelId.includes("opus-4.6") ||
88
+ modelId.includes("sonnet-4-6") ||
89
+ modelId.includes("sonnet-4.6"));
90
+ }
91
+ export function mapThinkingLevelToEffort(level, modelId) {
92
+ switch (level) {
93
+ case "minimal":
94
+ return "low";
95
+ case "low":
96
+ return "low";
97
+ case "medium":
98
+ return "medium";
99
+ case "high":
100
+ return "high";
101
+ case "xhigh":
102
+ return modelId.includes("opus-4-6") || modelId.includes("opus-4.6") ? "max" : "high";
103
+ default:
104
+ return "high";
105
+ }
106
+ }
107
+ export function isTransientNetworkError(error) {
108
+ if (!(error instanceof Error))
109
+ return false;
110
+ const msg = error.message.toLowerCase();
111
+ const code = error.code;
112
+ return (code === 'ECONNRESET' ||
113
+ code === 'EPIPE' ||
114
+ code === 'ETIMEDOUT' ||
115
+ code === 'ENOTFOUND' ||
116
+ code === 'EAI_AGAIN' ||
117
+ msg.includes('connector_closed') ||
118
+ msg.includes('socket hang up') ||
119
+ msg.includes('network') ||
120
+ msg.includes('connection') && msg.includes('closed') ||
121
+ msg.includes('fetch failed'));
122
+ }
123
+ export function extractRetryAfterMs(headers, errorText = "") {
124
+ const normalizeDelay = (ms) => (ms > 0 ? Math.ceil(ms + 1000) : undefined);
125
+ const retryAfter = headers.get("retry-after");
126
+ if (retryAfter) {
127
+ const seconds = Number(retryAfter);
128
+ if (Number.isFinite(seconds)) {
129
+ const delay = normalizeDelay(seconds * 1000);
130
+ if (delay !== undefined)
131
+ return delay;
132
+ }
133
+ const asDate = new Date(retryAfter).getTime();
134
+ if (!Number.isNaN(asDate)) {
135
+ const delay = normalizeDelay(asDate - Date.now());
136
+ if (delay !== undefined)
137
+ return delay;
138
+ }
139
+ }
140
+ for (const header of ["x-ratelimit-reset-requests", "x-ratelimit-reset-tokens"]) {
141
+ const value = headers.get(header);
142
+ if (value) {
143
+ const resetSeconds = Number(value);
144
+ if (Number.isFinite(resetSeconds)) {
145
+ const delay = normalizeDelay(resetSeconds * 1000 - Date.now());
146
+ if (delay !== undefined)
147
+ return delay;
148
+ }
149
+ }
150
+ }
151
+ return undefined;
152
+ }
153
+ export function normalizeToolCallId(id) {
154
+ return id.replace(/[^a-zA-Z0-9_-]/g, "_").slice(0, 64);
155
+ }
156
+ export function convertMessages(messages, model, isOAuthToken, cacheControl) {
157
+ const params = [];
158
+ const transformedMessages = transformMessages(messages, model, normalizeToolCallId);
159
+ for (let i = 0; i < transformedMessages.length; i++) {
160
+ const msg = transformedMessages[i];
161
+ if (msg.role === "user") {
162
+ if (typeof msg.content === "string") {
163
+ if (msg.content.trim().length > 0) {
164
+ params.push({
165
+ role: "user",
166
+ content: sanitizeSurrogates(msg.content),
167
+ });
168
+ }
169
+ }
170
+ else {
171
+ const blocks = msg.content.map((item) => {
172
+ if (item.type === "text") {
173
+ return {
174
+ type: "text",
175
+ text: sanitizeSurrogates(item.text),
176
+ };
177
+ }
178
+ else {
179
+ return {
180
+ type: "image",
181
+ source: {
182
+ type: "base64",
183
+ media_type: item.mimeType,
184
+ data: item.data,
185
+ },
186
+ };
187
+ }
188
+ });
189
+ let filteredBlocks = !model?.input.includes("image") ? blocks.filter((b) => b.type !== "image") : blocks;
190
+ filteredBlocks = filteredBlocks.filter((b) => {
191
+ if (b.type === "text") {
192
+ return b.text.trim().length > 0;
193
+ }
194
+ return true;
195
+ });
196
+ if (filteredBlocks.length === 0)
197
+ continue;
198
+ params.push({
199
+ role: "user",
200
+ content: filteredBlocks,
201
+ });
202
+ }
203
+ }
204
+ else if (msg.role === "assistant") {
205
+ const blocks = [];
206
+ for (const block of msg.content) {
207
+ if (block.type === "text") {
208
+ if (block.text.trim().length === 0)
209
+ continue;
210
+ blocks.push({
211
+ type: "text",
212
+ text: sanitizeSurrogates(block.text),
213
+ });
214
+ }
215
+ else if (block.type === "thinking") {
216
+ if (block.redacted) {
217
+ blocks.push({
218
+ type: "redacted_thinking",
219
+ data: block.thinkingSignature,
220
+ });
221
+ continue;
222
+ }
223
+ if (block.thinking.trim().length === 0)
224
+ continue;
225
+ if (!block.thinkingSignature || block.thinkingSignature.trim().length === 0) {
226
+ blocks.push({
227
+ type: "text",
228
+ text: sanitizeSurrogates(block.thinking),
229
+ });
230
+ }
231
+ else {
232
+ blocks.push({
233
+ type: "thinking",
234
+ thinking: sanitizeSurrogates(block.thinking),
235
+ signature: block.thinkingSignature,
236
+ });
237
+ }
238
+ }
239
+ else if (block.type === "toolCall") {
240
+ blocks.push({
241
+ type: "tool_use",
242
+ id: block.id,
243
+ name: isOAuthToken ? toClaudeCodeName(block.name) : block.name,
244
+ input: block.arguments ?? {},
245
+ });
246
+ }
247
+ else if (block.type === "serverToolUse") {
248
+ blocks.push({
249
+ type: "server_tool_use",
250
+ id: block.id,
251
+ name: block.name,
252
+ input: block.input ?? {},
253
+ });
254
+ }
255
+ else if (block.type === "webSearchResult") {
256
+ blocks.push({
257
+ type: "web_search_tool_result",
258
+ tool_use_id: block.toolUseId,
259
+ content: block.content,
260
+ });
261
+ }
262
+ }
263
+ if (blocks.length === 0)
264
+ continue;
265
+ params.push({
266
+ role: "assistant",
267
+ content: blocks,
268
+ });
269
+ }
270
+ else if (msg.role === "toolResult") {
271
+ const toolResults = [];
272
+ toolResults.push({
273
+ type: "tool_result",
274
+ tool_use_id: msg.toolCallId,
275
+ content: convertContentBlocks(msg.content),
276
+ is_error: msg.isError,
277
+ });
278
+ let j = i + 1;
279
+ while (j < transformedMessages.length && transformedMessages[j].role === "toolResult") {
280
+ const nextMsg = transformedMessages[j];
281
+ toolResults.push({
282
+ type: "tool_result",
283
+ tool_use_id: nextMsg.toolCallId,
284
+ content: convertContentBlocks(nextMsg.content),
285
+ is_error: nextMsg.isError,
286
+ });
287
+ j++;
288
+ }
289
+ i = j - 1;
290
+ params.push({
291
+ role: "user",
292
+ content: toolResults,
293
+ });
294
+ }
295
+ }
296
+ if (cacheControl && params.length > 0) {
297
+ const lastMessage = params[params.length - 1];
298
+ if (lastMessage.role === "user") {
299
+ if (Array.isArray(lastMessage.content)) {
300
+ const lastBlock = lastMessage.content[lastMessage.content.length - 1];
301
+ if (lastBlock &&
302
+ (lastBlock.type === "text" || lastBlock.type === "image" || lastBlock.type === "tool_result")) {
303
+ lastBlock.cache_control = cacheControl;
304
+ }
305
+ }
306
+ else if (typeof lastMessage.content === "string") {
307
+ lastMessage.content = [
308
+ {
309
+ type: "text",
310
+ text: lastMessage.content,
311
+ cache_control: cacheControl,
312
+ },
313
+ ];
314
+ }
315
+ }
316
+ }
317
+ return params;
318
+ }
319
+ export function convertTools(tools, isOAuthToken) {
320
+ if (!tools)
321
+ return [];
322
+ return tools.map((tool) => {
323
+ const jsonSchema = tool.parameters;
324
+ return {
325
+ name: isOAuthToken ? toClaudeCodeName(tool.name) : tool.name,
326
+ description: tool.description,
327
+ input_schema: {
328
+ type: "object",
329
+ properties: jsonSchema.properties || {},
330
+ required: jsonSchema.required || [],
331
+ },
332
+ };
333
+ });
334
+ }
335
+ export function buildParams(model, context, isOAuthToken, options) {
336
+ const { cacheControl } = getCacheControl(model.baseUrl, options?.cacheRetention);
337
+ const apiModelId = model.id.replace(/\[.*\]$/, "");
338
+ const params = {
339
+ model: apiModelId,
340
+ messages: convertMessages(context.messages, model, isOAuthToken, cacheControl),
341
+ max_tokens: options?.maxTokens || (model.maxTokens / 3) | 0,
342
+ stream: true,
343
+ };
344
+ if (isOAuthToken) {
345
+ params.system = [
346
+ {
347
+ type: "text",
348
+ text: "You are Claude Code, Anthropic's official CLI for Claude.",
349
+ ...(cacheControl ? { cache_control: cacheControl } : {}),
350
+ },
351
+ ];
352
+ if (context.systemPrompt) {
353
+ params.system.push({
354
+ type: "text",
355
+ text: sanitizeSurrogates(context.systemPrompt),
356
+ ...(cacheControl ? { cache_control: cacheControl } : {}),
357
+ });
358
+ }
359
+ }
360
+ else if (context.systemPrompt) {
361
+ params.system = [
362
+ {
363
+ type: "text",
364
+ text: sanitizeSurrogates(context.systemPrompt),
365
+ ...(cacheControl ? { cache_control: cacheControl } : {}),
366
+ },
367
+ ];
368
+ }
369
+ if (options?.temperature !== undefined && !options?.thinkingEnabled) {
370
+ params.temperature = options.temperature;
371
+ }
372
+ if (context.tools) {
373
+ params.tools = convertTools(context.tools, isOAuthToken);
374
+ }
375
+ if (options?.thinkingEnabled && model.reasoning) {
376
+ if (supportsAdaptiveThinking(model.id)) {
377
+ params.thinking = { type: "adaptive" };
378
+ if (options.effort) {
379
+ params.output_config = { effort: options.effort };
380
+ }
381
+ }
382
+ else {
383
+ params.thinking = {
384
+ type: "enabled",
385
+ budget_tokens: options.thinkingBudgetTokens || 1024,
386
+ };
387
+ }
388
+ }
389
+ if (options?.metadata) {
390
+ const userId = options.metadata.user_id;
391
+ if (typeof userId === "string") {
392
+ params.metadata = { user_id: userId };
393
+ }
394
+ }
395
+ if (options?.toolChoice) {
396
+ if (typeof options.toolChoice === "string") {
397
+ params.tool_choice = { type: options.toolChoice };
398
+ }
399
+ else {
400
+ params.tool_choice = options.toolChoice;
401
+ }
402
+ }
403
+ return params;
404
+ }
405
+ export function mapStopReason(reason) {
406
+ switch (reason) {
407
+ case "end_turn":
408
+ return "stop";
409
+ case "max_tokens":
410
+ return "length";
411
+ case "tool_use":
412
+ return "toolUse";
413
+ case "refusal":
414
+ return "error";
415
+ case "pause_turn":
416
+ return "stop";
417
+ case "stop_sequence":
418
+ return "stop";
419
+ case "sensitive":
420
+ return "error";
421
+ default:
422
+ throw new Error(`Unhandled stop reason: ${reason}`);
423
+ }
424
+ }
425
+ export function processAnthropicStream(stream, args) {
426
+ const { client, model, context, isOAuthToken, options, AnthropicSdkClass } = args;
427
+ (async () => {
428
+ const output = {
429
+ role: "assistant",
430
+ content: [],
431
+ api: model.api,
432
+ provider: model.provider,
433
+ model: model.id,
434
+ usage: {
435
+ input: 0,
436
+ output: 0,
437
+ cacheRead: 0,
438
+ cacheWrite: 0,
439
+ totalTokens: 0,
440
+ cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },
441
+ },
442
+ stopReason: "stop",
443
+ timestamp: Date.now(),
444
+ };
445
+ try {
446
+ let params = buildParams(model, context, isOAuthToken, options);
447
+ const nextParams = await options?.onPayload?.(params, model);
448
+ if (nextParams !== undefined) {
449
+ params = nextParams;
450
+ }
451
+ const anthropicStream = client.messages.stream({ ...params, stream: true }, { signal: options?.signal });
452
+ stream.push({ type: "start", partial: output });
453
+ const blocks = output.content;
454
+ for await (const event of anthropicStream) {
455
+ if (event.type === "message_start") {
456
+ output.usage.input = event.message.usage.input_tokens || 0;
457
+ output.usage.output = event.message.usage.output_tokens || 0;
458
+ output.usage.cacheRead = event.message.usage.cache_read_input_tokens || 0;
459
+ output.usage.cacheWrite = event.message.usage.cache_creation_input_tokens || 0;
460
+ output.usage.totalTokens =
461
+ output.usage.input + output.usage.output + output.usage.cacheRead + output.usage.cacheWrite;
462
+ calculateCost(model, output.usage);
463
+ }
464
+ else if (event.type === "content_block_start") {
465
+ if (event.content_block.type === "text") {
466
+ const block = {
467
+ type: "text",
468
+ text: "",
469
+ index: event.index,
470
+ };
471
+ output.content.push(block);
472
+ stream.push({ type: "text_start", contentIndex: output.content.length - 1, partial: output });
473
+ }
474
+ else if (event.content_block.type === "thinking") {
475
+ const block = {
476
+ type: "thinking",
477
+ thinking: "",
478
+ thinkingSignature: "",
479
+ index: event.index,
480
+ };
481
+ output.content.push(block);
482
+ stream.push({ type: "thinking_start", contentIndex: output.content.length - 1, partial: output });
483
+ }
484
+ else if (event.content_block.type === "redacted_thinking") {
485
+ const block = {
486
+ type: "thinking",
487
+ thinking: "[Reasoning redacted]",
488
+ thinkingSignature: event.content_block.data,
489
+ redacted: true,
490
+ index: event.index,
491
+ };
492
+ output.content.push(block);
493
+ stream.push({ type: "thinking_start", contentIndex: output.content.length - 1, partial: output });
494
+ }
495
+ else if (event.content_block.type === "tool_use") {
496
+ const block = {
497
+ type: "toolCall",
498
+ id: event.content_block.id,
499
+ name: isOAuthToken
500
+ ? fromClaudeCodeName(event.content_block.name, context.tools)
501
+ : event.content_block.name,
502
+ arguments: event.content_block.input ?? {},
503
+ partialJson: "",
504
+ index: event.index,
505
+ };
506
+ output.content.push(block);
507
+ stream.push({ type: "toolcall_start", contentIndex: output.content.length - 1, partial: output });
508
+ }
509
+ else if (event.content_block.type === "server_tool_use") {
510
+ const serverBlock = event.content_block;
511
+ const block = {
512
+ type: "serverToolUse",
513
+ id: serverBlock.id,
514
+ name: serverBlock.name,
515
+ input: serverBlock.input,
516
+ index: event.index,
517
+ };
518
+ output.content.push(block);
519
+ stream.push({ type: "server_tool_use", contentIndex: output.content.length - 1, partial: output });
520
+ }
521
+ else if (event.content_block.type === "web_search_tool_result") {
522
+ const resultBlock = event.content_block;
523
+ const block = {
524
+ type: "webSearchResult",
525
+ toolUseId: resultBlock.tool_use_id,
526
+ content: resultBlock.content,
527
+ index: event.index,
528
+ };
529
+ output.content.push(block);
530
+ stream.push({ type: "web_search_result", contentIndex: output.content.length - 1, partial: output });
531
+ }
532
+ }
533
+ else if (event.type === "content_block_delta") {
534
+ if (event.delta.type === "text_delta") {
535
+ const index = blocks.findIndex((b) => b.index === event.index);
536
+ const block = blocks[index];
537
+ if (block && block.type === "text") {
538
+ block.text += event.delta.text;
539
+ stream.push({
540
+ type: "text_delta",
541
+ contentIndex: index,
542
+ delta: event.delta.text,
543
+ partial: output,
544
+ });
545
+ }
546
+ }
547
+ else if (event.delta.type === "thinking_delta") {
548
+ const index = blocks.findIndex((b) => b.index === event.index);
549
+ const block = blocks[index];
550
+ if (block && block.type === "thinking") {
551
+ block.thinking += event.delta.thinking;
552
+ stream.push({
553
+ type: "thinking_delta",
554
+ contentIndex: index,
555
+ delta: event.delta.thinking,
556
+ partial: output,
557
+ });
558
+ }
559
+ }
560
+ else if (event.delta.type === "input_json_delta") {
561
+ const index = blocks.findIndex((b) => b.index === event.index);
562
+ const block = blocks[index];
563
+ if (block && block.type === "toolCall") {
564
+ block.partialJson += event.delta.partial_json;
565
+ block.arguments = parseStreamingJson(block.partialJson);
566
+ stream.push({
567
+ type: "toolcall_delta",
568
+ contentIndex: index,
569
+ delta: event.delta.partial_json,
570
+ partial: output,
571
+ });
572
+ }
573
+ }
574
+ else if (event.delta.type === "signature_delta") {
575
+ const index = blocks.findIndex((b) => b.index === event.index);
576
+ const block = blocks[index];
577
+ if (block && block.type === "thinking") {
578
+ block.thinkingSignature = block.thinkingSignature || "";
579
+ block.thinkingSignature += event.delta.signature;
580
+ }
581
+ }
582
+ }
583
+ else if (event.type === "content_block_stop") {
584
+ const index = blocks.findIndex((b) => b.index === event.index);
585
+ const block = blocks[index];
586
+ if (block) {
587
+ delete block.index;
588
+ if (block.type === "text") {
589
+ stream.push({
590
+ type: "text_end",
591
+ contentIndex: index,
592
+ content: block.text,
593
+ partial: output,
594
+ });
595
+ }
596
+ else if (block.type === "thinking") {
597
+ stream.push({
598
+ type: "thinking_end",
599
+ contentIndex: index,
600
+ content: block.thinking,
601
+ partial: output,
602
+ });
603
+ }
604
+ else if (block.type === "toolCall") {
605
+ block.arguments = parseStreamingJson(block.partialJson);
606
+ delete block.partialJson;
607
+ stream.push({
608
+ type: "toolcall_end",
609
+ contentIndex: index,
610
+ toolCall: block,
611
+ partial: output,
612
+ });
613
+ }
614
+ }
615
+ }
616
+ else if (event.type === "message_delta") {
617
+ if (event.delta.stop_reason) {
618
+ output.stopReason = mapStopReason(event.delta.stop_reason);
619
+ }
620
+ if (event.usage.input_tokens != null) {
621
+ output.usage.input = event.usage.input_tokens;
622
+ }
623
+ if (event.usage.output_tokens != null) {
624
+ output.usage.output = event.usage.output_tokens;
625
+ }
626
+ if (event.usage.cache_read_input_tokens != null) {
627
+ output.usage.cacheRead = event.usage.cache_read_input_tokens;
628
+ }
629
+ if (event.usage.cache_creation_input_tokens != null) {
630
+ output.usage.cacheWrite = event.usage.cache_creation_input_tokens;
631
+ }
632
+ output.usage.totalTokens =
633
+ output.usage.input + output.usage.output + output.usage.cacheRead + output.usage.cacheWrite;
634
+ calculateCost(model, output.usage);
635
+ }
636
+ }
637
+ if (options?.signal?.aborted) {
638
+ throw new Error("Request was aborted");
639
+ }
640
+ if (output.stopReason === "aborted" || output.stopReason === "error") {
641
+ throw new Error("An unknown error occurred");
642
+ }
643
+ stream.push({ type: "done", reason: output.stopReason, message: output });
644
+ stream.end();
645
+ }
646
+ catch (error) {
647
+ for (const block of output.content)
648
+ delete block.index;
649
+ output.stopReason = options?.signal?.aborted ? "aborted" : "error";
650
+ output.errorMessage = error instanceof Error ? error.message : JSON.stringify(error);
651
+ if (model.provider === "alibaba-coding-plan") {
652
+ output.errorMessage = `[alibaba-coding-plan] ${output.errorMessage}`;
653
+ }
654
+ if (AnthropicSdkClass && error instanceof AnthropicSdkClass.APIError && error.headers) {
655
+ const retryAfterMs = extractRetryAfterMs(error.headers, error.message);
656
+ if (retryAfterMs !== undefined) {
657
+ output.retryAfterMs = retryAfterMs;
658
+ }
659
+ }
660
+ if (isTransientNetworkError(error)) {
661
+ output.retryAfterMs = output.retryAfterMs ?? 5000;
662
+ }
663
+ stream.push({ type: "error", reason: output.stopReason, error: output });
664
+ stream.end();
665
+ }
666
+ })();
667
+ }
668
+ //# sourceMappingURL=anthropic-shared.js.map