@swifty.js/swifty 0.0.29 → 0.0.30

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 (35) hide show
  1. package/README.md +11 -11
  2. package/dist/{agent-YR6YK26C.js → agent-TCNIRVHD.js} +1 -1
  3. package/dist/anthropic-7RIVSEDF.js +4 -0
  4. package/dist/{checker-N5TIJEN5.js → checker-3LHDOATB.js} +1 -1
  5. package/dist/chunk-2IBMB3ZM.js +150 -0
  6. package/dist/chunk-AQ3A5CF4.js +5 -0
  7. package/dist/chunk-FA26MQ7K.js +257 -0
  8. package/dist/chunk-TKADLB2Q.js +4 -0
  9. package/dist/chunk-VA64DJNN.js +4 -0
  10. package/dist/lib/{agent-5WEKVRTD.js → agent-IRY7KR5D.js} +2 -2
  11. package/dist/lib/{anthropic-KWO3KLNV.js → anthropic-CL5IK7KN.js} +2 -2
  12. package/dist/lib/{checker-AXHPKVBY.js → checker-BS4MK3O6.js} +1 -1
  13. package/dist/lib/{chunk-2IVEVG5N.js → chunk-7QPDFSQE.js} +10 -17
  14. package/dist/lib/{chunk-3FBS5NB7.js → chunk-I7OPU4K2.js} +27 -11
  15. package/dist/lib/{chunk-KZSBR4FO.js → chunk-IYPTOY3Y.js} +48 -21
  16. package/dist/lib/{chunk-GCY44T7S.js → chunk-OOSNCCI7.js} +129 -254
  17. package/dist/lib/{chunk-Z4CYHTII.js → chunk-OQIQOU5S.js} +85 -26
  18. package/dist/lib/{chunk-DJ6AILPN.js → chunk-RMB3J46W.js} +13 -16
  19. package/dist/lib/index.d.ts +325 -123
  20. package/dist/lib/index.js +791 -1078
  21. package/dist/lib/{openai-PBF7EWNJ.js → openai-LH4E7ZQS.js} +2 -2
  22. package/dist/lib/{tool-filter-R6HDDJHE.js → tool-filter-CS6W2GMU.js} +1 -1
  23. package/dist/main.js +186 -178
  24. package/dist/{openai-QQ2K7GPF.js → openai-RZLCY55V.js} +15 -15
  25. package/dist/{server-G23HCFLI.js → server-IVIRQTO7.js} +17 -17
  26. package/dist/{tool-filter-VBP6WOGO.js → tool-filter-CG3KGQQW.js} +1 -1
  27. package/package.json +4 -3
  28. package/dist/anthropic-5GRR5JCT.js +0 -4
  29. package/dist/chunk-D34FUVGU.js +0 -4
  30. package/dist/chunk-LIMEBKCY.js +0 -408
  31. package/dist/chunk-POHIQUFP.js +0 -301
  32. package/dist/chunk-TMEX7RFA.js +0 -4
  33. package/dist/chunk-Y6SQB5FG.js +0 -4
  34. package/dist/glob.wasm +0 -0
  35. package/dist/lib/glob.wasm +0 -0
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env node
2
+ import { createRequire as __swiftyCreateRequire } from "node:module";
3
+ const require = __swiftyCreateRequire(import.meta.url);
4
+ import{c as A}from"./chunk-QCKJLO6X.js";import{D as h,I as j,R as u,d as b,e as F}from"./chunk-OTVZGPHD.js";import{b as S}from"./chunk-E55KH72M.js";import{readFileSync as B,writeFileSync as G,mkdirSync as U,statSync as T}from"fs";import{homedir as J,tmpdir as X}from"os";import{join as g,resolve as l,dirname as C}from"path";import{realpathSync as M}from"fs";import{basename as O,dirname as z,isAbsolute as L,join as I,relative as N,resolve as W,sep as Y}from"path";function d(i){let e=W(i),t=[];for(;;)try{return I(M(e),...t)}catch(n){if(!(n instanceof Error)||!("code"in n)||n.code!=="ENOENT"&&n.code!=="ENOTDIR")throw n;let r=z(e);if(r===e)return W(i);t.unshift(O(e)),e=r}}function p(i,e){let t=N(i,e);return t===""||t!==".."&&!t.startsWith(`..${Y}`)&&!L(t)}var P=j({module:"permissions"}),q=[],H=["ls","pwd","echo","cat","head","tail","wc","date","whoami","uname","hostname","which","type","file","git status","git log","git diff","git branch","git show","git rev-parse","git remote","bun test","bun run","npm test","npm run","go test","go build","go vet","python -c","node -e"],K={Bash:"command",PowerShell:"command",ReadFile:"file_path",WriteFile:"file_path",EditFile:"file_path",Glob:"pattern",Grep:"pattern",InstallSkill:"source"},Q=[".swifty/permissions.yaml",".agents/skills/"];function R(i,e){if(i===S)return A(u(e,"server",""),u(e,"tool",""));let t=K[i];if(!t)return"";let n=e[t];return typeof n=="string"?n:""}var x=class{allowedRoots;denyWritePaths;projectDir;constructor(e){this.projectDir=l(e),this.allowedRoots=[this.projectDir,X()],this.denyWritePaths=Q.map(t=>g(this.projectDir,t))}addRoot(e){this.allowedRoots.push(l(e))}addDenyWrite(e){this.denyWritePaths.push(l(e))}checkDenyWrite(e){let t=l(this.projectDir,e),n=d(t);for(let r of this.denyWritePaths)if(p(r,t)||p(d(r),n))return{effect:"deny",reason:`Path ${e} is in deny-write list`};return null}check(e){let t=d(l(this.projectDir,e));for(let n of this.allowedRoots)if(p(d(n),t))return null;return{effect:"deny",reason:`Path ${e} is outside allowed directories`}}};function V(i,e){let t="^"+i.replace(/[.+^${}()|[\]\\]/g,"\\$&").replace(/\*/g,".*").replace(/\?/g,".")+"$";try{return new RegExp(t).test(e)}catch(n){return P.error({err:n},"permissions operation failed"),!1}}var Z=/^(\w+)\((.+)\)$/;function $(i){let e;try{e=B(i,"utf-8")}catch(s){return s.code!=="ENOENT"&&P.error({err:s},"permissions operation failed"),[]}let t=h.object({rule:h.string().optional(),effect:h.string().optional()}),n;try{let s=b.load(e);n=F(h.array(t),s)}catch(s){return P.error({err:s},"permissions operation failed"),[]}let r=[];for(let s of n){if(s.effect!=="allow"&&s.effect!=="deny"&&s.effect!=="ask")continue;let o=Z.exec((s.rule??"").trim());o&&r.push({tool:o[1],pattern:o[2],effect:s.effect})}return r}function m(i,e,t){let n=null;for(let r of i)if(!(r.tool!==e&&r.tool!=="*")&&V(r.pattern,t)){if(r.effect==="deny")return"deny";r.effect==="ask"?n="ask":n??="allow"}return n}var D=class{userPath;projectPath;cache=new Map;constructor(e){this.userPath=g(J(),".swifty","permissions.yaml"),this.projectPath=g(e,".swifty","permissions.yaml")}rulesFor(e){let t;try{t=T(e,{bigint:!0})}catch{return this.cache.delete(e),[]}let n=this.cache.get(e);if(n?.mtimeNs===t.mtimeNs&&n.size===t.size)return n.rules;let r=$(e);return this.cache.set(e,{mtimeNs:t.mtimeNs,size:t.size,rules:r}),r}snapshot(){return[this.userPath,this.projectPath].flatMap(e=>this.rulesFor(e))}evaluate(e,t){return m(this.snapshot(),e,t)}appendProjectRule(e){U(C(this.projectPath),{recursive:!0});let t=$(this.projectPath);if(t.some(s=>s.tool===e.tool&&s.pattern===e.pattern&&s.effect===e.effect))return;t.push(e);let r=t.map(s=>({rule:`${s.tool}(${s.pattern})`,effect:s.effect}));G(this.projectPath,b.dump(r),"utf-8")}};function ee(i){for(let e of q)if(e.re.test(i))return e.reason;return""}function te(i){let e=i.trim();return e.includes(">")||e.includes("<")||/[\r\n&]/.test(e)||e.includes("|")||e.includes(";")||e.includes("&&")||e.includes("$(")||e.includes("`")?!1:H.some(t=>e===t||e.startsWith(t+" ")||e.startsWith(t+" "))}function ne(i,e){switch(i){case"bypassPermissions":return"allow";case"plan":return e==="read"?"allow":"ask";case"acceptEdits":return e==="command"?"ask":"allow";default:return e==="read"?"allow":"ask"}}var _=class i{constructor(e,t="default"){this.workDir=e;this.mode=t,this.sandbox=new x(e),this.ruleEngine=new D(e)}workDir;mode;planFilePath="";sandboxEnabled=!1;sandboxAutoAllow=!1;sandbox;ruleEngine;forWorkDir(e){let t=new i(e,this.mode);return t.ruleEngine=this.ruleEngine,t.sandboxEnabled=this.sandboxEnabled,t.sandboxAutoAllow=this.sandboxAutoAllow,t}check(e,t,n){let r=R(e,n),s=null,o=()=>s??=this.ruleEngine.snapshot(),a=m(o(),e,r);if(a==="deny"||a==="ask")return{effect:a,reason:`Permission rule: ${a}`};if(this.mode==="plan"&&(e==="WriteFile"||e==="EditFile")){let f=u(n,"file_path","");if(this.planFilePath&&d(l(this.workDir,f))===d(l(this.workDir,this.planFilePath))&&!this.sandbox.checkDenyWrite(f))return{effect:"allow",reason:"Plan file write allowed in plan mode"}}if(t==="command"&&te(r))return{effect:"allow",reason:"Safe read-only command"};let k=t==="command"?ee(r):"";if(k)return{effect:"deny",reason:`Dangerous command blocked: ${k}`};if(this.sandboxEnabled&&this.sandboxAutoAllow&&e==="Bash"){let f=u(n,"command").split(/\s*(?:&&|\|\||[;|])\s*/).map(y=>y.trim()).filter(Boolean),c=!1;for(let y of f){let v=m(o(),e,y);if(v==="deny")return{effect:"deny",reason:"Permission rule: deny"};v==="ask"&&(c=!0)}return c?{effect:"ask",reason:"Permission rule: ask (sandbox does not override)"}:{effect:"allow",reason:"Sandbox auto-allow: OS sandbox active"}}let w=u(n,"file_path",u(n,"path",""));if((t==="read"||t==="write")&&w){if(t==="write"){let c=this.sandbox.checkDenyWrite(w);if(c)return c}let f=this.sandbox.check(w);if(f&&this.mode!=="bypassPermissions"){let c=this.ruleEngine.evaluate(e,r);return c?{effect:c,reason:`Permission rule: ${c}`}:{effect:"ask",reason:f.reason}}}let E=m(o(),e,r);return E?{effect:E,reason:`Permission rule: ${E}`}:{effect:ne(this.mode,t),reason:`Mode: ${this.mode}`}}allowExtraRoot(e){this.sandbox.addRoot(e)}allowAlways(e,t){let n=R(e,t),r=e==="ReadFile"||e==="WriteFile"||e==="EditFile",s;if(r&&n){let o=l(this.workDir,n),a=!1;try{a=T(o).isDirectory()}catch{}s=g(a?o:C(o),"*")}else s=n.trim().split(/\s+/).slice(0,2).join(" ")+"*";this.ruleEngine.appendProjectRule({tool:e,pattern:s,effect:"allow"})}describeToolAction(e,t){let n=R(e,t);if(n)return n;let r=[];for(let[s,o]of Object.entries(t)){let a=String(o);a.length>80&&(a=a.slice(0,80)+"..."),r.push(`${s}: ${a}`)}return r.join(", ")}};export{d as a,p as b,R as c,x as d,m as e,D as f,te as g,_ as h};
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env node
2
+ import { createRequire as __swiftyCreateRequire } from "node:module";
3
+ const require = __swiftyCreateRequire(import.meta.url);
4
+ import{a as m,b as T}from"./chunk-E55KH72M.js";var c=class{tools=new Map;discovered=new Set;mcpLoadingMode="eager";exposeToolSearch=!1;exposeMcpCall=!1;register(e){this.tools.set(e.name,e)}get(e){return this.tools.get(e)}listTools(){return[...this.tools.values()]}getAllSchemas(e="anthropic"){let o=e==="openai"||e==="openai-compat",t=this.mcpLoadingMode==="native"&&!o,n=[];for(let s of this.tools.values()){if(s.name===m&&!this.exposeToolSearch||s.name===T&&!this.exposeMcpCall)continue;let a=!!s.deferred&&!this.discovered.has(s.name);if(a&&!t)continue;let i=s.schema();e==="openai"?n.push({strict:i.strict??!1,type:"function",name:i.name,description:i.description,parameters:i.input_schema}):e==="openai-compat"?n.push({type:"function",function:{name:i.name,description:i.description,parameters:i.input_schema,strict:i.strict??!1}}):n.push({...i,type:"custom",...a?{defer_loading:!0}:{}})}return n}getDeferredToolNames(){let e=[];for(let o of this.tools.values())o.deferred&&!this.discovered.has(o.name)&&e.push(o.name);return e.sort()}getDeferredTools(){return[...this.tools.values()].filter(e=>e.deferred&&!this.discovered.has(e.name))}searchDeferred(e,o=5){let t=e.toLowerCase(),n=[];for(let s of this.tools.values())if(!(!s.deferred||this.discovered.has(s.name))&&(s.name.toLowerCase().includes(t)||s.description.toLowerCase().includes(t))&&(n.push(s),n.length>=o))break;return n}findDeferredByNames(e){let o=new Map;for(let[t,n]of this.tools)o.set(t.toLowerCase(),n);return e.map(t=>o.get(t.toLowerCase())).filter(t=>t?.deferred??!1)}markDiscovered(e){this.discovered.add(e)}isDiscovered(e){return this.discovered.has(e)}};var h=new Set(["ExitPlanMode","Agent","AskUserQuestion","TaskStop"]),M=new Set(["TeamCreate","TeamDelete"]),f=new Set(["ExitPlanMode","Agent","AskUserQuestion","TaskStop"]),u=new Set(["ReadFile","Grep","Glob","Bash","PowerShell","EditFile","WriteFile","LoadSkill","SyntheticOutput","ToolSearch","EnterWorktree","ExitWorktree","McpCall"]);function g(r){return r.startsWith("mcp__")}function C(r,e,o,t,n=!1){let s=new Set(o??[]),a=new Set(e??[]),i=a.size>0&&!(a.size===1&&a.has("*")),p=new c;p.mcpLoadingMode=r.mcpLoadingMode;for(let d of r.listTools()){let l=d.name;if(g(l)){!s.has(l)&&(!i||a.has(l))&&p.register(d);continue}h.has(l)||n&&f.has(l)||t&&!u.has(l)||s.has(l)||i&&!a.has(l)||p.register(d)}return p}var S="agent:builtin:fork";function w(r){let e=new c;e.mcpLoadingMode=r.mcpLoadingMode;for(let o of r.listTools())if(o.name==="Agent"&&"querySource"in o){let t=Object.create(Object.getPrototypeOf(o),Object.getOwnPropertyDescriptors(o));t.querySource=S,e.register(t)}else e.register(o);return e}export{c as a,h as b,M as c,f as d,u as e,C as f,S as g,w as h};
@@ -1,8 +1,8 @@
1
1
  import {
2
2
  Agent
3
- } from "./chunk-GCY44T7S.js";
3
+ } from "./chunk-OOSNCCI7.js";
4
4
  import "./chunk-PIL7M52F.js";
5
- import "./chunk-Z4CYHTII.js";
5
+ import "./chunk-OQIQOU5S.js";
6
6
  import "./chunk-KG4MJGKQ.js";
7
7
  import "./chunk-EY7HE52Q.js";
8
8
  import "./chunk-GHF2PSEW.js";
@@ -5,9 +5,9 @@ import {
5
5
  markLastUserTailForCache,
6
6
  markToolsForCache,
7
7
  needsToolSearchBeta
8
- } from "./chunk-KZSBR4FO.js";
8
+ } from "./chunk-IYPTOY3Y.js";
9
9
  import "./chunk-PIL7M52F.js";
10
- import "./chunk-Z4CYHTII.js";
10
+ import "./chunk-OQIQOU5S.js";
11
11
  import "./chunk-KG4MJGKQ.js";
12
12
  import "./chunk-EY7HE52Q.js";
13
13
  import "./chunk-GHF2PSEW.js";
@@ -5,7 +5,7 @@ import {
5
5
  evaluateRules,
6
6
  extractContent,
7
7
  isSafeCommand
8
- } from "./chunk-DJ6AILPN.js";
8
+ } from "./chunk-RMB3J46W.js";
9
9
  import "./chunk-KG4MJGKQ.js";
10
10
  import "./chunk-EY7HE52Q.js";
11
11
  import "./chunk-GHF2PSEW.js";
@@ -45,33 +45,26 @@ var ToolRegistry = class {
45
45
  continue;
46
46
  }
47
47
  const s = tool.schema();
48
- if (isOpenAI) {
48
+ if (protocol === "openai") {
49
49
  schemas.push({
50
- strict: false,
51
- // Whether to enforce strict parameter validation. Default true.
50
+ strict: s.strict ?? false,
52
51
  type: "function",
53
52
  name: s.name,
54
53
  description: s.description,
55
- parameters: s.input_schema,
56
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
57
- // @ts-ignore
54
+ parameters: s.input_schema
55
+ });
56
+ } else if (protocol === "openai-compat") {
57
+ schemas.push({
58
+ type: "function",
58
59
  function: {
59
60
  name: s.name,
60
61
  description: s.description,
61
- parameters: s.input_schema
62
+ parameters: s.input_schema,
63
+ strict: s.strict ?? false
62
64
  }
63
65
  });
64
66
  } else {
65
- schemas.push(
66
- deferred ? {
67
- ...s,
68
- type: "custom",
69
- defer_loading: true
70
- } : {
71
- ...s,
72
- type: "custom"
73
- }
74
- );
67
+ schemas.push({ ...s, type: "custom", ...deferred ? { defer_loading: true } : {} });
75
68
  }
76
69
  }
77
70
  return schemas;
@@ -4,12 +4,14 @@ import {
4
4
  LLMError,
5
5
  NetworkError,
6
6
  RateLimitError,
7
+ clampThinkingLevel,
7
8
  ensureToolPairing,
8
9
  getMaxOutputTokens,
10
+ getSupportedThinkingLevels,
9
11
  getThinkingLevel,
10
12
  resolveAPIKey,
11
13
  toReasoningEffort
12
- } from "./chunk-Z4CYHTII.js";
14
+ } from "./chunk-OQIQOU5S.js";
13
15
  import {
14
16
  asRecord,
15
17
  asString,
@@ -28,6 +30,7 @@ var OpenAIClient = class {
28
30
  systemPrompt;
29
31
  maxOutputTokens;
30
32
  thinkingLevel;
33
+ config;
31
34
  constructor(config, systemPrompt) {
32
35
  const apiKey = resolveAPIKey(config);
33
36
  if (!apiKey) {
@@ -42,6 +45,7 @@ var OpenAIClient = class {
42
45
  this.model = config.model;
43
46
  this.systemPrompt = systemPrompt;
44
47
  this.maxOutputTokens = getMaxOutputTokens(config);
48
+ this.config = { ...config };
45
49
  this.thinkingLevel = getThinkingLevel(config);
46
50
  }
47
51
  async *stream(conversation, toolSchemas, abortSignal) {
@@ -61,18 +65,19 @@ var OpenAIClient = class {
61
65
  name: s.name,
62
66
  description: s.description,
63
67
  parameters: schema,
64
- strict: false
68
+ strict: s.strict ?? false
65
69
  };
66
70
  });
71
+ const effort = toReasoningEffort(this.getThinkingLevel(), this.config);
67
72
  const params = {
68
73
  model: this.model,
69
74
  input,
70
75
  stream: true,
71
76
  max_output_tokens: this.maxOutputTokens,
72
77
  ...tools.length > 0 ? { tools } : {},
73
- // PI-equivalent thinking level Responses API reasoning effort. Omitted
74
- // entirely when thinking is off so non-reasoning models are unaffected.
75
- ...this.thinkingLevel !== "off" ? { reasoning: { effort: toReasoningEffort(this.thinkingLevel), summary: "auto" } } : {}
78
+ // Only explicit reasoning:false omits the field. Off sends none to defeat
79
+ // server-default reasoning; requesting a summary while off is unnecessary.
80
+ ...effort !== null ? { reasoning: { effort, ...effort !== "none" ? { summary: "auto" } : {} } } : {}
76
81
  };
77
82
  let inputTokens = 0;
78
83
  let outputTokens = 0;
@@ -198,11 +203,15 @@ var OpenAIClient = class {
198
203
  this.maxOutputTokens = maxTokens;
199
204
  }
200
205
  setThinkingLevel(level) {
201
- this.thinkingLevel = level;
206
+ this.thinkingLevel = clampThinkingLevel(this.config, level);
207
+ return this.thinkingLevel;
202
208
  }
203
209
  getThinkingLevel() {
204
210
  return this.thinkingLevel;
205
211
  }
212
+ getSupportedThinkingLevels() {
213
+ return getSupportedThinkingLevels(this.config);
214
+ }
206
215
  };
207
216
  function imageDataUrl(block) {
208
217
  if (!isRecord(block) || block.type !== "image" || !isRecord(block.source)) {
@@ -400,6 +409,7 @@ var OpenAICompatClient = class {
400
409
  systemPrompt;
401
410
  maxOutputTokens;
402
411
  thinkingLevel;
412
+ config;
403
413
  constructor(config, systemPrompt) {
404
414
  const apiKey = resolveAPIKey(config);
405
415
  if (!apiKey) {
@@ -411,6 +421,7 @@ var OpenAICompatClient = class {
411
421
  this.model = config.model;
412
422
  this.systemPrompt = systemPrompt;
413
423
  this.maxOutputTokens = getMaxOutputTokens(config);
424
+ this.config = { ...config };
414
425
  this.thinkingLevel = getThinkingLevel(config);
415
426
  }
416
427
  setSystemPrompt(prompt) {
@@ -420,11 +431,15 @@ var OpenAICompatClient = class {
420
431
  this.maxOutputTokens = maxTokens;
421
432
  }
422
433
  setThinkingLevel(level) {
423
- this.thinkingLevel = level;
434
+ this.thinkingLevel = clampThinkingLevel(this.config, level);
435
+ return this.thinkingLevel;
424
436
  }
425
437
  getThinkingLevel() {
426
438
  return this.thinkingLevel;
427
439
  }
440
+ getSupportedThinkingLevels() {
441
+ return getSupportedThinkingLevels(this.config);
442
+ }
428
443
  async *stream(conversation, toolSchemas, abortSignal) {
429
444
  const messages = [
430
445
  {
@@ -441,9 +456,10 @@ var OpenAICompatClient = class {
441
456
  name: ts.name,
442
457
  description: ts.description,
443
458
  parameters: ts.input_schema,
444
- strict: false
459
+ strict: ts.strict ?? false
445
460
  }
446
461
  }));
462
+ const effort = toReasoningEffort(this.getThinkingLevel(), this.config);
447
463
  const params = {
448
464
  model: this.model,
449
465
  messages,
@@ -451,9 +467,9 @@ var OpenAICompatClient = class {
451
467
  stream_options: { include_usage: true },
452
468
  max_tokens: this.maxOutputTokens,
453
469
  ...tools.length > 0 ? { tools } : {},
454
- // PI-equivalent thinking level Chat Completions reasoning_effort.
455
- // Omitted when thinking is off so non-reasoning models are unaffected.
456
- ...this.thinkingLevel !== "off" ? { reasoning_effort: toReasoningEffort(this.thinkingLevel) } : {}
470
+ // Configured non-reasoning providers omit the field; off otherwise sends
471
+ // none explicitly so a server default cannot silently enable reasoning.
472
+ ...effort !== null ? { reasoning_effort: effort } : {}
457
473
  };
458
474
  let inputTokens = 0;
459
475
  let outputTokens = 0;
@@ -5,14 +5,19 @@ import {
5
5
  AuthenticationError,
6
6
  ContextTooLongError,
7
7
  LLMError,
8
+ MIN_THINKING_ANSWER_TOKENS,
8
9
  NetworkError,
9
10
  RateLimitError,
11
+ clampThinkingLevel,
10
12
  ensureToolPairing,
11
13
  getMaxOutputTokens,
14
+ getSupportedThinkingLevels,
12
15
  getThinkingLevel,
13
16
  resolveAPIKey,
14
- thinkingBudgetForLevel
15
- } from "./chunk-Z4CYHTII.js";
17
+ thinkingBudgetForLevel,
18
+ toAnthropicThinkingEffort,
19
+ toReasoningEffort
20
+ } from "./chunk-OQIQOU5S.js";
16
21
  import {
17
22
  MCP_TOOL_PREFIX,
18
23
  isMcpToolLike
@@ -96,8 +101,6 @@ function decideAndApply(registry, baseUrl, contextWindow) {
96
101
  }
97
102
 
98
103
  // src/llm/anthropic.ts
99
- var MIN_THINKING_BUDGET_TOKENS = 1024;
100
- var MIN_ANSWER_TOKENS = 1024;
101
104
  function markToolsForCache(tools) {
102
105
  for (let i = tools.length - 1; i >= 0; i--) {
103
106
  const t = tools[i];
@@ -255,13 +258,11 @@ function buildAnthropicMessages(messages) {
255
258
  var AnthropicClient = class {
256
259
  client;
257
260
  model;
258
- /**
259
- * PI-equivalent thinking level; maps to a thinking token budget.
260
- */
261
+ /** Effective logical level for budget or explicitly configured adaptive mode. */
261
262
  thinkingLevel;
262
263
  systemPrompt;
263
264
  maxOutputTokens;
264
- /** Currently not used */
265
+ config;
265
266
  constructor(config, systemPrompt) {
266
267
  const apiKey = resolveAPIKey(config);
267
268
  if (!apiKey) {
@@ -274,6 +275,7 @@ var AnthropicClient = class {
274
275
  baseURL: config.base_url
275
276
  });
276
277
  this.model = config.model;
278
+ this.config = { ...config };
277
279
  this.thinkingLevel = getThinkingLevel(config);
278
280
  this.systemPrompt = systemPrompt;
279
281
  this.maxOutputTokens = getMaxOutputTokens(config);
@@ -282,30 +284,37 @@ var AnthropicClient = class {
282
284
  this.systemPrompt = prompt;
283
285
  }
284
286
  setMaxOutputTokens(maxTokens) {
285
- this.maxOutputTokens = maxTokens;
287
+ this.config = { ...this.config, max_output_tokens: maxTokens };
288
+ this.maxOutputTokens = getMaxOutputTokens(this.config);
289
+ this.setThinkingLevel(this.thinkingLevel);
286
290
  }
287
291
  setThinkingLevel(level) {
288
- this.thinkingLevel = level;
292
+ this.thinkingLevel = clampThinkingLevel(this.config, level);
293
+ return this.thinkingLevel;
289
294
  }
290
295
  getThinkingLevel() {
291
296
  return this.thinkingLevel;
292
297
  }
298
+ getSupportedThinkingLevels() {
299
+ return getSupportedThinkingLevels(this.config);
300
+ }
293
301
  async *stream(conversation, toolSchemas, abortSignal) {
294
302
  const messages = buildAnthropicMessages(ensureToolPairing(conversation.getMessages()));
295
303
  const sendToolSearchBeta = needsToolSearchBeta(toolSchemas);
296
304
  const antToolSchemas = toolSchemas.map((s) => {
297
- const inputSchema = s.input_schema;
298
305
  const tool = {
299
306
  name: s.name,
300
307
  description: s.description,
301
- input_schema: {
302
- type: "object",
303
- properties: inputSchema.properties,
304
- required: inputSchema.required ?? []
305
- }
308
+ // Preserve constraints and definitions, not just properties/required.
309
+ input_schema: s.input_schema
306
310
  };
311
+ if (s.strict !== void 0) {
312
+ tool.strict = s.strict;
313
+ }
307
314
  if (s.defer_loading === true) {
308
315
  tool.defer_loading = true;
316
+ } else if (s.cache_control) {
317
+ tool.cache_control = s.cache_control;
309
318
  }
310
319
  return tool;
311
320
  });
@@ -328,11 +337,29 @@ var AnthropicClient = class {
328
337
  messages,
329
338
  ...antToolSchemas.length > 0 ? { tools: antToolSchemas } : {}
330
339
  };
331
- const budgetCeiling = this.maxOutputTokens - MIN_ANSWER_TOKENS;
332
- params.thinking = this.thinkingLevel !== "off" && budgetCeiling >= MIN_THINKING_BUDGET_TOKENS ? {
333
- type: "enabled",
334
- budget_tokens: Math.min(thinkingBudgetForLevel(this.thinkingLevel), budgetCeiling)
335
- } : { type: "disabled" };
340
+ const level = this.getThinkingLevel();
341
+ if (this.config.reasoning !== false) {
342
+ if (level === "off") {
343
+ params.thinking = { type: "disabled" };
344
+ } else if (this.config.thinking_mode === "adaptive") {
345
+ const effort = toAnthropicThinkingEffort(level, this.config);
346
+ if (effort !== null) {
347
+ params.thinking = { type: "adaptive" };
348
+ params.output_config = { effort };
349
+ }
350
+ } else {
351
+ const effort = toReasoningEffort(level, this.config);
352
+ if (effort !== null && effort !== "none") {
353
+ params.thinking = {
354
+ type: "enabled",
355
+ budget_tokens: Math.min(
356
+ thinkingBudgetForLevel(effort),
357
+ this.maxOutputTokens - MIN_THINKING_ANSWER_TOKENS
358
+ )
359
+ };
360
+ }
361
+ }
362
+ }
336
363
  let inputTokens = 0;
337
364
  let outputTokens = 0;
338
365
  let cacheReadInputTokens = 0;