@theokit/sdk 5.2.1 → 5.3.1

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 (34) hide show
  1. package/CHANGELOG.md +121 -0
  2. package/dist/{agent-VUNM33WJ.js → agent-G4OFQYLE.js} +3 -3
  3. package/dist/{agent-VUNM33WJ.js.map → agent-G4OFQYLE.js.map} +1 -1
  4. package/dist/{agent-GACKKINM.cjs → agent-UXU5AIOJ.cjs} +4 -4
  5. package/dist/{agent-GACKKINM.cjs.map → agent-UXU5AIOJ.cjs.map} +1 -1
  6. package/dist/agent.d.ts +20 -2
  7. package/dist/{chunk-DEJCKB65.cjs → chunk-5XNRWMMD.cjs} +37 -9
  8. package/dist/chunk-5XNRWMMD.cjs.map +1 -0
  9. package/dist/{chunk-PEAOQMWE.cjs → chunk-OZT6T2RI.cjs} +4 -4
  10. package/dist/{chunk-PEAOQMWE.cjs.map → chunk-OZT6T2RI.cjs.map} +1 -1
  11. package/dist/{chunk-43H4EBS2.js → chunk-ZFEOAC52.js} +35 -7
  12. package/dist/chunk-ZFEOAC52.js.map +1 -0
  13. package/dist/{chunk-WHTMFN4Q.js → chunk-ZU3HQCKR.js} +3 -3
  14. package/dist/{chunk-WHTMFN4Q.js.map → chunk-ZU3HQCKR.js.map} +1 -1
  15. package/dist/cron.cjs +3 -3
  16. package/dist/cron.js +2 -2
  17. package/dist/eval.cjs +2 -2
  18. package/dist/eval.js +1 -1
  19. package/dist/index.cjs +18 -18
  20. package/dist/index.d.cts +20 -2
  21. package/dist/index.d.ts +20 -2
  22. package/dist/index.js +4 -4
  23. package/dist/internal/persistence/list-sessions.d.cts +98 -0
  24. package/dist/internal/persistence/list-sessions.d.ts +98 -0
  25. package/dist/persistence.cjs +65 -0
  26. package/dist/persistence.cjs.map +1 -1
  27. package/dist/persistence.d.cts +1 -0
  28. package/dist/persistence.d.ts +1 -0
  29. package/dist/persistence.js +67 -2
  30. package/dist/persistence.js.map +1 -1
  31. package/docs/harness-capability-map.md +5 -1
  32. package/package.json +1 -1
  33. package/dist/chunk-43H4EBS2.js.map +0 -1
  34. package/dist/chunk-DEJCKB65.cjs.map +0 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,126 @@
1
1
  # Changelog
2
2
 
3
+ ## 5.3.1
4
+
5
+ ### Patch Changes
6
+
7
+ - [#614](https://github.com/usetheokit/theokit-sdk/pull/614) [`20794ef`](https://github.com/usetheokit/theokit-sdk/commit/20794efffa012edf200a3409abc53b988960e7af) Thanks [@usetheodev](https://github.com/usetheodev)! - `Agent.delete` removes the entry from the persisted registry ([#612](https://github.com/usetheokit/theokit-sdk/issues/612))
8
+
9
+ It did not. The method was a no-op against `registry.json` whenever the agent was not already in the
10
+ calling process's memory — which is every agent in a freshly started process, so every CLI
11
+ invocation:
12
+
13
+ ```ts
14
+ static async delete(agentId: string, _options: AgentOperationOptions = {}): Promise<void> {
15
+ removeRegisteredAgent(agentId); // Map is empty → returns false → no save scheduled
16
+ await flushRegistrySaves(); // flushes an empty queue
17
+ }
18
+ ```
19
+
20
+ `Agent.delete` returns `Promise<void>` and throws nothing when it removed nothing, so a caller had no
21
+ way to notice. Measured downstream as a `sessions delete` that reported success and exited 0 while
22
+ the session stayed in the listing — the transcript really was removed, leaving a registry entry
23
+ pointing at a file that no longer existed.
24
+
25
+ **What makes this an omission rather than a design:** every neighbouring mutator already hydrates.
26
+ `Agent.rename` and `Agent.archive` reach `getRegisteredAgentOrThrow`, which loads from disk on a
27
+ miss; `delete` was the only one that never did.
28
+
29
+ `options.cwd` is now read instead of being defaulted away — it is declared on
30
+ `AgentOperationOptions` and the parameter was `_options`. Hydrating `process.cwd()` unconditionally
31
+ would repeat B-115 (a documented option that compiles and does nothing) on the one path whose job is
32
+ to remove data.
33
+
34
+ **Deliberately unchanged:** deleting an unknown id still resolves rather than throwing. Matching
35
+ `rename`'s `UnknownAgentError` is defensible, but it is a breaking change for callers that delete
36
+ idempotently, and an entry and its transcript can legitimately outlive one another in both
37
+ directions. A persistence fix should not smuggle in an API break.
38
+
39
+ Consumers that already called `Agent.delete` and observed the entry surviving will now see it
40
+ removed. Nothing that behaved correctly before changes.
41
+
42
+ - [#614](https://github.com/usetheokit/theokit-sdk/pull/614) [`52d31d9`](https://github.com/usetheokit/theokit-sdk/commit/52d31d903fa5ddd3236db7f628f943e7e8ceae58) Thanks [@usetheodev](https://github.com/usetheodev)! - A local agent's public `summary` is a runtime label, not a fixture name ([#611](https://github.com/usetheokit/theokit-sdk/issues/611))
43
+
44
+ `SDKAgentInfo.summary` is `@public` and required, returned by `Agent.list()` and `Agent.get()`.
45
+ `registerLocalAgent` assigned it unconditionally:
46
+
47
+ ```ts
48
+ summary: "Local contract fixture",
49
+ ```
50
+
51
+ So that string was the **only** value the field could hold for a local agent, and `AgentOptions`
52
+ exposes no `summary` for a consumer to override it. It was found on a real user's session record on
53
+ disk, written through a consumer by a real turn — nothing about the run was a fixture.
54
+
55
+ The cloud sibling faces the same requirement and guards it, which is what makes this an omission
56
+ rather than a decision:
57
+
58
+ ```ts
59
+ summary: this.isFixtureMode() ? "Cloud contract fixture" : "Cloud agent",
60
+ ```
61
+
62
+ `isFixtureMode()` keys off a `theo_test_*` key with no configured base URL — it describes whether
63
+ the *remote* is stubbed, so there is no local equivalent to port. The local branch therefore takes
64
+ the cloud branch's non-fixture value: **`"Local agent"`**.
65
+
66
+ The `toLocalAgentInfo` / `toCloudAgentInfo` **fallbacks** carried the same two literals and move
67
+ with it. That pair is the reason this was worth fixing carefully rather than quickly: while the
68
+ registration wrote a fixture name unconditionally, the fallback could never be observed, so fixing
69
+ only the reachable site would have left the string ready to reappear for any record that arrives
70
+ without a summary.
71
+
72
+ Consumers rendering `summary` will see `Local agent` where they previously saw
73
+ `Local contract fixture`. Nothing reads the value programmatically in this package; a consumer that
74
+ matched on the old string was matching on a placeholder.
75
+
76
+ ## 5.3.0
77
+
78
+ ### Minor Changes
79
+
80
+ - [#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))
81
+
82
+ Every transcript helper this package published mapped **forward** — `sessionUuidFor`,
83
+ `transcriptPath`, `legacyTranscriptPath`, `encodeProjectDir`, `transcriptRoot`. **None enumerated.**
84
+ So a consumer that needed the list rebuilt it, and two independent ones did, in opposite directions,
85
+ and both derived the session id from the **filename**:
86
+
87
+ | consumer | direction | what broke |
88
+ |---|---|---|
89
+ | `@theokit/agents` | file → id | `sessionIdOf` returned the file stem |
90
+ | a downstream agent runtime | id → file | compared session ids against filenames |
91
+
92
+ The second was measured against `5.0.1`: the protected set never matched, so **neither the registered
93
+ sessions nor the live one were protected and everything classified as an orphan** — a garbage
94
+ collector that would delete the session in use.
95
+
96
+ ```ts
97
+ import { listSessions } from "@theokit/sdk/persistence";
98
+
99
+ for (const s of await listSessions(process.cwd())) {
100
+ if (s.idSource === "unavailable") continue; // do not guess, and do not delete
101
+
102
+ }
103
+ ```
104
+
105
+ **Documentation was not the fix, and that is the argument for the primitive.** The rename was
106
+ documented thoroughly. One of those two consumers had *read* it and broke anyway; the other had not
107
+ and broke identically. Two samples, one informed and one not, the same defect — so the cause is the
108
+ shape of the surface rather than the reader. Nor can it be closed with an inverse: the filename is a
109
+ UUIDv8 over SHA-256, which has none.
110
+
111
+ **Every entry carries `idSource`, and an unreadable id is `undefined` rather than guessed.** An
112
+ `id: string` that is sometimes read from the transcript and sometimes inferred is the same defect one
113
+ layer up — a value that reads as authoritative and occasionally is not, which is exactly what
114
+ produced the garbage-collector failure. A caller deciding what to *delete* needs to tell "not
115
+ registered" from "I could not read this file"; in a plain list those look identical and mean opposite
116
+ things.
117
+
118
+ Reading is capped (64KB by default, `idScanBytes`) because the id lives in the first record and a
119
+ transcript grows without bound: bounded work with a declared outcome beats an unbounded read.
120
+
121
+ Evidence gathered by the `theocode` session, which measured its own failure and obtained the
122
+ sibling's `file:line` rather than paraphrasing it.
123
+
3
124
  ## 5.2.1
4
125
 
5
126
  ### Patch Changes
@@ -1,4 +1,4 @@
1
- export { Agent } from './chunk-43H4EBS2.js';
1
+ export { Agent } from './chunk-ZFEOAC52.js';
2
2
  import './chunk-K2VMFZQ5.js';
3
3
  import './chunk-AWINL3ZC.js';
4
4
  import './chunk-K2BQQ445.js';
@@ -54,5 +54,5 @@ import './chunk-V22DZIXO.js';
54
54
  import './chunk-NJWYQWDL.js';
55
55
  import './chunk-ALUN2B4W.js';
56
56
  import './chunk-CZJ6Q7CW.js';
57
- //# sourceMappingURL=agent-VUNM33WJ.js.map
58
- //# sourceMappingURL=agent-VUNM33WJ.js.map
57
+ //# sourceMappingURL=agent-G4OFQYLE.js.map
58
+ //# sourceMappingURL=agent-G4OFQYLE.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":[],"names":[],"mappings":"","file":"agent-VUNM33WJ.js"}
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"agent-G4OFQYLE.js"}
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var chunkDEJCKB65_cjs = require('./chunk-DEJCKB65.cjs');
3
+ var chunk5XNRWMMD_cjs = require('./chunk-5XNRWMMD.cjs');
4
4
  require('./chunk-KVSAY6NZ.cjs');
5
5
  require('./chunk-Y2KYR2ED.cjs');
6
6
  require('./chunk-BUUUWQMB.cjs');
@@ -61,7 +61,7 @@ require('./chunk-6LHQPOMI.cjs');
61
61
 
62
62
  Object.defineProperty(exports, "Agent", {
63
63
  enumerable: true,
64
- get: function () { return chunkDEJCKB65_cjs.Agent; }
64
+ get: function () { return chunk5XNRWMMD_cjs.Agent; }
65
65
  });
66
- //# sourceMappingURL=agent-GACKKINM.cjs.map
67
- //# sourceMappingURL=agent-GACKKINM.cjs.map
66
+ //# sourceMappingURL=agent-UXU5AIOJ.cjs.map
67
+ //# sourceMappingURL=agent-UXU5AIOJ.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":[],"names":[],"mappings":"","file":"agent-GACKKINM.cjs"}
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"agent-UXU5AIOJ.cjs"}
package/dist/agent.d.ts CHANGED
@@ -268,9 +268,27 @@ export declare class Agent {
268
268
  */
269
269
  static describe(agentId: string): Promise<AgentDescription>;
270
270
  /**
271
- * Permanently delete a cloud agent.
271
+ * Permanently delete a registered agent — local or cloud.
272
+ *
273
+ * #612 — this HYDRATES before removing, and until it did the method was a no-op against the
274
+ * persisted registry whenever the agent was not already in this process's memory. Which is every
275
+ * agent in a freshly started process: `removeRegisteredAgent` only schedules a save when the entry
276
+ * was in the Map, so `agents.delete()` returned `false`, nothing was scheduled, and
277
+ * `flushRegistrySaves()` flushed an empty queue. The entry survived and this returned normally.
278
+ *
279
+ * Every neighbouring mutator already did this — `rename` and `archive` reach
280
+ * `getRegisteredAgentOrThrow`, which hydrates on a miss. `delete` was the only one that did not.
281
+ *
282
+ * `options.cwd` is read rather than defaulted away: it is declared on `AgentOperationOptions`, and
283
+ * hydrating `process.cwd()` unconditionally is the B-115 defect — an option that compiles and does
284
+ * nothing — on the one path that is supposed to remove data.
285
+ *
286
+ * Deleting an unknown id still resolves rather than throwing, deliberately. `rename` throws
287
+ * `UnknownAgentError` and matching it here is defensible, but it is a breaking change for callers
288
+ * that delete idempotently, and an entry and its transcript can legitimately outlive one another
289
+ * in both directions. That decision belongs to its own change, not to a persistence fix.
272
290
  *
273
291
  * @public
274
292
  */
275
- static delete(agentId: string, _options?: AgentOperationOptions): Promise<void>;
293
+ static delete(agentId: string, options?: AgentOperationOptions): Promise<void>;
276
294
  }
@@ -3440,7 +3440,7 @@ var HISTOGRAM_NAMES = {
3440
3440
  };
3441
3441
  function safeRequire(moduleName) {
3442
3442
  try {
3443
- const r = module$1.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('chunk-DEJCKB65.cjs', document.baseURI).href)));
3443
+ const r = module$1.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('chunk-5XNRWMMD.cjs', document.baseURI).href)));
3444
3444
  return r(moduleName);
3445
3445
  } catch {
3446
3446
  return void 0;
@@ -3683,7 +3683,7 @@ var cachedOtel;
3683
3683
  function loadOtel() {
3684
3684
  if (cachedOtel === void 0) {
3685
3685
  try {
3686
- const r = module$1.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('chunk-DEJCKB65.cjs', document.baseURI).href)));
3686
+ const r = module$1.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('chunk-5XNRWMMD.cjs', document.baseURI).href)));
3687
3687
  const mod = r("@opentelemetry/api");
3688
3688
  cachedOtel = mod;
3689
3689
  } catch {
@@ -4456,7 +4456,13 @@ function registerLocalAgent(args) {
4456
4456
  agentId: args.agentId,
4457
4457
  runtime: "local",
4458
4458
  name: args.options.name,
4459
- summary: "Local contract fixture",
4459
+ // #611 — a runtime label, not a fixture name. `SDKAgentInfo.summary` is `@public` and required,
4460
+ // `AgentOptions` has no `summary` for a consumer to override, and this line was unconditional —
4461
+ // so "Local contract fixture" was the only value the field could hold for a local agent, and it
4462
+ // was measured reaching a user's session record on disk. The cloud sibling already guards its
4463
+ // own fixture string behind `isFixtureMode()`; there is no local equivalent to port, so the
4464
+ // local branch simply takes the non-fixture value.
4465
+ summary: "Local agent",
4460
4466
  model: args.model,
4461
4467
  createdAt: Date.now(),
4462
4468
  lastModified: Date.now(),
@@ -10424,14 +10430,17 @@ function commonAgentInfo(agent, fallbackSummary) {
10424
10430
  }
10425
10431
  function toLocalAgentInfo(agent) {
10426
10432
  return {
10427
- ...commonAgentInfo(agent, "Local contract fixture"),
10433
+ ...commonAgentInfo(agent, "Local agent"),
10428
10434
  runtime: "local",
10429
10435
  ...agent.cwd !== void 0 ? { cwd: agent.cwd } : {}
10430
10436
  };
10431
10437
  }
10432
10438
  function toCloudAgentInfo(agent) {
10433
10439
  return {
10434
- ...commonAgentInfo(agent, "Cloud contract fixture"),
10440
+ // Same fallback, same reason (#611). The cloud REGISTRATION already guards its fixture string
10441
+ // behind `isFixtureMode()`, so this line only answers for a record that carries no summary —
10442
+ // and a fixture name is the wrong answer for that record whichever runtime it came from.
10443
+ ...commonAgentInfo(agent, "Cloud agent"),
10435
10444
  archived: agent.archived,
10436
10445
  runtime: "cloud",
10437
10446
  env: { type: "cloud" },
@@ -10923,11 +10932,30 @@ var Agent = class _Agent {
10923
10932
  };
10924
10933
  }
10925
10934
  /**
10926
- * Permanently delete a cloud agent.
10935
+ * Permanently delete a registered agent — local or cloud.
10936
+ *
10937
+ * #612 — this HYDRATES before removing, and until it did the method was a no-op against the
10938
+ * persisted registry whenever the agent was not already in this process's memory. Which is every
10939
+ * agent in a freshly started process: `removeRegisteredAgent` only schedules a save when the entry
10940
+ * was in the Map, so `agents.delete()` returned `false`, nothing was scheduled, and
10941
+ * `flushRegistrySaves()` flushed an empty queue. The entry survived and this returned normally.
10942
+ *
10943
+ * Every neighbouring mutator already did this — `rename` and `archive` reach
10944
+ * `getRegisteredAgentOrThrow`, which hydrates on a miss. `delete` was the only one that did not.
10945
+ *
10946
+ * `options.cwd` is read rather than defaulted away: it is declared on `AgentOperationOptions`, and
10947
+ * hydrating `process.cwd()` unconditionally is the B-115 defect — an option that compiles and does
10948
+ * nothing — on the one path that is supposed to remove data.
10949
+ *
10950
+ * Deleting an unknown id still resolves rather than throwing, deliberately. `rename` throws
10951
+ * `UnknownAgentError` and matching it here is defensible, but it is a breaking change for callers
10952
+ * that delete idempotently, and an entry and its transcript can legitimately outlive one another
10953
+ * in both directions. That decision belongs to its own change, not to a persistence fix.
10927
10954
  *
10928
10955
  * @public
10929
10956
  */
10930
- static async delete(agentId, _options = {}) {
10957
+ static async delete(agentId, options = {}) {
10958
+ await hydrateRegistryFromDisk(options.cwd ?? process.cwd());
10931
10959
  removeRegisteredAgent(agentId);
10932
10960
  await flushRegistrySaves();
10933
10961
  }
@@ -10991,5 +11019,5 @@ exports.generateCronId = generateCronId;
10991
11019
  exports.getPricingEntry = getPricingEntry;
10992
11020
  exports.openRouterMemoryEmbeddingProviderAdapter = openRouterMemoryEmbeddingProviderAdapter;
10993
11021
  exports.resolveSessionDir = resolveSessionDir;
10994
- //# sourceMappingURL=chunk-DEJCKB65.cjs.map
10995
- //# sourceMappingURL=chunk-DEJCKB65.cjs.map
11022
+ //# sourceMappingURL=chunk-5XNRWMMD.cjs.map
11023
+ //# sourceMappingURL=chunk-5XNRWMMD.cjs.map