@swifty.js/swifty 0.0.30 → 0.0.32

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 (53) hide show
  1. package/README.md +60 -3
  2. package/dist/agent-2DUTUJFX.js +4 -0
  3. package/dist/anthropic-KR5MXB5I.js +4 -0
  4. package/dist/checker-RKAWOOXC.js +4 -0
  5. package/dist/chunk-2EV72T5X.js +4 -0
  6. package/dist/chunk-4YVJP2CO.js +4 -0
  7. package/dist/chunk-BWWNI2FK.js +121 -0
  8. package/dist/{chunk-K5ZK27BX.js → chunk-JMF2DWGY.js} +1 -1
  9. package/dist/chunk-LTFPTWX4.js +612 -0
  10. package/dist/chunk-NERVCUWE.js +4 -0
  11. package/dist/chunk-S35E7OYL.js +5 -0
  12. package/dist/{chunk-QFSCPD63.js → chunk-TCQ4EB4G.js} +1 -1
  13. package/dist/{chunk-C3WGLVVZ.js → chunk-TKQ5T5VO.js} +1 -1
  14. package/dist/chunk-TW7RHCDS.js +150 -0
  15. package/dist/lib/agent-3OEC4SOB.js +10 -0
  16. package/dist/lib/{anthropic-CL5IK7KN.js → anthropic-B33M2AVN.js} +5 -6
  17. package/dist/lib/{checker-BS4MK3O6.js → checker-QNMXPZ7C.js} +3 -4
  18. package/dist/lib/{chunk-OQIQOU5S.js → chunk-3OFLDUAW.js} +121 -1
  19. package/dist/lib/{chunk-EY7HE52Q.js → chunk-3XCGUKGJ.js} +18 -24
  20. package/dist/lib/{chunk-7QPDFSQE.js → chunk-4BPKIIQD.js} +29 -10
  21. package/dist/lib/{chunk-KG4MJGKQ.js → chunk-BCBD34D2.js} +2 -5
  22. package/dist/lib/{chunk-IYPTOY3Y.js → chunk-FODSMOWP.js} +40 -31
  23. package/dist/lib/{chunk-RMB3J46W.js → chunk-SOOSTGHI.js} +198 -37
  24. package/dist/lib/{chunk-I7OPU4K2.js → chunk-TJLAJGG4.js} +194 -34
  25. package/dist/lib/{chunk-OOSNCCI7.js → chunk-UH5M7FDP.js} +151 -152
  26. package/dist/lib/{chunk-PIL7M52F.js → chunk-XT67KGWE.js} +16 -3
  27. package/dist/lib/index.d.ts +2103 -1344
  28. package/dist/lib/index.js +11869 -9629
  29. package/dist/lib/{openai-LH4E7ZQS.js → openai-C2PZFGJ2.js} +3 -3
  30. package/dist/lib/{tool-filter-CS6W2GMU.js → tool-filter-IMIU7CW2.js} +3 -2
  31. package/dist/main.js +186 -187
  32. package/dist/{node-4LTSRXL2.js → node-GXMM4JG3.js} +1 -1
  33. package/dist/openai-M7B2TITO.js +34 -0
  34. package/dist/seatbelt-3GM2YGXV.js +5 -0
  35. package/dist/{server-IVIRQTO7.js → server-QMMIYNXW.js} +16 -23
  36. package/dist/tool-filter-7LLVAHD5.js +4 -0
  37. package/package.json +9 -12
  38. package/dist/agent-TCNIRVHD.js +0 -4
  39. package/dist/anthropic-7RIVSEDF.js +0 -4
  40. package/dist/checker-3LHDOATB.js +0 -4
  41. package/dist/chunk-2IBMB3ZM.js +0 -150
  42. package/dist/chunk-AQ3A5CF4.js +0 -5
  43. package/dist/chunk-E55KH72M.js +0 -4
  44. package/dist/chunk-FA26MQ7K.js +0 -257
  45. package/dist/chunk-OTVZGPHD.js +0 -121
  46. package/dist/chunk-QCKJLO6X.js +0 -4
  47. package/dist/chunk-TKADLB2Q.js +0 -4
  48. package/dist/chunk-VA64DJNN.js +0 -4
  49. package/dist/lib/agent-IRY7KR5D.js +0 -11
  50. package/dist/lib/chunk-GHF2PSEW.js +0 -8
  51. package/dist/openai-RZLCY55V.js +0 -34
  52. package/dist/seatbelt-YXUQ5XR3.js +0 -5
  53. package/dist/tool-filter-CG3KGQQW.js +0 -4
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  createChildLogger
3
- } from "./chunk-EY7HE52Q.js";
3
+ } from "./chunk-3XCGUKGJ.js";
4
4
 
5
5
  // src/llm/errors.ts
6
6
  var LLMError = class extends Error {
@@ -288,6 +288,10 @@ function loadSingleFile(path) {
288
288
  const parsed2 = safeParse(z.array(MCPServerConfigSchema), raw.mcp_servers);
289
289
  if (parsed2.success) {
290
290
  mcpServers = parsed2.data;
291
+ } else {
292
+ throw new ConfigError(
293
+ `Invalid MCP server configuration in ${path}: ${getParseErrorMessage(parsed2.error)}`
294
+ );
291
295
  }
292
296
  }
293
297
  if ("hooks" in raw) {
@@ -323,6 +327,7 @@ function validateProviders(config) {
323
327
  throw new ConfigError("At least one provider MUST be configured.");
324
328
  }
325
329
  const requiredFields = ["name", "protocol", "base_url", "model"];
330
+ const baseUrls = /* @__PURE__ */ new Map();
326
331
  for (let i = 0; i < config.providers.length; i++) {
327
332
  const p = config.providers[i];
328
333
  const values = {
@@ -340,11 +345,123 @@ function validateProviders(config) {
340
345
  `Provider #${String(i + 1)}: invalid protocol '${p.protocol}', MUST be one of: ${Array.from(VALID_PROTOCOLS).join(", ")}`
341
346
  );
342
347
  }
348
+ const previous = baseUrls.get(p.base_url);
349
+ if (previous !== void 0) {
350
+ throw new ConfigError(
351
+ `Provider #${String(i + 1)}: duplicate base_url '${p.base_url}' (already used by provider #${String(previous + 1)}).`
352
+ );
353
+ }
354
+ baseUrls.set(p.base_url, i);
343
355
  }
344
356
  }
357
+ function validateMcpServers(config) {
358
+ const names = /* @__PURE__ */ new Map();
359
+ for (let i = 0; i < config.mcp_servers.length; i++) {
360
+ const server = config.mcp_servers[i];
361
+ const position = `MCP server #${String(i + 1)}`;
362
+ if (!server.name.trim()) {
363
+ throw new ConfigError(`${position}: name must not be empty.`);
364
+ }
365
+ const previous = names.get(server.name);
366
+ if (previous !== void 0) {
367
+ throw new ConfigError(
368
+ `${position}: duplicate name '${server.name}' (already used by MCP server #${String(previous + 1)}).`
369
+ );
370
+ }
371
+ names.set(server.name, i);
372
+ const hasCommand = Boolean(server.command?.trim());
373
+ const hasUrl = Boolean(server.url?.trim());
374
+ if (hasCommand === hasUrl) {
375
+ throw new ConfigError(
376
+ `${position} '${server.name}': configure exactly one of command or url.`
377
+ );
378
+ }
379
+ if (hasCommand && server.transport && server.transport !== "stdio") {
380
+ throw new ConfigError(`${position} '${server.name}': command servers must use stdio.`);
381
+ }
382
+ if (hasUrl && server.transport && !["http", "sse"].includes(server.transport)) {
383
+ throw new ConfigError(`${position} '${server.name}': URL transport must be http or sse.`);
384
+ }
385
+ }
386
+ }
387
+ var PROJECT_MCP_FILENAME = ".mcp.json";
388
+ var McpJsonEntrySchema = z.looseObject({
389
+ command: z.string().optional(),
390
+ args: z.array(z.string()).optional(),
391
+ env: z.record(z.string(), z.string()).optional(),
392
+ type: z.enum(["stdio", "sse", "http"]).optional(),
393
+ url: z.string().optional(),
394
+ headers: z.record(z.string(), z.string()).optional()
395
+ });
396
+ var McpJsonFileSchema = z.looseObject({
397
+ // Parse entries independently below so one bad server does not disable every
398
+ // valid server in the project file.
399
+ mcpServers: z.record(z.string(), z.unknown()).default({})
400
+ });
401
+ function mcpServerFromJsonEntry(name, entry) {
402
+ const transport = entry.type ?? (entry.command !== void 0 ? "stdio" : "http");
403
+ if (transport === "stdio") {
404
+ if (!entry.command || entry.url !== void 0) {
405
+ return null;
406
+ }
407
+ return { name, command: entry.command, args: entry.args, env: entry.env };
408
+ }
409
+ if (!entry.url || entry.command !== void 0) {
410
+ return null;
411
+ }
412
+ return { name, url: entry.url, transport, headers: entry.headers };
413
+ }
414
+ function loadProjectMcpServers(workDir) {
415
+ const path = join(workDir, PROJECT_MCP_FILENAME);
416
+ if (!existsSync(path)) {
417
+ return [];
418
+ }
419
+ let raw;
420
+ try {
421
+ raw = JSON.parse(readFileSync(path, "utf-8"));
422
+ } catch (err) {
423
+ log.error({ err, path }, "invalid .mcp.json");
424
+ return [];
425
+ }
426
+ const parsed = safeParse(McpJsonFileSchema, raw);
427
+ if (!parsed.success) {
428
+ log.error({ error: parsed.error, path }, "invalid .mcp.json");
429
+ return [];
430
+ }
431
+ const servers = [];
432
+ for (const [name, rawEntry] of Object.entries(parsed.data.mcpServers)) {
433
+ const parsedEntry = safeParse(McpJsonEntrySchema, rawEntry);
434
+ if (!name.trim() || !parsedEntry.success) {
435
+ log.warn(
436
+ { name, path, error: parsedEntry.success ? void 0 : parsedEntry.error },
437
+ "skipping invalid .mcp.json server entry"
438
+ );
439
+ continue;
440
+ }
441
+ const server = mcpServerFromJsonEntry(name, parsedEntry.data);
442
+ if (server) {
443
+ servers.push(server);
444
+ } else {
445
+ log.warn({ name, path }, "skipping invalid .mcp.json server entry");
446
+ }
447
+ }
448
+ return servers;
449
+ }
450
+ function withProjectMcpServers(config, workDir) {
451
+ const projectServers = loadProjectMcpServers(workDir);
452
+ if (projectServers.length === 0) {
453
+ return config;
454
+ }
455
+ const known = new Set(config.mcp_servers.map((s) => s.name));
456
+ return {
457
+ ...config,
458
+ mcp_servers: [...config.mcp_servers, ...projectServers.filter((s) => !known.has(s.name))]
459
+ };
460
+ }
345
461
  function loadConfig(path, options = {}) {
346
462
  if (path) {
347
463
  const config2 = loadSingleFile(path);
464
+ validateMcpServers(config2);
348
465
  if (!options.allowEmptyProviders || config2.providers.length > 0) {
349
466
  validateProviders(config2);
350
467
  }
@@ -358,6 +475,7 @@ function loadConfig(path, options = {}) {
358
475
  throw new ConfigError(`No config file found, expected ${candidate}.`);
359
476
  }
360
477
  const config = loadSingleFile(candidate);
478
+ validateMcpServers(config);
361
479
  if (!options.allowEmptyProviders || config.providers.length > 0) {
362
480
  validateProviders(config);
363
481
  }
@@ -444,6 +562,8 @@ export {
444
562
  resolveAPIKey,
445
563
  HookConfigSchema,
446
564
  forkEnabled,
565
+ loadProjectMcpServers,
566
+ withProjectMcpServers,
447
567
  loadConfig,
448
568
  INTERRUPTED_TOOL_RESULT,
449
569
  REJECTED_TOOL_RESULT,
@@ -228,7 +228,7 @@ function errSerializer(err) {
228
228
  return { message: safeStringify(err), value: err };
229
229
  }
230
230
 
231
- // src/utils/index.ts
231
+ // src/utils/utils.ts
232
232
  var log = createChildLogger({ module: "utils" });
233
233
  function contentToText(content) {
234
234
  if (typeof content === "string") {
@@ -336,29 +336,23 @@ function boolArg(args, key, fallback) {
336
336
  }
337
337
  return fallback ?? Boolean(v);
338
338
  }
339
- function quickSort(arr, compare) {
340
- if (arr.length <= 1) {
341
- return [...arr];
342
- }
343
- const pivotIndex = Math.floor(arr.length / 2);
344
- const pivot = arr[pivotIndex];
345
- if (pivot === void 0) {
346
- return [...arr];
347
- }
348
- const left = [];
349
- const right = [];
350
- const equal = [];
351
- for (const item of arr) {
352
- const result = compare(item, pivot);
353
- if (result < 0) {
354
- left.push(item);
355
- } else if (result > 0) {
356
- right.push(item);
357
- } else {
358
- equal.push(item);
359
- }
339
+ function formatToolArgs(args) {
340
+ if (args.command) {
341
+ return truncate(strArg(args, "command"), 80);
342
+ }
343
+ if (args.file_path) {
344
+ return truncate(strArg(args, "file_path"), 80);
345
+ }
346
+ if (args.pattern) {
347
+ return truncate(strArg(args, "pattern"), 80);
360
348
  }
361
- return [...quickSort(left, compare), ...equal, ...quickSort(right, compare)];
349
+ if (args.description) {
350
+ return truncate(strArg(args, "description"), 80);
351
+ }
352
+ return "";
353
+ }
354
+ function truncate(value, max) {
355
+ return value.length > max ? `${value.slice(0, max)}\u2026` : value;
362
356
  }
363
357
 
364
358
  export {
@@ -380,5 +374,5 @@ export {
380
374
  strList,
381
375
  strArg,
382
376
  boolArg,
383
- quickSort
377
+ formatToolArgs
384
378
  };
@@ -1,8 +1,3 @@
1
- import {
2
- MCP_CALL_TOOL_NAME,
3
- TOOL_SEARCH_TOOL_NAME
4
- } from "./chunk-GHF2PSEW.js";
5
-
6
1
  // src/tools/registry.ts
7
2
  var ToolRegistry = class {
8
3
  tools = /* @__PURE__ */ new Map();
@@ -26,26 +21,44 @@ var ToolRegistry = class {
26
21
  register(tool) {
27
22
  this.tools.set(tool.name, tool);
28
23
  }
24
+ /**
25
+ * Removes a tool and forgets its discovery state, so a re-registered tool
26
+ * with the same name starts deferred again. Used by /mcp reload to drop
27
+ * tools of servers that disappeared from the config.
28
+ */
29
+ unregister(name) {
30
+ this.tools.delete(name);
31
+ this.discovered.delete(name);
32
+ }
29
33
  get(name) {
30
34
  return this.tools.get(name);
31
35
  }
32
36
  listTools() {
33
37
  return [...this.tools.values()];
34
38
  }
35
- getAllSchemas(protocol = "anthropic") {
36
- const isOpenAI = protocol === "openai" || protocol === "openai-compat";
39
+ getAllSchemas(protocol, filter) {
40
+ const resolvedProtocol = protocol ?? "anthropic";
41
+ const isOpenAI = resolvedProtocol === "openai" || resolvedProtocol === "openai-compat";
37
42
  const native = this.mcpLoadingMode === "native" && !isOpenAI;
38
43
  const schemas = [];
39
44
  for (const tool of this.tools.values()) {
40
- if (tool.name === TOOL_SEARCH_TOOL_NAME && !this.exposeToolSearch || tool.name === MCP_CALL_TOOL_NAME && !this.exposeMcpCall) {
45
+ if (filter && !filter(tool.name)) {
46
+ continue;
47
+ }
48
+ if (tool.name === "ToolSearch" && !this.exposeToolSearch || tool.name === "McpCall" && !this.exposeMcpCall) {
41
49
  continue;
42
50
  }
43
51
  const deferred = Boolean(tool.deferred) && !this.discovered.has(tool.name);
44
52
  if (deferred && !native) {
45
53
  continue;
46
54
  }
55
+ const providerSchema = protocol ? tool.providerSchema?.(resolvedProtocol) : void 0;
56
+ if (providerSchema) {
57
+ schemas.push(providerSchema);
58
+ continue;
59
+ }
47
60
  const s = tool.schema();
48
- if (protocol === "openai") {
61
+ if (resolvedProtocol === "openai") {
49
62
  schemas.push({
50
63
  strict: s.strict ?? false,
51
64
  type: "function",
@@ -53,7 +66,7 @@ var ToolRegistry = class {
53
66
  description: s.description,
54
67
  parameters: s.input_schema
55
68
  });
56
- } else if (protocol === "openai-compat") {
69
+ } else if (resolvedProtocol === "openai-compat") {
57
70
  schemas.push({
58
71
  type: "function",
59
72
  function: {
@@ -120,11 +133,13 @@ var ToolRegistry = class {
120
133
  };
121
134
 
122
135
  // src/subagent/tool-filter.ts
136
+ var MAIN_AGENT_ONLY_TOOLS = /* @__PURE__ */ new Set(["ComputerUse"]);
123
137
  var SUBAGENT_DISALLOWED_TOOLS = /* @__PURE__ */ new Set([
124
138
  "ExitPlanMode",
125
139
  "Agent",
126
140
  // Prevents recursive spawning of subagents
127
141
  "AskUserQuestion",
142
+ ...MAIN_AGENT_ONLY_TOOLS,
128
143
  "TaskStop"
129
144
  ]);
130
145
  var TEAMMATE_DISALLOWED_TOOLS = /* @__PURE__ */ new Set(["TeamCreate", "TeamDelete"]);
@@ -193,6 +208,9 @@ function cloneRegistryForFork(registry) {
193
208
  const forked = new ToolRegistry();
194
209
  forked.mcpLoadingMode = registry.mcpLoadingMode;
195
210
  for (const tool of registry.listTools()) {
211
+ if (MAIN_AGENT_ONLY_TOOLS.has(tool.name)) {
212
+ continue;
213
+ }
196
214
  if (tool.name === "Agent" && "querySource" in tool) {
197
215
  const clone = Object.create(
198
216
  // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
@@ -210,6 +228,7 @@ function cloneRegistryForFork(registry) {
210
228
 
211
229
  export {
212
230
  ToolRegistry,
231
+ MAIN_AGENT_ONLY_TOOLS,
213
232
  SUBAGENT_DISALLOWED_TOOLS,
214
233
  TEAMMATE_DISALLOWED_TOOLS,
215
234
  CUSTOM_AGENT_DISALLOWED_TOOLS,
@@ -3,10 +3,7 @@ import {
3
3
  asRecord,
4
4
  createChildLogger,
5
5
  strArg
6
- } from "./chunk-EY7HE52Q.js";
7
- import {
8
- MCP_CALL_TOOL_NAME
9
- } from "./chunk-GHF2PSEW.js";
6
+ } from "./chunk-3XCGUKGJ.js";
10
7
 
11
8
  // src/mcp/tool-wrapper.ts
12
9
  var log = createChildLogger({ module: "mcp" });
@@ -148,7 +145,7 @@ var McpCallTool = class {
148
145
  this.registry = registry;
149
146
  }
150
147
  registry;
151
- name = MCP_CALL_TOOL_NAME;
148
+ name = "McpCall";
152
149
  description = "Invoke a tool on a connected MCP server. Call ToolSearch first to load the tool's schema, then pass its arguments here exactly as that schema requires, using the same JSON types.";
153
150
  category = "command";
154
151
  // This tool must stay in tools[] itself, otherwise the model has no entry point
@@ -1,6 +1,10 @@
1
1
  import {
2
2
  normalizeToolResultContentBlock
3
- } from "./chunk-PIL7M52F.js";
3
+ } from "./chunk-XT67KGWE.js";
4
+ import {
5
+ MCP_TOOL_PREFIX,
6
+ isMcpToolLike
7
+ } from "./chunk-BCBD34D2.js";
4
8
  import {
5
9
  AuthenticationError,
6
10
  ContextTooLongError,
@@ -17,11 +21,7 @@ import {
17
21
  thinkingBudgetForLevel,
18
22
  toAnthropicThinkingEffort,
19
23
  toReasoningEffort
20
- } from "./chunk-OQIQOU5S.js";
21
- import {
22
- MCP_TOOL_PREFIX,
23
- isMcpToolLike
24
- } from "./chunk-KG4MJGKQ.js";
24
+ } from "./chunk-3OFLDUAW.js";
25
25
  import {
26
26
  asErrorString,
27
27
  asRecord,
@@ -30,7 +30,7 @@ import {
30
30
  createChildLogger,
31
31
  isRecord,
32
32
  strArg
33
- } from "./chunk-EY7HE52Q.js";
33
+ } from "./chunk-3XCGUKGJ.js";
34
34
 
35
35
  // src/llm/anthropic.ts
36
36
  import Anthropic from "@anthropic-ai/sdk";
@@ -112,7 +112,23 @@ function markToolsForCache(tools) {
112
112
  }
113
113
  }
114
114
  function needsToolSearchBeta(toolSchemas) {
115
- return toolSchemas.some((s) => s.defer_loading);
115
+ return toolSchemas.some((schema) => "defer_loading" in schema && schema.defer_loading === true);
116
+ }
117
+ var COMPUTER_USE_BETA = "computer-use-2025-11-24";
118
+ function toAnthropicToolSchema(schema) {
119
+ if ("type" in schema && schema.type === "computer_20251124") {
120
+ return { ...schema };
121
+ }
122
+ if ("input_schema" in schema) {
123
+ const tool = schema;
124
+ const { cache_control: cacheControl, ...rest } = tool;
125
+ return {
126
+ ...rest,
127
+ type: "custom",
128
+ ...tool.defer_loading !== true && cacheControl ? { cache_control: cacheControl } : {}
129
+ };
130
+ }
131
+ throw new Error("Anthropic received a tool schema serialized for another protocol.");
116
132
  }
117
133
  var log = createChildLogger({ module: "llm" });
118
134
  var MODEL_FETCH_TIMEOUT_MS = 3e3;
@@ -196,7 +212,7 @@ function buildAnthropicMessages(messages) {
196
212
  type: "tool_use",
197
213
  // tool use **request**
198
214
  id: tu.toolUseId,
199
- name: tu.toolName,
215
+ name: tu.toolName === "ComputerUse" ? "computer" : tu.toolName,
200
216
  input: tu.arguments
201
217
  });
202
218
  }
@@ -256,6 +272,7 @@ function buildAnthropicMessages(messages) {
256
272
  return result;
257
273
  }
258
274
  var AnthropicClient = class {
275
+ protocol = "anthropic";
259
276
  client;
260
277
  model;
261
278
  /** Effective logical level for budget or explicitly configured adaptive mode. */
@@ -301,23 +318,10 @@ var AnthropicClient = class {
301
318
  async *stream(conversation, toolSchemas, abortSignal) {
302
319
  const messages = buildAnthropicMessages(ensureToolPairing(conversation.getMessages()));
303
320
  const sendToolSearchBeta = needsToolSearchBeta(toolSchemas);
304
- const antToolSchemas = toolSchemas.map((s) => {
305
- const tool = {
306
- name: s.name,
307
- description: s.description,
308
- // Preserve constraints and definitions, not just properties/required.
309
- input_schema: s.input_schema
310
- };
311
- if (s.strict !== void 0) {
312
- tool.strict = s.strict;
313
- }
314
- if (s.defer_loading === true) {
315
- tool.defer_loading = true;
316
- } else if (s.cache_control) {
317
- tool.cache_control = s.cache_control;
318
- }
319
- return tool;
320
- });
321
+ const antToolSchemas = toolSchemas.map(toAnthropicToolSchema);
322
+ const sendComputerUseBeta = antToolSchemas.some(
323
+ (schema) => "type" in schema && schema.type === "computer_20251124"
324
+ );
321
325
  markToolsForCache(antToolSchemas);
322
326
  markLastUserTailForCache(messages);
323
327
  const params = {
@@ -335,7 +339,10 @@ var AnthropicClient = class {
335
339
  }
336
340
  ],
337
341
  messages,
338
- ...antToolSchemas.length > 0 ? { tools: antToolSchemas } : {}
342
+ ...antToolSchemas.length > 0 ? (
343
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
344
+ { tools: antToolSchemas }
345
+ ) : {}
339
346
  };
340
347
  const level = this.getThinkingLevel();
341
348
  if (this.config.reasoning !== false) {
@@ -369,11 +376,13 @@ var AnthropicClient = class {
369
376
  let thinkingSignature = "";
370
377
  let inThinking = false;
371
378
  try {
379
+ const betas = [
380
+ ...sendToolSearchBeta ? [NATIVE_TOOL_USE_BETA] : [],
381
+ ...sendComputerUseBeta ? [COMPUTER_USE_BETA] : []
382
+ ];
372
383
  const response = this.client.messages.stream(params, {
373
384
  ...abortSignal ? { signal: abortSignal } : {},
374
- // If any tool uses defer_loading this beta header is required, otherwise the server does not recognize the field.
375
- // Only the official endpoint reaches this code path (see mcp/strategy).
376
- ...sendToolSearchBeta ? { headers: { "anthropic-beta": NATIVE_TOOL_USE_BETA } } : {}
385
+ ...betas.length > 0 ? { headers: { "anthropic-beta": betas.join(",") } } : {}
377
386
  });
378
387
  let currentToolName = "";
379
388
  let currentToolId = "";
@@ -388,7 +397,7 @@ var AnthropicClient = class {
388
397
  thinkingSignature = "";
389
398
  } else if (block.type === "tool_use") {
390
399
  currentToolId = block.id;
391
- currentToolName = block.name;
400
+ currentToolName = block.name === "computer" ? "ComputerUse" : block.name;
392
401
  jsonAccumulate = "";
393
402
  yield {
394
403
  type: "tool_call_start",