@theokit/sdk 5.2.0 → 5.3.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 +82 -0
- package/dist/index.cjs +9 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +10 -1
- package/dist/index.js.map +1 -1
- package/dist/internal/persistence/list-sessions.d.cts +98 -0
- package/dist/internal/persistence/list-sessions.d.ts +98 -0
- package/dist/persistence.cjs +65 -0
- package/dist/persistence.cjs.map +1 -1
- package/dist/persistence.d.cts +1 -0
- package/dist/persistence.d.ts +1 -0
- package/dist/persistence.js +67 -2
- package/dist/persistence.js.map +1 -1
- package/docs/error-codes.md +2 -1
- package/docs/harness-capability-map.md +5 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,87 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 5.3.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#607](https://github.com/usetheokit/theokit-sdk/pull/607) [`a7ed8e0`](https://github.com/usetheokit/theokit-sdk/commit/a7ed8e0c37105375e439ef567a51c7643ffc7754) Thanks [@usetheodev](https://github.com/usetheodev)! - `listSessions` — enumerate sessions, and say where each id came from ([#598](https://github.com/usetheokit/theokit-sdk/issues/598))
|
|
8
|
+
|
|
9
|
+
Every transcript helper this package published mapped **forward** — `sessionUuidFor`,
|
|
10
|
+
`transcriptPath`, `legacyTranscriptPath`, `encodeProjectDir`, `transcriptRoot`. **None enumerated.**
|
|
11
|
+
So a consumer that needed the list rebuilt it, and two independent ones did, in opposite directions,
|
|
12
|
+
and both derived the session id from the **filename**:
|
|
13
|
+
|
|
14
|
+
| consumer | direction | what broke |
|
|
15
|
+
|---|---|---|
|
|
16
|
+
| `@theokit/agents` | file → id | `sessionIdOf` returned the file stem |
|
|
17
|
+
| a downstream agent runtime | id → file | compared session ids against filenames |
|
|
18
|
+
|
|
19
|
+
The second was measured against `5.0.1`: the protected set never matched, so **neither the registered
|
|
20
|
+
sessions nor the live one were protected and everything classified as an orphan** — a garbage
|
|
21
|
+
collector that would delete the session in use.
|
|
22
|
+
|
|
23
|
+
```ts
|
|
24
|
+
import { listSessions } from "@theokit/sdk/persistence";
|
|
25
|
+
|
|
26
|
+
for (const s of await listSessions(process.cwd())) {
|
|
27
|
+
if (s.idSource === "unavailable") continue; // do not guess, and do not delete
|
|
28
|
+
…
|
|
29
|
+
}
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
**Documentation was not the fix, and that is the argument for the primitive.** The rename was
|
|
33
|
+
documented thoroughly. One of those two consumers had *read* it and broke anyway; the other had not
|
|
34
|
+
and broke identically. Two samples, one informed and one not, the same defect — so the cause is the
|
|
35
|
+
shape of the surface rather than the reader. Nor can it be closed with an inverse: the filename is a
|
|
36
|
+
UUIDv8 over SHA-256, which has none.
|
|
37
|
+
|
|
38
|
+
**Every entry carries `idSource`, and an unreadable id is `undefined` rather than guessed.** An
|
|
39
|
+
`id: string` that is sometimes read from the transcript and sometimes inferred is the same defect one
|
|
40
|
+
layer up — a value that reads as authoritative and occasionally is not, which is exactly what
|
|
41
|
+
produced the garbage-collector failure. A caller deciding what to *delete* needs to tell "not
|
|
42
|
+
registered" from "I could not read this file"; in a plain list those look identical and mean opposite
|
|
43
|
+
things.
|
|
44
|
+
|
|
45
|
+
Reading is capped (64KB by default, `idScanBytes`) because the id lives in the first record and a
|
|
46
|
+
transcript grows without bound: bounded work with a declared outcome beats an unbounded read.
|
|
47
|
+
|
|
48
|
+
Evidence gathered by the `theocode` session, which measured its own failure and obtained the
|
|
49
|
+
sibling's `file:line` rather than paraphrasing it.
|
|
50
|
+
|
|
51
|
+
## 5.2.1
|
|
52
|
+
|
|
53
|
+
### Patch Changes
|
|
54
|
+
|
|
55
|
+
- [#594](https://github.com/usetheokit/theokit-sdk/pull/594) [`9dc8cf5`](https://github.com/usetheokit/theokit-sdk/commit/9dc8cf52bee690bfb9cf55bee63bcda71d3132b3) Thanks [@usetheodev](https://github.com/usetheodev)! - `effectiveToolNames` refuses a created tool instead of answering confidently about it ([#583](https://github.com/usetheokit/theokit-sdk/issues/583) follow-up)
|
|
56
|
+
|
|
57
|
+
Every field on `AgentOptions` is optional, so the `CustomTool` that `SubAgent.create()` returns —
|
|
58
|
+
`{ name, description, inputSchema, handler }` — satisfies the type **by vacuity, with no cast**.
|
|
59
|
+
Measured: a `@ts-expect-error` on that call is reported unused (`TS2578`), so the compiler genuinely
|
|
60
|
+
does not refuse it.
|
|
61
|
+
|
|
62
|
+
What came back was worse than a wrong number:
|
|
63
|
+
|
|
64
|
+
```ts
|
|
65
|
+
effectiveToolNames(SubAgent.create({ name: "analyst", … }))
|
|
66
|
+
// { names: ["shell"], unresolved: [] }
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
The empty `unresolved` claims **completeness** about an object the function never understood. A
|
|
70
|
+
caller reads that as *"this subagent still announces a shell"* and either disbelieves a fix that
|
|
71
|
+
worked, or "fixes" something on the strength of it. That is the defect [#583](https://github.com/usetheokit/theokit-sdk/issues/583) exists to eliminate, one
|
|
72
|
+
function further on — and the same argument that made this return `{ names, unresolved }` rather than
|
|
73
|
+
a bare array forbids it.
|
|
74
|
+
|
|
75
|
+
It now throws a `ConfigurationError` naming what to pass instead. The detection is exact rather than
|
|
76
|
+
heuristic: `AgentOptions` declares neither `handler` nor `inputSchema`, so an object carrying **both**
|
|
77
|
+
is a tool and not options.
|
|
78
|
+
|
|
79
|
+
**The workaround is still needed, and the 5.2.0 notes should not have implied otherwise.**
|
|
80
|
+
`SubAgent.create()` closes its spec inside the handler, so the spec cannot be recovered from the
|
|
81
|
+
returned tool — keep it in a variable, or extract it into a function a test can call, and pass that.
|
|
82
|
+
|
|
83
|
+
Reported by the `theocode` session, against advice of mine that was wrong.
|
|
84
|
+
|
|
3
85
|
## 5.2.0
|
|
4
86
|
|
|
5
87
|
### Minor Changes
|
package/dist/index.cjs
CHANGED
|
@@ -919,8 +919,17 @@ var NoopMemoryProvider = class {
|
|
|
919
919
|
var ALWAYS_REGISTERED = ["shell"];
|
|
920
920
|
var MEMORY_BUILTINS = ["memory_search", "memory_get"];
|
|
921
921
|
function effectiveToolNames(options) {
|
|
922
|
+
refuseCreatedTool(options);
|
|
922
923
|
return { names: resolvableNames(options), unresolved: unresolvableSources(options) };
|
|
923
924
|
}
|
|
925
|
+
function refuseCreatedTool(options) {
|
|
926
|
+
const candidate = options;
|
|
927
|
+
if (candidate.handler === void 0 || candidate.inputSchema === void 0) return;
|
|
928
|
+
throw new chunkJ7J7J2GN_cjs.ConfigurationError(
|
|
929
|
+
`effectiveToolNames received a created tool${typeof candidate.name === "string" ? ` ("${candidate.name}")` : ""}, not AgentOptions. \`SubAgent.create()\` returns a CustomTool and closes its spec inside the handler, so the spec cannot be recovered from it. Pass the spec you built it from \u2014 keep it in a variable, or extract it into a function the test can call.`,
|
|
930
|
+
{ code: "effective_tools_expected_options" }
|
|
931
|
+
);
|
|
932
|
+
}
|
|
924
933
|
function resolvableNames(options) {
|
|
925
934
|
const withheld = new Set(options.withheldBuiltinTools ?? []);
|
|
926
935
|
const builtins = [
|