agentenkit 0.1.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.
Files changed (159) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +226 -0
  3. package/dist/adapters/inline.d.ts +27 -0
  4. package/dist/adapters/inline.d.ts.map +1 -0
  5. package/dist/adapters/inline.js +41 -0
  6. package/dist/adapters/inline.js.map +1 -0
  7. package/dist/adapters/memory.d.ts +74 -0
  8. package/dist/adapters/memory.d.ts.map +1 -0
  9. package/dist/adapters/memory.js +194 -0
  10. package/dist/adapters/memory.js.map +1 -0
  11. package/dist/adapters/prisma.d.ts +176 -0
  12. package/dist/adapters/prisma.d.ts.map +1 -0
  13. package/dist/adapters/prisma.js +107 -0
  14. package/dist/adapters/prisma.js.map +1 -0
  15. package/dist/adapters/qstash.d.ts +36 -0
  16. package/dist/adapters/qstash.d.ts.map +1 -0
  17. package/dist/adapters/qstash.js +26 -0
  18. package/dist/adapters/qstash.js.map +1 -0
  19. package/dist/adapters/redis.d.ts +49 -0
  20. package/dist/adapters/redis.d.ts.map +1 -0
  21. package/dist/adapters/redis.js +60 -0
  22. package/dist/adapters/redis.js.map +1 -0
  23. package/dist/adapters/sqlite.d.ts +67 -0
  24. package/dist/adapters/sqlite.d.ts.map +1 -0
  25. package/dist/adapters/sqlite.js +199 -0
  26. package/dist/adapters/sqlite.js.map +1 -0
  27. package/dist/adapters/upstash.d.ts +48 -0
  28. package/dist/adapters/upstash.d.ts.map +1 -0
  29. package/dist/adapters/upstash.js +46 -0
  30. package/dist/adapters/upstash.js.map +1 -0
  31. package/dist/admin/default.d.ts +15 -0
  32. package/dist/admin/default.d.ts.map +1 -0
  33. package/dist/admin/default.js +22 -0
  34. package/dist/admin/default.js.map +1 -0
  35. package/dist/admin/memory.d.ts +29 -0
  36. package/dist/admin/memory.d.ts.map +1 -0
  37. package/dist/admin/memory.js +83 -0
  38. package/dist/admin/memory.js.map +1 -0
  39. package/dist/admin/postgres.d.ts +43 -0
  40. package/dist/admin/postgres.d.ts.map +1 -0
  41. package/dist/admin/postgres.js +201 -0
  42. package/dist/admin/postgres.js.map +1 -0
  43. package/dist/admin/sqlite.d.ts +35 -0
  44. package/dist/admin/sqlite.d.ts.map +1 -0
  45. package/dist/admin/sqlite.js +187 -0
  46. package/dist/admin/sqlite.js.map +1 -0
  47. package/dist/core/admin.d.ts +88 -0
  48. package/dist/core/admin.d.ts.map +1 -0
  49. package/dist/core/admin.js +147 -0
  50. package/dist/core/admin.js.map +1 -0
  51. package/dist/core/agent.d.ts +29 -0
  52. package/dist/core/agent.d.ts.map +1 -0
  53. package/dist/core/agent.js +41 -0
  54. package/dist/core/agent.js.map +1 -0
  55. package/dist/core/cache.d.ts +37 -0
  56. package/dist/core/cache.d.ts.map +1 -0
  57. package/dist/core/cache.js +68 -0
  58. package/dist/core/cache.js.map +1 -0
  59. package/dist/core/context.d.ts +13 -0
  60. package/dist/core/context.d.ts.map +1 -0
  61. package/dist/core/context.js +87 -0
  62. package/dist/core/context.js.map +1 -0
  63. package/dist/core/deleteThread.d.ts +14 -0
  64. package/dist/core/deleteThread.d.ts.map +1 -0
  65. package/dist/core/deleteThread.js +34 -0
  66. package/dist/core/deleteThread.js.map +1 -0
  67. package/dist/core/engine.d.ts +79 -0
  68. package/dist/core/engine.d.ts.map +1 -0
  69. package/dist/core/engine.js +489 -0
  70. package/dist/core/engine.js.map +1 -0
  71. package/dist/core/follow.d.ts +50 -0
  72. package/dist/core/follow.d.ts.map +1 -0
  73. package/dist/core/follow.js +153 -0
  74. package/dist/core/follow.js.map +1 -0
  75. package/dist/core/hitl.d.ts +98 -0
  76. package/dist/core/hitl.d.ts.map +1 -0
  77. package/dist/core/hitl.js +199 -0
  78. package/dist/core/hitl.js.map +1 -0
  79. package/dist/core/keys.d.ts +26 -0
  80. package/dist/core/keys.d.ts.map +1 -0
  81. package/dist/core/keys.js +32 -0
  82. package/dist/core/keys.js.map +1 -0
  83. package/dist/core/loop.d.ts +105 -0
  84. package/dist/core/loop.d.ts.map +1 -0
  85. package/dist/core/loop.js +234 -0
  86. package/dist/core/loop.js.map +1 -0
  87. package/dist/core/publish.d.ts +18 -0
  88. package/dist/core/publish.d.ts.map +1 -0
  89. package/dist/core/publish.js +34 -0
  90. package/dist/core/publish.js.map +1 -0
  91. package/dist/core/reclaim.d.ts +20 -0
  92. package/dist/core/reclaim.d.ts.map +1 -0
  93. package/dist/core/reclaim.js +56 -0
  94. package/dist/core/reclaim.js.map +1 -0
  95. package/dist/core/run.d.ts +8 -0
  96. package/dist/core/run.d.ts.map +1 -0
  97. package/dist/core/run.js +102 -0
  98. package/dist/core/run.js.map +1 -0
  99. package/dist/core/state.d.ts +50 -0
  100. package/dist/core/state.d.ts.map +1 -0
  101. package/dist/core/state.js +39 -0
  102. package/dist/core/state.js.map +1 -0
  103. package/dist/core/stop.d.ts +7 -0
  104. package/dist/core/stop.d.ts.map +1 -0
  105. package/dist/core/stop.js +15 -0
  106. package/dist/core/stop.js.map +1 -0
  107. package/dist/core/stream.d.ts +12 -0
  108. package/dist/core/stream.d.ts.map +1 -0
  109. package/dist/core/stream.js +21 -0
  110. package/dist/core/stream.js.map +1 -0
  111. package/dist/core/subagent.d.ts +77 -0
  112. package/dist/core/subagent.d.ts.map +1 -0
  113. package/dist/core/subagent.js +261 -0
  114. package/dist/core/subagent.js.map +1 -0
  115. package/dist/core/tools.d.ts +36 -0
  116. package/dist/core/tools.d.ts.map +1 -0
  117. package/dist/core/tools.js +22 -0
  118. package/dist/core/tools.js.map +1 -0
  119. package/dist/core/types.d.ts +286 -0
  120. package/dist/core/types.d.ts.map +1 -0
  121. package/dist/core/types.js +49 -0
  122. package/dist/core/types.js.map +1 -0
  123. package/dist/core/usage.d.ts +40 -0
  124. package/dist/core/usage.d.ts.map +1 -0
  125. package/dist/core/usage.js +43 -0
  126. package/dist/core/usage.js.map +1 -0
  127. package/dist/index.d.ts +25 -0
  128. package/dist/index.d.ts.map +1 -0
  129. package/dist/index.js +23 -0
  130. package/dist/index.js.map +1 -0
  131. package/dist/ports/admin.d.ts +102 -0
  132. package/dist/ports/admin.d.ts.map +1 -0
  133. package/dist/ports/admin.js +2 -0
  134. package/dist/ports/admin.js.map +1 -0
  135. package/dist/ports/bus.d.ts +13 -0
  136. package/dist/ports/bus.d.ts.map +1 -0
  137. package/dist/ports/bus.js +2 -0
  138. package/dist/ports/bus.js.map +1 -0
  139. package/dist/ports/kv.d.ts +16 -0
  140. package/dist/ports/kv.d.ts.map +1 -0
  141. package/dist/ports/kv.js +2 -0
  142. package/dist/ports/kv.js.map +1 -0
  143. package/dist/ports/queue.d.ts +18 -0
  144. package/dist/ports/queue.d.ts.map +1 -0
  145. package/dist/ports/queue.js +2 -0
  146. package/dist/ports/queue.js.map +1 -0
  147. package/dist/ports/runtime.d.ts +260 -0
  148. package/dist/ports/runtime.d.ts.map +1 -0
  149. package/dist/ports/runtime.js +2 -0
  150. package/dist/ports/runtime.js.map +1 -0
  151. package/dist/ports/storage.d.ts +72 -0
  152. package/dist/ports/storage.d.ts.map +1 -0
  153. package/dist/ports/storage.js +2 -0
  154. package/dist/ports/storage.js.map +1 -0
  155. package/dist/runtime.d.ts +5 -0
  156. package/dist/runtime.d.ts.map +1 -0
  157. package/dist/runtime.js +177 -0
  158. package/dist/runtime.js.map +1 -0
  159. package/package.json +126 -0
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=bus.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bus.js","sourceRoot":"","sources":["../../src/ports/bus.ts"],"names":[],"mappings":""}
@@ -0,0 +1,16 @@
1
+ /** Hot key-value port: thread state cache, HITL handoff keys, seq & attempt
2
+ * counters, per-thread run locks (§3.2). Backed by Redis in the reference
3
+ * adapters — any KV works. */
4
+ export interface Kv {
5
+ get(key: string): Promise<string | null>;
6
+ /** Returns true iff the value was written. With `onlyIfNotExists` (SET NX),
7
+ * returns false when the key already existed — this is the atomic
8
+ * primitive behind the per-thread run lock (§3.4). */
9
+ set(key: string, value: string, opts?: {
10
+ exSeconds?: number;
11
+ onlyIfNotExists?: boolean;
12
+ }): Promise<boolean>;
13
+ del(key: string): Promise<void>;
14
+ incr(key: string): Promise<number>;
15
+ }
16
+ //# sourceMappingURL=kv.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kv.d.ts","sourceRoot":"","sources":["../../src/ports/kv.ts"],"names":[],"mappings":"AAAA;;+BAE+B;AAC/B,MAAM,WAAW,EAAE;IACjB,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IACzC;;2DAEuD;IACvD,GAAG,CACD,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,MAAM,EACb,IAAI,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,eAAe,CAAC,EAAE,OAAO,CAAA;KAAE,GACvD,OAAO,CAAC,OAAO,CAAC,CAAC;IACpB,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAChC,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CACpC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=kv.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kv.js","sourceRoot":"","sources":["../../src/ports/kv.ts"],"names":[],"mappings":""}
@@ -0,0 +1,18 @@
1
+ import type { RunJob } from '../core/types.js';
2
+ export interface EnqueueOptions {
3
+ /** Hold the job for this many seconds before delivering it: the HITL expiry
4
+ * (§2.5) and a job blocked by an older run's lock (§2.8).
5
+ *
6
+ * An adapter that cannot delay may deliver immediately — both callers treat
7
+ * an early arrival as a no-op — but it must NOT throw, or a park would fail
8
+ * the run that scheduled it. Note the shape of the reference adapter: QStash
9
+ * supports delays on publish only and rejects them on queue enqueue, so
10
+ * QStashQueue publishes delayed jobs and queues the rest. */
11
+ delaySeconds?: number;
12
+ }
13
+ /** Durable dispatch port (§2.8). Delivery is at-least-once — the engine's
14
+ * state guard + Storage.threads.claimState make double dispatch a no-op. */
15
+ export interface Queue {
16
+ enqueue(job: RunJob, opts?: EnqueueOptions): Promise<void>;
17
+ }
18
+ //# sourceMappingURL=queue.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"queue.d.ts","sourceRoot":"","sources":["../../src/ports/queue.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAE/C,MAAM,WAAW,cAAc;IAC7B;;;;;;;kEAO8D;IAC9D,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;6EAC6E;AAC7E,MAAM,WAAW,KAAK;IACpB,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC5D"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=queue.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"queue.js","sourceRoot":"","sources":["../../src/ports/queue.ts"],"names":[],"mappings":""}
@@ -0,0 +1,260 @@
1
+ import type { ToolSet } from 'ai';
2
+ import type { AgentEvent, AgentConfig, AgentKind, ContextUsage, ExecutionState, MessageDTO, ProviderOptions, ResolvedModel, RunJob, RunRecord, SubagentsConfig, ThreadDTO, UsageTotals } from '../core/types.js';
3
+ import type { Storage } from './storage.js';
4
+ import type { AdminStore, RunFilter, StepRecord } from './admin.js';
5
+ import type { AgentRunState, BoundStorage } from '../core/state.js';
6
+ import type { FollowOptions, SseOptions, SseStream } from '../core/follow.js';
7
+ export type { AdminStore, NewStepRecord, RunFilter, StepRecord } from './admin.js';
8
+ export type { AgentRunState, BoundStorage, StorageContext } from '../core/state.js';
9
+ import type { EventBus } from './bus.js';
10
+ import type { Queue } from './queue.js';
11
+ import type { Kv } from './kv.js';
12
+ import type { ExecuteInput, ExecuteOutcome } from '../core/engine.js';
13
+ import type { AdminOverview, RunDetail, RunStats, ThreadDetail, ThreadSummary } from '../core/admin.js';
14
+ export type { AdminOverview, RunDetail, RunStats, } from '../core/admin.js';
15
+ export type { ExecuteInput, ExecuteOutcome } from '../core/engine.js';
16
+ export type { AgentKind, ProviderOptions, ResolvedModel, RunJob, SubagentsConfig } from '../core/types.js';
17
+ /** The ports bundle — everything in core/ receives this and nothing else.
18
+ *
19
+ * `storage` is the caller's implementation with THIS run's context already
20
+ * bound (§2.10), so core keeps calling `messages.append(threadId, msg)` while
21
+ * the implementation still receives the state. `admin` is the platform's own
22
+ * operational store (§2.9) — never the caller's. */
23
+ export interface RuntimePorts {
24
+ storage: BoundStorage;
25
+ admin: AdminStore;
26
+ bus: EventBus;
27
+ queue: Queue;
28
+ kv: Kv;
29
+ /** User-provided model resolution (§3.3): models can live in any shape on
30
+ * the consumer side — the platform only ever sees `ResolvedModel`. */
31
+ resolveModel(modelName: string): ResolvedModel;
32
+ config: AgentConfig;
33
+ }
34
+ export interface RuntimeOptions {
35
+ storage: Storage;
36
+ /** Where operational history goes (§2.9). Omitted, it is chosen from the
37
+ * environment: Postgres when AGENTIC_KIT_ADMIN_DATABASE_URL is set, SQLite
38
+ * on disk otherwise. Pass one to decide for yourself. */
39
+ admin?: AdminStore;
40
+ bus: EventBus;
41
+ queue: Queue;
42
+ kv: Kv;
43
+ /** Models can come in any shape — config files, a database, provider SDKs.
44
+ * The platform only ever sees the resolved `ResolvedModel`. */
45
+ resolveModel(modelName: string): ResolvedModel;
46
+ config?: Partial<AgentConfig>;
47
+ }
48
+ export interface RunInput {
49
+ /** Omit to create a fresh thread first (threads.create, §3.2) */
50
+ threadId?: string;
51
+ prompt: string;
52
+ /** Carried through this whole run (§2.10): every storage call, every tool,
53
+ * every nested run. Persisted on the dispatch, so a worker picking the job
54
+ * up later — or resuming it after an approval — sees the same thing. The
55
+ * platform never reads it. */
56
+ state?: AgentRunState;
57
+ /** Edit + resend (§5.1): replace this user message with `prompt` and drop
58
+ * every message after it, then answer again from that point. Must name a
59
+ * message in this thread whose role is 'user'. Omit for a normal turn. */
60
+ editMessageId?: string;
61
+ /** Registry key or provider instance reference — resolved via
62
+ * `AgentCore.resolveModel`. Overrides the spec default. */
63
+ model?: string;
64
+ /** Max cumulative tokens (input + output) for this run — overrides
65
+ * spec.tokenBudget / config (§2.1 safety cap). Flows to the worker
66
+ * via RunJob.tokenBudget. */
67
+ tokenBudget?: number;
68
+ /** Additional provider-specific options, passed through to the provider
69
+ * from the AI SDK (§3.1). Merged over the spec default: the execute
70
+ * input wins per provider namespace. */
71
+ providerOptions?: ProviderOptions;
72
+ }
73
+ export interface RunResult {
74
+ accepted: boolean;
75
+ threadId: string;
76
+ /** This run's id (§2.1) — the same one carried by the enqueued job. An
77
+ * in-process worker must pass it back, or its dispatch has no identity. */
78
+ runId?: string;
79
+ state?: ExecutionState;
80
+ error?: string;
81
+ }
82
+ export interface StopResult {
83
+ accepted: boolean;
84
+ error?: string;
85
+ }
86
+ export interface DeleteThreadResult {
87
+ accepted: boolean;
88
+ error?: string;
89
+ }
90
+ export interface RespondInput {
91
+ threadId: string;
92
+ toolCallId: string;
93
+ approved: boolean;
94
+ payload?: unknown;
95
+ /** The run state (§2.10) for the storage calls answering makes. The RESUMED
96
+ * run rebuilds its own state from the park's ticket — this is only for the
97
+ * reads and writes `respond` itself performs. */
98
+ state?: AgentRunState;
99
+ }
100
+ export interface RespondResult {
101
+ delivered: boolean;
102
+ error?: string;
103
+ }
104
+ /** What a thread has spent, and how full its context is (§2.6, §4). */
105
+ export interface ThreadUsage {
106
+ /** Every run segment's tokens, summed. */
107
+ tokens: UsageTotals;
108
+ /** What the next run's prompt would carry before compaction. */
109
+ context: ContextUsage;
110
+ /** The model the budget was measured against. */
111
+ model: string;
112
+ }
113
+ /** Durable state used to hydrate a client before it starts live event replay. */
114
+ export interface ThreadSnapshot {
115
+ thread: ThreadDTO;
116
+ messages: MessageDTO[];
117
+ /** Nested runs on this thread (§2.7) — name, depth and final state, so a
118
+ * reconnecting client rebuilds its subagent panel without depending on
119
+ * events that only replay while a run is unfinished. */
120
+ runs: RunRecord[];
121
+ /** Cursor for starting live replay without duplicating snapshot state. */
122
+ lastEventSeq: number;
123
+ /** Only the unfinished run's events, used to restore transient activity. */
124
+ activeEvents: AgentEvent[];
125
+ }
126
+ /** Everything streamText accepts except the platform-owned keys (§3.1).
127
+ * `onChunk` / `onFinish` ARE allowed — the platform chains them (§4). */
128
+ export type StreamTextAgentSpec = {
129
+ /** Unique handle key — the queue dispatch key (§5). */
130
+ name: string;
131
+ /** Registry key for this agent's model — resolved via
132
+ * `AgentCore.resolveModel` (instance + contextWindow). */
133
+ model?: string;
134
+ /** Opt-in subagent delegation (§2.7). */
135
+ subagents?: boolean | SubagentsConfig;
136
+ /** Default per-run token budget (input + output). Per-run
137
+ * `input.tokenBudget` wins; `undefined` = unbounded apart from `maxSteps`. */
138
+ tokenBudget?: number;
139
+ /** Additional provider-specific options, passed through to the provider
140
+ * from the AI SDK. Per-provider namespace; the execute input wins. */
141
+ providerOptions?: ProviderOptions;
142
+ } & Omit<Parameters<typeof import('ai').streamText>[0], 'model' | 'messages' | 'prompt' | 'system' | 'abortSignal' | 'maxSteps' | 'onStepFinish' | 'onError'> & {
143
+ /** `system` is allowed here (static persona); per-run system is not. */
144
+ system?: string;
145
+ tools?: ToolSet;
146
+ onChunk?: (para: any) => void | Promise<void>;
147
+ onFinish?: (finishParams: any) => void | Promise<void>;
148
+ };
149
+ export type GenerateTextAgentSpec = {
150
+ /** Unique handle key — the queue dispatch key (§5). */
151
+ name: string;
152
+ model?: string;
153
+ subagents?: boolean | SubagentsConfig;
154
+ tokenBudget?: number;
155
+ providerOptions?: ProviderOptions;
156
+ } & Omit<Parameters<typeof import('ai').generateText>[0], 'model' | 'messages' | 'prompt' | 'abortSignal' | 'onFinish' | 'onStepFinish'> & {
157
+ tools?: ToolSet;
158
+ onFinish?: (finishParams: any) => void | Promise<void>;
159
+ };
160
+ /** An executor bound to a generation flavor and to the user's generation
161
+ * arguments (§3). Returned by the `create*Agent` factories. */
162
+ export interface AgentHandle {
163
+ readonly name: string;
164
+ readonly kind: AgentKind;
165
+ /** Worker-side only (§5.6). Throws on failure — see executeWithPolicy.
166
+ * Returns 'lock-conflict' when another worker owns the thread's run lock
167
+ * (nothing was executed) and 'stale' when a newer run has replaced this
168
+ * one (§2.1, §2.8). */
169
+ execute(input: ExecuteInput): Promise<ExecuteOutcome>;
170
+ /** execute + §2.8 failure policy: redrive < maxAttempts, else finalize FAILED */
171
+ executeWithPolicy(input: ExecuteInput, policy?: {
172
+ maxAttempts?: number;
173
+ }): Promise<void>;
174
+ /** Persist user message → state RUNNING → enqueue a job dispatched back to
175
+ * THIS handle (the job carries `agent: this.name` and `tokenBudget`). */
176
+ run(input: RunInput): Promise<RunResult>;
177
+ /** Platform stop (§2.1) — works regardless of which agent's run is active. */
178
+ stop(threadId: string, state?: AgentRunState): Promise<StopResult>;
179
+ }
180
+ export interface AgentCore {
181
+ /** Resolve a registry key to the stable identity and provider instance used
182
+ * by execution, compaction, usage attribution, and persisted run metadata. */
183
+ resolveModel(modelName: string): ResolvedModel;
184
+ /** Most recent first — thread pickers / sidebars. Takes the run state
185
+ * (§2.10) so a tenant-scoped Storage can filter; a read has no dispatch
186
+ * ticket to carry it on. */
187
+ listThreads(state?: AgentRunState): Promise<ThreadDTO[]>;
188
+ /** One call for UIs / history routes: thread + messages + recent events. */
189
+ getThreadSnapshot(threadId: string, state?: AgentRunState): Promise<ThreadSnapshot | null>;
190
+ /** Tokens spent so far and the §2.6 context load. Null when the thread is
191
+ * gone. Kept out of the snapshot so hydration stays one cheap read. */
192
+ getThreadUsage(threadId: string, state?: AgentRunState): Promise<ThreadUsage | null>;
193
+ /** Delete a thread and everything that follows it — messages, events,
194
+ * usage rows, subagent runs, and the thread's hot kv keys (§3.2).
195
+ * Refused while a run is active; stop() first. */
196
+ deleteThread(threadId: string, state?: AgentRunState): Promise<DeleteThreadResult>;
197
+ hitl: {
198
+ respond(input: RespondInput): Promise<RespondResult>;
199
+ reclaimIfOrphaned(threadId: string, state?: AgentRunState): Promise<boolean>;
200
+ };
201
+ events: {
202
+ since(threadId: string, sinceSeq: number, state?: AgentRunState): Promise<AgentEvent[]>;
203
+ subscribe(threadId: string, handler: (event: AgentEvent) => void): Promise<() => void>;
204
+ /** Replay then live, as one sequence, with the cursor discipline already
205
+ * applied (§2.2): subscribe before replaying, never emit at or below the
206
+ * cursor, forward a seq-0 notice without moving it.
207
+ *
208
+ * Framework-neutral — an async iterable is something Express, Nest, Hono,
209
+ * Next or a plain worker can each consume in their own way. Pass a signal,
210
+ * or the subscription outlives the client. */
211
+ follow(threadId: string, options?: FollowOptions & {
212
+ state?: AgentRunState;
213
+ }): AsyncGenerator<AgentEvent>;
214
+ /** `follow`, encoded as Server-Sent Events. Returns the stream and the
215
+ * headers rather than a Response, because half the ecosystem has none. */
216
+ sse(threadId: string, options?: SseOptions & {
217
+ state?: AgentRunState;
218
+ }): SseStream;
219
+ };
220
+ /** Agent factories — see §4. Each call registers a handle under `spec.name`. */
221
+ createStreamTextAgent(spec: StreamTextAgentSpec): AgentHandle;
222
+ createGenerateTextAgent(spec: GenerateTextAgentSpec): AgentHandle;
223
+ /** Worker-side resolution of a registered handle from the queue job. */
224
+ getAgent(name: string): AgentHandle | null;
225
+ /** Operational reads (§2.9). The platform records what runs did; building a
226
+ * view over it is the caller's business. Everything here comes from the
227
+ * platform's OWN store — it never reads the caller's database. */
228
+ admin: {
229
+ overview(range?: {
230
+ since?: Date;
231
+ }): Promise<AdminOverview>;
232
+ listRuns(filter?: RunFilter): Promise<RunRecord[]>;
233
+ stats(range?: {
234
+ since?: Date;
235
+ until?: Date;
236
+ }): Promise<RunStats>;
237
+ getRun(runId: string): Promise<RunDetail | null>;
238
+ listRunsByThread(threadId: string): Promise<RunRecord[]>;
239
+ listSteps(runId: string): Promise<StepRecord[]>;
240
+ /** Threads with their runs rolled up — the top level of an operational
241
+ * view, since a thread is what a person recognises (§2.9). */
242
+ listThreads(filter?: {
243
+ state?: ExecutionState[];
244
+ since?: Date;
245
+ limit?: number;
246
+ }): Promise<ThreadSummary[]>;
247
+ getThread(threadId: string): Promise<ThreadDetail | null>;
248
+ };
249
+ /** The queue dispatch side of the platform (§2.8): resolves the handle,
250
+ * applies the failure policy, and is idempotent under at-least-once
251
+ * delivery (the per-thread run lock, §3.4). The HTTP layer only verifies
252
+ * signatures, parses JSON, and calls this. */
253
+ worker: {
254
+ handleJob(job: RunJob): Promise<{
255
+ accepted: boolean;
256
+ reason?: string;
257
+ }>;
258
+ };
259
+ }
260
+ //# sourceMappingURL=runtime.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../src/ports/runtime.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;AAClC,OAAO,KAAK,EACV,UAAU,EACV,WAAW,EACX,SAAS,EACT,YAAY,EACZ,cAAc,EACd,UAAU,EACV,eAAe,EACf,aAAa,EACb,MAAM,EACN,SAAS,EACT,eAAe,EACf,SAAS,EACT,WAAW,EACZ,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACpE,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACpE,OAAO,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAE9E,YAAY,EAAE,UAAU,EAAE,aAAa,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACnF,YAAY,EAAE,aAAa,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACpF,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACtE,OAAO,KAAK,EACV,aAAa,EACb,SAAS,EACT,QAAQ,EACR,YAAY,EACZ,aAAa,EACd,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EACV,aAAa,EACb,SAAS,EACT,QAAQ,GACT,MAAM,kBAAkB,CAAC;AAE1B,YAAY,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAGtE,YAAY,EAAE,SAAS,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAE3G;;;;;qDAKqD;AACrD,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,YAAY,CAAC;IACtB,KAAK,EAAE,UAAU,CAAC;IAClB,GAAG,EAAE,QAAQ,CAAC;IACd,KAAK,EAAE,KAAK,CAAC;IACb,EAAE,EAAE,EAAE,CAAC;IACP;2EACuE;IACvE,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,aAAa,CAAC;IAC/C,MAAM,EAAE,WAAW,CAAC;CACrB;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB;;8DAE0D;IAC1D,KAAK,CAAC,EAAE,UAAU,CAAC;IACnB,GAAG,EAAE,QAAQ,CAAC;IACd,KAAK,EAAE,KAAK,CAAC;IACb,EAAE,EAAE,EAAE,CAAC;IACP;oEACgE;IAChE,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,aAAa,CAAC;IAC/C,MAAM,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC;CAC/B;AAED,MAAM,WAAW,QAAQ;IACvB,iEAAiE;IACjE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf;;;mCAG+B;IAC/B,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB;;+EAE2E;IAC3E,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;gEAC4D;IAC5D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;kCAE8B;IAC9B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;6CAEyC;IACzC,eAAe,CAAC,EAAE,eAAe,CAAC;CACnC;AAED,MAAM,WAAW,SAAS;IACxB,QAAQ,EAAE,OAAO,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB;gFAC4E;IAC5E,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,cAAc,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,OAAO,CAAC;IAClB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;sDAEkD;IAClD,KAAK,CAAC,EAAE,aAAa,CAAC;CACvB;AAED,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,OAAO,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,uEAAuE;AACvE,MAAM,WAAW,WAAW;IAC1B,0CAA0C;IAC1C,MAAM,EAAE,WAAW,CAAC;IACpB,gEAAgE;IAChE,OAAO,EAAE,YAAY,CAAC;IACtB,iDAAiD;IACjD,KAAK,EAAE,MAAM,CAAC;CACf;AAED,iFAAiF;AACjF,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,SAAS,CAAC;IAClB,QAAQ,EAAE,UAAU,EAAE,CAAC;IACvB;;6DAEyD;IACzD,IAAI,EAAE,SAAS,EAAE,CAAC;IAClB,0EAA0E;IAC1E,YAAY,EAAE,MAAM,CAAC;IACrB,4EAA4E;IAC5E,YAAY,EAAE,UAAU,EAAE,CAAC;CAC5B;AAED;0EAC0E;AAC1E,MAAM,MAAM,mBAAmB,GAAG;IAChC,uDAAuD;IACvD,IAAI,EAAE,MAAM,CAAC;IACb;+DAC2D;IAC3D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,yCAAyC;IACzC,SAAS,CAAC,EAAE,OAAO,GAAG,eAAe,CAAC;IACtC;mFAC+E;IAC/E,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;2EACuE;IACvE,eAAe,CAAC,EAAE,eAAe,CAAC;CACnC,GAAG,IAAI,CAAC,UAAU,CAAC,cAAc,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,EAClD,OAAO,GAAG,UAAU,GAAG,QAAQ,GAAG,QAAQ,GAAG,aAAa,GACxD,UAAU,GAAG,cAAc,GAAG,SAAS,CAAC,GAAG;IAC/C,wEAAwE;IACxE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,GAAG,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9C,QAAQ,CAAC,EAAE,CAAC,YAAY,EAAE,GAAG,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACxD,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IAClC,uDAAuD;IACvD,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,OAAO,GAAG,eAAe,CAAC;IACtC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,eAAe,CAAC,EAAE,eAAe,CAAC;CACnC,GAAG,IAAI,CAAC,UAAU,CAAC,cAAc,IAAI,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC,EACpD,OAAO,GAAG,UAAU,GAAG,QAAQ,GAAG,aAAa,GAAG,UAAU,GAAG,cAAc,CAAC,GAAG;IACnF,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,QAAQ,CAAC,EAAE,CAAC,YAAY,EAAE,GAAG,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACxD,CAAC;AAEF;gEACgE;AAChE,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IAEzB;;;4BAGwB;IACxB,OAAO,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;IAEtD,iFAAiF;IACjF,iBAAiB,CACf,KAAK,EAAE,YAAY,EACnB,MAAM,CAAC,EAAE;QAAE,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,GAChC,OAAO,CAAC,IAAI,CAAC,CAAC;IAEjB;8EAC0E;IAC1E,GAAG,CAAC,KAAK,EAAE,QAAQ,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;IAEzC,8EAA8E;IAC9E,IAAI,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;CACpE;AAED,MAAM,WAAW,SAAS;IACxB;mFAC+E;IAC/E,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,aAAa,CAAC;IAE/C;;iCAE6B;IAC7B,WAAW,CAAC,KAAK,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC;IAEzD,4EAA4E;IAC5E,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC;IAE3F;4EACwE;IACxE,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;IAErF;;uDAEmD;IACnD,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAAC;IAEnF,IAAI,EAAE;QACJ,OAAO,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;QACrD,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;KAC9E,CAAC;IAEF,MAAM,EAAE;QACN,KAAK,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC;QACxF,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,GAAG,OAAO,CAAC,MAAM,IAAI,CAAC,CAAC;QACvF;;;;;;uDAM+C;QAC/C,MAAM,CACJ,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,aAAa,GAAG;YAAE,KAAK,CAAC,EAAE,aAAa,CAAA;SAAE,GAClD,cAAc,CAAC,UAAU,CAAC,CAAC;QAC9B;mFAC2E;QAC3E,GAAG,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,UAAU,GAAG;YAAE,KAAK,CAAC,EAAE,aAAa,CAAA;SAAE,GAAG,SAAS,CAAC;KACpF,CAAC;IAEF,gFAAgF;IAChF,qBAAqB,CAAC,IAAI,EAAE,mBAAmB,GAAG,WAAW,CAAC;IAC9D,uBAAuB,CAAC,IAAI,EAAE,qBAAqB,GAAG,WAAW,CAAC;IAElE,wEAAwE;IACxE,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI,CAAC;IAE3C;;uEAEmE;IACnE,KAAK,EAAE;QACL,QAAQ,CAAC,KAAK,CAAC,EAAE;YAAE,KAAK,CAAC,EAAE,IAAI,CAAA;SAAE,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;QAC3D,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC;QACnD,KAAK,CAAC,KAAK,CAAC,EAAE;YAAE,KAAK,CAAC,EAAE,IAAI,CAAC;YAAC,KAAK,CAAC,EAAE,IAAI,CAAA;SAAE,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;QACjE,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CAAC;QACjD,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC;QACzD,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC;QAChD;uEAC+D;QAC/D,WAAW,CAAC,MAAM,CAAC,EAAE;YACnB,KAAK,CAAC,EAAE,cAAc,EAAE,CAAC;YACzB,KAAK,CAAC,EAAE,IAAI,CAAC;YACb,KAAK,CAAC,EAAE,MAAM,CAAC;SAChB,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC,CAAC;QAC7B,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAAC;KAC3D,CAAC;IAEF;;;mDAG+C;IAC/C,MAAM,EAAE;QACN,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;YAAE,QAAQ,EAAE,OAAO,CAAC;YAAC,MAAM,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;KACzE,CAAC;CACH"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=runtime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime.js","sourceRoot":"","sources":["../../src/ports/runtime.ts"],"names":[],"mappings":""}
@@ -0,0 +1,72 @@
1
+ import type { StorageContext } from '../core/state.js';
2
+ import type { AgentEvent, ExecutionState, MessageDTO, NewMessage, NewUsage, UsageTotals, ThreadDTO } from '../core/types.js';
3
+ /** Persistence port for a caller's OWN data (§3.2): threads, messages, events,
4
+ * usage. DTOs cross the boundary; ORM/entity types never leak into core.
5
+ * Implement it once for MongoDB, MySQL, DynamoDB — or use the shipped
6
+ * PrismaStorage reference adapter.
7
+ *
8
+ * Operational history — run records, timings, step markers — is NOT here.
9
+ * agentic-kit owns and stores that itself (§2.9); callers only read it back
10
+ * through `runtime.admin`.
11
+ *
12
+ * Every method receives the run's StorageContext as its last argument, so an
13
+ * implementation can scope a query to a tenant, stamp a row with who caused
14
+ * it, or route to a different database entirely (§2.10). */
15
+ export interface Storage {
16
+ threads: {
17
+ get(threadId: string, ctx: StorageContext): Promise<ThreadDTO | null>;
18
+ create(init: {
19
+ model?: string;
20
+ } | undefined, ctx: StorageContext): Promise<ThreadDTO>;
21
+ /** Most recent first — thread pickers / sidebars. */
22
+ list(ctx: StorageContext): Promise<ThreadDTO[]>;
23
+ setState(threadId: string, state: ExecutionState, ctx: StorageContext): Promise<void>;
24
+ /** Delete the thread AND everything that follows it: messages, events,
25
+ * usage rows, and subagent runs. Throws if the thread does not exist.
26
+ * The reference Prisma schema cascades via `onDelete: Cascade`. */
27
+ delete(threadId: string, ctx: StorageContext): Promise<void>;
28
+ /** Compare-and-set: returns true iff THIS caller performed the transition.
29
+ * Backs HITL reclamation + double-dispatch protection (§2.5, §2.8).
30
+ * Must be atomic — a single conditional UPDATE or equivalent. */
31
+ claimState(threadId: string, from: ExecutionState, to: ExecutionState, ctx: StorageContext): Promise<boolean>;
32
+ };
33
+ messages: {
34
+ append(threadId: string, message: NewMessage, ctx: StorageContext): Promise<MessageDTO>;
35
+ /** Oldest first. The scope decides WHOSE turns come back (§2.7):
36
+ * - `{ agentId: null }` — the main agent's stream. Compaction (§2.6) and
37
+ * the edit lookup (§5.1) must use this; unscoped, a subagent's turns
38
+ * leak into the parent's prompt and context isolation is gone.
39
+ * - `{ agentId: 'sub_1' }` — that nested run's own stream.
40
+ * - omitted — every row on the thread, for UI hydration (§2.2). */
41
+ list(threadId: string, opts: {
42
+ agentId?: string | null;
43
+ } | undefined, ctx: StorageContext): Promise<MessageDTO[]>;
44
+ /** Delete `messageId` and every message after it, in the same order
45
+ * `list` returns (§5.1 edit + resend). Returns how many rows went; 0 when
46
+ * the id is not in this thread.
47
+ *
48
+ * Dropping a suffix only leaves the history well-formed if it starts at a
49
+ * user turn — cutting from a tool result would strip it off the assistant
50
+ * tool-call that produced it, and a dangling call is a conversation no
51
+ * provider accepts. `run()` enforces that; adapters just delete. */
52
+ deleteFrom(threadId: string, messageId: string, ctx: StorageContext): Promise<number>;
53
+ };
54
+ events: {
55
+ append(threadId: string, event: AgentEvent, ctx: StorageContext): Promise<void>;
56
+ /** All events after the cursor, ascending by seq — SSE replay (§2.2) */
57
+ listSince(threadId: string, sinceSeq: number, ctx: StorageContext): Promise<AgentEvent[]>;
58
+ /** Most recent event of a type — the HITL pending check (§2.5) */
59
+ latest(threadId: string, type: string, ctx: StorageContext): Promise<AgentEvent | null>;
60
+ /** Every event of a type, ascending by seq. The open-approval set (§2.7)
61
+ * is derived from these; scanning `listSince` instead would drag every
62
+ * CHUNK on the thread through memory. */
63
+ listByType(threadId: string, type: string, ctx: StorageContext): Promise<AgentEvent[]>;
64
+ };
65
+ usage: {
66
+ record(threadId: string, usage: NewUsage, ctx: StorageContext): Promise<void>;
67
+ /** Every recorded segment for the thread, summed (§4). A thread with no
68
+ * usage rows yet returns zeroes, never null. */
69
+ total(threadId: string, ctx: StorageContext): Promise<UsageTotals>;
70
+ };
71
+ }
72
+ //# sourceMappingURL=storage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../../src/ports/storage.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,KAAK,EACV,UAAU,EACV,cAAc,EACd,UAAU,EACV,UAAU,EACV,QAAQ,EACR,WAAW,EACX,SAAS,EACV,MAAM,kBAAkB,CAAC;AAE1B;;;;;;;;;;;6DAW6D;AAC7D,MAAM,WAAW,OAAO;IACtB,OAAO,EAAE;QACP,GAAG,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CAAC;QACtE,MAAM,CAAC,IAAI,EAAE;YAAE,KAAK,CAAC,EAAE,MAAM,CAAA;SAAE,GAAG,SAAS,EAAE,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;QACtF,qDAAqD;QACrD,IAAI,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC;QAChD,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,cAAc,EAAE,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;QACtF;;4EAEoE;QACpE,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;QAC7D;;0EAEkE;QAClE,UAAU,CACR,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,cAAc,EACpB,EAAE,EAAE,cAAc,EAClB,GAAG,EAAE,cAAc,GAClB,OAAO,CAAC,OAAO,CAAC,CAAC;KACrB,CAAC;IACF,QAAQ,EAAE;QACR,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;QACxF;;;;;4EAKoE;QACpE,IAAI,CACF,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE;YAAE,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;SAAE,GAAG,SAAS,EAC7C,GAAG,EAAE,cAAc,GAClB,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC;QACzB;;;;;;;6EAOqE;QACrE,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;KACvF,CAAC;IACF,MAAM,EAAE;QACN,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,EAAE,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;QAChF,wEAAwE;QACxE,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC;QAC1F,kEAAkE;QAClE,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC;QACxF;;kDAE0C;QAC1C,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC;KACxF,CAAC;IACF,KAAK,EAAE;QACL,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;QAC9E;yDACiD;QACjD,KAAK,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;KACpE,CAAC;CACH"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=storage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storage.js","sourceRoot":"","sources":["../../src/ports/storage.ts"],"names":[],"mappings":""}
@@ -0,0 +1,5 @@
1
+ import type { AgentCore, RuntimeOptions } from './ports/runtime.js';
2
+ /** Bind the ports to the core behaviors (§3.3). This is the package's public
3
+ * entry point — the only place where anything is wired together. */
4
+ export declare function setupAgentCore(opts: RuntimeOptions): Promise<AgentCore>;
5
+ //# sourceMappingURL=runtime.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,SAAS,EAMT,cAAc,EAGf,MAAM,oBAAoB,CAAC;AAY5B;qEACqE;AACrE,wBAAsB,cAAc,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,SAAS,CAAC,CA6M7E"}
@@ -0,0 +1,177 @@
1
+ import { resolveConfig } from './core/types.js';
2
+ import { contextUsage } from './core/context.js';
3
+ import { createGenerateTextAgent, createStreamTextAgent } from './core/agent.js';
4
+ import * as adminReads from './core/admin.js';
5
+ import { bindStorage } from './core/state.js';
6
+ import { followEvents, toSseStream } from './core/follow.js';
7
+ import { openDefaultAdminStore } from './admin/default.js';
8
+ import { reclaimIfOrphaned } from './core/reclaim.js';
9
+ import { respond } from './core/hitl.js';
10
+ import { deleteThread } from './core/deleteThread.js';
11
+ /** Bind the ports to the core behaviors (§3.3). This is the package's public
12
+ * entry point — the only place where anything is wired together. */
13
+ export async function setupAgentCore(opts) {
14
+ // Operational history is the platform's own (§2.9). Nothing configured means
15
+ // SQLite on disk: history that survives a restart should be the default, not
16
+ // something you have to remember to switch on.
17
+ //
18
+ // Opened here, eagerly, which is why this function is async: a store that
19
+ // cannot be opened is a startup error you see immediately, rather than a
20
+ // surprise on the first run — and losing run history silently looks exactly
21
+ // like having no traffic.
22
+ const admin = opts.admin ?? (await openDefaultAdminStore());
23
+ const shared = {
24
+ admin,
25
+ bus: opts.bus,
26
+ queue: opts.queue,
27
+ kv: opts.kv,
28
+ resolveModel: (modelName) => opts.resolveModel(modelName),
29
+ config: resolveConfig(opts.config),
30
+ };
31
+ /** Ports for ONE run: the caller's storage with that run's state bound, so
32
+ * every query, insert and update their implementation makes can see it
33
+ * (§2.10). Called per entry point rather than once, because state belongs
34
+ * to a run and a runtime outlives many. */
35
+ const scope = (state = {}, runId) => ({
36
+ ...shared,
37
+ storage: bindStorage(opts.storage, { state, runId }),
38
+ });
39
+ // For reads that are not on behalf of any particular run.
40
+ const deps = scope();
41
+ // Handle registry — keyed by spec.name, resolved by the queue dispatch.
42
+ const registry = new Map();
43
+ // The first registered stream-text handle is the default for jobs that
44
+ // omit `agent` (§5).
45
+ let defaultAgent = null;
46
+ const register = (name, kind, spec) => {
47
+ const handle = kind === 'stream-text'
48
+ ? createStreamTextAgent(scope, spec)
49
+ : createGenerateTextAgent(scope, spec);
50
+ registry.set(name, handle);
51
+ return handle;
52
+ };
53
+ const core = {
54
+ resolveModel: (modelName) => deps.resolveModel(modelName),
55
+ // Reads take the run state too (§2.10). A run carries it on its ticket,
56
+ // but a read has no ticket to carry — so a tenant-scoped Storage would see
57
+ // an empty context here and either return nothing or, worse, everything.
58
+ listThreads: (state) => scope(state).storage.threads.list(),
59
+ deleteThread: (threadId, state) => deleteThread(scope(state), threadId),
60
+ getThreadSnapshot: async (threadId, state) => {
61
+ const deps = scope(state);
62
+ const thread = await deps.storage.threads.get(threadId);
63
+ if (!thread)
64
+ return null;
65
+ const messages = await deps.storage.messages.list(threadId, undefined);
66
+ const runs = await deps.admin.runs.listByThread(threadId);
67
+ const events = await deps.storage.events.listSince(threadId, -1);
68
+ const lastEventSeq = events.at(-1)?.seq ?? -1;
69
+ let activeEvents = [];
70
+ if (thread.state === 'RUNNING' || thread.state === 'WAITING_FOR_INPUT') {
71
+ let boundary = -1;
72
+ for (let index = events.length - 1; index >= 0; index -= 1) {
73
+ const event = events[index];
74
+ if (event.type === 'STATE_CHANGE' &&
75
+ event.payload?.state === 'RUNNING') {
76
+ boundary = index;
77
+ break;
78
+ }
79
+ }
80
+ const active = events.slice(Math.max(0, boundary));
81
+ // Everything up to the last committed step is ALREADY in `messages`
82
+ // (§2.2). Replaying those chunks too would render each finished step's
83
+ // text twice — once from the durable message, once from the stream
84
+ // that produced it. Only the in-flight step's chunks are missing from
85
+ // durable history, so only those are transient.
86
+ //
87
+ // Chunks alone: a park (INPUT_REQUIRED) is published DURING the step,
88
+ // before its messages commit, so slicing the whole window by this
89
+ // boundary would drop the very approval a reconnecting client needs.
90
+ const lastCommitted = active.reduce((seq, e) => (e.type === 'STEP_COMMITTED' ? e.seq : seq), -1);
91
+ const isStream = (type) => type === 'CHUNK' || type === 'SUBAGENT_CHUNK';
92
+ activeEvents = active.filter((e) => !(isStream(e.type) && e.seq !== 0 && e.seq <= lastCommitted));
93
+ }
94
+ return { thread, messages, runs, lastEventSeq, activeEvents };
95
+ },
96
+ admin: {
97
+ overview: (range) => adminReads.overview(deps, range),
98
+ listRuns: (filter) => adminReads.listRuns(deps, filter),
99
+ stats: (range) => adminReads.runStats(deps, range),
100
+ getRun: (runId) => adminReads.getRun(deps, runId),
101
+ listRunsByThread: (threadId) => deps.admin.runs.listByThread(threadId),
102
+ listSteps: (runId) => adminReads.listSteps(deps, runId),
103
+ listThreads: (filter) => adminReads.listThreads(deps, filter),
104
+ getThread: (threadId) => adminReads.getThread(deps, threadId),
105
+ },
106
+ getThreadUsage: async (threadId, state) => {
107
+ const deps = scope(state);
108
+ const thread = await deps.storage.threads.get(threadId);
109
+ if (!thread)
110
+ return null;
111
+ const [tokens, context] = await Promise.all([
112
+ deps.storage.usage.total(threadId),
113
+ contextUsage(deps, threadId, thread.model),
114
+ ]);
115
+ return { tokens, context, model: thread.model };
116
+ },
117
+ hitl: {
118
+ respond: (input) => {
119
+ // Scoped like the run it resumes: answering an approval reads and
120
+ // writes the caller's rows (§2.10).
121
+ const scoped = scope(input.state);
122
+ // Heal an orphaned wait first — if reclamation claims the thread, the
123
+ // response is rejected as late (§2.5)
124
+ return (async () => {
125
+ await reclaimIfOrphaned(scoped, input.threadId);
126
+ return respond(scoped, input);
127
+ })();
128
+ },
129
+ reclaimIfOrphaned: (threadId, state) => reclaimIfOrphaned(scope(state), threadId),
130
+ },
131
+ events: {
132
+ since: (threadId, sinceSeq, state) => scope(state).storage.events.listSince(threadId, sinceSeq),
133
+ subscribe: async (threadId, handler) => deps.bus.subscribe(threadId, handler),
134
+ // The replay-then-tail dance lives here rather than in every route
135
+ // handler: subscribe first, never emit at or below the cursor, and let a
136
+ // seq-0 notice through without moving it (§2.2).
137
+ follow: (threadId, options = {}) => followEvents(scope(options.state), threadId, options),
138
+ sse: (threadId, options = {}) => toSseStream(followEvents(scope(options.state), threadId, options), options),
139
+ },
140
+ createStreamTextAgent: (spec) => {
141
+ const handle = register(spec.name, 'stream-text', spec);
142
+ if (defaultAgent === null)
143
+ defaultAgent = spec.name;
144
+ return handle;
145
+ },
146
+ createGenerateTextAgent: (spec) => register(spec.name, 'generate-text', spec),
147
+ getAgent: (name) => registry.get(name) ?? null,
148
+ worker: {
149
+ handleJob: async (job) => {
150
+ // Missing `agent` → the default handle (first registered stream-text)
151
+ const agent = (job.agent ? registry.get(job.agent) : null) ??
152
+ (defaultAgent ? registry.get(defaultAgent) : null);
153
+ if (!agent)
154
+ return { accepted: false, reason: 'unknown-agent' };
155
+ // executeWithPolicy: run lock (idempotent under at-least-once
156
+ // delivery, §3.4) + §2.8 failure policy — redrive < maxAttempts,
157
+ // else finalize FAILED; a user stop is never retried.
158
+ await agent.executeWithPolicy({
159
+ threadId: job.threadId,
160
+ // The dispatch's identity (§2.1) — without it the worker cannot tell
161
+ // it has been replaced by a newer run, and a blocked job is dropped.
162
+ runId: job.runId,
163
+ // Carries the queue wait through to the run record (§2.9).
164
+ enqueuedAt: job.enqueuedAt,
165
+ // Rehydrated from the ticket: this worker never saw the caller (§2.10).
166
+ state: job.state,
167
+ model: job.model,
168
+ tokenBudget: job.tokenBudget,
169
+ providerOptions: job.providerOptions,
170
+ });
171
+ return { accepted: true };
172
+ },
173
+ },
174
+ };
175
+ return core;
176
+ }
177
+ //# sourceMappingURL=runtime.js.map