@theokit/agents 9.3.0 → 10.0.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 +197 -0
- package/dist/{define-agent-3Kuf6iKM.d.ts → agent-compiler-CIPQkehU.d.ts} +3 -233
- package/dist/ask.d.ts +17 -5
- package/dist/ask.js.map +1 -1
- package/dist/{bridge-entry-51lU7LQw.d.ts → bridge-entry-emr2PSXC.d.ts} +99 -464
- package/dist/bridge.d.ts +4 -2
- package/dist/bridge.js +27 -17
- package/dist/{chunk-RZCNKKOG.js → chunk-CKRM5Q2K.js} +172 -1227
- package/dist/chunk-CKRM5Q2K.js.map +1 -0
- package/dist/chunk-QJN2LLPF.js +1110 -0
- package/dist/chunk-QJN2LLPF.js.map +1 -0
- package/dist/config.d.ts +115 -3
- package/dist/config.js +115 -17
- package/dist/config.js.map +1 -1
- package/dist/define-agent-BO5QSjV8.d.ts +236 -0
- package/dist/delegation-scoring-CDvtrYKd.d.ts +469 -0
- package/dist/index.d.ts +8 -4
- package/dist/index.js +41 -31
- package/dist/index.js.map +1 -1
- package/dist/interactive.d.ts +0 -1
- package/dist/session.d.ts +251 -6
- package/dist/session.js +328 -39
- package/dist/session.js.map +1 -1
- package/dist/testing.d.ts +2 -1
- package/dist/tools.d.ts +54 -0
- package/dist/tools.js +100 -1
- package/dist/tools.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-RZCNKKOG.js.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,202 @@
|
|
|
1
1
|
# @theokit/agents
|
|
2
2
|
|
|
3
|
+
## 10.0.0
|
|
4
|
+
|
|
5
|
+
### Major Changes
|
|
6
|
+
|
|
7
|
+
- 4cd49ef: BREAKING: `deleteSession` and `runTranscriptGC` are now `async`.
|
|
8
|
+
|
|
9
|
+
Their return type goes from `T` to `Promise<T>`. A caller that does not `await` reads `undefined`
|
|
10
|
+
instead of the result and throws on the first field access — which is what happened to this repo's
|
|
11
|
+
own `theokit agent sessions gc` command, unnoticed for a day because the workspace typecheck was
|
|
12
|
+
measured against a stale `.d.ts`.
|
|
13
|
+
|
|
14
|
+
The change is required rather than cosmetic: the only agent registry in the ecosystem is
|
|
15
|
+
`Agent.delete(id): Promise<void>`, and the registry half of session deletion is unreachable without
|
|
16
|
+
awaiting it. Migration is `await`.
|
|
17
|
+
|
|
18
|
+
BREAKING: `SessionRegistryRemoverError` changes constructor arity and meaning. It was
|
|
19
|
+
`constructor(sessionId)` for "you passed a thenable to a synchronous seam"; it is now
|
|
20
|
+
`constructor(sessionId, timeoutMs)` for "the registry did not answer in time". The old condition no
|
|
21
|
+
longer exists, so a `catch` that depended on it will never fire again. The class moved module and is
|
|
22
|
+
re-exported from its old home, so import paths are unaffected.
|
|
23
|
+
|
|
24
|
+
Also: the registry timeout now has a bounded DEFAULT (`DEFAULT_REGISTRY_TIMEOUT_MS`, 30s) where it
|
|
25
|
+
previously waited forever. Unbounded remains available by passing a non-finite value.
|
|
26
|
+
|
|
27
|
+
### Minor Changes
|
|
28
|
+
|
|
29
|
+
- 7519927: Security: `auto-edit` no longer auto-approves from a framework-chosen default. A product declares its own set.
|
|
30
|
+
|
|
31
|
+
`shouldAutoApprove`'s `auto-edit` branch defaulted to `WRITE_SCOPED_TOOLS` — `apply_patch`, `edit_file`, `write_file`. The only real consumer auto-approves one of those and registers two, so adopting the framework symbol would have made `edit_file` stop requiring a human: a live, model-callable write tool, silently un-gated as a side effect of deleting duplicated code.
|
|
32
|
+
|
|
33
|
+
Two questions had been conflated. "Does this tool bound its own writes to a write root?" is a fact about the SDK's tool factories, and the framework can answer it. "May this tool run without asking a human?" is the product's policy, and the framework cannot answer it — it does not know which tools the product registered or what it renamed them to.
|
|
34
|
+
|
|
35
|
+
`auto-edit` with no `writeScopedTools` now approves nothing, which is the same shape the module already applies to sandbox posture (an absent posture counts as unconfined). `WRITE_SCOPED_TOOLS` is still exported as the catalog; passing it is a decision rather than an inheritance.
|
|
36
|
+
|
|
37
|
+
`WRITE_SCOPED_TOOLS` is now genuinely immutable — its mutators throw. `ReadonlySet` is erased at runtime, and one cast on an approval gate reachable from every consumer would widen what auto-approves everywhere. `Object.freeze` alone is not enough for a `Set`: entries live in internal slots, not own properties, so freezing leaves `add` working.
|
|
38
|
+
|
|
39
|
+
Not a breaking change for published consumers: `npm pack @theokit/agents@9.4.0` exports neither `shouldAutoApprove` nor `WRITE_SCOPED_TOOLS`. Anyone already calling it on a pre-release build must pass `{ writeScopedTools }` to keep `auto-edit` approving anything.
|
|
40
|
+
|
|
41
|
+
- 0513d03: `deleteSession` re-checks protection immediately before unlinking, instead of trusting a snapshot taken before an await.
|
|
42
|
+
|
|
43
|
+
The protection check ran at the top of the function; control then left for as long as the caller's registry remover took — 30s by default, unbounded with `registryTimeoutMs: Infinity` — and only then was the transcript removed. Anything concluded before that await is a snapshot, and a user resuming the session during the window makes it false. The file was deleted anyway and `SessionInUseError` never fired, which is the outcome that error exists to prevent.
|
|
44
|
+
|
|
45
|
+
The batch path already treats this as non-negotiable: `transcript-gc.ts` invariant 4 is "the apply phase re-checks — a plan is a snapshot, and between snapshot and delete a user can resume a session". The single-session path skipped it, and it is the one with no later sweep to catch the mistake.
|
|
46
|
+
|
|
47
|
+
`SessionInUseError` gains `registryRemoved`. Refusing after the registry half has run leaves an orphan file — the recoverable direction the function already chose in its ordering — but the caller has to be told, or it retries a removal that is already done and reads the resulting `false` ("no entry to remove") as a failure. The constructor parameter is optional and defaults to `false`, so existing construction sites are unaffected.
|
|
48
|
+
|
|
49
|
+
- 01735c7: `classifyProjects` (`@theokit/agents/session`) — answers "does the project behind `projects/<encoded>/` still exist?" without the caller writing the search itself.
|
|
50
|
+
|
|
51
|
+
`minor`, not `major`, and the distinction was measured rather than assumed: `npm pack @theokit/agents@9.4.0` ships the `./session` subpath but contains neither `classifyProjects` nor `FsSeam`. This is a new export on an existing subpath, so the option and seam changes made while stabilising it break no published consumer — there is none. The only migration note that would be honest is the one for the consumer this was absorbed from, and it is written as adoption guidance below rather than as a break.
|
|
52
|
+
|
|
53
|
+
The question is hard because `encodeProjectDir(cwd)` is `cwd.replace(/[^a-zA-Z0-9]/g, '-')` — one-way and many-to-one, so a directory name cannot be turned back into a path, only CHECKED against candidates. Every product that retains or garbage-collects transcripts has to answer it; the consumer's own version is 188 lines whose docstring measured 13,269 project directories, ~3,200 falling through to filesystem search and ~64M syscalls without a shared budget.
|
|
54
|
+
|
|
55
|
+
Three properties carry the safety of this module, and each exists because dropping it produced a measured deletion of live data:
|
|
56
|
+
|
|
57
|
+
- **The verdict is three-valued and `undetermined` is not a soft `dead`.** Callers DELETE on `dead`. Budget spent, unreadable directory, enumeration threw — all resolve to `undetermined`, because deleting on "could not tell" is data loss and the two errors are not symmetric.
|
|
58
|
+
- **`FsSeam.exists` returns `boolean | undefined`.** The third state is in the return type rather than in prose because that is the only place an adapter author reliably reads it. A signature of `=> boolean` invites `try { return existsSync(p) } catch { return false }` — which is exactly the consumer's scar B-020, where a cwd that exists but cannot be stat-ed (EACCES on a non-traversable parent, ENOTDIR mid-path, EMFILE under a wide sweep) was classified DEAD.
|
|
59
|
+
- **Every member of the collision class is probed, not the first match.** Because the encoding is many-to-one, `encodeProjectDir(cwd) === name` narrows to a CLASS, never to a path — `/home/op/my-app` and `/home/op/my/app` share one project directory. First-match-wins lets one record condemn the rest, and transcripts are user-writable, so that record can be PLANTED. Any live member now yields `alive`; `dead` requires every member to be definitively gone.
|
|
60
|
+
|
|
61
|
+
**The budget is shared across the whole sweep, not per project.** A bound that resets each iteration is not a bound — that is what produced the 64M figure.
|
|
62
|
+
|
|
63
|
+
Adoption (for a product that already wrote this search): supply `candidatePaths` returning REAL ABSOLUTE PATHS — not encoded directory names, which is the distinction that made 6 of 6 live projects classify `dead` while the two sides were being wired together — pass `projectsRoot` via the exported `projectsRoot()` rather than joining the segment by hand, and give `fs` an `exists` that returns `undefined` for every errno except ENOENT.
|
|
64
|
+
|
|
65
|
+
## 9.4.0
|
|
66
|
+
|
|
67
|
+
### Minor Changes
|
|
68
|
+
|
|
69
|
+
- 299a014: `createDelegateTool` — the agent can now ask the framework to delegate.
|
|
70
|
+
|
|
71
|
+
`@theokit/agents/tools` handed the model 23 tools and none of them delegated to a local sub-agent.
|
|
72
|
+
The capability shipped — `delegate()`, `delegateWithScoring()`, `delegateBackground()`, `Squad` —
|
|
73
|
+
but only the app could reach it. `createA2ATool` did not cover the case: its target is a remote peer,
|
|
74
|
+
inheriting none of the parent's tools, budget or authority.
|
|
75
|
+
|
|
76
|
+
The factory is deliberately thin. `delegate()` already merges the parent's tools, clamps the budget
|
|
77
|
+
and propagates authority; re-deriving any of that here would create a second owner of one rule.
|
|
78
|
+
|
|
79
|
+
It refuses at construction what would otherwise fail on the model's first call: an empty roster,
|
|
80
|
+
duplicate names (which collapse in the enum and dispatch silently to the wrong sub-agent) and a
|
|
81
|
+
missing credential. Budget and timeout failures come back as JSON the model can act on rather than
|
|
82
|
+
ending the parent's turn; an unexpected error propagates.
|
|
83
|
+
|
|
84
|
+
- d6a5928: `CustomCommand.frontmatter` carries the frontmatter lines, so a product can read its own keys.
|
|
85
|
+
|
|
86
|
+
The loader knows one key (`description`). A product's commands declare more, and the sets do not
|
|
87
|
+
agree: the closest consumer reads `model`, `agent`, `subtask` and `hints`, while Claude Code's custom
|
|
88
|
+
commands declare `model` and `argument-hint`. Two vocabularies already, and neither is the
|
|
89
|
+
framework's to adopt.
|
|
90
|
+
|
|
91
|
+
Measured cost of not carrying them: that consumer wrote a 122-line loader — same directories, same
|
|
92
|
+
trust gate, same precedence — because the result gave it nowhere to read its own keys from. The lines
|
|
93
|
+
travel now, and `frontmatterValue` (already exported) reads whichever key the caller cares about.
|
|
94
|
+
|
|
95
|
+
- 7825605: `loadInstructionTree` takes an `order`, so a rules folder is walked the way a rules folder means.
|
|
96
|
+
|
|
97
|
+
The predicate made a rules directory walkable and left the ordering the one an instruction TREE
|
|
98
|
+
needs — every file at a level before descending, because there the outer file states the general rule
|
|
99
|
+
and the inner one refines it. A rules FOLDER is the opposite shape: the files are peers, and the
|
|
100
|
+
contract its users depend on is that the same directory assembles the same prompt on any machine, in
|
|
101
|
+
one alphabetical pass.
|
|
102
|
+
|
|
103
|
+
Half a capability is its own kind of defect: offering the walk without the order left a caller able
|
|
104
|
+
to read a rules folder only in an order that misrepresents it.
|
|
105
|
+
|
|
106
|
+
Additive — `'outward-in'` stays the default, so no existing caller shifts.
|
|
107
|
+
|
|
108
|
+
- c70eadb: `loadInstructionTree` now accepts a predicate for `fileNames`, so a rules DIRECTORY can be walked.
|
|
109
|
+
|
|
110
|
+
`fileNames.includes(entry)` matched a basename, so the walk could only collect files the caller
|
|
111
|
+
could name in advance. A rules directory is the opposite shape: the user drops arbitrarily named
|
|
112
|
+
files in and expects all of them read. That is not one product's idiosyncrasy — Claude Code reads
|
|
113
|
+
`.claude/rules/` and Cursor reads `.cursor/rules/*.mdc`, both arbitrary-name directories.
|
|
114
|
+
|
|
115
|
+
Measured consequence of the gap: the closest consumer wrote its own 112-line walk — budget, depth
|
|
116
|
+
ceiling, cycle guard and all — to ask `entry.endsWith('.md')`. The walk was ours; only the question
|
|
117
|
+
was theirs.
|
|
118
|
+
|
|
119
|
+
Additive: `fileNames` still accepts an array, with unchanged semantics.
|
|
120
|
+
|
|
121
|
+
- 339852d: `loadCustomCommands` reads subdirectories, so a namespaced command is no longer invisible.
|
|
122
|
+
|
|
123
|
+
The loader stopped at `!statSync(path).isFile()`, which means a command in a subdirectory was not
|
|
124
|
+
"unsupported" — it was invisible. No warning, no error: the file sits there and the command does not
|
|
125
|
+
exist.
|
|
126
|
+
|
|
127
|
+
Namespacing is not one product's idea. Claude Code reads `.claude/commands/frontend/component.md` as
|
|
128
|
+
a namespaced command, and the closest consumer names nested files by their relative path for the same
|
|
129
|
+
reason a flat directory stops scaling past a dozen commands.
|
|
130
|
+
|
|
131
|
+
The name is now the path relative to the commands root with the extension removed
|
|
132
|
+
(`frontend/component`). How it is rendered — `frontend:component`, `frontend/component` — stays the
|
|
133
|
+
product's, because the two known products already disagree.
|
|
134
|
+
|
|
135
|
+
- b30fe9f: `projectsRoot(root?)` — one owner for where every project's transcripts live.
|
|
136
|
+
|
|
137
|
+
`join(root, 'projects', …)` was written in three places: twice inside `project-index.ts`, and once in
|
|
138
|
+
the closest consumer, which restated it as `join(transcriptRoot(), 'projects')` to enumerate every
|
|
139
|
+
project for a GC sweep.
|
|
140
|
+
|
|
141
|
+
The failure mode is what makes it worth a function rather than a comment. That consumer guards its
|
|
142
|
+
enumeration with `existsSync(root) ? readdir(root) : []`, so a segment that stops matching does not
|
|
143
|
+
throw — it returns an empty list. The sweep then finds nothing, deletes nothing, and reports success.
|
|
144
|
+
A wrong path that throws is a bug report; a wrong path that returns nothing is a collector that
|
|
145
|
+
quietly stopped collecting.
|
|
146
|
+
|
|
147
|
+
- e7c4d28: `InstructionBlock.scopesUnreadable` — a declared `paths:` that yields nothing is no longer
|
|
148
|
+
indistinguishable from no scope at all.
|
|
149
|
+
|
|
150
|
+
`parsePathsScope` reads lines and never fails, so a `paths:` whose value it cannot extract returned
|
|
151
|
+
`[]` — the same value as a file that declared no scope. A consumer rendering `scopes` then turned a
|
|
152
|
+
rule written for one subtree into a rule applying everywhere, and nothing said so.
|
|
153
|
+
|
|
154
|
+
Widening a scope silently is the one frontmatter failure with a consequence: the model obeys a rule
|
|
155
|
+
outside the files it was written for. The flag lets a product with a fail-closed policy drop the
|
|
156
|
+
block instead of publishing it unscoped, and `onWarn` now reports the case.
|
|
157
|
+
|
|
158
|
+
### Patch Changes
|
|
159
|
+
|
|
160
|
+
- 6b15741: Frontmatter is read on CRLF files instead of being reported as never closing.
|
|
161
|
+
|
|
162
|
+
`splitFrontmatter` split on `'\n'`, so on a CRLF checkout the closing line is `'---\r'`, which never
|
|
163
|
+
equalled the fence: a perfectly valid file returned "frontmatter never closes" and was skipped. On
|
|
164
|
+
Windows that is every instruction file with frontmatter, silently, with a warning blaming a missing
|
|
165
|
+
`---` that is sitting right there.
|
|
166
|
+
|
|
167
|
+
The trap ran one level deeper. `.` does not match `\r` and `$` does not match before it, so the
|
|
168
|
+
list-item pattern behind `paths:` failed on `' - src/**\r'`. Fixing only the fence would have
|
|
169
|
+
turned "the file is skipped" into "the file is read and silently unscoped" — worse, because a rule
|
|
170
|
+
that applies everywhere looks like it works.
|
|
171
|
+
|
|
172
|
+
Line endings are now normalised at the boundary, and the closing fence is compared trimmed like the
|
|
173
|
+
opening one already was — an asymmetry that let a file open a frontmatter block it could never close.
|
|
174
|
+
|
|
175
|
+
- b8f47a9: Two silent failures in the instruction-tree walk.
|
|
176
|
+
|
|
177
|
+
`paths: [unclosed` produced the scope `unclose`. The inline branch did
|
|
178
|
+
`inline.slice(1, inline.lastIndexOf(']'))`, and `lastIndexOf` returns -1 when the bracket never
|
|
179
|
+
arrives — so the slice quietly dropped the last character and handed back a scope nobody wrote.
|
|
180
|
+
Worse than an empty list, because a scope that exists suppresses `scopesUnreadable`: the block looked
|
|
181
|
+
correctly scoped, to a path matching nothing, so the rule stopped applying anywhere and said nothing.
|
|
182
|
+
|
|
183
|
+
The depth ceiling stopped in silence. The file ceiling already announced itself
|
|
184
|
+
(`instruction budget: stopped at N files`) and this one was a bare `return false` — indistinguishable
|
|
185
|
+
from a directory that had nothing left in it, which sends the reader looking for a typo in a filename
|
|
186
|
+
that is spelled correctly.
|
|
187
|
+
|
|
188
|
+
- b023cef: `deleteSession` now refuses an async `removeFromRegistry` instead of reporting a delete that has not
|
|
189
|
+
happened.
|
|
190
|
+
|
|
191
|
+
The seam is synchronous by contract, and `options.removeFromRegistry?.(id) ?? false` sat at the
|
|
192
|
+
return: hand it an async remover and the field evaluated to a Promise — truthy — so `registryRemoved`
|
|
193
|
+
said the entry was gone before the removal occurred, and any rejection surfaced as an unhandled
|
|
194
|
+
rejection. That is not a corner case. `Agent.delete` returns `Promise<void>` and is the only agent
|
|
195
|
+
registry in the ecosystem, so every real caller has an async remover.
|
|
196
|
+
|
|
197
|
+
The check now runs BEFORE the transcript is unlinked, so a refused call leaves the session intact and
|
|
198
|
+
the caller can retry: await the registry removal first, then pass its outcome.
|
|
199
|
+
|
|
3
200
|
## 9.3.0
|
|
4
201
|
|
|
5
202
|
### Minor Changes
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import { McpServerConfig, SystemPromptResolver, InlineSkill, SettingSource, MemorySettings, SkillsSettings, ContextSettings
|
|
2
|
-
import { z } from 'zod';
|
|
1
|
+
import { McpServerConfig, SystemPromptResolver, InlineSkill, SettingSource, MemorySettings, SkillsSettings, ContextSettings } from '@theokit/sdk';
|
|
3
2
|
import { TheokitAgentError } from '@theokit/sdk/errors';
|
|
4
|
-
import {
|
|
3
|
+
import { z } from 'zod';
|
|
5
4
|
|
|
6
5
|
/**
|
|
7
6
|
* Provider-agnostic extended-thinking knob (M1 reasoning-visibility). The common set autocompletes;
|
|
@@ -401,233 +400,4 @@ interface CompiledAgentOptions {
|
|
|
401
400
|
skillsResolver?: SkillsSelection;
|
|
402
401
|
}
|
|
403
402
|
|
|
404
|
-
|
|
405
|
-
* M68 — the trust gate for `settingSources`.
|
|
406
|
-
*
|
|
407
|
-
* ## The defect this module closes
|
|
408
|
-
*
|
|
409
|
-
* `settingSources` enables on-disk config discovery. `'user'` reads `~/.theokit/` — the operator's
|
|
410
|
-
* own machine, which no third party controls. `'project'` reads `<cwd>/.theokit/`, **including
|
|
411
|
-
* `hooks.json`, which executes shell**.
|
|
412
|
-
*
|
|
413
|
-
* The previous API took `readonly SettingSource[]`, and its JSDoc justified the risk this way:
|
|
414
|
-
* *"it is opt-in because `.theokit/` is the app's own repo (informed consent)"*. That premise holds
|
|
415
|
-
* for a web app whose `cwd` is its own deploy. It does **not** hold for the class of product this
|
|
416
|
-
* framework addresses — an agent whose `cwd` is a repository the user just cloned. There `.theokit/`
|
|
417
|
-
* is attacker-controlled content, and enabling `'project'` is remote code execution on the first
|
|
418
|
-
* `build()`.
|
|
419
|
-
*
|
|
420
|
-
* Documenting it did not prevent it. The measured consumer (TheoCode) did not trust the API: it
|
|
421
|
-
* gated from the outside, with a `posture.allows` of its own (`chat.ts:386`, comment B-008). It
|
|
422
|
-
* already **had** the right decision and could not pass it through, because the API only accepted
|
|
423
|
-
* strings. The gate existed on its side and evaporated at the boundary.
|
|
424
|
-
*
|
|
425
|
-
* ## The evidence is the SDK's, not one invented here
|
|
426
|
-
*
|
|
427
|
-
* `TrustPosture` is `@theokit/sdk`'s own trust primitive, and `recordWiring`'s doc says *"a posture
|
|
428
|
-
* is the only thing in this package that retains a capability"*. A bespoke type would make two trust
|
|
429
|
-
* grammars coexist and drift apart (ADR 0063).
|
|
430
|
-
*/
|
|
431
|
-
/**
|
|
432
|
-
* The framework's capability vocabulary — deliberately a single name (ADR 0065).
|
|
433
|
-
*
|
|
434
|
-
* `allows` is all-or-nothing in the SDK: every declared `K` gets the same boolean. A finer
|
|
435
|
-
* vocabulary (`hooks`, `skills`, `subagents`, `mcp`) would promise the consumer it can gate one
|
|
436
|
-
* without gating the other, and the primitive does not deliver that. An API that suggests a
|
|
437
|
-
* distinction the runtime does not make teaches the wrong thing, and the error only surfaces when
|
|
438
|
-
* somebody depends on the distinction.
|
|
439
|
-
*/
|
|
440
|
-
type SettingSourceCapability = 'projectSettings';
|
|
441
|
-
/** Authorization to read config from the working directory. Requires the posture, never a claim. */
|
|
442
|
-
interface ProjectSettingsGrant {
|
|
443
|
-
/**
|
|
444
|
-
* Typically the output of `resolveTrustPosture` — which is what gives it `source` (`'env' |
|
|
445
|
-
* 'store' | 'default'`) and therefore a refusal that says WHERE the decision came from instead of
|
|
446
|
-
* merely denying.
|
|
447
|
-
*/
|
|
448
|
-
readonly trustedBy: TrustPosture<SettingSourceCapability>;
|
|
449
|
-
}
|
|
450
|
-
/**
|
|
451
|
-
* Which on-disk config roots the agent may read.
|
|
452
|
-
*
|
|
453
|
-
* The asymmetry is the design: `user` is a boolean because `~/.theokit/` belongs to the operator;
|
|
454
|
-
* `project` requires evidence because `<cwd>/.theokit/` may not. Omitting a root is not enabling it
|
|
455
|
-
* — never "enabling without a gate". The asymmetry is inherited from the SDK itself, whose
|
|
456
|
-
* `TrustPostureInput.envOverride` documents that `false` and `undefined` both mean "the operator did
|
|
457
|
-
* not turn it on", not "turned it off".
|
|
458
|
-
*/
|
|
459
|
-
interface SettingSourcesSelection {
|
|
460
|
-
/** `~/.theokit/` — the operator's machine. No gate: no third party controls it. */
|
|
461
|
-
readonly user?: boolean;
|
|
462
|
-
/** `<cwd>/.theokit/` — controlled by whoever wrote the open repository. Requires evidence. */
|
|
463
|
-
readonly project?: ProjectSettingsGrant;
|
|
464
|
-
}
|
|
465
|
-
/**
|
|
466
|
-
* Refusal to read the working directory for lack of trust.
|
|
467
|
-
*
|
|
468
|
-
* Descends from `TheokitAgentError` because typed errors are an unbreakable rule here — and because
|
|
469
|
-
* `isTransientError` only sees this hierarchy. A class extending plain `Error` would be invisible to
|
|
470
|
-
* the predicate that separates recoverable from unrecoverable (the defect M67 fixed in five
|
|
471
|
-
* classes).
|
|
472
|
-
*/
|
|
473
|
-
declare class UntrustedSettingSourceError extends TheokitAgentError {
|
|
474
|
-
/** Where the trust decision came from: `'env' | 'store' | 'default'`. */
|
|
475
|
-
readonly trustSource: string;
|
|
476
|
-
/** The refused capability. */
|
|
477
|
-
readonly capability: SettingSourceCapability;
|
|
478
|
-
readonly name = "UntrustedSettingSourceError";
|
|
479
|
-
constructor(message: string,
|
|
480
|
-
/** Where the trust decision came from: `'env' | 'store' | 'default'`. */
|
|
481
|
-
trustSource: string,
|
|
482
|
-
/** The refused capability. */
|
|
483
|
-
capability: SettingSourceCapability);
|
|
484
|
-
}
|
|
485
|
-
/**
|
|
486
|
-
* Translate the declared selection into the `SettingSource`s the SDK accepts, refusing what the
|
|
487
|
-
* posture does not authorize.
|
|
488
|
-
*
|
|
489
|
-
* Refuses rather than ignores (ADR 0064). Ignoring would leave the product running in the belief
|
|
490
|
-
* that the repository's hooks are active — a silent failure mode, on the wrong side. The SDK already
|
|
491
|
-
* picked that side for the same problem: `recordWiring` throws `UngatedCapabilityError` when
|
|
492
|
-
* somebody registers a capability the posture does not gate.
|
|
493
|
-
*
|
|
494
|
-
* @throws {UntrustedSettingSourceError} when `project` is requested and the posture does not grant it.
|
|
495
|
-
*/
|
|
496
|
-
declare function resolveSettingSources(selection: SettingSourcesSelection | undefined): readonly SettingSource[];
|
|
497
|
-
|
|
498
|
-
/**
|
|
499
|
-
* M2 (theokit-ai-first) — `defineAgent`, the zero-config imperative agent surface.
|
|
500
|
-
*
|
|
501
|
-
* ADR-B1: `defineAgent({...})` (default-exported from a top-level `agents/<name>.ts`) is
|
|
502
|
-
* the canonical zero-config surface; the `@Agent` class decorator stays the advanced/DI
|
|
503
|
-
* surface. Both compile to {@link CompiledAgentOptions} and run through the same SDK
|
|
504
|
-
* runtime (`createSdkAgentStream`) — one runtime, two syntaxes.
|
|
505
|
-
*
|
|
506
|
-
* This module is PURE metadata (sdk-runtime.md / G2): `defineAgent` describes an agent, it
|
|
507
|
-
* NEVER calls an LLM. It imports only `zod` (types) + the compiler shape — no `theokit`
|
|
508
|
-
* core, preserving the agents → (nothing) dependency direction (G1).
|
|
509
|
-
*/
|
|
510
|
-
|
|
511
|
-
/**
|
|
512
|
-
* Brand tag for a `defineAgent` value. `Symbol.for` (global registry, not `Symbol()`) so
|
|
513
|
-
* the brand survives duplicate module instances (dual-package / bundling) — the scanner's
|
|
514
|
-
* brand-check then works regardless of which copy created the definition.
|
|
515
|
-
*/
|
|
516
|
-
declare const AGENT_BRAND: unique symbol;
|
|
517
|
-
/** Config accepted by {@link defineAgent}. */
|
|
518
|
-
interface DefineAgentConfig<TInput extends z.ZodType = z.ZodType> {
|
|
519
|
-
/** Zod schema for the request body — lifted into the typed client (M2, {@link InferAgentInput}). */
|
|
520
|
-
input?: TInput;
|
|
521
|
-
/** Model id (e.g. `claude-sonnet-4-6`). Falls back to the SDK default when omitted. */
|
|
522
|
-
model?: string;
|
|
523
|
-
/** Static system prompt. */
|
|
524
|
-
system?: string;
|
|
525
|
-
/** Extended-thinking effort. */
|
|
526
|
-
reasoningEffort?: ReasoningEffort;
|
|
527
|
-
/**
|
|
528
|
-
* Pre-built tools. Accepts the `@theokit/sdk` `CustomTool` that `defineAgentTool`
|
|
529
|
-
* (theokit/server) and every `@theokit/sdk-tools` factory return (issue #81) — they are
|
|
530
|
-
* normalized to the internal {@link CompiledTool} shape at compile time.
|
|
531
|
-
*/
|
|
532
|
-
tools?: readonly CustomTool[];
|
|
533
|
-
/**
|
|
534
|
-
* M7 — run-context: an opaque, per-agent object forwarded to every tool handler's
|
|
535
|
-
* `ctx.context` at run time (injected by the theokit adapter's tool wrapper). Set shared config
|
|
536
|
-
* (e.g. `{ projectRoot }`) ONCE at the agent level instead of baking it into each tool
|
|
537
|
-
* factory. Mirrors ai-sdk `experimental_context`, mastra `RuntimeContext`, and
|
|
538
|
-
* openai-agents-js `RunContext`. Distinct from `@Agent`'s context-window `context`.
|
|
539
|
-
*/
|
|
540
|
-
context?: Record<string, unknown>;
|
|
541
|
-
/**
|
|
542
|
-
* M9 — guardrails: input/output guards applied at the framework boundary (ADR-0040 § D2).
|
|
543
|
-
* Input guards run on the user message before the SDK runtime; a `block` fails the run fast.
|
|
544
|
-
* Built-ins live in `@theokit/agents` (`promptInjectionDetector`, `piiDetector`, `costGuard`,
|
|
545
|
-
* `unicodeNormalizer`, `outputModeration`).
|
|
546
|
-
*/
|
|
547
|
-
guardrails?: readonly Guardrail[];
|
|
548
|
-
/**
|
|
549
|
-
* M14 — HITL approvals keyed by tool name. Each gated tool pauses the run and emits an
|
|
550
|
-
* `approval_required` event until approved (reuses the same `compiled.hitl` wiring the `@Agent`
|
|
551
|
-
* + `@HumanInTheLoop` path produces). A key that does not match a declared tool fails fast at
|
|
552
|
-
* compile time.
|
|
553
|
-
*/
|
|
554
|
-
approvals?: Record<string, HumanInTheLoopOptions>;
|
|
555
|
-
/**
|
|
556
|
-
* M13 — skills selection: a static list (compiled straight to the SDK `skills.enabled`) OR a
|
|
557
|
-
* per-request resolver `(ctx) => string[]` (carried on `compiled.skillsResolver`, resolved by the
|
|
558
|
-
* request path against the run-context). Absent ⇒ the SDK enables every discovered skill.
|
|
559
|
-
*/
|
|
560
|
-
skills?: SkillsSelection;
|
|
561
|
-
/**
|
|
562
|
-
* theokit-file-based-config — opt into `.theokit/` file-based config (skills, subagents, hooks,
|
|
563
|
-
* MCP, context, cron). The SDK discovers config from these roots under the app's `cwd`:
|
|
564
|
-
* `project` = `<cwd>/.theokit/`, `user` = `~/.theokit/`. Absent ⇒ inline (code) config only.
|
|
565
|
-
*
|
|
566
|
-
* SECURITY (M68): `project` reads `.theokit/hooks.json`, which **executes shell**, so it requires
|
|
567
|
-
* a `TrustPosture` rather than a string. This field used to take `readonly SettingSource[]`, and
|
|
568
|
-
* its own JSDoc justified the risk as *"opt-in because `.theokit/` is the app's own repo (informed
|
|
569
|
-
* consent)"*. That premise holds for a web app whose `cwd` is its own deploy; it does not hold for
|
|
570
|
-
* an agent whose `cwd` is a repository the user just cloned, where `.theokit/` is
|
|
571
|
-
* attacker-controlled content.
|
|
572
|
-
*
|
|
573
|
-
* `user` stays a plain boolean — `~/.theokit/` is the operator's own machine. Omitting a root is
|
|
574
|
-
* not enabling it. The SDK owns discovery + execution (G2 / ADR-0040); theokit resolves the
|
|
575
|
-
* selection through `resolveSettingSources` and wires the result into
|
|
576
|
-
* `Agent.create({ local.settingSources })`.
|
|
577
|
-
*/
|
|
578
|
-
settingSources?: SettingSourcesSelection;
|
|
579
|
-
/**
|
|
580
|
-
* M49 — durable memory (the SDK's `.theokit/memory/` subsystem: `Remember:` capture, MEMORY.md
|
|
581
|
-
* store, auto-injected `<memory>` block, `memory_search`/`memory_get` tools). The shape is the
|
|
582
|
-
* SDK's own `MemorySettings` — the canonical runtime contract. Projected into
|
|
583
|
-
* `Agent.create({ memory })` by `assembleM8CreateOptions`.
|
|
584
|
-
*/
|
|
585
|
-
memory?: MemorySettings;
|
|
586
|
-
/**
|
|
587
|
-
* Code `Plugin` objects forwarded to `Agent.create({ plugins })` — EXTENSION units (tools,
|
|
588
|
-
* commands, model providers, memory adapters). For lifecycle interception use {@link hooks}.
|
|
589
|
-
*/
|
|
590
|
-
plugins?: readonly unknown[];
|
|
591
|
-
/**
|
|
592
|
-
* Lifecycle hooks keyed by `HookName` (`pre_tool_call` may veto via `{ block, message }`). Set by
|
|
593
|
-
* the builder's `hooks()`; converted into a code plugin at `build()` and never reaching the SDK
|
|
594
|
-
* under this name — the plugin is the TRANSPORT, this is the contract callers write against.
|
|
595
|
-
*/
|
|
596
|
-
hooks?: HookHandlers | Readonly<Record<string, unknown>>;
|
|
597
|
-
/**
|
|
598
|
-
* MCP servers available to the agent — the builder-chain equivalent of the `@MCP` class
|
|
599
|
-
* decorator. Each key is a server name; the value is the server configuration. Forwarded
|
|
600
|
-
* unchanged to `Agent.create({ mcpServers })` (the SDK owns MCP execution). Absent ⇒ no MCP.
|
|
601
|
-
*/
|
|
602
|
-
mcpServers?: McpServersMap;
|
|
603
|
-
}
|
|
604
|
-
/**
|
|
605
|
-
* A branded agent definition — the value {@link defineAgent} returns.
|
|
606
|
-
*
|
|
607
|
-
* `TTools` (M8) is a phantom type parameter carrying the tool-name union: the `AgentBuilder.create()` builder
|
|
608
|
-
* threads its accumulated literal tool names here (`.build()` returns `AgentDefinition<TInput,
|
|
609
|
-
* 'a' | 'b'>`), so the generated client (`.theokit/agents.d.ts`) can expose them via
|
|
610
|
-
* {@link InferAgentToolNames}. `defineAgent` leaves it `string` (its tools array carries no literal
|
|
611
|
-
* names). Never present at runtime.
|
|
612
|
-
*/
|
|
613
|
-
type AgentDefinition<TInput extends z.ZodType = z.ZodType, TTools extends string = string> = DefineAgentConfig<TInput> & {
|
|
614
|
-
readonly [AGENT_BRAND]: true;
|
|
615
|
-
readonly __toolNames?: TTools;
|
|
616
|
-
};
|
|
617
|
-
/** Infer the request type of an agent definition from its `input` Zod schema. */
|
|
618
|
-
type InferAgentInput<T> = T extends AgentDefinition<infer S> ? (S extends z.ZodType ? z.infer<S> : never) : never;
|
|
619
|
-
/**
|
|
620
|
-
* Infer the tool-name union of an agent definition (M8). Yields the literal union for agents built
|
|
621
|
-
* with the `AgentBuilder.create()` builder (`'read_file' | 'count_lines'`), or `string` for `defineAgent` agents
|
|
622
|
-
* whose tools array carries no literal names.
|
|
623
|
-
*/
|
|
624
|
-
type InferAgentToolNames<T> = T extends AgentDefinition<z.ZodType, infer N> ? N : never;
|
|
625
|
-
/** Brand-check: is `value` a {@link defineAgent} result? */
|
|
626
|
-
declare function isAgentDefinition(value: unknown): value is AgentDefinition;
|
|
627
|
-
/**
|
|
628
|
-
* Lower a definition to the SDK-ready {@link CompiledAgentOptions} — the same shape
|
|
629
|
-
* `compileAgent` (decorator path) produces, so both surfaces converge on one runtime.
|
|
630
|
-
*/
|
|
631
|
-
declare function compileAgentDefinition(def: AgentDefinition): CompiledAgentOptions;
|
|
632
|
-
|
|
633
|
-
export { type AgentDefinition as A, type BudgetOptions as B, type CompiledAgentOptions as C, type DefineAgentConfig as D, type Guardrail as G, type HumanInTheLoopOptions as H, type InferAgentInput as I, type MainLoopMeta as M, type PolicyHandler as P, type ReasoningEffort as R, type SettingSourcesSelection as S, type ToolOptions as T, UntrustedSettingSourceError as U, type CompiledTool as a, type ApprovalOptions as b, AGENT_BRAND as c, type AgentOptions as d, CostBudgetExceededError as e, type GuardrailAction as f, type GuardrailPhase as g, type GuardrailResult as h, GuardrailViolationError as i, type InferAgentToolNames as j, type MainLoopOptions as k, type McpServersMap as l, type ProjectSettingsGrant as m, type SettingSourceCapability as n, type SkillsRequestContext as o, type SkillsSelection as p, type TimeoutAction as q, type ToolWalkResult as r, type ToolboxOptions as s, type ToolboxWalkResult as t, compileAgentDefinition as u, compileTools as v, isAgentDefinition as w, resolveEnabledSkills as x, resolveSettingSources as y, type ProjectContextOptions as z };
|
|
403
|
+
export { type ApprovalOptions as A, type BudgetOptions as B, type CompiledAgentOptions as C, type Guardrail as G, type HumanInTheLoopOptions as H, type McpServersMap as M, type PolicyHandler as P, type ReasoningEffort as R, type SkillsSelection as S, type ToolOptions as T, type MainLoopMeta as a, type CompiledTool as b, type AgentOptions as c, CostBudgetExceededError as d, type GuardrailAction as e, type GuardrailPhase as f, type GuardrailResult as g, GuardrailViolationError as h, type MainLoopOptions as i, type SkillsRequestContext as j, type TimeoutAction as k, type ToolWalkResult as l, type ToolboxOptions as m, type ToolboxWalkResult as n, compileTools as o, type ProjectContextOptions as p, resolveEnabledSkills as r };
|
package/dist/ask.d.ts
CHANGED
|
@@ -118,7 +118,7 @@ declare function createAskBridge(): AskBridge;
|
|
|
118
118
|
* and tested without a mock.
|
|
119
119
|
*/
|
|
120
120
|
/** A decision waiting for a human, as the surface knows it. */
|
|
121
|
-
interface PendingItem {
|
|
121
|
+
interface PendingItem<TPayload = undefined> {
|
|
122
122
|
/** The framework's id for the decision (an approval id, a question id). */
|
|
123
123
|
readonly id: string;
|
|
124
124
|
/**
|
|
@@ -128,15 +128,27 @@ interface PendingItem {
|
|
|
128
128
|
* everything attached to messages that no longer exist.
|
|
129
129
|
*/
|
|
130
130
|
readonly messageIndex: number;
|
|
131
|
+
/**
|
|
132
|
+
* The SURFACE's own state for this item — render timestamps, collapsed flags, whatever it needs.
|
|
133
|
+
*
|
|
134
|
+
* T2.7. The framework never reads it; it is carried, not interpreted. Without this slot a surface
|
|
135
|
+
* adopting the ledger has to keep a SECOND map keyed by the same id, which is strictly worse than
|
|
136
|
+
* the single map it already maintains — and that is the measured reason `createPendingLedger`
|
|
137
|
+
* shipped and went unused while a hand-written ledger stayed in the only real consumer.
|
|
138
|
+
*
|
|
139
|
+
* The default of `undefined` is what keeps this non-breaking: every existing caller writes
|
|
140
|
+
* `PendingItem` with no argument and passes items with no payload.
|
|
141
|
+
*/
|
|
142
|
+
readonly payload?: TPayload;
|
|
131
143
|
}
|
|
132
|
-
interface PendingLedger {
|
|
144
|
+
interface PendingLedger<TPayload = undefined> {
|
|
133
145
|
/**
|
|
134
146
|
* Record what the framework reports as pending.
|
|
135
147
|
*
|
|
136
148
|
* Additive and idempotent: the same list arrives on every poll. An id already settled is NOT
|
|
137
149
|
* re-added — that single rule is what stops the dismissed card from coming back.
|
|
138
150
|
*/
|
|
139
|
-
ingest(items: readonly PendingItem[]): void;
|
|
151
|
+
ingest(items: readonly PendingItem<TPayload>[]): void;
|
|
140
152
|
/**
|
|
141
153
|
* Mark one as answered. `false` when it was unknown or already settled.
|
|
142
154
|
*
|
|
@@ -145,7 +157,7 @@ interface PendingLedger {
|
|
|
145
157
|
*/
|
|
146
158
|
settle(id: string): boolean;
|
|
147
159
|
/** The oldest unsettled item, or `undefined`. A surface shows one at a time. */
|
|
148
|
-
findNext(): PendingItem | undefined;
|
|
160
|
+
findNext(): PendingItem<TPayload> | undefined;
|
|
149
161
|
/**
|
|
150
162
|
* Forget everything attached to a message before `messageIndex`, settled or not. Returns how many
|
|
151
163
|
* unsettled items were dropped.
|
|
@@ -154,7 +166,7 @@ interface PendingLedger {
|
|
|
154
166
|
*/
|
|
155
167
|
pruneBefore(messageIndex: number): number;
|
|
156
168
|
}
|
|
157
|
-
declare function createPendingLedger(): PendingLedger
|
|
169
|
+
declare function createPendingLedger<TPayload = undefined>(): PendingLedger<TPayload>;
|
|
158
170
|
|
|
159
171
|
/**
|
|
160
172
|
* M77 — adapt an {@link AskBridge} to the `askUser` shape the question tool expects.
|
package/dist/ask.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/ask/ask-bridge.ts","../src/ask/pending-ledger.ts","../src/ask/ask-user-via.ts"],"mappings":"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
|
|
1
|
+
{"version":3,"sources":["../src/ask/ask-bridge.ts","../src/ask/pending-ledger.ts","../src/ask/ask-user-via.ts"],"mappings":"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","names":["TheokitAgentError","ConcurrentQuestionError","TheokitAgentError","name","threadId","code","ConcurrentListenerError","QuestionAbandonedError","why","createAskBridge","pendingByThread","Map","pendingById","listeners","forget","id","delete","ask","question","has","Promise","reject","listener","get","undefined","crypto","randomUUID","promise","resolve","entry","settle","answer","fail","error","set","notify","abandon","onAbandon","setListener","options","createPendingLedger","open","Map","settled","ingest","items","item","has","id","set","settle","get","undefined","delete","messageIndex","findNext","oldest","values","pruneBefore","dropped","at","askUserVia","bridge","question","threadId","undefined","Promise","reject","QuestionAbandonedError","ask"]}
|