@theokit/sdk 4.15.4 → 4.16.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.
- package/CHANGELOG.md +12 -0
- package/dist/agent.d.ts +13 -0
- package/dist/compaction.cjs.map +1 -1
- package/dist/compaction.d.cts +10 -2
- package/dist/compaction.d.ts +10 -2
- package/dist/compaction.js.map +1 -1
- package/dist/cron.cjs +13146 -12327
- package/dist/cron.cjs.map +1 -1
- package/dist/cron.d.cts +1 -1
- package/dist/cron.d.ts +1 -1
- package/dist/cron.js +13149 -12330
- package/dist/cron.js.map +1 -1
- package/dist/eval.cjs +13159 -12340
- package/dist/eval.cjs.map +1 -1
- package/dist/eval.js +13162 -12343
- package/dist/eval.js.map +1 -1
- package/dist/index.cjs +15238 -14452
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +69 -2
- package/dist/index.d.ts +69 -2
- package/dist/index.js +15241 -14455
- package/dist/index.js.map +1 -1
- package/dist/internal/runtime/compression/compression-summarizer.d.ts +1 -0
- package/dist/internal/session/agent-session-store.d.ts +9 -0
- package/dist/internal/session/compact-session.d.ts +78 -0
- package/package.json +1 -1
- package/dist/{cron-DY0uC1ng.d.ts → cron-B_vVYc-_.d.ts} +92 -92
- package/dist/{cron-ElTj1cSH.d.cts → cron-Dj8FAU5V.d.cts} +92 -92
|
@@ -17,6 +17,15 @@ import type { SessionMessage } from "./session-types.js";
|
|
|
17
17
|
export interface PersistTurnInput {
|
|
18
18
|
userText: string;
|
|
19
19
|
conversation: readonly ConversationTurn[];
|
|
20
|
+
/**
|
|
21
|
+
* M50 — when supplied, size-driven auto-compaction runs in the SAME write chain after the turn
|
|
22
|
+
* persists (usage real vs the model's context window; summarizer injected by the caller).
|
|
23
|
+
*/
|
|
24
|
+
autoCompact?: {
|
|
25
|
+
usageTotal?: number | undefined;
|
|
26
|
+
contextWindow?: number | undefined;
|
|
27
|
+
summarize: (messages: readonly import("../../compaction.js").CompressibleMessage[]) => Promise<string>;
|
|
28
|
+
};
|
|
20
29
|
}
|
|
21
30
|
/**
|
|
22
31
|
* The per-agent transcript metadata used to seed a {@link SessionTranscript}. The
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* M50 (agent-builder) — session-transcript compaction, Codex-faithful.
|
|
3
|
+
*
|
|
4
|
+
* Mirrors the vendored Codex mechanism (`codex-rs/core/src/compact.rs`):
|
|
5
|
+
* - the replacement history = recent USER messages verbatim (newest→oldest under a token budget;
|
|
6
|
+
* prior summaries filtered by marker) + ONE summary message with a textual marker prefix,
|
|
7
|
+
* injected as `role:"user"` (`build_compacted_history`, compact.rs:589-663);
|
|
8
|
+
* - persistence is APPEND-ONLY: a `compact_boundary` record becomes the new DAG root and the
|
|
9
|
+
* replacement messages are chained onto it — resume replays boundary→replacement→suffix
|
|
10
|
+
* (equivalent of `CompactedItem.replacement_history`, rollout is never truncated);
|
|
11
|
+
* - a failing summarizer leaves the transcript UNTOUCHED (typed error; no partial state).
|
|
12
|
+
*
|
|
13
|
+
* The summarizer is dependency-injected: tests pass a deterministic fake; the public
|
|
14
|
+
* `Agent.compact` wires the ADR-D440 compression summarizer (its first real caller).
|
|
15
|
+
*/
|
|
16
|
+
import { type CompressibleMessage } from "../../compaction.js";
|
|
17
|
+
import type { SessionStore } from "../../types/session-store.js";
|
|
18
|
+
/** Textual marker prefixing every compact summary (Codex `SUMMARY_PREFIX` analog). */
|
|
19
|
+
export declare const COMPACT_SUMMARY_MARKER = "[[theokit:compact-summary]]";
|
|
20
|
+
/** Budget of VERBATIM user messages preserved in the replacement (Codex `COMPACT_USER_MESSAGE_MAX_TOKENS`). */
|
|
21
|
+
export declare const COMPACT_USER_MESSAGE_MAX_TOKENS = 20000;
|
|
22
|
+
export interface CompactLocation {
|
|
23
|
+
cwd: string;
|
|
24
|
+
agentId: string;
|
|
25
|
+
model?: string;
|
|
26
|
+
}
|
|
27
|
+
export interface CompactResult {
|
|
28
|
+
preTokens: number;
|
|
29
|
+
postTokens: number;
|
|
30
|
+
}
|
|
31
|
+
/** Is this message a summary produced by a PRIOR compaction? (filtered from verbatim preservation). */
|
|
32
|
+
export declare function isCompactSummary(content: string): boolean;
|
|
33
|
+
/**
|
|
34
|
+
* Compact one session transcript: summarize the reconstructed history, then append (append-only)
|
|
35
|
+
* a `compact_boundary` + the replacement chain (recent user messages verbatim + marker'd summary).
|
|
36
|
+
*
|
|
37
|
+
* @throws whatever `summarize` throws — with the transcript guaranteed untouched.
|
|
38
|
+
*/
|
|
39
|
+
export declare function compactSessionTranscript(opts: {
|
|
40
|
+
store: SessionStore;
|
|
41
|
+
loc: CompactLocation;
|
|
42
|
+
sessionId: string;
|
|
43
|
+
trigger: "manual" | "auto";
|
|
44
|
+
summarize: (messages: readonly CompressibleMessage[]) => Promise<string>;
|
|
45
|
+
}): Promise<CompactResult>;
|
|
46
|
+
/**
|
|
47
|
+
* Build the default summarizer for `Agent.compact`: the D440 `compressConversationWindow`
|
|
48
|
+
* (aux-LLM summarization with typed failure) driven by a router-resolved LLM client. The
|
|
49
|
+
* compression model resolves via the D440 registry with the agent's own model as fallback.
|
|
50
|
+
*/
|
|
51
|
+
export declare function buildDefaultSummarizer(opts: {
|
|
52
|
+
agentModel: string;
|
|
53
|
+
apiKey?: string;
|
|
54
|
+
}): (messages: readonly CompressibleMessage[]) => Promise<string>;
|
|
55
|
+
/**
|
|
56
|
+
* Should auto-compaction fire? Codex parity: `token_limit_reached` when real usage crosses 90% of
|
|
57
|
+
* the model's context window (`context_window.rs:74-79`; limit default `(cw*9)/10`,
|
|
58
|
+
* `openai_models.rs:459-469`). Missing inputs (no usage reported / model absent from the catalog)
|
|
59
|
+
* NEVER fire — fail-safe toward "do nothing".
|
|
60
|
+
*/
|
|
61
|
+
export declare function shouldAutoCompact(opts: {
|
|
62
|
+
usageTotal?: number | undefined;
|
|
63
|
+
contextWindow?: number | undefined;
|
|
64
|
+
}): boolean;
|
|
65
|
+
/**
|
|
66
|
+
* Fire auto-compaction when the threshold is crossed — at most ONE attempt per turn per agent
|
|
67
|
+
* (anti-cascade: a failing summarizer or a non-reducing summary must not loop). Returns whether a
|
|
68
|
+
* compaction actually happened. Failures WARN and leave the transcript untouched.
|
|
69
|
+
*/
|
|
70
|
+
export declare function autoCompactIfNeeded(opts: {
|
|
71
|
+
store: SessionStore;
|
|
72
|
+
loc: CompactLocation;
|
|
73
|
+
sessionId: string;
|
|
74
|
+
usageTotal?: number | undefined;
|
|
75
|
+
contextWindow?: number | undefined;
|
|
76
|
+
turnCount: number;
|
|
77
|
+
summarize: (messages: readonly CompressibleMessage[]) => Promise<string>;
|
|
78
|
+
}): Promise<boolean>;
|
package/package.json
CHANGED
|
@@ -2,6 +2,98 @@ import * as zod from 'zod';
|
|
|
2
2
|
import { ZodType } from 'zod';
|
|
3
3
|
import { M as ModelSelection, ac as SDKUserMessage, ae as SendOptions, b as Run, G as GenerateOptions, n as GenerateRunResult, _ as RunToCompletionOptions, $ as RunToCompletionResult, S as SDKMessage, al as StreamToCompletionResult, C as CustomTool, c as PermissionMode, a as McpServerConfig, P as Processor, u as MessageOrigin } from './run-DFM1H2jW.js';
|
|
4
4
|
|
|
5
|
+
/**
|
|
6
|
+
* `SessionRecord` — the native on-disk transcript record shape (SE40).
|
|
7
|
+
*
|
|
8
|
+
* The theokit session format IS the Claude Code record shape: a
|
|
9
|
+
* `uuid`/`parentUuid` DAG of records with structured
|
|
10
|
+
* `text`/`tool_use`/`tool_result`/`thinking` blocks. This is the contract the
|
|
11
|
+
* pluggable {@link SessionStore} seam operates over.
|
|
12
|
+
*
|
|
13
|
+
* DIP-correct home (SE46): the contract lives in the domain `types/` layer;
|
|
14
|
+
* the application-layer DAG core (`internal/persistence/session-transcript.ts`)
|
|
15
|
+
* re-exports it for back-compat while owning the record builders + reader.
|
|
16
|
+
*
|
|
17
|
+
* @public
|
|
18
|
+
*/
|
|
19
|
+
/** One transcript record (one JSONL line). `message` absent on `system` (compact_boundary) records. */
|
|
20
|
+
interface SessionRecord {
|
|
21
|
+
type: "user" | "assistant" | "system";
|
|
22
|
+
uuid: string;
|
|
23
|
+
parentUuid: string | null;
|
|
24
|
+
sessionId: string;
|
|
25
|
+
timestamp: string;
|
|
26
|
+
isSidechain?: boolean;
|
|
27
|
+
userType?: string;
|
|
28
|
+
cwd?: string;
|
|
29
|
+
version?: string;
|
|
30
|
+
subtype?: string;
|
|
31
|
+
compactMetadata?: {
|
|
32
|
+
preTokens: number;
|
|
33
|
+
trigger: string;
|
|
34
|
+
};
|
|
35
|
+
message?: Record<string, unknown>;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* SE41 — the pluggable `SessionStore` seam over the NATIVE session transcript.
|
|
40
|
+
*
|
|
41
|
+
* A minimal, two-method port so an external store (Postgres / Redis / KV /
|
|
42
|
+
* durable object) can be the **primary store AND resume source** — the
|
|
43
|
+
* serverless (ephemeral FS) and multi-host / multi-pod use case that SE40
|
|
44
|
+
* dropped when it removed the `ConversationStorageAdapter`. This is deliberately
|
|
45
|
+
* NOT that removed ~10-method adapter: the seam is JUST record read/append over
|
|
46
|
+
* the native {@link SessionRecord} shape (no getMessages / getSessionMeta /
|
|
47
|
+
* delete / objective methods).
|
|
48
|
+
*
|
|
49
|
+
* The SDK ships a real default implementation, `FsSessionStore`, that reads and
|
|
50
|
+
* append-writes the native Claude-shaped `.jsonl` transcript — omitting
|
|
51
|
+
* `local.sessionStore` yields byte-identical current behavior (back-compat, zero
|
|
52
|
+
* consumer change). Injected via `local.sessionStore` for external stores.
|
|
53
|
+
*
|
|
54
|
+
* Consistency contract: `appendRecords` is append-only and ordering-preserving.
|
|
55
|
+
* The FS default serializes appends per agent with a cross-process file lock;
|
|
56
|
+
* external implementations own (and MUST document) their own concurrency
|
|
57
|
+
* guarantees for two hosts appending to the same `agentId`.
|
|
58
|
+
*
|
|
59
|
+
* @public
|
|
60
|
+
*/
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* The pluggable session-store seam. Exactly two methods over the native
|
|
64
|
+
* {@link SessionRecord} shape.
|
|
65
|
+
*
|
|
66
|
+
* @public
|
|
67
|
+
*/
|
|
68
|
+
interface SessionStore {
|
|
69
|
+
/**
|
|
70
|
+
* Return every persisted record for `agentId`, in append order. A session
|
|
71
|
+
* that was never written MUST resolve to `[]` (not throw) — a fresh agent has
|
|
72
|
+
* no history. The SDK reconstructs the resumable `LlmMessage[]` from these
|
|
73
|
+
* records via the native DAG reader, so the shape MUST be the exact
|
|
74
|
+
* {@link SessionRecord} the SDK writes.
|
|
75
|
+
*
|
|
76
|
+
* A store that cannot READ (e.g. the backing DB is unreachable on resume)
|
|
77
|
+
* MUST throw a typed error rather than silently returning `[]` — a silent
|
|
78
|
+
* empty read would masquerade as "no history" and drop the conversation.
|
|
79
|
+
*/
|
|
80
|
+
readRecords(agentId: string): Promise<SessionRecord[]>;
|
|
81
|
+
/**
|
|
82
|
+
* Append `records` (the new-turn delta) to `agentId`'s session, append-only.
|
|
83
|
+
* MUST preserve order and MUST NOT drop or rewrite prior records — the native
|
|
84
|
+
* format is an append-only `parentUuid` DAG (compaction is a new-root
|
|
85
|
+
* `compact_boundary` record, still an append).
|
|
86
|
+
*
|
|
87
|
+
* Note on the write path: per-turn persistence is fire-and-forget so `send()`
|
|
88
|
+
* is never blocked by store I/O — an `appendRecords` rejection is logged to
|
|
89
|
+
* stderr, NOT thrown to the caller (best-effort write). An external store that
|
|
90
|
+
* must guarantee durability should make `appendRecords` resilient (retry /
|
|
91
|
+
* durable write) internally. This differs from {@link SessionStore.readRecords},
|
|
92
|
+
* which MUST throw on failure (a resume cannot proceed on a silent partial history).
|
|
93
|
+
*/
|
|
94
|
+
appendRecords(agentId: string, records: readonly SessionRecord[]): Promise<void>;
|
|
95
|
+
}
|
|
96
|
+
|
|
5
97
|
/**
|
|
6
98
|
* Public `MemoryAdapter` contract (T1.1, ADRs D141 / D147).
|
|
7
99
|
*
|
|
@@ -233,98 +325,6 @@ declare class Skill {
|
|
|
233
325
|
static create(spec: CreateSkillSpec): InlineSkill;
|
|
234
326
|
}
|
|
235
327
|
|
|
236
|
-
/**
|
|
237
|
-
* `SessionRecord` — the native on-disk transcript record shape (SE40).
|
|
238
|
-
*
|
|
239
|
-
* The theokit session format IS the Claude Code record shape: a
|
|
240
|
-
* `uuid`/`parentUuid` DAG of records with structured
|
|
241
|
-
* `text`/`tool_use`/`tool_result`/`thinking` blocks. This is the contract the
|
|
242
|
-
* pluggable {@link SessionStore} seam operates over.
|
|
243
|
-
*
|
|
244
|
-
* DIP-correct home (SE46): the contract lives in the domain `types/` layer;
|
|
245
|
-
* the application-layer DAG core (`internal/persistence/session-transcript.ts`)
|
|
246
|
-
* re-exports it for back-compat while owning the record builders + reader.
|
|
247
|
-
*
|
|
248
|
-
* @public
|
|
249
|
-
*/
|
|
250
|
-
/** One transcript record (one JSONL line). `message` absent on `system` (compact_boundary) records. */
|
|
251
|
-
interface SessionRecord {
|
|
252
|
-
type: "user" | "assistant" | "system";
|
|
253
|
-
uuid: string;
|
|
254
|
-
parentUuid: string | null;
|
|
255
|
-
sessionId: string;
|
|
256
|
-
timestamp: string;
|
|
257
|
-
isSidechain?: boolean;
|
|
258
|
-
userType?: string;
|
|
259
|
-
cwd?: string;
|
|
260
|
-
version?: string;
|
|
261
|
-
subtype?: string;
|
|
262
|
-
compactMetadata?: {
|
|
263
|
-
preTokens: number;
|
|
264
|
-
trigger: string;
|
|
265
|
-
};
|
|
266
|
-
message?: Record<string, unknown>;
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
/**
|
|
270
|
-
* SE41 — the pluggable `SessionStore` seam over the NATIVE session transcript.
|
|
271
|
-
*
|
|
272
|
-
* A minimal, two-method port so an external store (Postgres / Redis / KV /
|
|
273
|
-
* durable object) can be the **primary store AND resume source** — the
|
|
274
|
-
* serverless (ephemeral FS) and multi-host / multi-pod use case that SE40
|
|
275
|
-
* dropped when it removed the `ConversationStorageAdapter`. This is deliberately
|
|
276
|
-
* NOT that removed ~10-method adapter: the seam is JUST record read/append over
|
|
277
|
-
* the native {@link SessionRecord} shape (no getMessages / getSessionMeta /
|
|
278
|
-
* delete / objective methods).
|
|
279
|
-
*
|
|
280
|
-
* The SDK ships a real default implementation, `FsSessionStore`, that reads and
|
|
281
|
-
* append-writes the native Claude-shaped `.jsonl` transcript — omitting
|
|
282
|
-
* `local.sessionStore` yields byte-identical current behavior (back-compat, zero
|
|
283
|
-
* consumer change). Injected via `local.sessionStore` for external stores.
|
|
284
|
-
*
|
|
285
|
-
* Consistency contract: `appendRecords` is append-only and ordering-preserving.
|
|
286
|
-
* The FS default serializes appends per agent with a cross-process file lock;
|
|
287
|
-
* external implementations own (and MUST document) their own concurrency
|
|
288
|
-
* guarantees for two hosts appending to the same `agentId`.
|
|
289
|
-
*
|
|
290
|
-
* @public
|
|
291
|
-
*/
|
|
292
|
-
|
|
293
|
-
/**
|
|
294
|
-
* The pluggable session-store seam. Exactly two methods over the native
|
|
295
|
-
* {@link SessionRecord} shape.
|
|
296
|
-
*
|
|
297
|
-
* @public
|
|
298
|
-
*/
|
|
299
|
-
interface SessionStore {
|
|
300
|
-
/**
|
|
301
|
-
* Return every persisted record for `agentId`, in append order. A session
|
|
302
|
-
* that was never written MUST resolve to `[]` (not throw) — a fresh agent has
|
|
303
|
-
* no history. The SDK reconstructs the resumable `LlmMessage[]` from these
|
|
304
|
-
* records via the native DAG reader, so the shape MUST be the exact
|
|
305
|
-
* {@link SessionRecord} the SDK writes.
|
|
306
|
-
*
|
|
307
|
-
* A store that cannot READ (e.g. the backing DB is unreachable on resume)
|
|
308
|
-
* MUST throw a typed error rather than silently returning `[]` — a silent
|
|
309
|
-
* empty read would masquerade as "no history" and drop the conversation.
|
|
310
|
-
*/
|
|
311
|
-
readRecords(agentId: string): Promise<SessionRecord[]>;
|
|
312
|
-
/**
|
|
313
|
-
* Append `records` (the new-turn delta) to `agentId`'s session, append-only.
|
|
314
|
-
* MUST preserve order and MUST NOT drop or rewrite prior records — the native
|
|
315
|
-
* format is an append-only `parentUuid` DAG (compaction is a new-root
|
|
316
|
-
* `compact_boundary` record, still an append).
|
|
317
|
-
*
|
|
318
|
-
* Note on the write path: per-turn persistence is fire-and-forget so `send()`
|
|
319
|
-
* is never blocked by store I/O — an `appendRecords` rejection is logged to
|
|
320
|
-
* stderr, NOT thrown to the caller (best-effort write). An external store that
|
|
321
|
-
* must guarantee durability should make `appendRecords` resilient (retry /
|
|
322
|
-
* durable write) internally. This differs from {@link SessionStore.readRecords},
|
|
323
|
-
* which MUST throw on failure (a resume cannot proceed on a silent partial history).
|
|
324
|
-
*/
|
|
325
|
-
appendRecords(agentId: string, records: readonly SessionRecord[]): Promise<void>;
|
|
326
|
-
}
|
|
327
|
-
|
|
328
328
|
/**
|
|
329
329
|
* `BudgetTracker` — runtime contract for budget/usage tracking in the
|
|
330
330
|
* agent loop (SDK 2.0 Phase 2 / T2.1 — ADR D1 interface inversion).
|
|
@@ -2,6 +2,98 @@ import * as zod from 'zod';
|
|
|
2
2
|
import { ZodType } from 'zod';
|
|
3
3
|
import { M as ModelSelection, ac as SDKUserMessage, ae as SendOptions, b as Run, G as GenerateOptions, n as GenerateRunResult, _ as RunToCompletionOptions, $ as RunToCompletionResult, S as SDKMessage, al as StreamToCompletionResult, C as CustomTool, c as PermissionMode, a as McpServerConfig, P as Processor, u as MessageOrigin } from './run-DFM1H2jW.cjs';
|
|
4
4
|
|
|
5
|
+
/**
|
|
6
|
+
* `SessionRecord` — the native on-disk transcript record shape (SE40).
|
|
7
|
+
*
|
|
8
|
+
* The theokit session format IS the Claude Code record shape: a
|
|
9
|
+
* `uuid`/`parentUuid` DAG of records with structured
|
|
10
|
+
* `text`/`tool_use`/`tool_result`/`thinking` blocks. This is the contract the
|
|
11
|
+
* pluggable {@link SessionStore} seam operates over.
|
|
12
|
+
*
|
|
13
|
+
* DIP-correct home (SE46): the contract lives in the domain `types/` layer;
|
|
14
|
+
* the application-layer DAG core (`internal/persistence/session-transcript.ts`)
|
|
15
|
+
* re-exports it for back-compat while owning the record builders + reader.
|
|
16
|
+
*
|
|
17
|
+
* @public
|
|
18
|
+
*/
|
|
19
|
+
/** One transcript record (one JSONL line). `message` absent on `system` (compact_boundary) records. */
|
|
20
|
+
interface SessionRecord {
|
|
21
|
+
type: "user" | "assistant" | "system";
|
|
22
|
+
uuid: string;
|
|
23
|
+
parentUuid: string | null;
|
|
24
|
+
sessionId: string;
|
|
25
|
+
timestamp: string;
|
|
26
|
+
isSidechain?: boolean;
|
|
27
|
+
userType?: string;
|
|
28
|
+
cwd?: string;
|
|
29
|
+
version?: string;
|
|
30
|
+
subtype?: string;
|
|
31
|
+
compactMetadata?: {
|
|
32
|
+
preTokens: number;
|
|
33
|
+
trigger: string;
|
|
34
|
+
};
|
|
35
|
+
message?: Record<string, unknown>;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* SE41 — the pluggable `SessionStore` seam over the NATIVE session transcript.
|
|
40
|
+
*
|
|
41
|
+
* A minimal, two-method port so an external store (Postgres / Redis / KV /
|
|
42
|
+
* durable object) can be the **primary store AND resume source** — the
|
|
43
|
+
* serverless (ephemeral FS) and multi-host / multi-pod use case that SE40
|
|
44
|
+
* dropped when it removed the `ConversationStorageAdapter`. This is deliberately
|
|
45
|
+
* NOT that removed ~10-method adapter: the seam is JUST record read/append over
|
|
46
|
+
* the native {@link SessionRecord} shape (no getMessages / getSessionMeta /
|
|
47
|
+
* delete / objective methods).
|
|
48
|
+
*
|
|
49
|
+
* The SDK ships a real default implementation, `FsSessionStore`, that reads and
|
|
50
|
+
* append-writes the native Claude-shaped `.jsonl` transcript — omitting
|
|
51
|
+
* `local.sessionStore` yields byte-identical current behavior (back-compat, zero
|
|
52
|
+
* consumer change). Injected via `local.sessionStore` for external stores.
|
|
53
|
+
*
|
|
54
|
+
* Consistency contract: `appendRecords` is append-only and ordering-preserving.
|
|
55
|
+
* The FS default serializes appends per agent with a cross-process file lock;
|
|
56
|
+
* external implementations own (and MUST document) their own concurrency
|
|
57
|
+
* guarantees for two hosts appending to the same `agentId`.
|
|
58
|
+
*
|
|
59
|
+
* @public
|
|
60
|
+
*/
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* The pluggable session-store seam. Exactly two methods over the native
|
|
64
|
+
* {@link SessionRecord} shape.
|
|
65
|
+
*
|
|
66
|
+
* @public
|
|
67
|
+
*/
|
|
68
|
+
interface SessionStore {
|
|
69
|
+
/**
|
|
70
|
+
* Return every persisted record for `agentId`, in append order. A session
|
|
71
|
+
* that was never written MUST resolve to `[]` (not throw) — a fresh agent has
|
|
72
|
+
* no history. The SDK reconstructs the resumable `LlmMessage[]` from these
|
|
73
|
+
* records via the native DAG reader, so the shape MUST be the exact
|
|
74
|
+
* {@link SessionRecord} the SDK writes.
|
|
75
|
+
*
|
|
76
|
+
* A store that cannot READ (e.g. the backing DB is unreachable on resume)
|
|
77
|
+
* MUST throw a typed error rather than silently returning `[]` — a silent
|
|
78
|
+
* empty read would masquerade as "no history" and drop the conversation.
|
|
79
|
+
*/
|
|
80
|
+
readRecords(agentId: string): Promise<SessionRecord[]>;
|
|
81
|
+
/**
|
|
82
|
+
* Append `records` (the new-turn delta) to `agentId`'s session, append-only.
|
|
83
|
+
* MUST preserve order and MUST NOT drop or rewrite prior records — the native
|
|
84
|
+
* format is an append-only `parentUuid` DAG (compaction is a new-root
|
|
85
|
+
* `compact_boundary` record, still an append).
|
|
86
|
+
*
|
|
87
|
+
* Note on the write path: per-turn persistence is fire-and-forget so `send()`
|
|
88
|
+
* is never blocked by store I/O — an `appendRecords` rejection is logged to
|
|
89
|
+
* stderr, NOT thrown to the caller (best-effort write). An external store that
|
|
90
|
+
* must guarantee durability should make `appendRecords` resilient (retry /
|
|
91
|
+
* durable write) internally. This differs from {@link SessionStore.readRecords},
|
|
92
|
+
* which MUST throw on failure (a resume cannot proceed on a silent partial history).
|
|
93
|
+
*/
|
|
94
|
+
appendRecords(agentId: string, records: readonly SessionRecord[]): Promise<void>;
|
|
95
|
+
}
|
|
96
|
+
|
|
5
97
|
/**
|
|
6
98
|
* Public `MemoryAdapter` contract (T1.1, ADRs D141 / D147).
|
|
7
99
|
*
|
|
@@ -233,98 +325,6 @@ declare class Skill {
|
|
|
233
325
|
static create(spec: CreateSkillSpec): InlineSkill;
|
|
234
326
|
}
|
|
235
327
|
|
|
236
|
-
/**
|
|
237
|
-
* `SessionRecord` — the native on-disk transcript record shape (SE40).
|
|
238
|
-
*
|
|
239
|
-
* The theokit session format IS the Claude Code record shape: a
|
|
240
|
-
* `uuid`/`parentUuid` DAG of records with structured
|
|
241
|
-
* `text`/`tool_use`/`tool_result`/`thinking` blocks. This is the contract the
|
|
242
|
-
* pluggable {@link SessionStore} seam operates over.
|
|
243
|
-
*
|
|
244
|
-
* DIP-correct home (SE46): the contract lives in the domain `types/` layer;
|
|
245
|
-
* the application-layer DAG core (`internal/persistence/session-transcript.ts`)
|
|
246
|
-
* re-exports it for back-compat while owning the record builders + reader.
|
|
247
|
-
*
|
|
248
|
-
* @public
|
|
249
|
-
*/
|
|
250
|
-
/** One transcript record (one JSONL line). `message` absent on `system` (compact_boundary) records. */
|
|
251
|
-
interface SessionRecord {
|
|
252
|
-
type: "user" | "assistant" | "system";
|
|
253
|
-
uuid: string;
|
|
254
|
-
parentUuid: string | null;
|
|
255
|
-
sessionId: string;
|
|
256
|
-
timestamp: string;
|
|
257
|
-
isSidechain?: boolean;
|
|
258
|
-
userType?: string;
|
|
259
|
-
cwd?: string;
|
|
260
|
-
version?: string;
|
|
261
|
-
subtype?: string;
|
|
262
|
-
compactMetadata?: {
|
|
263
|
-
preTokens: number;
|
|
264
|
-
trigger: string;
|
|
265
|
-
};
|
|
266
|
-
message?: Record<string, unknown>;
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
/**
|
|
270
|
-
* SE41 — the pluggable `SessionStore` seam over the NATIVE session transcript.
|
|
271
|
-
*
|
|
272
|
-
* A minimal, two-method port so an external store (Postgres / Redis / KV /
|
|
273
|
-
* durable object) can be the **primary store AND resume source** — the
|
|
274
|
-
* serverless (ephemeral FS) and multi-host / multi-pod use case that SE40
|
|
275
|
-
* dropped when it removed the `ConversationStorageAdapter`. This is deliberately
|
|
276
|
-
* NOT that removed ~10-method adapter: the seam is JUST record read/append over
|
|
277
|
-
* the native {@link SessionRecord} shape (no getMessages / getSessionMeta /
|
|
278
|
-
* delete / objective methods).
|
|
279
|
-
*
|
|
280
|
-
* The SDK ships a real default implementation, `FsSessionStore`, that reads and
|
|
281
|
-
* append-writes the native Claude-shaped `.jsonl` transcript — omitting
|
|
282
|
-
* `local.sessionStore` yields byte-identical current behavior (back-compat, zero
|
|
283
|
-
* consumer change). Injected via `local.sessionStore` for external stores.
|
|
284
|
-
*
|
|
285
|
-
* Consistency contract: `appendRecords` is append-only and ordering-preserving.
|
|
286
|
-
* The FS default serializes appends per agent with a cross-process file lock;
|
|
287
|
-
* external implementations own (and MUST document) their own concurrency
|
|
288
|
-
* guarantees for two hosts appending to the same `agentId`.
|
|
289
|
-
*
|
|
290
|
-
* @public
|
|
291
|
-
*/
|
|
292
|
-
|
|
293
|
-
/**
|
|
294
|
-
* The pluggable session-store seam. Exactly two methods over the native
|
|
295
|
-
* {@link SessionRecord} shape.
|
|
296
|
-
*
|
|
297
|
-
* @public
|
|
298
|
-
*/
|
|
299
|
-
interface SessionStore {
|
|
300
|
-
/**
|
|
301
|
-
* Return every persisted record for `agentId`, in append order. A session
|
|
302
|
-
* that was never written MUST resolve to `[]` (not throw) — a fresh agent has
|
|
303
|
-
* no history. The SDK reconstructs the resumable `LlmMessage[]` from these
|
|
304
|
-
* records via the native DAG reader, so the shape MUST be the exact
|
|
305
|
-
* {@link SessionRecord} the SDK writes.
|
|
306
|
-
*
|
|
307
|
-
* A store that cannot READ (e.g. the backing DB is unreachable on resume)
|
|
308
|
-
* MUST throw a typed error rather than silently returning `[]` — a silent
|
|
309
|
-
* empty read would masquerade as "no history" and drop the conversation.
|
|
310
|
-
*/
|
|
311
|
-
readRecords(agentId: string): Promise<SessionRecord[]>;
|
|
312
|
-
/**
|
|
313
|
-
* Append `records` (the new-turn delta) to `agentId`'s session, append-only.
|
|
314
|
-
* MUST preserve order and MUST NOT drop or rewrite prior records — the native
|
|
315
|
-
* format is an append-only `parentUuid` DAG (compaction is a new-root
|
|
316
|
-
* `compact_boundary` record, still an append).
|
|
317
|
-
*
|
|
318
|
-
* Note on the write path: per-turn persistence is fire-and-forget so `send()`
|
|
319
|
-
* is never blocked by store I/O — an `appendRecords` rejection is logged to
|
|
320
|
-
* stderr, NOT thrown to the caller (best-effort write). An external store that
|
|
321
|
-
* must guarantee durability should make `appendRecords` resilient (retry /
|
|
322
|
-
* durable write) internally. This differs from {@link SessionStore.readRecords},
|
|
323
|
-
* which MUST throw on failure (a resume cannot proceed on a silent partial history).
|
|
324
|
-
*/
|
|
325
|
-
appendRecords(agentId: string, records: readonly SessionRecord[]): Promise<void>;
|
|
326
|
-
}
|
|
327
|
-
|
|
328
328
|
/**
|
|
329
329
|
* `BudgetTracker` — runtime contract for budget/usage tracking in the
|
|
330
330
|
* agent loop (SDK 2.0 Phase 2 / T2.1 — ADR D1 interface inversion).
|