@theokit/agents 13.0.0-next.9 → 13.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +1821 -0
- package/README.md +31 -0
- package/dist/{agent-compiler-DZorqtK2.d.ts → agent-compiler-B_Z3OZel.d.ts} +196 -194
- package/dist/ask.d.ts +1 -0
- package/dist/auth.d.ts +175 -1
- package/dist/auth.js +94 -0
- package/dist/auth.js.map +1 -1
- package/dist/{bridge-entry-B0FqqPlt.d.ts → bridge-entry-vzdHNu_x.d.ts} +72 -6
- package/dist/bridge.d.ts +6 -4
- package/dist/bridge.js +9 -4
- package/dist/{chunk-TZCHACY7.js → chunk-AAW4I45J.js} +118 -18
- package/dist/chunk-AAW4I45J.js.map +1 -0
- package/dist/{chunk-6WFRR24F.js → chunk-HBHZV3KL.js} +566 -342
- package/dist/chunk-HBHZV3KL.js.map +1 -0
- package/dist/chunk-M5DRNOIU.js +109 -0
- package/dist/chunk-M5DRNOIU.js.map +1 -0
- package/dist/chunk-M5J3Q6YC.js +17 -0
- package/dist/chunk-M5J3Q6YC.js.map +1 -0
- package/dist/{chunk-RKWCXVYG.js → chunk-MJ6FRILJ.js} +67 -5
- package/dist/chunk-MJ6FRILJ.js.map +1 -0
- package/dist/{chunk-LPS65NGG.js → chunk-PMMOOXR6.js} +33 -10
- package/dist/chunk-PMMOOXR6.js.map +1 -0
- package/dist/chunk-U72XTMYB.js +7 -0
- package/dist/chunk-U72XTMYB.js.map +1 -0
- package/dist/client-react.d.ts +1 -0
- package/dist/client.d.ts +1 -0
- package/dist/config.d.ts +205 -36
- package/dist/config.js +221 -18
- package/dist/config.js.map +1 -1
- package/dist/{define-agent-D9b3h3VU.d.ts → define-agent-Cm7UGHx-.d.ts} +27 -3
- package/dist/{delegation-scoring-MbnqL68u.d.ts → delegation-scoring-195_ROT3.d.ts} +14 -2
- package/dist/hooks.d.ts +0 -32
- package/dist/hooks.js +42 -14
- package/dist/hooks.js.map +1 -1
- package/dist/index.d.ts +191 -16
- package/dist/index.js +43 -5
- package/dist/index.js.map +1 -1
- package/dist/sandbox.js.map +1 -1
- package/dist/setting-sources-gate-DFu51i50.d.ts +278 -0
- package/dist/testing.d.ts +5 -2
- package/dist/testing.js +1 -1
- package/dist/tools.d.ts +4 -2
- package/dist/tools.js +22 -4
- package/dist/tools.js.map +1 -1
- package/dist/usage.d.ts +30 -0
- package/dist/usage.js +3 -0
- package/dist/usage.js.map +1 -1
- package/package.json +3 -3
- package/dist/chunk-6WFRR24F.js.map +0 -1
- package/dist/chunk-LPS65NGG.js.map +0 -1
- package/dist/chunk-RKWCXVYG.js.map +0 -1
- package/dist/chunk-TZCHACY7.js.map +0 -1
package/README.md
CHANGED
|
@@ -90,6 +90,37 @@ shipped the symbol is the answer — every entry names the version it landed in.
|
|
|
90
90
|
- Web Standards over Node APIs inside `src/` — `Request`/`Response`, `fetch`, `crypto.randomUUID`.
|
|
91
91
|
Node APIs live in adapters.
|
|
92
92
|
|
|
93
|
+
## Who decides policy
|
|
94
|
+
|
|
95
|
+
**An operator who did not write the code can impose policy on it.** That is a decision, recorded
|
|
96
|
+
here because it is the one a team evaluating this framework for deployment needs before anything
|
|
97
|
+
else.
|
|
98
|
+
|
|
99
|
+
It was not always true. Hooks, MCP servers, permissions and skill execution were each a value the
|
|
100
|
+
*programmer* passed at build time — a constructor argument, decided in code, by whoever wrote the
|
|
101
|
+
agent. That is a defensible design for a framework and an indefensible one for anything an
|
|
102
|
+
organisation deploys: it means the person responsible for what an agent may do on a machine has no
|
|
103
|
+
way to say so.
|
|
104
|
+
|
|
105
|
+
Policy is read from disk, and the layers have a fixed precedence:
|
|
106
|
+
|
|
107
|
+
| Layer | Who writes it | Wins against |
|
|
108
|
+
|---|---|---|
|
|
109
|
+
| `managed-settings.json` | the operator / the organisation | everything below |
|
|
110
|
+
| `.claude/settings.json`, `.theokit/settings.json` | the project | the code |
|
|
111
|
+
| `defineAgent({ … })` | the programmer | nothing |
|
|
112
|
+
|
|
113
|
+
A programmer can still decide everything, and in a single-author project nothing above them exists.
|
|
114
|
+
What changed is that they are no longer the *only* one who can.
|
|
115
|
+
|
|
116
|
+
Two consequences worth stating, because they are the cost:
|
|
117
|
+
|
|
118
|
+
- A value declared in code can be **overridden by a file the programmer does not control**. That is
|
|
119
|
+
the point, and it means a build-time guarantee is not one.
|
|
120
|
+
- An operator restriction is refused loudly rather than silently narrowed. A policy that quietly
|
|
121
|
+
did less than it said would be worse than none — the failure this repository keeps finding under
|
|
122
|
+
other names.
|
|
123
|
+
|
|
93
124
|
## Licence
|
|
94
125
|
|
|
95
126
|
See `LICENSE`.
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
import { InlineSkill,
|
|
1
|
+
import { InlineSkill, SystemPromptResolver, SessionStore, PermissionGate, MemorySettings, SkillsSettings, ContextSettings, TelemetrySettings } from '@theokit/sdk';
|
|
2
|
+
import { AgentDefinition } from '@theokit/sdk/subagents-loader';
|
|
2
3
|
import { TheokitAgentError } from '@theokit/sdk/errors';
|
|
3
4
|
import { R as ReasoningEffort, a as MemoryOptions, P as ProjectContextOptions, M as McpServersMap, H as HumanInTheLoopOptions, C as CheckpointOptions, T as ToolOptions, A as ApprovalOptions, B as BudgetOptions } from './types-C16Wuh9E.js';
|
|
5
|
+
import { G as GatedSettingSource, a as GatedCompatSource } from './setting-sources-gate-DFu51i50.js';
|
|
4
6
|
|
|
5
7
|
/**
|
|
6
8
|
* M9 (theokit-ai-first) — guardrail contract + typed errors.
|
|
@@ -35,23 +37,87 @@ interface Guardrail {
|
|
|
35
37
|
}
|
|
36
38
|
/** Which boundary phase a violation happened in. */
|
|
37
39
|
type GuardrailPhase = 'input' | 'output';
|
|
38
|
-
/** Thrown (fail-fast) when a guard returns `action: 'block'`. Typed per error-handling.md. */
|
|
39
40
|
/**
|
|
40
|
-
*
|
|
41
|
+
* A guard declared `redact` and supplied no replacement text.
|
|
41
42
|
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
*
|
|
43
|
+
* Distinct from {@link GuardrailViolationError} on purpose: that one says the guard REFUSED
|
|
44
|
+
* something, which is a decision working as designed. This says the guard is MALFORMED — it asked
|
|
45
|
+
* for a redaction and gave nothing to redact with, so nothing was redacted.
|
|
46
|
+
*
|
|
47
|
+
* Until B-008 this condition was silent: `pipeline.ts` tested `r.text !== undefined` and moved on, so
|
|
48
|
+
* the caller received the original text and believed a guard had run on it. That is the shape this
|
|
49
|
+
* package's hook engine calls "worse than no hook at all" — a belief in a protection that is not
|
|
50
|
+
* there. Throwing is fail-fast per `rules/error-handling.md § 2`, and the alternative was leaving
|
|
51
|
+
* unredacted output to reach a model because a guard was written wrong.
|
|
52
|
+
*
|
|
53
|
+
* `''` is NOT this case. An empty replacement is a guard choosing to erase everything, which is the
|
|
54
|
+
* strongest redaction available, and treating it as absent would invert the defect.
|
|
55
|
+
*/
|
|
56
|
+
/**
|
|
57
|
+
* The base every guardrail error shares, so the seams that must treat them alike can do so BY
|
|
58
|
+
* CONSTRUCTION rather than by remembering a list.
|
|
59
|
+
*
|
|
60
|
+
* The list is how B-020 happened. `run-reflective-loop.ts` let `GuardrailViolationError` pass
|
|
61
|
+
* through unwrapped, and its sibling in this same file was not added — so a malformed result was
|
|
62
|
+
* wrapped in a `DelegationError`, whose message interpolates its cause and whose code is on the
|
|
63
|
+
* delegate tool's message allowlist. The guard's name crossed to the model, and a guard DEFECT was
|
|
64
|
+
* reported as a delegation failure.
|
|
65
|
+
*
|
|
66
|
+
* A base is not airtight on its own: a new class can still extend `TheokitAgentError` directly.
|
|
67
|
+
* `tests/unit/a-guardrail-defect-does-not-name-its-guard.test.ts` walks this module's barrel and
|
|
68
|
+
* fails on any exported error class that skipped it. The two together are the construction; either
|
|
69
|
+
* alone is a convention.
|
|
70
|
+
*
|
|
71
|
+
* Abstract because there is nothing to throw at this level — every guardrail failure is one of the
|
|
72
|
+
* specific kinds below, and a bare `GuardrailError` would say only that something guard-shaped
|
|
73
|
+
* happened.
|
|
74
|
+
*/
|
|
75
|
+
declare abstract class GuardrailError extends TheokitAgentError {
|
|
76
|
+
}
|
|
77
|
+
declare class MalformedGuardrailResultError extends GuardrailError {
|
|
78
|
+
readonly guardName: string;
|
|
79
|
+
readonly phase: GuardrailPhase;
|
|
80
|
+
readonly name = "MalformedGuardrailResultError";
|
|
81
|
+
constructor(guardName: string, phase: GuardrailPhase);
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Thrown (fail-fast) when a guard returns `action: 'block'`. Typed per error-handling.md.
|
|
85
|
+
*
|
|
86
|
+
* M80 — extends {@link TheokitAgentError}, not plain `Error`. `isTransientError` is defined over
|
|
87
|
+
* `TheokitAgentError`, so a class outside that hierarchy is INVISIBLE to it and the only recourse
|
|
88
|
+
* left to a consumer is matching on message text — a regex over an eight-level `cause` chain, which
|
|
89
|
+
* is what one actually wrote. `code` is stable across a rename of the class; `isRetryable` is
|
|
90
|
+
* DECLARED rather than defaulted, because a default would be a retry policy nobody chose.
|
|
47
91
|
*/
|
|
48
|
-
declare class GuardrailViolationError extends
|
|
92
|
+
declare class GuardrailViolationError extends GuardrailError {
|
|
49
93
|
readonly guardName: string;
|
|
50
94
|
readonly phase: GuardrailPhase;
|
|
51
95
|
readonly reason: string;
|
|
52
96
|
readonly name = "GuardrailViolationError";
|
|
53
97
|
constructor(guardName: string, phase: GuardrailPhase, reason: string);
|
|
54
98
|
}
|
|
99
|
+
/**
|
|
100
|
+
* A text-carrying event arrived with a `content` that is not text.
|
|
101
|
+
*
|
|
102
|
+
* Distinct from the two above on purpose: they say a guard REFUSED something or was WRITTEN WRONG.
|
|
103
|
+
* This says the STREAM is malformed — the event announces itself as text and carries something a
|
|
104
|
+
* guard cannot read.
|
|
105
|
+
*
|
|
106
|
+
* Until B-021 this was silent. Both extractors tested `typeof e.content === 'string'` and returned
|
|
107
|
+
* `undefined` otherwise, which `moderateOutputStream` reads as "this event carries no text" — so the
|
|
108
|
+
* payload was never accumulated, never shown to a guard, and yielded VERBATIM. The failure direction
|
|
109
|
+
* is DELIVER: a guard declared to stop that payload never saw it, and the run reported green.
|
|
110
|
+
*
|
|
111
|
+
* Refused rather than coerced. Coercing would moderate `"[object Object]"` — a guard consulted about
|
|
112
|
+
* a string the model never produced, returning a verdict about nothing, while the real payload rides
|
|
113
|
+
* along underneath. That is the redaction-computed-and-discarded shape with an extra step.
|
|
114
|
+
*/
|
|
115
|
+
declare class UnreadableTextPayloadError extends GuardrailError {
|
|
116
|
+
readonly eventType: string;
|
|
117
|
+
readonly received: unknown;
|
|
118
|
+
readonly name = "UnreadableTextPayloadError";
|
|
119
|
+
constructor(eventType: string, received: unknown);
|
|
120
|
+
}
|
|
55
121
|
/** Thrown when {@link costGuard}'s cumulative token budget is exceeded. */
|
|
56
122
|
/**
|
|
57
123
|
* M80 — extends {@link TheokitAgentError}, not plain `Error`.
|
|
@@ -62,7 +128,7 @@ declare class GuardrailViolationError extends TheokitAgentError {
|
|
|
62
128
|
* rename of the class; `isRetryable` is DECLARED rather than defaulted, because a default would be a
|
|
63
129
|
* retry policy nobody chose.
|
|
64
130
|
*/
|
|
65
|
-
declare class CostBudgetExceededError extends
|
|
131
|
+
declare class CostBudgetExceededError extends GuardrailError {
|
|
66
132
|
readonly usedTokens: number;
|
|
67
133
|
readonly maxTokens: number;
|
|
68
134
|
readonly name = "CostBudgetExceededError";
|
|
@@ -98,181 +164,39 @@ type SkillsSelection = readonly (string | InlineSkill)[] | ((ctx: SkillsRequestC
|
|
|
98
164
|
declare function resolveEnabledSkills(selection: SkillsSelection | undefined, ctx: SkillsRequestContext): Promise<string[] | undefined>;
|
|
99
165
|
|
|
100
166
|
/**
|
|
101
|
-
*
|
|
102
|
-
*
|
|
103
|
-
* ## The defect this module closes
|
|
104
|
-
*
|
|
105
|
-
* `settingSources` enables on-disk config discovery. `'user'` reads `~/.theokit/` — the operator's
|
|
106
|
-
* own machine, which no third party controls. `'project'` reads `<cwd>/.theokit/`, **including
|
|
107
|
-
* `hooks.json`, which executes shell**.
|
|
108
|
-
*
|
|
109
|
-
* The previous API took `readonly SettingSource[]`, and its JSDoc justified the risk this way:
|
|
110
|
-
* *"it is opt-in because `.theokit/` is the app's own repo (informed consent)"*. That premise holds
|
|
111
|
-
* for a web app whose `cwd` is its own deploy. It does **not** hold for the class of product this
|
|
112
|
-
* framework addresses — an agent whose `cwd` is a repository the user just cloned. There `.theokit/`
|
|
113
|
-
* is attacker-controlled content, and enabling `'project'` is remote code execution on the first
|
|
114
|
-
* `build()`.
|
|
115
|
-
*
|
|
116
|
-
* Documenting it did not prevent it. The measured consumer (TheoCode) did not trust the API: it
|
|
117
|
-
* gated from the outside, with a `posture.allows` of its own (`chat.ts:386`, comment B-008). It
|
|
118
|
-
* already **had** the right decision and could not pass it through, because the API only accepted
|
|
119
|
-
* strings. The gate existed on its side and evaporated at the boundary.
|
|
120
|
-
*
|
|
121
|
-
* ## The evidence is the SDK's, not one invented here
|
|
122
|
-
*
|
|
123
|
-
* `TrustPosture` is `@theokit/sdk`'s own trust primitive, and `recordWiring`'s doc says *"a posture
|
|
124
|
-
* is the only thing in this package that retains a capability"*. A bespoke type would make two trust
|
|
125
|
-
* grammars coexist and drift apart (ADR 0063).
|
|
126
|
-
*/
|
|
127
|
-
/**
|
|
128
|
-
* The framework's capability vocabulary — deliberately a single name (ADR 0065).
|
|
129
|
-
*
|
|
130
|
-
* `allows` is all-or-nothing in the SDK: every declared `K` gets the same boolean. A finer
|
|
131
|
-
* vocabulary (`hooks`, `skills`, `subagents`, `mcp`) would promise the consumer it can gate one
|
|
132
|
-
* without gating the other, and the primitive does not deliver that. An API that suggests a
|
|
133
|
-
* distinction the runtime does not make teaches the wrong thing, and the error only surfaces when
|
|
134
|
-
* somebody depends on the distinction.
|
|
135
|
-
*/
|
|
136
|
-
type SettingSourceCapability = 'projectSettings';
|
|
137
|
-
/** Authorization to read config from the working directory. Requires the posture, never a claim. */
|
|
138
|
-
interface ProjectSettingsGrant {
|
|
139
|
-
/**
|
|
140
|
-
* Typically the output of `resolveTrustPosture` — which is what gives it `source` (`'env' |
|
|
141
|
-
* 'store' | 'default'`) and therefore a refusal that says WHERE the decision came from instead of
|
|
142
|
-
* merely denying.
|
|
143
|
-
*/
|
|
144
|
-
readonly trustedBy: TrustPosture<SettingSourceCapability>;
|
|
145
|
-
}
|
|
146
|
-
/**
|
|
147
|
-
* Which on-disk config roots the agent may read.
|
|
148
|
-
*
|
|
149
|
-
* The asymmetry is the design: `user` is a boolean because `~/.theokit/` belongs to the operator;
|
|
150
|
-
* `project` requires evidence because `<cwd>/.theokit/` may not. Omitting a root is not enabling it
|
|
151
|
-
* — never "enabling without a gate". The asymmetry is inherited from the SDK itself, whose
|
|
152
|
-
* `TrustPostureInput.envOverride` documents that `false` and `undefined` both mean "the operator did
|
|
153
|
-
* not turn it on", not "turned it off".
|
|
154
|
-
*/
|
|
155
|
-
interface SettingSourcesSelection {
|
|
156
|
-
/** `~/.theokit/` — the operator's machine. No gate: no third party controls it. */
|
|
157
|
-
readonly user?: boolean;
|
|
158
|
-
/** `<cwd>/.theokit/` — controlled by whoever wrote the open repository. Requires evidence. */
|
|
159
|
-
readonly project?: ProjectSettingsGrant;
|
|
160
|
-
/**
|
|
161
|
-
* `<cwd>/.claude/` — a FOREIGN configuration dialect, read only once declared
|
|
162
|
-
* (`usetheokit/theokit-sdk#524`).
|
|
163
|
-
*
|
|
164
|
-
* ## Two questions, and which half of this field answers each
|
|
165
|
-
*
|
|
166
|
-
* The SDK's docblock separates them, and the separation is the whole point of `compatSources`:
|
|
167
|
-
* a trust gate answers *"do I trust the code in this directory?"*; importing another product's
|
|
168
|
-
* configuration answers *"do I want it imported into this one?"*. They come apart in the ordinary
|
|
169
|
-
* case, because `.claude/` is populated in exactly the repository one trusts most — for a
|
|
170
|
-
* different tool, by a teammate who never heard of this runtime.
|
|
171
|
-
*
|
|
172
|
-
* So the two are answered by two different things here, and it matters which:
|
|
173
|
-
*
|
|
174
|
-
* | Question | Answered by |
|
|
175
|
-
* |---|---|
|
|
176
|
-
* | do I want the foreign dialect imported? | **declaring this field at all** — omitting is not enabling |
|
|
177
|
-
* | do I trust this directory's code to run? | the `TrustPosture` inside the grant |
|
|
178
|
-
*
|
|
179
|
-
* ## Why the grant is `ProjectSettingsGrant` and not a vocabulary of its own
|
|
180
|
-
*
|
|
181
|
-
* Not because the two questions are the same — they are not. Because a separate grant could not
|
|
182
|
-
* carry the distinction even if it existed: `TrustPosture.allows` is `Record<K, boolean>` and the
|
|
183
|
-
* SDK documents every value as moving together with the level, so a `'foreignDialects'` capability
|
|
184
|
-
* beside `'projectSettings'` would promise an operator they can grant one and withhold the other,
|
|
185
|
-
* and `resolveTrustPosture` would hand back the same boolean for both. That is precisely the
|
|
186
|
-
* failure ADR 0065 exists to prevent, and inventing the second name would commit it while looking
|
|
187
|
-
* like rigour.
|
|
188
|
-
*
|
|
189
|
-
* The consent half is therefore carried by the declaration, which is a real and sufficient
|
|
190
|
-
* boundary: an operator who trusts a repository completely still reads no `.claude/` until they
|
|
191
|
-
* write this field. What the grant adds on top is stricter than the SDK — there, listing a dialect
|
|
192
|
-
* is enough — and the extra strictness is deliberate: this reads a `hooks.json` that executes
|
|
193
|
-
* shell out of a directory that usually arrived with the clone.
|
|
194
|
-
*/
|
|
195
|
-
readonly claudeCode?: ProjectSettingsGrant & {
|
|
196
|
-
/**
|
|
197
|
-
* #686 — WHICH surfaces of the foreign root to import. Absent means all of them, which is what
|
|
198
|
-
* every caller before this meant and still means.
|
|
199
|
-
*
|
|
200
|
-
* The distinction is the reason the grant exists. `.claude/` usually arrives with the clone and
|
|
201
|
-
* its `hooks.json` executes shell, so "take the skills, refuse the hooks" is the ordinary thing
|
|
202
|
-
* to want — and before this the only choices were all of it or none of it.
|
|
203
|
-
*
|
|
204
|
-
* Requires `@theokit/sdk >= 5.4.0`, which is where the narrowed form landed. On an older SDK the
|
|
205
|
-
* runtime drops an unrecognised shape in SILENCE, so declaring it there would import nothing at
|
|
206
|
-
* all rather than importing less — refused at resolve time instead.
|
|
207
|
-
*/
|
|
208
|
-
readonly import?: readonly CompatSurface[];
|
|
209
|
-
};
|
|
210
|
-
}
|
|
211
|
-
/**
|
|
212
|
-
* The surfaces a foreign configuration root can contribute.
|
|
213
|
-
*
|
|
214
|
-
* Written out rather than imported, for the same reason as the `claude-code` literal below:
|
|
215
|
-
* `CompatSurface` does not exist in `@theokit/sdk@4.52.1`, this package's declared floor, and a gate
|
|
216
|
-
* that cannot build against its own minimum dependency is worse than a constant that has been
|
|
217
|
-
* checked. Verified against the published 5.4.0 `.d.ts`, where the union is
|
|
218
|
-
* `"hooks" | "plugins" | "skills" | "subagents"` — note `subagents`, not `agents`.
|
|
219
|
-
*/
|
|
220
|
-
type CompatSurface = 'hooks' | 'plugins' | 'skills' | 'subagents';
|
|
221
|
-
/** What `resolveCompatSources` returns: the whole root, or the root narrowed to some surfaces. */
|
|
222
|
-
type ResolvedCompatSource = 'claude-code' | {
|
|
223
|
-
readonly kind: 'claude-code';
|
|
224
|
-
readonly import: readonly CompatSurface[];
|
|
225
|
-
};
|
|
226
|
-
/**
|
|
227
|
-
* Refusal to read the working directory for lack of trust.
|
|
228
|
-
*
|
|
229
|
-
* Descends from `TheokitAgentError` because typed errors are an unbreakable rule here — and because
|
|
230
|
-
* `isTransientError` only sees this hierarchy. A class extending plain `Error` would be invisible to
|
|
231
|
-
* the predicate that separates recoverable from unrecoverable (the defect M67 fixed in five
|
|
232
|
-
* classes).
|
|
233
|
-
*/
|
|
234
|
-
declare class UntrustedSettingSourceError extends TheokitAgentError {
|
|
235
|
-
/** Where the trust decision came from: `'env' | 'store' | 'default'`. */
|
|
236
|
-
readonly trustSource: string;
|
|
237
|
-
/** The refused capability. */
|
|
238
|
-
readonly capability: SettingSourceCapability;
|
|
239
|
-
readonly name = "UntrustedSettingSourceError";
|
|
240
|
-
constructor(message: string,
|
|
241
|
-
/** Where the trust decision came from: `'env' | 'store' | 'default'`. */
|
|
242
|
-
trustSource: string,
|
|
243
|
-
/** The refused capability. */
|
|
244
|
-
capability: SettingSourceCapability);
|
|
245
|
-
}
|
|
246
|
-
/**
|
|
247
|
-
* Translate the declared selection into the `SettingSource`s the SDK accepts, refusing what the
|
|
248
|
-
* posture does not authorize.
|
|
167
|
+
* The shape this layer registers with the SDK's lifecycle-hook seam.
|
|
249
168
|
*
|
|
250
|
-
*
|
|
251
|
-
*
|
|
252
|
-
*
|
|
253
|
-
* somebody registers a capability the posture does not gate.
|
|
254
|
-
*
|
|
255
|
-
* @throws {UntrustedSettingSourceError} when `project` is requested and the posture does not grant it.
|
|
169
|
+
* Deliberately structural and minimal: the SDK owns the full `Plugin` contract, and restating it
|
|
170
|
+
* here would be a second declaration to drift from. What this needs to know is the one thing that
|
|
171
|
+
* tells a code plugin from a bundle reference.
|
|
256
172
|
*/
|
|
257
|
-
declare function resolveSettingSources(selection: SettingSourcesSelection | undefined): readonly SettingSource[];
|
|
258
173
|
/**
|
|
259
|
-
*
|
|
260
|
-
*
|
|
261
|
-
* ## Why it is a separate function and the same vocabulary
|
|
262
|
-
*
|
|
263
|
-
* Separate because the SDK takes them on a separate option (`local.compatSources`); the same
|
|
264
|
-
* `ProjectSettingsGrant` because the thing being authorised is identical — reading a `hooks.json`
|
|
265
|
-
* that executes shell out of a directory the operator does not necessarily control.
|
|
174
|
+
* A code plugin, in any of the three kinds `@theokit/sdk`'s `Plugin` union defines.
|
|
266
175
|
*
|
|
267
|
-
*
|
|
176
|
+
* `general` `register(ctx)` registers tools, commands, hooks
|
|
177
|
+
* `model-provider` `profile` supplies a model provider
|
|
178
|
+
* `memory` `createProvider` supplies a memory adapter
|
|
268
179
|
*
|
|
269
|
-
*
|
|
270
|
-
*
|
|
271
|
-
*
|
|
180
|
+
* The first version of this type required `register`, which accepted the first kind and refused the
|
|
181
|
+
* other two — while the docblock on `AgentBuilder.plugins`, written in the same commit, already
|
|
182
|
+
* described all three. A real consumer found it: on `@theokit/agents@13.0.0` a `model-provider`
|
|
183
|
+
* plugin failed to compile with "Property 'register' is missing". A guard written to refuse the
|
|
184
|
+
* FILESYSTEM-bundle form was refusing two thirds of the CODE form instead.
|
|
272
185
|
*
|
|
273
|
-
*
|
|
186
|
+
* Modelled here as name-plus-one-capability rather than by importing the SDK union, for the reason
|
|
187
|
+
* the module header gives: this layer must not depend on the SDK's value side, and the published
|
|
188
|
+
* floor is `^4.52.1` where the union's shape is not guaranteed identical. The capability keys ARE
|
|
189
|
+
* the discriminator, so the refusal below stays exact.
|
|
274
190
|
*/
|
|
275
|
-
|
|
191
|
+
type CodePlugin = {
|
|
192
|
+
readonly name: string;
|
|
193
|
+
} & ({
|
|
194
|
+
readonly register: (...args: never[]) => unknown;
|
|
195
|
+
} | {
|
|
196
|
+
readonly profile: unknown;
|
|
197
|
+
} | {
|
|
198
|
+
readonly createProvider: (...args: never[]) => unknown;
|
|
199
|
+
});
|
|
276
200
|
|
|
277
201
|
/**
|
|
278
202
|
* Project the M8 fields from `CompiledAgentOptions` into `Agent.create()` arguments. Only the async
|
|
@@ -325,6 +249,33 @@ declare class HookGateUnsupportedError extends TheokitAgentError {
|
|
|
325
249
|
readonly name = "HookGateUnsupportedError";
|
|
326
250
|
constructor(version: string | undefined);
|
|
327
251
|
}
|
|
252
|
+
/**
|
|
253
|
+
* A narrowed `import` on an SDK that cannot read it.
|
|
254
|
+
*
|
|
255
|
+
* Refuses rather than warns, and the asymmetry with {@link warnIfSdkCannotReadCompatSources} is
|
|
256
|
+
* deliberate: an unrecognised `compatSources` shape means the foreign root is not read, so a
|
|
257
|
+
* consumer who asked for "the skills but not the hooks" silently gets NOTHING — strictly further
|
|
258
|
+
* from what they asked for than the un-narrowed form, which at least reads something. Failing loud
|
|
259
|
+
* is recoverable; a silent nothing is discovered by wondering why a skill is missing.
|
|
260
|
+
*
|
|
261
|
+
* ## The cost, which this file argues against two functions above
|
|
262
|
+
*
|
|
263
|
+
* An unreadable version is refused too, on the principle {@link assertSdkCanGateHooks} states:
|
|
264
|
+
* "cannot tell" and "is supported" must not collapse. The sibling WARNING takes the opposite view
|
|
265
|
+
* for itself — *"a bundled or vendored SDK may not resolve that subpath, and refusing to create an
|
|
266
|
+
* agent over a diagnostic would be the cure being worse than the disease."*
|
|
267
|
+
*
|
|
268
|
+
* Both are right for what they guard, and the difference is what the check IS. A diagnostic that
|
|
269
|
+
* cannot read a version should stay quiet; a GATE that cannot read one has not established the
|
|
270
|
+
* thing it exists to establish. But the cost is real and belongs here rather than in a reviewer's
|
|
271
|
+
* report: a consumer who bundles the SDK so `@theokit/sdk/package.json` does not resolve cannot
|
|
272
|
+
* create an agent with a narrowed `import`, even on 5.4.0+. Their exit is to omit `import` and read
|
|
273
|
+
* the whole root.
|
|
274
|
+
*/
|
|
275
|
+
declare class CompatImportUnsupportedError extends TheokitAgentError {
|
|
276
|
+
readonly name = "CompatImportUnsupportedError";
|
|
277
|
+
constructor(version: string | undefined);
|
|
278
|
+
}
|
|
328
279
|
|
|
329
280
|
/**
|
|
330
281
|
* Agent compiler — transforms decorator metadata into SDK calls.
|
|
@@ -385,18 +336,23 @@ interface CompiledTool {
|
|
|
385
336
|
* @param toolboxInstances - Map of Toolbox class → instantiated object (for `this` binding)
|
|
386
337
|
*/
|
|
387
338
|
declare function compileTools(toolboxes: ToolboxWalkResult[], toolboxInstances: Map<ClassToken, object>): CompiledTool[];
|
|
388
|
-
/**
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
339
|
+
/**
|
|
340
|
+
* A compiled sub-agent IS the SDK's own `AgentDefinition`, re-exported here under the name the
|
|
341
|
+
* public barrel already uses for it.
|
|
342
|
+
*
|
|
343
|
+
* It used to be a narrower local type, `CompiledSubAgent { model?, systemPrompt? }`, and ADR D3
|
|
344
|
+
* deferred projecting it: "a resolver here is carried, not invoked". **That deferral has ended** —
|
|
345
|
+
* `assembleM8CreateOptions` now projects `agents` into `Agent.create`.
|
|
346
|
+
*
|
|
347
|
+
* The narrow type could not have been projected as it stood. `AgentDefinition` requires
|
|
348
|
+
* `description` and `prompt`, and the local shape carried neither; a sub-agent with no description
|
|
349
|
+
* is one the parent model has no basis to delegate to. Every other surface already agreed on the
|
|
350
|
+
* SDK shape — `RuntimeOverrides.agents` (the per-run door that always worked) is
|
|
351
|
+
* `Record<string, AgentDefinition>`, and the same type crosses the barrel as `SubagentDefinition`.
|
|
352
|
+
* The local type was referenced in exactly two places, both of them its own declaration and the
|
|
353
|
+
* field that held it, so adopting the SDK shape removed a mismatch rather than migrating users.
|
|
354
|
+
*/
|
|
355
|
+
type CompiledSubAgent = AgentDefinition;
|
|
400
356
|
/** Compiled agent options ready for SDK Agent.create(). */
|
|
401
357
|
interface CompiledAgentOptions {
|
|
402
358
|
model?: string;
|
|
@@ -415,14 +371,14 @@ interface CompiledAgentOptions {
|
|
|
415
371
|
* Projected into `Agent.create({ local: { settingSources } })` by `assembleM8CreateOptions`
|
|
416
372
|
* (merged with `cwd`, decoupled from inline skills). Absent ⇒ inline (code) config only.
|
|
417
373
|
*/
|
|
418
|
-
settingSources?: readonly
|
|
374
|
+
settingSources?: readonly GatedSettingSource[];
|
|
419
375
|
/**
|
|
420
376
|
* Foreign configuration dialects, already authorised (usetheokit/theokit#634).
|
|
421
377
|
*
|
|
422
378
|
* Resolved at compile time by `resolveCompatSources`, exactly like `settingSources`: a value here
|
|
423
379
|
* can only hold a source some posture granted, so the adapter projects rather than decides.
|
|
424
380
|
*/
|
|
425
|
-
compatSources?: readonly
|
|
381
|
+
compatSources?: readonly GatedCompatSource[];
|
|
426
382
|
/**
|
|
427
383
|
* #686 — the consumer's pre-spawn approval gate, forwarded to `Agent.create({ local: { hooks } })`.
|
|
428
384
|
*
|
|
@@ -432,12 +388,58 @@ interface CompiledAgentOptions {
|
|
|
432
388
|
*/
|
|
433
389
|
hookApproval?: HookApprovalGate;
|
|
434
390
|
/** Code `Plugin` objects forwarded to `Agent.create({ plugins })` (lifecycle-hook seam). */
|
|
435
|
-
|
|
391
|
+
/**
|
|
392
|
+
* Code plugins — `{ name, register }` objects registered with the SDK's lifecycle-hook seam.
|
|
393
|
+
*
|
|
394
|
+
* `readonly unknown[]` is what let the WRONG shape through silently: a consumer who read the
|
|
395
|
+
* Claude Code documentation passed `[{ type: 'local', path: './p' }]`, the compiler accepted it,
|
|
396
|
+
* and the agent ran with the plugin absent. `assertCodePlugins` refuses it at the projection, and
|
|
397
|
+
* the type says what belongs here.
|
|
398
|
+
*
|
|
399
|
+
* NOT the filesystem-bundle form. A bundle is declared by living in a `plugins/` directory under
|
|
400
|
+
* `.theokit/` or `.claude/`, where its `skills/` and `agents/` are discovered.
|
|
401
|
+
*/
|
|
402
|
+
plugins?: readonly CodePlugin[];
|
|
403
|
+
/**
|
|
404
|
+
* B-060 — an external session store (Postgres / Redis / KV / durable object), used by the SDK as
|
|
405
|
+
* the PRIMARY session store and resume source.
|
|
406
|
+
*
|
|
407
|
+
* Without it a serverless deployment resumed from a filesystem that no longer exists, and a
|
|
408
|
+
* multi-pod one resumed from whichever host happened to take the request. The only way to reach
|
|
409
|
+
* it was importing `@theokit/sdk` directly — the one thing this layer's doctrine forbids, so the
|
|
410
|
+
* doctrine and the capability disagreed and the consumer paid.
|
|
411
|
+
*
|
|
412
|
+
* Typed against the SDK's own `SessionStore` rather than restated here: a hand-written copy that
|
|
413
|
+
* drifts by one method stops fitting, which the mirrored `permissionMode` field measured one item
|
|
414
|
+
* earlier.
|
|
415
|
+
*/
|
|
416
|
+
sessionStore?: SessionStore;
|
|
417
|
+
/**
|
|
418
|
+
* B-056 — the callback that sees every tool call the earlier steps did not resolve.
|
|
419
|
+
*
|
|
420
|
+
* The SDK's engine is fail-closed: an unmatched call resolves to `ask`, and an ABSENT gate blocks
|
|
421
|
+
* it. So the value of declaring one is not that unresolved calls stop being approved — they never
|
|
422
|
+
* were — it is that they reach somebody who can decide instead of being refused with nobody to
|
|
423
|
+
* consult. A tool added after the approvals were written keeps defaulting to asking.
|
|
424
|
+
*
|
|
425
|
+
* Typed against the SDK's `PermissionGate`, not restated: its decision shape is veto-or-allow, and
|
|
426
|
+
* a hand-written copy would be the place an `updatedInput` field gets invented for a seam that
|
|
427
|
+
* discards it.
|
|
428
|
+
*/
|
|
429
|
+
canUseTool?: PermissionGate;
|
|
436
430
|
tools: CompiledTool[];
|
|
437
431
|
agents: Record<string, CompiledSubAgent>;
|
|
438
432
|
memory?: MemoryOptions | MemorySettings;
|
|
439
433
|
skills?: SkillsSettings;
|
|
440
434
|
context?: ContextSettings;
|
|
435
|
+
/**
|
|
436
|
+
* B-072 — OpenTelemetry settings, projected onto `Agent.create({ telemetry })`.
|
|
437
|
+
*
|
|
438
|
+
* Typed against the SDK's `TelemetrySettings` rather than restated, for the reason `canUseTool`
|
|
439
|
+
* above gives about `PermissionGate`: a hand-written copy is where a field gets invented for a
|
|
440
|
+
* seam that discards it, and this one has six keys with real defaults behind them.
|
|
441
|
+
*/
|
|
442
|
+
telemetry?: TelemetrySettings;
|
|
441
443
|
/**
|
|
442
444
|
* M7 — run-context injected into every tool handler's `ctx.context` by the theokit adapter
|
|
443
445
|
* (`buildSdkTools` wrapper). Populated by `defineAgent({ context })` (functional surface).
|
|
@@ -475,4 +477,4 @@ interface CompiledAgentOptions {
|
|
|
475
477
|
skillsResolver?: SkillsSelection;
|
|
476
478
|
}
|
|
477
479
|
|
|
478
|
-
export { type
|
|
480
|
+
export { type CodePlugin as C, type Guardrail as G, type HookApprovalGate as H, MalformedGuardrailResultError as M, type SkillsSelection as S, type ToolWalkResult as T, UnreadableTextPayloadError as U, type CompiledAgentOptions as a, type CompiledTool as b, CompatImportUnsupportedError as c, CostBudgetExceededError as d, type GuardrailAction as e, GuardrailError as f, type GuardrailPhase as g, type GuardrailResult as h, GuardrailViolationError as i, type HookApprovalRequest as j, HookGateUnsupportedError as k, type SkillsRequestContext as l, type ToolboxWalkResult as m, compileTools as n, resolveEnabledSkills as r };
|