zidane 2.0.1 → 2.1.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.
@@ -21,6 +21,13 @@ interface ClassifiedError {
21
21
  providerCode?: string;
22
22
  /** Optional human-readable message override. Falls back to the underlying error's message. */
23
23
  message?: string;
24
+ /**
25
+ * Hint that the error is transient and a retry with backoff is reasonable
26
+ * (e.g. 429, 5xx, truncated stream). Omitted when the provider can't decide;
27
+ * callers should default to "do not retry" when absent to avoid hammering
28
+ * terminal failures (auth, invalid request).
29
+ */
30
+ retryable?: boolean;
24
31
  }
25
32
  interface TypedErrorOptions {
26
33
  /** Provider name, always set (e.g. `anthropic`, `openrouter`) */
@@ -29,6 +36,8 @@ interface TypedErrorOptions {
29
36
  providerCode?: string;
30
37
  /** Original error from the provider SDK/HTTP layer */
31
38
  cause?: unknown;
39
+ /** See {@link ClassifiedError.retryable}. */
40
+ retryable?: boolean;
32
41
  }
33
42
  /**
34
43
  * Thrown when the model or provider signals that the context window was exceeded.
@@ -48,6 +57,12 @@ declare class AgentProviderError extends Error {
48
57
  readonly code: "provider_error";
49
58
  readonly provider: string;
50
59
  readonly providerCode?: string;
60
+ /**
61
+ * Whether a retry with backoff is likely to succeed. See
62
+ * {@link ClassifiedError.retryable}. Absent when the provider did not
63
+ * classify the error — callers should treat absent as "don't retry".
64
+ */
65
+ readonly retryable?: boolean;
51
66
  constructor(message: string, options: TypedErrorOptions);
52
67
  }
53
68
  /**
@@ -306,6 +321,18 @@ interface AgentRunOptions {
306
321
  * Accepts either a single handler or an array (all handlers register).
307
322
  */
308
323
  hooks?: RunHookMap;
324
+ /**
325
+ * Parent run id. Populated automatically by the `spawn` tool when the child
326
+ * shares the parent's session; recorded on the resulting `SessionRun` so the
327
+ * parent↔child run tree can be reconstructed from a persisted session.
328
+ */
329
+ parentRunId?: string;
330
+ /**
331
+ * Zero-based subagent depth. 0 = top-level `agent.run()`, 1 = first-level
332
+ * child spawned by a parent agent, and so on. Used by the spawn tool to
333
+ * enforce `maxDepth` and to stamp `child:*` forwarded hook payloads.
334
+ */
335
+ depth?: number;
309
336
  }
310
337
  /** Reason the provider gave for stopping the turn */
311
338
  type TurnFinishReason = 'stop' | 'tool-calls' | 'length' | 'content-filter' | 'error' | 'other';
@@ -356,6 +383,24 @@ interface ChildRunStats {
356
383
  id: string;
357
384
  task: string;
358
385
  stats: AgentStats;
386
+ /**
387
+ * Subagent depth when this child ran. 1 = direct child of the top-level
388
+ * agent, 2 = grandchild, etc. Useful for telemetry that wants to group
389
+ * runs by depth.
390
+ */
391
+ depth?: number;
392
+ /**
393
+ * Terminal state of the child run. `'completed'` is the default. Exposed so
394
+ * a parent reading `stats.children` can distinguish aborted/timed-out
395
+ * children without re-parsing the returned string.
396
+ */
397
+ status?: 'completed' | 'aborted' | 'timeout' | 'error';
398
+ /**
399
+ * Final structured output when the child was run with `behavior.schema`.
400
+ * Mirrors `AgentStats.output` but is surfaced here so the parent can read
401
+ * it without peeking at the nested `stats` bag.
402
+ */
403
+ output?: Record<string, unknown>;
359
404
  }
360
405
  /**
361
406
  * Base context for tool execution hooks.
@@ -406,6 +451,12 @@ interface SessionHookContext {
406
451
  interface SpawnHookContext {
407
452
  id: string;
408
453
  task: string;
454
+ /**
455
+ * Subagent depth for the spawn. 1 = direct child of the top-level agent.
456
+ * Present on spawn:before/complete/error. Absent for grandchild spawns that
457
+ * bubble through `child:*` events (which carry their own `depth`).
458
+ */
459
+ depth?: number;
409
460
  }
410
461
  /** Context for stream hooks */
411
462
  interface StreamHookContext {
@@ -712,79 +763,345 @@ interface Provider {
712
763
  }
713
764
 
714
765
  /**
715
- * Types for the Agent Skills system.
766
+ * File-map session store.
716
767
  *
717
- * Follows the Agent Skills open standard (agentskills.io/specification).
718
- * Zidane-specific metadata conventionally uses the `zidane.` key prefix
719
- * (e.g. `metadata['zidane.paths']`) to stay spec-compliant.
768
+ * Wraps a narrow 3-method adapter (`get` / `save` / `delete`) that exchanges a flat
769
+ * map of filename string content. Useful for embedding zidane sessions inside
770
+ * host-provided session backends that only speak in file maps (not zidane's native
771
+ * `SessionStore` shape).
772
+ *
773
+ * Serialization format:
774
+ * - `turns.jsonl` — one `SessionTurn` per line.
775
+ * - `meta.json` — session metadata (id, agentId, status, runs, metadata, timestamps).
776
+ *
777
+ * JSONL for turns keeps history inspectable with tools like `jq` and resilient to
778
+ * partial corruption — parse up to the first bad line and you still have a valid
779
+ * prefix. Metadata lives in its own file so large turn logs don't bloat the
780
+ * metadata path.
781
+ *
782
+ * Scope: each `createFileMapStore` handles a **single session** — the adapter's
783
+ * file map holds at most one zidane session at a time. This matches how host SDKs
784
+ * scope their session stores per conversation.
785
+ *
786
+ * Divergences from the built-in memory / sqlite stores:
787
+ * - `appendTurns` / `updateStatus` / `updateRun` auto-create a minimal `SessionData`
788
+ * record on first write, instead of silently no-oping when the session hasn't been
789
+ * explicitly `save()`-ed. This matches the host-SDK integration path where
790
+ * `createSession(...)` → `agent.run(...)` directly without an explicit `save()` call.
791
+ * - `updateRun` inserts the run if not found in the cached record (rather than
792
+ * silently dropping). Run records therefore always reach the adapter.
720
793
  */
721
- interface SkillResource {
722
- /** Relative path from skill directory */
723
- path: string;
724
- /** Resource type inferred from directory */
725
- type: 'script' | 'reference' | 'asset' | 'other';
794
+
795
+ /**
796
+ * Host-provided file-map adapter. Three methods exchanging `Record<string, string>`
797
+ * payloads the whole persistence surface the wrapper needs.
798
+ */
799
+ interface FileMapAdapter {
800
+ /** Load the current file map. Returns an empty `files` record when nothing is persisted. */
801
+ get: () => Promise<{
802
+ files: Record<string, string>;
803
+ }>;
804
+ /** Replace the persisted file map. Full-rewrite semantics. */
805
+ save: (files: Record<string, string>) => Promise<void>;
806
+ /** Delete all persisted state. */
807
+ delete: () => Promise<void>;
808
+ }
809
+ interface FileMapStoreOptions {
810
+ /** Filename for the JSONL turns log. Default: `turns.jsonl`. */
811
+ turnsFile?: string;
812
+ /** Filename for the metadata JSON. Default: `meta.json`. */
813
+ metaFile?: string;
726
814
  }
727
815
  /**
728
- * Where the skill came from. Used for collision precedence (project beats user)
729
- * and for host SDKs to gate project-level skills on a trust check.
816
+ * Create a single-session `SessionStore` backed by a file-map adapter.
817
+ *
818
+ * @example
819
+ * ```ts
820
+ * const session = await createSession({
821
+ * store: createFileMapStore(hostSessionStore),
822
+ * })
823
+ * ```
730
824
  */
731
- type SkillSource = 'project' | 'user' | 'inline' | 'builtin';
732
- /** Severity + code for lenient-load warnings surfaced to host UIs. */
733
- interface SkillDiagnostic {
734
- severity: 'warning' | 'error';
735
- /** Stable machine-readable code (e.g. `name-mismatch-directory`). */
736
- code: string;
737
- /** Human-readable description. */
738
- message: string;
739
- /** Optional frontmatter field name the diagnostic relates to. */
740
- field?: string;
825
+ declare function createFileMapStore(adapter: FileMapAdapter, options?: FileMapStoreOptions): SessionStore;
826
+
827
+ /**
828
+ * In-memory session store.
829
+ * Useful for development and testing. Data is lost when the process exits.
830
+ */
831
+
832
+ declare function createMemoryStore(): SessionStore;
833
+
834
+ /**
835
+ * Canonical SessionMessage format with converters from/to Anthropic and OpenAI-compat formats.
836
+ */
837
+
838
+ declare function fromAnthropic(msg: {
839
+ role: string;
840
+ content: unknown;
841
+ }): SessionMessage;
842
+ declare function fromOpenAI(msg: {
843
+ role: string;
844
+ content: unknown;
845
+ }): SessionMessage;
846
+ declare function toAnthropic(msg: SessionMessage): {
847
+ role: string;
848
+ content: unknown;
849
+ };
850
+ declare function toOpenAI(msg: SessionMessage): {
851
+ role: string;
852
+ content: unknown;
853
+ };
854
+ declare function autoDetectAndConvert(msg: {
855
+ role: string;
856
+ content: unknown;
857
+ }): SessionMessage;
858
+
859
+ /**
860
+ * Remote session store via HTTP API.
861
+ *
862
+ * Expects a REST API with:
863
+ * GET {url}/sessions/{id} -> SessionData | 404
864
+ * PUT {url}/sessions/{id} -> save SessionData
865
+ * DELETE {url}/sessions/{id} -> delete
866
+ * GET {url}/sessions?agentId=&limit= -> { ids: string[] }
867
+ * POST {url}/sessions/{id}/turns -> append turns
868
+ * GET {url}/sessions/{id}/turns?from=&limit= -> SessionTurn[]
869
+ * PUT {url}/sessions/{id}/runs/{runId} -> update run
870
+ * PATCH {url}/sessions/{id} -> { status }
871
+ */
872
+
873
+ interface RemoteStoreOptions {
874
+ /** Base URL of the session API */
875
+ url: string;
876
+ /** Optional headers (e.g. for authentication) */
877
+ headers?: Record<string, string>;
741
878
  }
742
- interface SkillConfig {
743
- /** Skill name: 1-64 chars, lowercase alphanumeric + hyphens */
744
- name: string;
745
- /** What the skill does and when to use it (1-1024 chars) */
746
- description: string;
747
- /** The SKILL.md body content (after YAML frontmatter) */
748
- instructions: string;
749
- /**
750
- * Where this skill was loaded from. Drives collision precedence and the
751
- * `trustProjectSkills` gate. Optional — `parseSkillFile` stamps it; raw
752
- * fixtures that omit it are treated as `'project'` by downstream readers.
753
- */
754
- source?: SkillSource;
755
- /** Absolute path to SKILL.md (undefined for inline skills) */
756
- location?: string;
757
- /** Skill directory path for resolving relative references */
758
- baseDir?: string;
759
- /** License identifier or reference */
760
- license?: string;
761
- /** Environment requirements */
762
- compatibility?: string;
879
+ declare function createRemoteStore(options: RemoteStoreOptions): SessionStore;
880
+
881
+ /**
882
+ * Session management for agents.
883
+ *
884
+ * A session tracks identity, turn history, and run metadata.
885
+ * Plug in any storage backend by implementing the SessionStore interface,
886
+ * or use one of the built-in stores: memory, sqlite, remote.
887
+ */
888
+
889
+ interface SessionRun {
890
+ id: string;
891
+ startedAt: number;
892
+ endedAt?: number;
893
+ prompt: string;
894
+ status: 'running' | 'completed' | 'aborted' | 'error';
895
+ turns?: number;
896
+ tokensIn?: number;
897
+ tokensOut?: number;
898
+ error?: string;
899
+ /** Per-turn usage breakdown */
900
+ turnUsage?: TurnUsage[];
901
+ /** Total usage across all turns */
902
+ totalUsage?: TurnUsage;
903
+ /** Estimated cost in USD */
904
+ cost?: number;
763
905
  /**
764
- * Flat key-value metadata bag per the spec. For Zidane-specific hints,
765
- * use the `zidane.` key prefix (e.g. `metadata['zidane.paths']`).
906
+ * The run that spawned this one, when the agent is a subagent sharing its
907
+ * parent's session. Undefined on top-level `agent.run()`. Consumers can walk
908
+ * `runs` by `parentRunId` to reconstruct the subagent tree.
766
909
  */
767
- metadata?: Record<string, string>;
768
- /** Pre-approved tool names (experimental per spec) */
769
- allowedTools?: string[];
770
- /** Bundled resource files discovered in the skill directory */
771
- resources?: SkillResource[];
910
+ parentRunId?: string;
772
911
  /**
773
- * Lenient-load warnings recorded during parsing. Host SDKs can surface these
774
- * as inline UI hints. Absent when no issues were found.
912
+ * Zero-based subagent depth. 0 = top-level run, 1 = direct child, …
913
+ * Recorded here so hosts can query/filter by level without walking the tree.
775
914
  */
776
- diagnostics?: SkillDiagnostic[];
915
+ depth?: number;
777
916
  }
778
- interface SkillsConfig {
917
+ interface SessionData {
918
+ id: string;
919
+ agentId?: string;
920
+ turns: SessionTurn[];
921
+ runs: SessionRun[];
922
+ status: 'idle' | 'running' | 'completed' | 'error';
923
+ metadata: Record<string, unknown>;
924
+ createdAt: number;
925
+ updatedAt: number;
926
+ }
927
+ interface SessionStore {
928
+ /** Optional: generate a session ID server-side (e.g. Supabase UUID). */
929
+ generateSessionId?: () => string | Promise<string>;
930
+ /** Optional: generate a turn ID server-side. */
931
+ generateTurnId?: () => string | Promise<string>;
932
+ /** Load a session by ID. Returns null if not found. */
933
+ load: (sessionId: string) => Promise<SessionData | null>;
934
+ /** Save a session (create or update, full document). */
935
+ save: (session: SessionData) => Promise<void>;
936
+ /** Delete a session. */
937
+ delete: (sessionId: string) => Promise<void>;
938
+ /** List session IDs, optionally filtered. */
939
+ list: (filter?: {
940
+ agentId?: string;
941
+ limit?: number;
942
+ }) => Promise<string[]>;
943
+ /** Append new turns to a session (incremental, avoids full re-save). */
944
+ appendTurns: (sessionId: string, turns: SessionTurn[]) => Promise<void>;
945
+ /** Return a slice of turns for a session. */
946
+ getTurns: (sessionId: string, from?: number, limit?: number) => Promise<SessionTurn[]>;
947
+ /** Persist an updated run record (called after completeRun / abortRun / errorRun). */
948
+ updateRun: (sessionId: string, run: SessionRun) => Promise<void>;
949
+ /** Update the top-level status of a session. */
950
+ updateStatus: (sessionId: string, status: SessionData['status']) => Promise<void>;
951
+ }
952
+ interface Session {
953
+ /** Session ID */
954
+ readonly id: string;
955
+ /** Agent ID (optional label) */
956
+ readonly agentId?: string;
957
+ /** Current turn history */
958
+ readonly turns: SessionTurn[];
779
959
  /**
780
- * Control which skills are active.
781
- * - `true` (default): all discovered skills are enabled
782
- * - `false` or `[]`: fully disable the skills system (no resolution, no catalog, no hooks)
783
- * - `string[]`: allowlist only skills with matching names are enabled
960
+ * True when this session has no turns yet.
961
+ *
962
+ * Use this as a first-prompt signal when setting up a run e.g. writing initial
963
+ * configuration only on fresh sessions. Equivalent to `turns.length === 0`.
784
964
  */
785
- enabled?: boolean | string[];
786
- /** Directories to scan for SKILL.md files */
787
- scan?: string[];
965
+ readonly isEmpty: boolean;
966
+ /** Top-level session status */
967
+ readonly status: SessionData['status'];
968
+ /** All runs in this session */
969
+ readonly runs: SessionRun[];
970
+ /** Arbitrary metadata */
971
+ readonly metadata: Record<string, unknown>;
972
+ /**
973
+ * Start tracking a new run. `extras.parentRunId` + `extras.depth` are
974
+ * populated by the spawn tool when a child agent shares its parent's
975
+ * session; regular top-level `agent.run()` calls omit them.
976
+ */
977
+ startRun: (runId: string, prompt?: string, extras?: {
978
+ parentRunId?: string;
979
+ depth?: number;
980
+ }) => void;
981
+ /** Mark a run as completed */
982
+ completeRun: (runId: string, stats: {
983
+ turns: number;
984
+ tokensIn: number;
985
+ tokensOut: number;
986
+ turnUsage?: TurnUsage[];
987
+ cost?: number;
988
+ }) => void;
989
+ /** Mark a run as aborted */
990
+ abortRun: (runId: string) => void;
991
+ /** Mark a run as errored */
992
+ errorRun: (runId: string, error: string) => void;
993
+ /** Append turns to in-memory history AND persist via store.appendTurns (if store present) */
994
+ appendTurns: (turns: SessionTurn[]) => Promise<void>;
995
+ /** Replace all turns in-memory (does not persist — use save() for that) */
996
+ setTurns: (turns: SessionTurn[]) => void;
997
+ /** Update the session status in memory AND via store.updateStatus (if store present) */
998
+ updateStatus: (status: SessionData['status']) => Promise<void>;
999
+ /** Persist an updated run record via store.updateRun (if store present) */
1000
+ updateRun: (run: SessionRun) => Promise<void>;
1001
+ /** Generate a turn ID using store.generateTurnId if available, else crypto.randomUUID() */
1002
+ generateTurnId: () => string | Promise<string>;
1003
+ /** Set metadata key */
1004
+ setMeta: (key: string, value: unknown) => void;
1005
+ /** Persist the full session document to the store */
1006
+ save: () => Promise<void>;
1007
+ /** Serialize to SessionData */
1008
+ toJSON: () => SessionData;
1009
+ }
1010
+ interface CreateSessionOptions {
1011
+ /** Session ID. If omitted and store provides generateSessionId, that is used. */
1012
+ id?: string;
1013
+ /** Agent ID label */
1014
+ agentId?: string;
1015
+ /** Initial metadata */
1016
+ metadata?: Record<string, unknown>;
1017
+ /** Storage backend (optional, enables save/load) */
1018
+ store?: SessionStore;
1019
+ _data?: SessionData;
1020
+ }
1021
+ /**
1022
+ * Create a new session.
1023
+ * Async so stores that generate IDs server-side (e.g. Supabase) can be supported.
1024
+ */
1025
+ declare function createSession(options?: CreateSessionOptions): Promise<Session>;
1026
+ /**
1027
+ * Load an existing session from a store.
1028
+ */
1029
+ declare function loadSession(store: SessionStore, sessionId: string): Promise<Session | null>;
1030
+
1031
+ /**
1032
+ * Types for the Agent Skills system.
1033
+ *
1034
+ * Follows the Agent Skills open standard (agentskills.io/specification).
1035
+ * Zidane-specific metadata conventionally uses the `zidane.` key prefix
1036
+ * (e.g. `metadata['zidane.paths']`) to stay spec-compliant.
1037
+ */
1038
+ interface SkillResource {
1039
+ /** Relative path from skill directory */
1040
+ path: string;
1041
+ /** Resource type inferred from directory */
1042
+ type: 'script' | 'reference' | 'asset' | 'other';
1043
+ }
1044
+ /**
1045
+ * Where the skill came from. Used for collision precedence (project beats user)
1046
+ * and for host SDKs to gate project-level skills on a trust check.
1047
+ */
1048
+ type SkillSource = 'project' | 'user' | 'inline' | 'builtin';
1049
+ /** Severity + code for lenient-load warnings surfaced to host UIs. */
1050
+ interface SkillDiagnostic {
1051
+ severity: 'warning' | 'error';
1052
+ /** Stable machine-readable code (e.g. `name-mismatch-directory`). */
1053
+ code: string;
1054
+ /** Human-readable description. */
1055
+ message: string;
1056
+ /** Optional frontmatter field name the diagnostic relates to. */
1057
+ field?: string;
1058
+ }
1059
+ interface SkillConfig {
1060
+ /** Skill name: 1-64 chars, lowercase alphanumeric + hyphens */
1061
+ name: string;
1062
+ /** What the skill does and when to use it (1-1024 chars) */
1063
+ description: string;
1064
+ /** The SKILL.md body content (after YAML frontmatter) */
1065
+ instructions: string;
1066
+ /**
1067
+ * Where this skill was loaded from. Drives collision precedence and the
1068
+ * `trustProjectSkills` gate. Optional — `parseSkillFile` stamps it; raw
1069
+ * fixtures that omit it are treated as `'project'` by downstream readers.
1070
+ */
1071
+ source?: SkillSource;
1072
+ /** Absolute path to SKILL.md (undefined for inline skills) */
1073
+ location?: string;
1074
+ /** Skill directory path for resolving relative references */
1075
+ baseDir?: string;
1076
+ /** License identifier or reference */
1077
+ license?: string;
1078
+ /** Environment requirements */
1079
+ compatibility?: string;
1080
+ /**
1081
+ * Flat key-value metadata bag per the spec. For Zidane-specific hints,
1082
+ * use the `zidane.` key prefix (e.g. `metadata['zidane.paths']`).
1083
+ */
1084
+ metadata?: Record<string, string>;
1085
+ /** Pre-approved tool names (experimental per spec) */
1086
+ allowedTools?: string[];
1087
+ /** Bundled resource files discovered in the skill directory */
1088
+ resources?: SkillResource[];
1089
+ /**
1090
+ * Lenient-load warnings recorded during parsing. Host SDKs can surface these
1091
+ * as inline UI hints. Absent when no issues were found.
1092
+ */
1093
+ diagnostics?: SkillDiagnostic[];
1094
+ }
1095
+ interface SkillsConfig {
1096
+ /**
1097
+ * Control which skills are active.
1098
+ * - `true` (default): all discovered skills are enabled
1099
+ * - `false` or `[]`: fully disable the skills system (no resolution, no catalog, no hooks)
1100
+ * - `string[]`: allowlist — only skills with matching names are enabled
1101
+ */
1102
+ enabled?: boolean | string[];
1103
+ /** Directories to scan for SKILL.md files */
1104
+ scan?: string[];
788
1105
  /** Dynamic skills written to disk at agent start, then loaded normally */
789
1106
  write?: SkillConfig[];
790
1107
  /** Skill names to exclude from the catalog */
@@ -843,6 +1160,27 @@ interface ToolContext {
843
1160
  turnId: string;
844
1161
  /** Tool call ID from the model */
845
1162
  callId: string;
1163
+ /**
1164
+ * The run id this tool call is part of. Populated by the agent loop when
1165
+ * invoking tools. Optional on the type so host code constructing contexts
1166
+ * by hand (tests, direct tool invocations) doesn't have to synthesize one.
1167
+ *
1168
+ * Spawn-style tools rely on this to tag child runs with `parentRunId` so
1169
+ * the subagent tree can be reconstructed from a persisted session.
1170
+ */
1171
+ runId?: string;
1172
+ /**
1173
+ * The agent's session, when one was provided to `createAgent`. Tools that
1174
+ * want to persist their own state (or, in the case of `spawn`, inherit the
1175
+ * parent's session for child persistence) can read from here.
1176
+ */
1177
+ session?: Session;
1178
+ /**
1179
+ * Subagent depth for the agent owning this tool call. 0 = top-level,
1180
+ * 1 = first-level child, … Used by spawn to enforce a `maxDepth` cap.
1181
+ * Undefined is treated as 0 by spawn.
1182
+ */
1183
+ depth?: number;
846
1184
  }
847
1185
  interface ToolDef {
848
1186
  spec: ToolSpec;
@@ -968,254 +1306,6 @@ declare function normalizeMcpBlocks(content: unknown): ToolResultContent[] | nul
968
1306
  */
969
1307
  declare function connectMcpServers(configs: McpServerConfig[], _clientFactory?: () => Client, hooks?: Hookable<AgentHooks>): Promise<McpConnection>;
970
1308
 
971
- /**
972
- * File-map session store.
973
- *
974
- * Wraps a narrow 3-method adapter (`get` / `save` / `delete`) that exchanges a flat
975
- * map of filename → string content. Useful for embedding zidane sessions inside
976
- * host-provided session backends that only speak in file maps (not zidane's native
977
- * `SessionStore` shape).
978
- *
979
- * Serialization format:
980
- * - `turns.jsonl` — one `SessionTurn` per line.
981
- * - `meta.json` — session metadata (id, agentId, status, runs, metadata, timestamps).
982
- *
983
- * JSONL for turns keeps history inspectable with tools like `jq` and resilient to
984
- * partial corruption — parse up to the first bad line and you still have a valid
985
- * prefix. Metadata lives in its own file so large turn logs don't bloat the
986
- * metadata path.
987
- *
988
- * Scope: each `createFileMapStore` handles a **single session** — the adapter's
989
- * file map holds at most one zidane session at a time. This matches how host SDKs
990
- * scope their session stores per conversation.
991
- *
992
- * Divergences from the built-in memory / sqlite stores:
993
- * - `appendTurns` / `updateStatus` / `updateRun` auto-create a minimal `SessionData`
994
- * record on first write, instead of silently no-oping when the session hasn't been
995
- * explicitly `save()`-ed. This matches the host-SDK integration path where
996
- * `createSession(...)` → `agent.run(...)` directly without an explicit `save()` call.
997
- * - `updateRun` inserts the run if not found in the cached record (rather than
998
- * silently dropping). Run records therefore always reach the adapter.
999
- */
1000
-
1001
- /**
1002
- * Host-provided file-map adapter. Three methods exchanging `Record<string, string>`
1003
- * payloads — the whole persistence surface the wrapper needs.
1004
- */
1005
- interface FileMapAdapter {
1006
- /** Load the current file map. Returns an empty `files` record when nothing is persisted. */
1007
- get: () => Promise<{
1008
- files: Record<string, string>;
1009
- }>;
1010
- /** Replace the persisted file map. Full-rewrite semantics. */
1011
- save: (files: Record<string, string>) => Promise<void>;
1012
- /** Delete all persisted state. */
1013
- delete: () => Promise<void>;
1014
- }
1015
- interface FileMapStoreOptions {
1016
- /** Filename for the JSONL turns log. Default: `turns.jsonl`. */
1017
- turnsFile?: string;
1018
- /** Filename for the metadata JSON. Default: `meta.json`. */
1019
- metaFile?: string;
1020
- }
1021
- /**
1022
- * Create a single-session `SessionStore` backed by a file-map adapter.
1023
- *
1024
- * @example
1025
- * ```ts
1026
- * const session = await createSession({
1027
- * store: createFileMapStore(hostSessionStore),
1028
- * })
1029
- * ```
1030
- */
1031
- declare function createFileMapStore(adapter: FileMapAdapter, options?: FileMapStoreOptions): SessionStore;
1032
-
1033
- /**
1034
- * In-memory session store.
1035
- * Useful for development and testing. Data is lost when the process exits.
1036
- */
1037
-
1038
- declare function createMemoryStore(): SessionStore;
1039
-
1040
- /**
1041
- * Canonical SessionMessage format with converters from/to Anthropic and OpenAI-compat formats.
1042
- */
1043
-
1044
- declare function fromAnthropic(msg: {
1045
- role: string;
1046
- content: unknown;
1047
- }): SessionMessage;
1048
- declare function fromOpenAI(msg: {
1049
- role: string;
1050
- content: unknown;
1051
- }): SessionMessage;
1052
- declare function toAnthropic(msg: SessionMessage): {
1053
- role: string;
1054
- content: unknown;
1055
- };
1056
- declare function toOpenAI(msg: SessionMessage): {
1057
- role: string;
1058
- content: unknown;
1059
- };
1060
- declare function autoDetectAndConvert(msg: {
1061
- role: string;
1062
- content: unknown;
1063
- }): SessionMessage;
1064
-
1065
- /**
1066
- * Remote session store via HTTP API.
1067
- *
1068
- * Expects a REST API with:
1069
- * GET {url}/sessions/{id} -> SessionData | 404
1070
- * PUT {url}/sessions/{id} -> save SessionData
1071
- * DELETE {url}/sessions/{id} -> delete
1072
- * GET {url}/sessions?agentId=&limit= -> { ids: string[] }
1073
- * POST {url}/sessions/{id}/turns -> append turns
1074
- * GET {url}/sessions/{id}/turns?from=&limit= -> SessionTurn[]
1075
- * PUT {url}/sessions/{id}/runs/{runId} -> update run
1076
- * PATCH {url}/sessions/{id} -> { status }
1077
- */
1078
-
1079
- interface RemoteStoreOptions {
1080
- /** Base URL of the session API */
1081
- url: string;
1082
- /** Optional headers (e.g. for authentication) */
1083
- headers?: Record<string, string>;
1084
- }
1085
- declare function createRemoteStore(options: RemoteStoreOptions): SessionStore;
1086
-
1087
- /**
1088
- * Session management for agents.
1089
- *
1090
- * A session tracks identity, turn history, and run metadata.
1091
- * Plug in any storage backend by implementing the SessionStore interface,
1092
- * or use one of the built-in stores: memory, sqlite, remote.
1093
- */
1094
-
1095
- interface SessionRun {
1096
- id: string;
1097
- startedAt: number;
1098
- endedAt?: number;
1099
- prompt: string;
1100
- status: 'running' | 'completed' | 'aborted' | 'error';
1101
- turns?: number;
1102
- tokensIn?: number;
1103
- tokensOut?: number;
1104
- error?: string;
1105
- /** Per-turn usage breakdown */
1106
- turnUsage?: TurnUsage[];
1107
- /** Total usage across all turns */
1108
- totalUsage?: TurnUsage;
1109
- /** Estimated cost in USD */
1110
- cost?: number;
1111
- }
1112
- interface SessionData {
1113
- id: string;
1114
- agentId?: string;
1115
- turns: SessionTurn[];
1116
- runs: SessionRun[];
1117
- status: 'idle' | 'running' | 'completed' | 'error';
1118
- metadata: Record<string, unknown>;
1119
- createdAt: number;
1120
- updatedAt: number;
1121
- }
1122
- interface SessionStore {
1123
- /** Optional: generate a session ID server-side (e.g. Supabase UUID). */
1124
- generateSessionId?: () => string | Promise<string>;
1125
- /** Optional: generate a turn ID server-side. */
1126
- generateTurnId?: () => string | Promise<string>;
1127
- /** Load a session by ID. Returns null if not found. */
1128
- load: (sessionId: string) => Promise<SessionData | null>;
1129
- /** Save a session (create or update, full document). */
1130
- save: (session: SessionData) => Promise<void>;
1131
- /** Delete a session. */
1132
- delete: (sessionId: string) => Promise<void>;
1133
- /** List session IDs, optionally filtered. */
1134
- list: (filter?: {
1135
- agentId?: string;
1136
- limit?: number;
1137
- }) => Promise<string[]>;
1138
- /** Append new turns to a session (incremental, avoids full re-save). */
1139
- appendTurns: (sessionId: string, turns: SessionTurn[]) => Promise<void>;
1140
- /** Return a slice of turns for a session. */
1141
- getTurns: (sessionId: string, from?: number, limit?: number) => Promise<SessionTurn[]>;
1142
- /** Persist an updated run record (called after completeRun / abortRun / errorRun). */
1143
- updateRun: (sessionId: string, run: SessionRun) => Promise<void>;
1144
- /** Update the top-level status of a session. */
1145
- updateStatus: (sessionId: string, status: SessionData['status']) => Promise<void>;
1146
- }
1147
- interface Session {
1148
- /** Session ID */
1149
- readonly id: string;
1150
- /** Agent ID (optional label) */
1151
- readonly agentId?: string;
1152
- /** Current turn history */
1153
- readonly turns: SessionTurn[];
1154
- /**
1155
- * True when this session has no turns yet.
1156
- *
1157
- * Use this as a first-prompt signal when setting up a run — e.g. writing initial
1158
- * configuration only on fresh sessions. Equivalent to `turns.length === 0`.
1159
- */
1160
- readonly isEmpty: boolean;
1161
- /** Top-level session status */
1162
- readonly status: SessionData['status'];
1163
- /** All runs in this session */
1164
- readonly runs: SessionRun[];
1165
- /** Arbitrary metadata */
1166
- readonly metadata: Record<string, unknown>;
1167
- /** Start tracking a new run */
1168
- startRun: (runId: string, prompt?: string) => void;
1169
- /** Mark a run as completed */
1170
- completeRun: (runId: string, stats: {
1171
- turns: number;
1172
- tokensIn: number;
1173
- tokensOut: number;
1174
- turnUsage?: TurnUsage[];
1175
- cost?: number;
1176
- }) => void;
1177
- /** Mark a run as aborted */
1178
- abortRun: (runId: string) => void;
1179
- /** Mark a run as errored */
1180
- errorRun: (runId: string, error: string) => void;
1181
- /** Append turns to in-memory history AND persist via store.appendTurns (if store present) */
1182
- appendTurns: (turns: SessionTurn[]) => Promise<void>;
1183
- /** Replace all turns in-memory (does not persist — use save() for that) */
1184
- setTurns: (turns: SessionTurn[]) => void;
1185
- /** Update the session status in memory AND via store.updateStatus (if store present) */
1186
- updateStatus: (status: SessionData['status']) => Promise<void>;
1187
- /** Persist an updated run record via store.updateRun (if store present) */
1188
- updateRun: (run: SessionRun) => Promise<void>;
1189
- /** Generate a turn ID using store.generateTurnId if available, else crypto.randomUUID() */
1190
- generateTurnId: () => string | Promise<string>;
1191
- /** Set metadata key */
1192
- setMeta: (key: string, value: unknown) => void;
1193
- /** Persist the full session document to the store */
1194
- save: () => Promise<void>;
1195
- /** Serialize to SessionData */
1196
- toJSON: () => SessionData;
1197
- }
1198
- interface CreateSessionOptions {
1199
- /** Session ID. If omitted and store provides generateSessionId, that is used. */
1200
- id?: string;
1201
- /** Agent ID label */
1202
- agentId?: string;
1203
- /** Initial metadata */
1204
- metadata?: Record<string, unknown>;
1205
- /** Storage backend (optional, enables save/load) */
1206
- store?: SessionStore;
1207
- _data?: SessionData;
1208
- }
1209
- /**
1210
- * Create a new session.
1211
- * Async so stores that generate IDs server-side (e.g. Supabase) can be supported.
1212
- */
1213
- declare function createSession(options?: CreateSessionOptions): Promise<Session>;
1214
- /**
1215
- * Load an existing session from a store.
1216
- */
1217
- declare function loadSession(store: SessionStore, sessionId: string): Promise<Session | null>;
1218
-
1219
1309
  /**
1220
1310
  * Per-agent skill activation state machine.
1221
1311
  *
@@ -1341,6 +1431,45 @@ interface AgentHooks {
1341
1431
  'spawn:error': (ctx: SpawnHookContext & {
1342
1432
  error: Error;
1343
1433
  }) => void;
1434
+ 'child:stream:text': (ctx: StreamHookContext & {
1435
+ delta: string;
1436
+ text: string;
1437
+ childId: string;
1438
+ depth: number;
1439
+ }) => void;
1440
+ 'child:stream:thinking': (ctx: StreamHookContext & {
1441
+ delta: string;
1442
+ thinking: string;
1443
+ childId: string;
1444
+ depth: number;
1445
+ }) => void;
1446
+ 'child:stream:end': (ctx: StreamHookContext & {
1447
+ text: string;
1448
+ childId: string;
1449
+ depth: number;
1450
+ }) => void;
1451
+ 'child:tool:before': (ctx: ToolHookContext & {
1452
+ childId: string;
1453
+ depth: number;
1454
+ }) => void;
1455
+ 'child:tool:after': (ctx: ToolHookContext & {
1456
+ result: string | ToolResultContent[];
1457
+ childId: string;
1458
+ depth: number;
1459
+ }) => void;
1460
+ 'child:tool:error': (ctx: ToolHookContext & {
1461
+ error: Error;
1462
+ childId: string;
1463
+ depth: number;
1464
+ }) => void;
1465
+ 'child:turn:after': (ctx: {
1466
+ turn: number;
1467
+ turnId: string;
1468
+ usage: TurnUsage;
1469
+ message: SessionTurn;
1470
+ childId: string;
1471
+ depth: number;
1472
+ }) => void;
1344
1473
  'mcp:connect': (ctx: {
1345
1474
  name: string;
1346
1475
  transport: string;
@@ -1438,8 +1567,16 @@ interface Agent {
1438
1567
  steer: (message: string) => void;
1439
1568
  followUp: (message: string) => void;
1440
1569
  waitForIdle: () => Promise<void>;
1441
- reset: () => void;
1442
- /** Destroy the execution context and clean up resources */
1570
+ /**
1571
+ * Clear the agent's in-memory state (turns, queues, skill activations).
1572
+ * Fires `skills:deactivate` with `reason: 'reset'` for each previously active
1573
+ * skill. Awaiting lets host apps observe listener rejections.
1574
+ */
1575
+ reset: () => Promise<void>;
1576
+ /**
1577
+ * Destroy the execution context and clean up resources.
1578
+ * Idempotent — safe to call from both a `finally` block and a signal handler.
1579
+ */
1443
1580
  destroy: () => Promise<void>;
1444
1581
  /**
1445
1582
  * Explicitly activate a skill by name. Fires `skills:activate` with