@theokit/sdk 4.54.0 → 4.55.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.
Files changed (72) hide show
  1. package/CHANGELOG.md +96 -0
  2. package/dist/{agent-CIUgz7cN.d.cts → agent-D3Xr_-6Z.d.cts} +61 -6
  3. package/dist/{agent-DSec-E0c.d.ts → agent-DIu6FooJ.d.ts} +61 -6
  4. package/dist/{agent-VGD5WL4N.js → agent-HDEVVUBS.js} +7 -7
  5. package/dist/{agent-VGD5WL4N.js.map → agent-HDEVVUBS.js.map} +1 -1
  6. package/dist/{agent-NOEGF4GI.cjs → agent-R2HOJFZJ.cjs} +8 -8
  7. package/dist/{agent-NOEGF4GI.cjs.map → agent-R2HOJFZJ.cjs.map} +1 -1
  8. package/dist/{chunk-SSQZA3DZ.js → chunk-2BDH744Z.js} +3 -3
  9. package/dist/{chunk-SSQZA3DZ.js.map → chunk-2BDH744Z.js.map} +1 -1
  10. package/dist/chunk-6HTXPPHK.cjs +18 -0
  11. package/dist/{chunk-3KGLRRFC.cjs.map → chunk-6HTXPPHK.cjs.map} +1 -1
  12. package/dist/{chunk-UFAO4T7Z.cjs → chunk-F5WMX4EA.cjs} +114 -73
  13. package/dist/chunk-F5WMX4EA.cjs.map +1 -0
  14. package/dist/{chunk-UNDROG5N.cjs → chunk-HLPSLDGL.cjs} +94 -26
  15. package/dist/chunk-HLPSLDGL.cjs.map +1 -0
  16. package/dist/{chunk-TPTZA6NI.js → chunk-I5BE5M5L.js} +68 -27
  17. package/dist/chunk-I5BE5M5L.js.map +1 -0
  18. package/dist/{chunk-TTHBHAJI.cjs → chunk-ITSSOVOB.cjs} +4 -4
  19. package/dist/{chunk-TTHBHAJI.cjs.map → chunk-ITSSOVOB.cjs.map} +1 -1
  20. package/dist/{chunk-AGSBJD2L.js → chunk-IVNNSANC.js} +3 -3
  21. package/dist/{chunk-AGSBJD2L.js.map → chunk-IVNNSANC.js.map} +1 -1
  22. package/dist/{chunk-VDEWG5TV.js → chunk-MVAPK2BX.js} +77 -9
  23. package/dist/chunk-MVAPK2BX.js.map +1 -0
  24. package/dist/{chunk-RM7Y65IG.cjs → chunk-NIRE5CNO.cjs} +10 -3
  25. package/dist/{chunk-FXEUP75G.js.map → chunk-NIRE5CNO.cjs.map} +1 -1
  26. package/dist/{chunk-DUIF54UP.js → chunk-OHBIUXKM.js} +3 -3
  27. package/dist/{chunk-DUIF54UP.js.map → chunk-OHBIUXKM.js.map} +1 -1
  28. package/dist/{chunk-FXEUP75G.js → chunk-Q4CMI2LP.js} +9 -2
  29. package/dist/chunk-Q4CMI2LP.js.map +1 -0
  30. package/dist/{chunk-5BJV5UPY.cjs → chunk-V2UUGUY4.cjs} +3 -3
  31. package/dist/{chunk-5BJV5UPY.cjs.map → chunk-V2UUGUY4.cjs.map} +1 -1
  32. package/dist/{compact-session-K5LXTBPJ.js → compact-session-FUJDVF7B.js} +4 -4
  33. package/dist/{compact-session-K5LXTBPJ.js.map → compact-session-FUJDVF7B.js.map} +1 -1
  34. package/dist/{compact-session-YCT6JMBX.cjs → compact-session-LEWF554G.cjs} +12 -12
  35. package/dist/{compact-session-YCT6JMBX.cjs.map → compact-session-LEWF554G.cjs.map} +1 -1
  36. package/dist/{cron-DxxeQ-sK.d.cts → cron-BcWmzWzT.d.cts} +1 -1
  37. package/dist/{cron-CRwy2JBF.d.ts → cron-De6hzWCF.d.ts} +1 -1
  38. package/dist/cron.cjs +7 -7
  39. package/dist/cron.d.cts +2 -2
  40. package/dist/cron.d.ts +2 -2
  41. package/dist/cron.js +6 -6
  42. package/dist/eval.cjs +6 -6
  43. package/dist/eval.js +5 -5
  44. package/dist/index.cjs +36 -36
  45. package/dist/index.d.cts +3 -3
  46. package/dist/index.d.ts +3 -3
  47. package/dist/index.js +8 -8
  48. package/dist/{inject-session-DDR6X6PC.js → inject-session-BJMJH5BX.js} +3 -3
  49. package/dist/{inject-session-DDR6X6PC.js.map → inject-session-BJMJH5BX.js.map} +1 -1
  50. package/dist/{inject-session-XLO3KTBM.cjs → inject-session-WQGGMCQY.cjs} +4 -4
  51. package/dist/{inject-session-XLO3KTBM.cjs.map → inject-session-WQGGMCQY.cjs.map} +1 -1
  52. package/dist/internal/llm/prompt-cache-key.d.ts +1 -0
  53. package/dist/internal/llm/responses.d.ts +67 -1
  54. package/dist/internal/llm/types.d.ts +15 -0
  55. package/dist/internal/local-agent/real-local-run-tools.d.ts +17 -6
  56. package/dist/models.cjs +9 -9
  57. package/dist/models.js +1 -1
  58. package/dist/providers.cjs +4 -4
  59. package/dist/providers.js +2 -2
  60. package/dist/subagents-loader.d.cts +1 -1
  61. package/dist/subagents-loader.d.ts +1 -1
  62. package/dist/types/agent.d.ts +47 -5
  63. package/dist/types/provider-profile.d.ts +13 -0
  64. package/docs/error-codes.md +19 -19
  65. package/docs/harness-capability-map.md +2 -1
  66. package/package.json +1 -1
  67. package/dist/chunk-3KGLRRFC.cjs +0 -18
  68. package/dist/chunk-RM7Y65IG.cjs.map +0 -1
  69. package/dist/chunk-TPTZA6NI.js.map +0 -1
  70. package/dist/chunk-UFAO4T7Z.cjs.map +0 -1
  71. package/dist/chunk-UNDROG5N.cjs.map +0 -1
  72. package/dist/chunk-VDEWG5TV.js.map +0 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,101 @@
1
1
  # Changelog
2
2
 
3
+ ## 4.55.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 1988b1d: Responses-API requests now carry `prompt_cache_key`, so the provider can reuse the cached prompt
8
+ prefix between rounds instead of re-charging the whole system prompt and tool schema every time.
9
+
10
+ Measured on a consumer product against OpenAI Codex — same provider, same model, same reasoning
11
+ effort, same task — the SDK sent a THIRD of the bytes (24,691 c vs 76,331 c) and paid 2.8x the tokens
12
+ (24,914 vs 9,036). The difference was not what was sent; it was that theirs was cached and ours was
13
+ not, because no key told the provider which prefix to match.
14
+
15
+ The key is derived (SHA-256, truncated, prefixed) from the run's session identity — the id
16
+ `Agent.getOrCreate(sessionId)` keys on — so it is identical across every round of a turn and every
17
+ turn of a session, different for unrelated sessions, and stable across a process restart, while
18
+ disclosing nothing about a caller-chosen session name. Both halves matter: a key that changes per
19
+ round caches nothing, and a key shared between sessions asks the provider to match one conversation's
20
+ prefix against another's.
21
+
22
+ Alongside it, a provider profile may now declare `encryptedReasoning: true`. When it does, the
23
+ request adds `include: ["reasoning.encrypted_content"]` and `reasoning.context: "all_turns"`, and the
24
+ transport replays the ciphertext the provider returned immediately before the tool call it produced,
25
+ so the model does not re-derive its chain of thought on every round. It is off by default and on for
26
+ the builtin `openai-chatgpt` profile: `include` is a documented Responses-API field but
27
+ `reasoning.context` is not, and that endpoint is the one where acceptance was observed rather than
28
+ assumed. Every other provider's request body is unchanged.
29
+
30
+ `store` stays `false`, now as a recorded decision rather than an unexamined default. Codex sends
31
+ `true`; SDK requests routinely carry a consumer's source code and shell output from machines whose
32
+ operator never agreed to server-side retention, and nothing in the caching work needs it — the cache
33
+ key handles the prefix and the encrypted-reasoning carry is precisely the mechanism for keeping
34
+ reasoning without server-side state.
35
+
36
+ Fixes `usetheokit/theokit-sdk#383`.
37
+
38
+ - 63b0831: A local agent can now withhold the SDK's builtin tools from the catalog it declares to the model,
39
+ and a disabled memory store no longer writes a session transcript into the consumer's repository.
40
+
41
+ `AgentOptions.withheldBuiltinTools?: readonly BuiltinToolName[]` names builtins — `shell`,
42
+ `memory_search`, `memory_get` — that this agent must not declare. Absent or empty, every builtin the
43
+ rest of the configuration would register is declared exactly as before, so nothing changes for an
44
+ agent that does not ask.
45
+
46
+ The option exists because denying a tool and never offering it are different things. A consumer
47
+ whose sandbox scope cannot admit `shell` could already refuse the call in a `pre_tool_call` hook, and
48
+ paid for the tool twice anyway: 267 characters of schema in every request of every round, plus a
49
+ round the model can spend discovering a refusal it had no way to anticipate. Withholding removes the
50
+ tool from the catalog, so the model is never shown what it cannot have. Withholding also releases the
51
+ name — a withheld `shell` may be replaced by a custom tool called `shell` without the
52
+ `tool_reserved_name` error, since the reservation exists to prevent a collision that no longer
53
+ exists. Builtins still declared stay reserved.
54
+
55
+ Fixes `usetheokit/theokit-sdk#381`.
56
+
57
+ `memory: { enabled: false }` now suppresses the per-run session transcript at
58
+ `<cwd>/.theokit/memory/sessions/<runId>.md`. It previously did not: that write was gated on the run's
59
+ status and nothing else, so an agent with memory switched off still had the full user prompt and
60
+ assistant reply written into the working directory — someone else's git repository, in the reported
61
+ case. Every other memory surface already honoured the flag, so "memory is off" was true of the
62
+ subsystem apart from the one part of it that creates files. Both writers are covered, the legacy
63
+ call and the `MemoryProvider.recordSessionSummary` port.
64
+
65
+ Leaving `memory` unset is unchanged and still writes, because that file is what
66
+ `memory_search({ corpus: "sessions" })` reads once memory is switched on; treating an absent config
67
+ as off would empty that corpus for consumers who asked for nothing. Writing `enabled: false` is the
68
+ opt-out.
69
+
70
+ So: if you run an agent inside a repository and were adding `.theokit/` to `.gitignore` to keep
71
+ prompts and replies out of it, `memory: { enabled: false }` now stops them being written at all.
72
+ `memory_search({ corpus: "sessions" })` returns nothing for those runs, which is the trade — no
73
+ transcript on disk, nothing to recall from it.
74
+
75
+ Fixes `usetheokit/theokit-sdk#382`.
76
+
77
+ ### Patch Changes
78
+
79
+ - a3bdbd1: The Responses transport now reads `input_tokens_details.cached_tokens` and `.cache_write_tokens`,
80
+ so a consumer can tell what a turn actually cost.
81
+
82
+ `input_tokens` INCLUDES the slice the provider served from its prompt cache. This transport reported
83
+ `cacheReadTokens: 0` regardless, so adding input to output counted tokens nobody is paying for.
84
+ Measured on a three-round turn with `prompt_cache_key` in use: the provider reported
85
+ `cached_tokens: 4608` on every round, and the consumer received 9,835 where 619 were new — 16x.
86
+
87
+ The sibling Chat Completions transport has always read the equivalent
88
+ (`prompt_tokens_details.cached_tokens`); this one read `output_tokens_details.reasoning_tokens`
89
+ beside it and skipped this one. The response type declared neither, so it was invisible at the type
90
+ level too.
91
+
92
+ It matters beyond an inaccurate number: it makes the SDK look expensive when it is not. Comparing a
93
+ consumer against OpenAI Codex on identical tasks, the gross figure said 2.8x. Codex reports the net
94
+ figure (`non_cached_input + output`). Measured with the same formula on both sides, the same task
95
+ costs 14,317 against 13,560 — inside the run-to-run variance.
96
+
97
+ Fixes `usetheokit/theokit-sdk#386`.
98
+
3
99
  ## 4.54.0
4
100
 
5
101
  ### Minor Changes
@@ -551,6 +551,19 @@ interface ProviderProfile {
551
551
  * Default off — only enable for routes/models known to leak (e.g. a qwen3-coder profile variant).
552
552
  */
553
553
  extractToolCallsFromContent?: boolean;
554
+ /**
555
+ * Opt-in encrypted-reasoning carry for `apiMode: "responses_api"` (usetheokit/theokit-sdk#383).
556
+ * When `true`, the request adds `include: ["reasoning.encrypted_content"]` and
557
+ * `reasoning.context: "all_turns"`, and the transport replays the ciphertext the provider returned
558
+ * so the model does not re-derive its chain of thought on every round of a turn.
559
+ *
560
+ * Default off, and deliberately per-profile rather than per-`apiMode`: `include` is a documented
561
+ * Responses-API field but `reasoning.context` is not, so a provider that validates strictly
562
+ * answers it with `400`. Enable it only for a backend measured to accept both — the builtin
563
+ * `openai-chatgpt` profile is one, because issue #383 captured OpenAI Codex sending exactly these
564
+ * fields to that endpoint. Ignored by every other `apiMode`.
565
+ */
566
+ encryptedReasoning?: boolean;
554
567
  }
555
568
 
556
569
  /**
@@ -799,6 +812,19 @@ type Plugin = (BasePlugin & {
799
812
  * @public
800
813
  */
801
814
  type SettingSource = "project" | "user" | "team" | "mdm" | "plugins" | "all";
815
+ /**
816
+ * A tool the SDK declares to the model on its own initiative — not one the consumer passed in
817
+ * {@link AgentOptions.tools}, and not one an MCP server exposed.
818
+ *
819
+ * These three names are also the ones the SDK reserves: a custom tool may not claim them. Listing
820
+ * one in {@link AgentOptions.withheldBuiltinTools} both stops it being declared and releases the
821
+ * name, because nothing of the SDK's is occupying it any more.
822
+ *
823
+ * Named for usetheokit/theokit-sdk#381, which is the report that the catalog had no opt-out.
824
+ *
825
+ * @public
826
+ */
827
+ type BuiltinToolName = "shell" | "memory_search" | "memory_get";
802
828
  /**
803
829
  * Local agent configuration.
804
830
  *
@@ -809,14 +835,17 @@ type SettingSource = "project" | "user" | "team" | "mdm" | "plugins" | "all";
809
835
  * an evaluation invalidated this way: the working directory held the benchmark's answer key, and
810
836
  * two transcripts show the model citing it. Deny it explicitly if that matters —
811
837
  * `{ tool: "shell", action: "deny" }` on a {@link PermissionEngine} rule is terminal under every
812
- * permission mode, including `bypass`. Note the tool still appears in the advertised catalog, so
813
- * the model may attempt it and be refused, rather than never seeing it.
838
+ * permission mode, including `bypass`. A deny rule still leaves the tool in the advertised
839
+ * catalog, so the model may attempt it and be refused; to keep it out of the catalog entirely,
840
+ * pass `withheldBuiltinTools: ["shell"]` on {@link AgentOptions} (usetheokit/theokit-sdk#381).
814
841
  *
815
842
  * 2. **Finished runs write a transcript to disk**, at `.theokit/memory/sessions/<runId>.md` under
816
843
  * the workspace `cwd`, with the full prompt and reply. This happens with no `memory` config and
817
- * with `settingSources: []` — it is what `memory_search({ corpus: "sessions" })` reads. It is not
818
- * currently opt-out. If the workspace is a git repository, add `.theokit/` to `.gitignore`: one
819
- * report describes a transcript reaching a public repo before it was noticed.
844
+ * with `settingSources: []` — it is what `memory_search({ corpus: "sessions" })` reads. Opt out
845
+ * with `memory: { enabled: false }`, which suppresses the write entirely
846
+ * (usetheokit/theokit-sdk#382). Leaving `memory`
847
+ * unset still writes, so if the workspace is a git repository, add `.theokit/` to `.gitignore`:
848
+ * one report describes a transcript reaching a public repo before it was noticed.
820
849
  *
821
850
  * @public
822
851
  */
@@ -1220,6 +1249,32 @@ interface AgentOptions {
1220
1249
  * See {@link CustomTool}.
1221
1250
  */
1222
1251
  tools?: CustomTool[];
1252
+ /**
1253
+ * Builtin tools this agent must NOT declare to the model. Absent or empty ⇒ every builtin the
1254
+ * rest of the configuration would register is declared, exactly as before this option existed.
1255
+ *
1256
+ * WHY WITHHOLDING IS NOT THE SAME AS DENYING. A consumer that cannot allow `shell` — because it
1257
+ * reaches outside their own sandbox scope — can already refuse the call in a `pre_tool_call` hook
1258
+ * or with a {@link PermissionEngine} deny rule. That stops the execution and pays for the offer
1259
+ * twice over: the schema rides in EVERY request of EVERY round (measured at 267 characters for
1260
+ * `shell`, 1,462 for `memory_search` + `memory_get` together — usetheokit/theokit-sdk#381), and
1261
+ * the model can spend a whole round discovering a refusal it had no way to anticipate. Declaring
1262
+ * a tool that is guaranteed to be refused is the wrong shape; withholding removes it from the
1263
+ * catalog, so the model is never offered what it cannot have.
1264
+ *
1265
+ * WITHHOLDING RELEASES THE NAME. `withheldBuiltinTools: ["shell"]` lets {@link AgentOptions.tools}
1266
+ * declare a tool called `shell` without the `tool_reserved_name` error — the reservation exists to
1267
+ * stop a collision with the SDK's own tool, and there is no longer one to collide with. Every
1268
+ * builtin still declared stays reserved.
1269
+ *
1270
+ * This governs DECLARATION, not authorization. A withheld builtin is simply absent from the
1271
+ * catalog: a model that invents the name anyway gets `Unknown tool <name>` (exit 127) rather than
1272
+ * an execution, but nothing here evaluates a policy. Keep the deny rule if you need one that a
1273
+ * per-send `tools` override cannot reopen.
1274
+ *
1275
+ * @public
1276
+ */
1277
+ withheldBuiltinTools?: readonly BuiltinToolName[];
1223
1278
  /**
1224
1279
  * SE37 — opt-in reasoning. When `true`, the agent gets a chain-of-thought
1225
1280
  * preamble prepended to its system prompt AND the `think` reasoning tool
@@ -1583,4 +1638,4 @@ interface ListResult<T> {
1583
1638
  nextCursor?: string;
1584
1639
  }
1585
1640
 
1586
- export { type TelemetrySettings as $, type AgentOptions as A, type BudgetTracker as B, type CloudOptions as C, type PostAssistantReplyContext as D, type PostToolCallContext as E, type PreToolCallContext as F, type GetAgentOptions as G, type HookName as H, type InlineSkill as I, type PreUserSendContext as J, type PreUserSendResult as K, type LocalOptions as L, type MemorySettings as M, type ProviderTransform as N, type ProviderTransformContext as O, type Plugin as P, type SessionLifecycleContext as Q, type RecordSessionSummaryArgs as R, type SystemPromptResolver as S, type SessionRecord as T, type SessionStore as U, type SettingSource as V, Skill as W, type SkillsResolver as X, type SkillsResolverContext as Y, type SystemPromptContext as Z, type SystemPromptMemoryFact as _, type AgentDefinition as a, type ToolCallSummary as a0, type ToolResultTransformContext as a1, type TransformContext as a2, type SkillsSettings as b, type ListAgentsOptions as c, type ListResult as d, type SDKAgentInfo as e, type ListRunsOptions as f, type GetRunOptions as g, type AgentOperationOptions as h, type AgentDescription as i, type ProviderProfile as j, type MemoryProvider as k, type PreToolCallDecision as l, type ActiveMemoryPassArgs as m, type ActiveMemoryPassResult as n, type AgentSubagentDescription as o, type AgentToolDescription as p, type BudgetCheck as q, type BudgetTotal as r, type BudgetUsageEvent as s, type CloudEnv as t, type CloudRepo as u, type CreateSkillSpec as v, type MemoryProviderFactory as w, type MemoryProviderHandle as x, type MemoryProviderInitOptions as y, type PluginContext as z };
1641
+ export { type SystemPromptMemoryFact as $, type AgentOptions as A, type BudgetTracker as B, type CloudOptions as C, type PluginContext as D, type PostAssistantReplyContext as E, type PostToolCallContext as F, type GetAgentOptions as G, type HookName as H, type InlineSkill as I, type PreToolCallContext as J, type PreUserSendContext as K, type LocalOptions as L, type MemorySettings as M, type PreUserSendResult as N, type ProviderTransform as O, type Plugin as P, type ProviderTransformContext as Q, type RecordSessionSummaryArgs as R, type SystemPromptResolver as S, type SessionLifecycleContext as T, type SessionRecord as U, type SessionStore as V, type SettingSource as W, Skill as X, type SkillsResolver as Y, type SkillsResolverContext as Z, type SystemPromptContext as _, type AgentDefinition as a, type TelemetrySettings as a0, type ToolCallSummary as a1, type ToolResultTransformContext as a2, type TransformContext as a3, type SkillsSettings as b, type ListAgentsOptions as c, type ListResult as d, type SDKAgentInfo as e, type ListRunsOptions as f, type GetRunOptions as g, type AgentOperationOptions as h, type AgentDescription as i, type ProviderProfile as j, type MemoryProvider as k, type PreToolCallDecision as l, type ActiveMemoryPassArgs as m, type ActiveMemoryPassResult as n, type AgentSubagentDescription as o, type AgentToolDescription as p, type BudgetCheck as q, type BudgetTotal as r, type BudgetUsageEvent as s, type BuiltinToolName as t, type CloudEnv as u, type CloudRepo as v, type CreateSkillSpec as w, type MemoryProviderFactory as x, type MemoryProviderHandle as y, type MemoryProviderInitOptions as z };
@@ -551,6 +551,19 @@ interface ProviderProfile {
551
551
  * Default off — only enable for routes/models known to leak (e.g. a qwen3-coder profile variant).
552
552
  */
553
553
  extractToolCallsFromContent?: boolean;
554
+ /**
555
+ * Opt-in encrypted-reasoning carry for `apiMode: "responses_api"` (usetheokit/theokit-sdk#383).
556
+ * When `true`, the request adds `include: ["reasoning.encrypted_content"]` and
557
+ * `reasoning.context: "all_turns"`, and the transport replays the ciphertext the provider returned
558
+ * so the model does not re-derive its chain of thought on every round of a turn.
559
+ *
560
+ * Default off, and deliberately per-profile rather than per-`apiMode`: `include` is a documented
561
+ * Responses-API field but `reasoning.context` is not, so a provider that validates strictly
562
+ * answers it with `400`. Enable it only for a backend measured to accept both — the builtin
563
+ * `openai-chatgpt` profile is one, because issue #383 captured OpenAI Codex sending exactly these
564
+ * fields to that endpoint. Ignored by every other `apiMode`.
565
+ */
566
+ encryptedReasoning?: boolean;
554
567
  }
555
568
 
556
569
  /**
@@ -799,6 +812,19 @@ type Plugin = (BasePlugin & {
799
812
  * @public
800
813
  */
801
814
  type SettingSource = "project" | "user" | "team" | "mdm" | "plugins" | "all";
815
+ /**
816
+ * A tool the SDK declares to the model on its own initiative — not one the consumer passed in
817
+ * {@link AgentOptions.tools}, and not one an MCP server exposed.
818
+ *
819
+ * These three names are also the ones the SDK reserves: a custom tool may not claim them. Listing
820
+ * one in {@link AgentOptions.withheldBuiltinTools} both stops it being declared and releases the
821
+ * name, because nothing of the SDK's is occupying it any more.
822
+ *
823
+ * Named for usetheokit/theokit-sdk#381, which is the report that the catalog had no opt-out.
824
+ *
825
+ * @public
826
+ */
827
+ type BuiltinToolName = "shell" | "memory_search" | "memory_get";
802
828
  /**
803
829
  * Local agent configuration.
804
830
  *
@@ -809,14 +835,17 @@ type SettingSource = "project" | "user" | "team" | "mdm" | "plugins" | "all";
809
835
  * an evaluation invalidated this way: the working directory held the benchmark's answer key, and
810
836
  * two transcripts show the model citing it. Deny it explicitly if that matters —
811
837
  * `{ tool: "shell", action: "deny" }` on a {@link PermissionEngine} rule is terminal under every
812
- * permission mode, including `bypass`. Note the tool still appears in the advertised catalog, so
813
- * the model may attempt it and be refused, rather than never seeing it.
838
+ * permission mode, including `bypass`. A deny rule still leaves the tool in the advertised
839
+ * catalog, so the model may attempt it and be refused; to keep it out of the catalog entirely,
840
+ * pass `withheldBuiltinTools: ["shell"]` on {@link AgentOptions} (usetheokit/theokit-sdk#381).
814
841
  *
815
842
  * 2. **Finished runs write a transcript to disk**, at `.theokit/memory/sessions/<runId>.md` under
816
843
  * the workspace `cwd`, with the full prompt and reply. This happens with no `memory` config and
817
- * with `settingSources: []` — it is what `memory_search({ corpus: "sessions" })` reads. It is not
818
- * currently opt-out. If the workspace is a git repository, add `.theokit/` to `.gitignore`: one
819
- * report describes a transcript reaching a public repo before it was noticed.
844
+ * with `settingSources: []` — it is what `memory_search({ corpus: "sessions" })` reads. Opt out
845
+ * with `memory: { enabled: false }`, which suppresses the write entirely
846
+ * (usetheokit/theokit-sdk#382). Leaving `memory`
847
+ * unset still writes, so if the workspace is a git repository, add `.theokit/` to `.gitignore`:
848
+ * one report describes a transcript reaching a public repo before it was noticed.
820
849
  *
821
850
  * @public
822
851
  */
@@ -1220,6 +1249,32 @@ interface AgentOptions {
1220
1249
  * See {@link CustomTool}.
1221
1250
  */
1222
1251
  tools?: CustomTool[];
1252
+ /**
1253
+ * Builtin tools this agent must NOT declare to the model. Absent or empty ⇒ every builtin the
1254
+ * rest of the configuration would register is declared, exactly as before this option existed.
1255
+ *
1256
+ * WHY WITHHOLDING IS NOT THE SAME AS DENYING. A consumer that cannot allow `shell` — because it
1257
+ * reaches outside their own sandbox scope — can already refuse the call in a `pre_tool_call` hook
1258
+ * or with a {@link PermissionEngine} deny rule. That stops the execution and pays for the offer
1259
+ * twice over: the schema rides in EVERY request of EVERY round (measured at 267 characters for
1260
+ * `shell`, 1,462 for `memory_search` + `memory_get` together — usetheokit/theokit-sdk#381), and
1261
+ * the model can spend a whole round discovering a refusal it had no way to anticipate. Declaring
1262
+ * a tool that is guaranteed to be refused is the wrong shape; withholding removes it from the
1263
+ * catalog, so the model is never offered what it cannot have.
1264
+ *
1265
+ * WITHHOLDING RELEASES THE NAME. `withheldBuiltinTools: ["shell"]` lets {@link AgentOptions.tools}
1266
+ * declare a tool called `shell` without the `tool_reserved_name` error — the reservation exists to
1267
+ * stop a collision with the SDK's own tool, and there is no longer one to collide with. Every
1268
+ * builtin still declared stays reserved.
1269
+ *
1270
+ * This governs DECLARATION, not authorization. A withheld builtin is simply absent from the
1271
+ * catalog: a model that invents the name anyway gets `Unknown tool <name>` (exit 127) rather than
1272
+ * an execution, but nothing here evaluates a policy. Keep the deny rule if you need one that a
1273
+ * per-send `tools` override cannot reopen.
1274
+ *
1275
+ * @public
1276
+ */
1277
+ withheldBuiltinTools?: readonly BuiltinToolName[];
1223
1278
  /**
1224
1279
  * SE37 — opt-in reasoning. When `true`, the agent gets a chain-of-thought
1225
1280
  * preamble prepended to its system prompt AND the `think` reasoning tool
@@ -1583,4 +1638,4 @@ interface ListResult<T> {
1583
1638
  nextCursor?: string;
1584
1639
  }
1585
1640
 
1586
- export { type TelemetrySettings as $, type AgentOptions as A, type BudgetTracker as B, type CloudOptions as C, type PostAssistantReplyContext as D, type PostToolCallContext as E, type PreToolCallContext as F, type GetAgentOptions as G, type HookName as H, type InlineSkill as I, type PreUserSendContext as J, type PreUserSendResult as K, type LocalOptions as L, type MemorySettings as M, type ProviderTransform as N, type ProviderTransformContext as O, type Plugin as P, type SessionLifecycleContext as Q, type RecordSessionSummaryArgs as R, type SystemPromptResolver as S, type SessionRecord as T, type SessionStore as U, type SettingSource as V, Skill as W, type SkillsResolver as X, type SkillsResolverContext as Y, type SystemPromptContext as Z, type SystemPromptMemoryFact as _, type AgentDefinition as a, type ToolCallSummary as a0, type ToolResultTransformContext as a1, type TransformContext as a2, type SkillsSettings as b, type ListAgentsOptions as c, type ListResult as d, type SDKAgentInfo as e, type ListRunsOptions as f, type GetRunOptions as g, type AgentOperationOptions as h, type AgentDescription as i, type ProviderProfile as j, type MemoryProvider as k, type PreToolCallDecision as l, type ActiveMemoryPassArgs as m, type ActiveMemoryPassResult as n, type AgentSubagentDescription as o, type AgentToolDescription as p, type BudgetCheck as q, type BudgetTotal as r, type BudgetUsageEvent as s, type CloudEnv as t, type CloudRepo as u, type CreateSkillSpec as v, type MemoryProviderFactory as w, type MemoryProviderHandle as x, type MemoryProviderInitOptions as y, type PluginContext as z };
1641
+ export { type SystemPromptMemoryFact as $, type AgentOptions as A, type BudgetTracker as B, type CloudOptions as C, type PluginContext as D, type PostAssistantReplyContext as E, type PostToolCallContext as F, type GetAgentOptions as G, type HookName as H, type InlineSkill as I, type PreToolCallContext as J, type PreUserSendContext as K, type LocalOptions as L, type MemorySettings as M, type PreUserSendResult as N, type ProviderTransform as O, type Plugin as P, type ProviderTransformContext as Q, type RecordSessionSummaryArgs as R, type SystemPromptResolver as S, type SessionLifecycleContext as T, type SessionRecord as U, type SessionStore as V, type SettingSource as W, Skill as X, type SkillsResolver as Y, type SkillsResolverContext as Z, type SystemPromptContext as _, type AgentDefinition as a, type TelemetrySettings as a0, type ToolCallSummary as a1, type ToolResultTransformContext as a2, type TransformContext as a3, type SkillsSettings as b, type ListAgentsOptions as c, type ListResult as d, type SDKAgentInfo as e, type ListRunsOptions as f, type GetRunOptions as g, type AgentOperationOptions as h, type AgentDescription as i, type ProviderProfile as j, type MemoryProvider as k, type PreToolCallDecision as l, type ActiveMemoryPassArgs as m, type ActiveMemoryPassResult as n, type AgentSubagentDescription as o, type AgentToolDescription as p, type BudgetCheck as q, type BudgetTotal as r, type BudgetUsageEvent as s, type BuiltinToolName as t, type CloudEnv as u, type CloudRepo as v, type CreateSkillSpec as w, type MemoryProviderFactory as x, type MemoryProviderHandle as y, type MemoryProviderInitOptions as z };
@@ -1,5 +1,5 @@
1
- export { Agent } from './chunk-TPTZA6NI.js';
2
- import './chunk-DUIF54UP.js';
1
+ export { Agent } from './chunk-I5BE5M5L.js';
2
+ import './chunk-OHBIUXKM.js';
3
3
  import './chunk-DAPSQZT4.js';
4
4
  import './chunk-YMA4S2WO.js';
5
5
  import './chunk-2SFBB54R.js';
@@ -8,7 +8,7 @@ import './chunk-K2BQQ445.js';
8
8
  import './chunk-XN7NOENA.js';
9
9
  import './chunk-H73MEMQB.js';
10
10
  import './chunk-GJ6RK75E.js';
11
- import './chunk-VDEWG5TV.js';
11
+ import './chunk-MVAPK2BX.js';
12
12
  import './chunk-3E77SX4H.js';
13
13
  import './chunk-WTMU7J4U.js';
14
14
  import './chunk-5JLFFPCH.js';
@@ -40,13 +40,13 @@ import './chunk-2QKTVKH3.js';
40
40
  import './chunk-AG5JPQIY.js';
41
41
  import './chunk-F7AQV62G.js';
42
42
  import './chunk-R7WIIPUR.js';
43
- import './chunk-SSQZA3DZ.js';
44
- import './chunk-FXEUP75G.js';
43
+ import './chunk-2BDH744Z.js';
44
+ import './chunk-Q4CMI2LP.js';
45
45
  import './chunk-44MBDIHG.js';
46
46
  import './chunk-UQGQFBRL.js';
47
47
  import './chunk-3OR54XG4.js';
48
48
  import './chunk-IDCKSLYH.js';
49
49
  import './chunk-T7XEKOVW.js';
50
50
  import './chunk-T7O6K6PX.js';
51
- //# sourceMappingURL=agent-VGD5WL4N.js.map
52
- //# sourceMappingURL=agent-VGD5WL4N.js.map
51
+ //# sourceMappingURL=agent-HDEVVUBS.js.map
52
+ //# sourceMappingURL=agent-HDEVVUBS.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":[],"names":[],"mappings":"","file":"agent-VGD5WL4N.js"}
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"agent-HDEVVUBS.js"}
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
- var chunkUFAO4T7Z_cjs = require('./chunk-UFAO4T7Z.cjs');
4
- require('./chunk-5BJV5UPY.cjs');
3
+ var chunkF5WMX4EA_cjs = require('./chunk-F5WMX4EA.cjs');
4
+ require('./chunk-V2UUGUY4.cjs');
5
5
  require('./chunk-5UOVYM3P.cjs');
6
6
  require('./chunk-53CBTBWO.cjs');
7
7
  require('./chunk-BV2MWEMV.cjs');
@@ -10,7 +10,7 @@ require('./chunk-BUUUWQMB.cjs');
10
10
  require('./chunk-EI2Q7SJ5.cjs');
11
11
  require('./chunk-GHX4P3V2.cjs');
12
12
  require('./chunk-YPJ5NH5N.cjs');
13
- require('./chunk-UNDROG5N.cjs');
13
+ require('./chunk-HLPSLDGL.cjs');
14
14
  require('./chunk-F3YZMOAU.cjs');
15
15
  require('./chunk-4OTIXDMU.cjs');
16
16
  require('./chunk-DQKERTND.cjs');
@@ -42,8 +42,8 @@ require('./chunk-HJBMA5MB.cjs');
42
42
  require('./chunk-IWBGCBR6.cjs');
43
43
  require('./chunk-XSX2UU6Y.cjs');
44
44
  require('./chunk-3EE6LVWT.cjs');
45
- require('./chunk-3KGLRRFC.cjs');
46
- require('./chunk-RM7Y65IG.cjs');
45
+ require('./chunk-6HTXPPHK.cjs');
46
+ require('./chunk-NIRE5CNO.cjs');
47
47
  require('./chunk-5USCYPPI.cjs');
48
48
  require('./chunk-BVZW2B5V.cjs');
49
49
  require('./chunk-52NKC5HT.cjs');
@@ -55,7 +55,7 @@ require('./chunk-NUKRL3I6.cjs');
55
55
 
56
56
  Object.defineProperty(exports, "Agent", {
57
57
  enumerable: true,
58
- get: function () { return chunkUFAO4T7Z_cjs.Agent; }
58
+ get: function () { return chunkF5WMX4EA_cjs.Agent; }
59
59
  });
60
- //# sourceMappingURL=agent-NOEGF4GI.cjs.map
61
- //# sourceMappingURL=agent-NOEGF4GI.cjs.map
60
+ //# sourceMappingURL=agent-R2HOJFZJ.cjs.map
61
+ //# sourceMappingURL=agent-R2HOJFZJ.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":[],"names":[],"mappings":"","file":"agent-NOEGF4GI.cjs"}
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"agent-R2HOJFZJ.cjs"}
@@ -1,4 +1,4 @@
1
- import { registerBuiltins, listProviders, getProviderProfile } from './chunk-FXEUP75G.js';
1
+ import { registerBuiltins, listProviders, getProviderProfile } from './chunk-Q4CMI2LP.js';
2
2
 
3
3
  // src/providers.ts
4
4
  function listProviders2() {
@@ -11,5 +11,5 @@ function getProviderProfile2(name) {
11
11
  }
12
12
 
13
13
  export { getProviderProfile2 as getProviderProfile, listProviders2 as listProviders };
14
- //# sourceMappingURL=chunk-SSQZA3DZ.js.map
15
- //# sourceMappingURL=chunk-SSQZA3DZ.js.map
14
+ //# sourceMappingURL=chunk-2BDH744Z.js.map
15
+ //# sourceMappingURL=chunk-2BDH744Z.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/providers.ts"],"names":["listProviders","getProviderProfile"],"mappings":";;;AA4BO,SAASA,cAAAA,GAA4C;AAC1D,EAAA,gBAAA,EAAiB;AACjB,EAAA,OAAO,aAAA,EAAa;AACtB;AAQO,SAASC,oBAAmB,IAAA,EAA2C;AAC5E,EAAA,gBAAA,EAAiB;AACjB,EAAA,OAAO,mBAAW,IAAI,CAAA;AACxB","file":"chunk-SSQZA3DZ.js","sourcesContent":["/**\n * The provider registry, as public API.\n *\n * It was `@internal`, which meant the SDK was the only thing that could answer \"which providers\n * exist, and what does each one need?\". `theokit` consequently kept a hand-written list of three —\n * against the 46 registered here — so an agent declaring `ollama/qwen2.5:3b` routed to whatever\n * key happened to be set instead of to Ollama (usetheokit/theokit#326).\n *\n * A second table that nothing forces to agree with the first is not a cache, it is a future bug.\n * These two functions exist so there is one table.\n *\n * Both ensure the builtins are registered before answering: registration is lazy (it happens when\n * an agent is created, a run is routed, or a provider is defined), so a caller asking early would\n * otherwise get an empty registry and reasonably conclude the SDK knows nothing.\n */\n\nimport { registerBuiltins } from \"./internal/providers/builtin/index.js\";\nimport {\n getProviderProfile as getProfile,\n listProviders as listProfiles,\n} from \"./internal/providers/registry.js\";\nimport type { ProviderProfile } from \"./internal/providers/types.js\";\n\n/**\n * Every registered provider — builtins, the JSON catalog, and anything a plugin registered.\n *\n * @public\n */\nexport function listProviders(): readonly ProviderProfile[] {\n registerBuiltins();\n return listProfiles();\n}\n\n/**\n * One provider by name or alias (`lm-studio` resolves to `lmstudio`), or `undefined` when nothing\n * has registered it.\n *\n * @public\n */\nexport function getProviderProfile(name: string): ProviderProfile | undefined {\n registerBuiltins();\n return getProfile(name);\n}\n"]}
1
+ {"version":3,"sources":["../src/providers.ts"],"names":["listProviders","getProviderProfile"],"mappings":";;;AA4BO,SAASA,cAAAA,GAA4C;AAC1D,EAAA,gBAAA,EAAiB;AACjB,EAAA,OAAO,aAAA,EAAa;AACtB;AAQO,SAASC,oBAAmB,IAAA,EAA2C;AAC5E,EAAA,gBAAA,EAAiB;AACjB,EAAA,OAAO,mBAAW,IAAI,CAAA;AACxB","file":"chunk-2BDH744Z.js","sourcesContent":["/**\n * The provider registry, as public API.\n *\n * It was `@internal`, which meant the SDK was the only thing that could answer \"which providers\n * exist, and what does each one need?\". `theokit` consequently kept a hand-written list of three —\n * against the 46 registered here — so an agent declaring `ollama/qwen2.5:3b` routed to whatever\n * key happened to be set instead of to Ollama (usetheokit/theokit#326).\n *\n * A second table that nothing forces to agree with the first is not a cache, it is a future bug.\n * These two functions exist so there is one table.\n *\n * Both ensure the builtins are registered before answering: registration is lazy (it happens when\n * an agent is created, a run is routed, or a provider is defined), so a caller asking early would\n * otherwise get an empty registry and reasonably conclude the SDK knows nothing.\n */\n\nimport { registerBuiltins } from \"./internal/providers/builtin/index.js\";\nimport {\n getProviderProfile as getProfile,\n listProviders as listProfiles,\n} from \"./internal/providers/registry.js\";\nimport type { ProviderProfile } from \"./internal/providers/types.js\";\n\n/**\n * Every registered provider — builtins, the JSON catalog, and anything a plugin registered.\n *\n * @public\n */\nexport function listProviders(): readonly ProviderProfile[] {\n registerBuiltins();\n return listProfiles();\n}\n\n/**\n * One provider by name or alias (`lm-studio` resolves to `lmstudio`), or `undefined` when nothing\n * has registered it.\n *\n * @public\n */\nexport function getProviderProfile(name: string): ProviderProfile | undefined {\n registerBuiltins();\n return getProfile(name);\n}\n"]}
@@ -0,0 +1,18 @@
1
+ 'use strict';
2
+
3
+ var chunkNIRE5CNO_cjs = require('./chunk-NIRE5CNO.cjs');
4
+
5
+ // src/providers.ts
6
+ function listProviders2() {
7
+ chunkNIRE5CNO_cjs.registerBuiltins();
8
+ return chunkNIRE5CNO_cjs.listProviders();
9
+ }
10
+ function getProviderProfile2(name) {
11
+ chunkNIRE5CNO_cjs.registerBuiltins();
12
+ return chunkNIRE5CNO_cjs.getProviderProfile(name);
13
+ }
14
+
15
+ exports.getProviderProfile = getProviderProfile2;
16
+ exports.listProviders = listProviders2;
17
+ //# sourceMappingURL=chunk-6HTXPPHK.cjs.map
18
+ //# sourceMappingURL=chunk-6HTXPPHK.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/providers.ts"],"names":["listProviders","registerBuiltins","getProviderProfile"],"mappings":";;;;;AA4BO,SAASA,cAAAA,GAA4C;AAC1D,EAAAC,kCAAA,EAAiB;AACjB,EAAA,OAAOD,+BAAA,EAAa;AACtB;AAQO,SAASE,oBAAmB,IAAA,EAA2C;AAC5E,EAAAD,kCAAA,EAAiB;AACjB,EAAA,OAAOC,qCAAW,IAAI,CAAA;AACxB","file":"chunk-3KGLRRFC.cjs","sourcesContent":["/**\n * The provider registry, as public API.\n *\n * It was `@internal`, which meant the SDK was the only thing that could answer \"which providers\n * exist, and what does each one need?\". `theokit` consequently kept a hand-written list of three —\n * against the 46 registered here — so an agent declaring `ollama/qwen2.5:3b` routed to whatever\n * key happened to be set instead of to Ollama (usetheokit/theokit#326).\n *\n * A second table that nothing forces to agree with the first is not a cache, it is a future bug.\n * These two functions exist so there is one table.\n *\n * Both ensure the builtins are registered before answering: registration is lazy (it happens when\n * an agent is created, a run is routed, or a provider is defined), so a caller asking early would\n * otherwise get an empty registry and reasonably conclude the SDK knows nothing.\n */\n\nimport { registerBuiltins } from \"./internal/providers/builtin/index.js\";\nimport {\n getProviderProfile as getProfile,\n listProviders as listProfiles,\n} from \"./internal/providers/registry.js\";\nimport type { ProviderProfile } from \"./internal/providers/types.js\";\n\n/**\n * Every registered provider — builtins, the JSON catalog, and anything a plugin registered.\n *\n * @public\n */\nexport function listProviders(): readonly ProviderProfile[] {\n registerBuiltins();\n return listProfiles();\n}\n\n/**\n * One provider by name or alias (`lm-studio` resolves to `lmstudio`), or `undefined` when nothing\n * has registered it.\n *\n * @public\n */\nexport function getProviderProfile(name: string): ProviderProfile | undefined {\n registerBuiltins();\n return getProfile(name);\n}\n"]}
1
+ {"version":3,"sources":["../src/providers.ts"],"names":["listProviders","registerBuiltins","getProviderProfile"],"mappings":";;;;;AA4BO,SAASA,cAAAA,GAA4C;AAC1D,EAAAC,kCAAA,EAAiB;AACjB,EAAA,OAAOD,+BAAA,EAAa;AACtB;AAQO,SAASE,oBAAmB,IAAA,EAA2C;AAC5E,EAAAD,kCAAA,EAAiB;AACjB,EAAA,OAAOC,qCAAW,IAAI,CAAA;AACxB","file":"chunk-6HTXPPHK.cjs","sourcesContent":["/**\n * The provider registry, as public API.\n *\n * It was `@internal`, which meant the SDK was the only thing that could answer \"which providers\n * exist, and what does each one need?\". `theokit` consequently kept a hand-written list of three —\n * against the 46 registered here — so an agent declaring `ollama/qwen2.5:3b` routed to whatever\n * key happened to be set instead of to Ollama (usetheokit/theokit#326).\n *\n * A second table that nothing forces to agree with the first is not a cache, it is a future bug.\n * These two functions exist so there is one table.\n *\n * Both ensure the builtins are registered before answering: registration is lazy (it happens when\n * an agent is created, a run is routed, or a provider is defined), so a caller asking early would\n * otherwise get an empty registry and reasonably conclude the SDK knows nothing.\n */\n\nimport { registerBuiltins } from \"./internal/providers/builtin/index.js\";\nimport {\n getProviderProfile as getProfile,\n listProviders as listProfiles,\n} from \"./internal/providers/registry.js\";\nimport type { ProviderProfile } from \"./internal/providers/types.js\";\n\n/**\n * Every registered provider — builtins, the JSON catalog, and anything a plugin registered.\n *\n * @public\n */\nexport function listProviders(): readonly ProviderProfile[] {\n registerBuiltins();\n return listProfiles();\n}\n\n/**\n * One provider by name or alias (`lm-studio` resolves to `lmstudio`), or `undefined` when nothing\n * has registered it.\n *\n * @public\n */\nexport function getProviderProfile(name: string): ProviderProfile | undefined {\n registerBuiltins();\n return getProfile(name);\n}\n"]}