@nanoagent/kernel 0.0.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.
@@ -0,0 +1,407 @@
1
+ import { openai } from '@ai-sdk/openai';
2
+ import { Effect } from 'effect';
3
+ import { type LanguageModelResponseMetadata, type LanguageModelUsage, type ModelMessage, streamText, type TextStreamPart, type ToolSet } from 'ai';
4
+ import type { AssistantModelMessage, MaybePromiseLike, ToolCall, ToolModelMessage } from '@ai-sdk/provider-utils';
5
+ export type JsonPrimitive = string | number | boolean | null;
6
+ export type JsonLike = JsonPrimitive | {
7
+ readonly [key: string]: JsonLike;
8
+ } | readonly JsonLike[];
9
+ export type ReadonlyDeep<T> = T extends (...args: unknown[]) => unknown ? T : T extends readonly (infer ITEM)[] ? readonly ReadonlyDeep<ITEM>[] : T extends object ? {
10
+ readonly [KEY in keyof T]: ReadonlyDeep<T[KEY]>;
11
+ } : T;
12
+ export type AgentToolCall = ToolCall<string, unknown>;
13
+ export type ReadonlyAgentToolCall = ReadonlyDeep<AgentToolCall>;
14
+ export type AgentToolCallResponse = {
15
+ toolCallId: string;
16
+ toolName: string;
17
+ input: unknown;
18
+ output: unknown;
19
+ error?: never;
20
+ } | {
21
+ toolCallId: string;
22
+ toolName: string;
23
+ input: unknown;
24
+ error: unknown;
25
+ output?: never;
26
+ };
27
+ export type AgentResponse = LanguageModelResponseMetadata & {
28
+ messages: Array<AssistantModelMessage | ToolModelMessage>;
29
+ };
30
+ type DistributiveOmit<T, K extends PropertyKey> = T extends unknown ? Omit<T, K> : never;
31
+ export type AgentStreamTextOptions = DistributiveOmit<Parameters<typeof streamText<ToolSet>>[0], 'model' | 'tools' | 'abortSignal'>;
32
+ export type AgentModelArgs = AgentStreamTextOptions & {
33
+ model: string;
34
+ toolNames: string[];
35
+ };
36
+ export type AgentRawModelResult = ReturnType<typeof streamText>;
37
+ export type AgentModelResult = {
38
+ finishReason?: string;
39
+ response: AgentResponse;
40
+ totalUsage: LanguageModelUsage;
41
+ text?: string;
42
+ reasoning?: Awaited<AgentRawModelResult['reasoning']>;
43
+ reasoningText?: string;
44
+ sources?: Awaited<AgentRawModelResult['sources']>;
45
+ warnings?: Awaited<AgentRawModelResult['warnings']>;
46
+ providerMetadata?: Awaited<AgentRawModelResult['providerMetadata']>;
47
+ };
48
+ export type SerializedError = {
49
+ message: string;
50
+ name?: string;
51
+ stack?: string;
52
+ };
53
+ export type AgentCompletionSource = 'caller' | 'model_done' | 'max_turns';
54
+ export type AgentPhase = 'run_started' | 'turn_started' | 'turn_prepared' | 'model_started' | 'model_completed' | 'tool_calls_started' | 'tool_call_started' | 'tool_call_completed' | 'tool_calls_completed' | 'turn_completed';
55
+ export type AgentRunStatus = {
56
+ type: 'running';
57
+ phase: AgentPhase;
58
+ } | {
59
+ type: 'paused';
60
+ phase: AgentPhase;
61
+ reason?: string;
62
+ metadata?: JsonLike;
63
+ createdAt: string;
64
+ } | {
65
+ type: 'completed';
66
+ source: AgentCompletionSource;
67
+ reason?: string;
68
+ metadata?: JsonLike;
69
+ createdAt: string;
70
+ } | {
71
+ type: 'failed';
72
+ phase: AgentPhase;
73
+ error: SerializedError;
74
+ createdAt: string;
75
+ };
76
+ export type ToolCallsSnapshot = {
77
+ pending: AgentToolCall[];
78
+ inFlight: AgentToolCall[];
79
+ completed: AgentToolCallResponse[];
80
+ };
81
+ export type Turn = {
82
+ turnId: string;
83
+ turn: number;
84
+ modelArgs?: AgentModelArgs;
85
+ modelResult?: AgentModelResult;
86
+ toolCalls: ToolCallsSnapshot;
87
+ };
88
+ export type AgentPause = {
89
+ type: 'pause';
90
+ reason?: string;
91
+ metadata?: JsonLike;
92
+ };
93
+ export type AgentFinish = {
94
+ type: 'finish';
95
+ reason?: string;
96
+ metadata?: JsonLike;
97
+ };
98
+ export type AgentContinue = {
99
+ type: 'continue';
100
+ };
101
+ export type AgentControl = AgentPause | AgentFinish | AgentContinue;
102
+ export type AgentRunState<CONTEXT extends JsonLike> = {
103
+ runId: string;
104
+ revision: number;
105
+ status: AgentRunStatus;
106
+ context: CONTEXT;
107
+ turns: Turn[];
108
+ currentTurn?: Turn;
109
+ updatedAt: string;
110
+ };
111
+ export type AgentPhaseEvent = {
112
+ type: 'run_started';
113
+ runId: string;
114
+ revision: number;
115
+ createdAt: string;
116
+ } | {
117
+ type: 'turn_started' | 'turn_prepared' | 'model_started' | 'tool_calls_started' | 'tool_call_started' | 'tool_calls_completed';
118
+ runId: string;
119
+ revision: number;
120
+ createdAt: string;
121
+ turn: Turn;
122
+ } | {
123
+ type: 'pause';
124
+ runId: string;
125
+ revision: number;
126
+ createdAt: string;
127
+ phase: AgentPhase;
128
+ turn?: Turn;
129
+ reason?: string;
130
+ metadata?: JsonLike;
131
+ } | {
132
+ type: 'model_restarted';
133
+ runId: string;
134
+ createdAt: string;
135
+ turn: Turn;
136
+ } | {
137
+ type: 'model_completed';
138
+ runId: string;
139
+ revision: number;
140
+ createdAt: string;
141
+ duration: number;
142
+ args: AgentModelArgs;
143
+ result: AgentModelResult;
144
+ turn: Turn;
145
+ } | {
146
+ type: 'tool_call_completed';
147
+ runId: string;
148
+ revision: number;
149
+ createdAt: string;
150
+ duration: number;
151
+ turn: Turn;
152
+ toolCallId: string;
153
+ toolName: string;
154
+ input: unknown;
155
+ output?: unknown;
156
+ error?: unknown;
157
+ } | {
158
+ type: 'turn_completed';
159
+ runId: string;
160
+ revision: number;
161
+ createdAt: string;
162
+ duration: number;
163
+ turn: Turn;
164
+ } | {
165
+ type: 'run_completed';
166
+ runId: string;
167
+ revision: number;
168
+ createdAt: string;
169
+ duration: number;
170
+ turns: Turn[];
171
+ source: AgentCompletionSource;
172
+ reason?: string;
173
+ metadata?: JsonLike;
174
+ } | {
175
+ type: 'run_failed';
176
+ runId: string;
177
+ revision: number;
178
+ createdAt: string;
179
+ phase: AgentPhase;
180
+ error: SerializedError;
181
+ };
182
+ export type AgentStreamEvent = AgentPhaseEvent | {
183
+ type: 'stream_part';
184
+ runId: string;
185
+ turnId: string;
186
+ turn: number;
187
+ createdAt: string;
188
+ part: TextStreamPart<ToolSet>;
189
+ };
190
+ export type AgentSaveState<CONTEXT extends JsonLike> = (args: {
191
+ state: AgentRunState<CONTEXT>;
192
+ events: AgentPhaseEvent[];
193
+ }) => AgentEffectResult<void>;
194
+ export type AgentMiddlewareNext<INPUT, OUTPUT> = (input: INPUT) => Promise<OUTPUT>;
195
+ export type AgentMiddleware<INPUT, OUTPUT> = (args: {
196
+ input: INPUT;
197
+ next: AgentMiddlewareNext<INPUT, OUTPUT>;
198
+ }) => AgentEffectResult<OUTPUT>;
199
+ export type AgentEffectResult<A, E extends Error = Error> = MaybePromiseLike<A> | Effect.Effect<A, E, never>;
200
+ export type AgentHookResult<VALUE, CONTEXT extends JsonLike> = void | {
201
+ context?: CONTEXT;
202
+ value?: VALUE;
203
+ control?: AgentControl;
204
+ };
205
+ export type AgentVoidHookResult<CONTEXT extends JsonLike> = void | {
206
+ context?: CONTEXT;
207
+ control?: AgentControl;
208
+ };
209
+ export type AgentToolCallsStartedValue = readonly AgentToolCall[];
210
+ export type AgentToolCallStartedValue = AgentToolCall | {
211
+ type: 'skip';
212
+ result: AgentToolCallResponse;
213
+ };
214
+ export type AgentModelProviders = Record<string, (modelName: string) => ReturnType<typeof openai>>;
215
+ export type AgentTurnPreparedValue = AgentStreamTextOptions & {
216
+ model: string;
217
+ };
218
+ export type BaseHookArgs<CONTEXT extends JsonLike> = {
219
+ context: ReadonlyDeep<CONTEXT>;
220
+ state: ReadonlyDeep<AgentRunState<CONTEXT>>;
221
+ runId: string;
222
+ };
223
+ export type AgentRunStartedArgs<CONTEXT extends JsonLike> = BaseHookArgs<CONTEXT> & {
224
+ createdAt: string;
225
+ };
226
+ export type AgentTurnStartedArgs<CONTEXT extends JsonLike> = BaseHookArgs<CONTEXT> & {
227
+ createdAt: string;
228
+ turn: Turn;
229
+ };
230
+ export type AgentTurnPreparedArgs<CONTEXT extends JsonLike> = BaseHookArgs<CONTEXT> & {
231
+ createdAt: string;
232
+ turn: Turn;
233
+ };
234
+ export type AgentModelStartedArgs<CONTEXT extends JsonLike> = BaseHookArgs<CONTEXT> & {
235
+ args: AgentModelArgs;
236
+ createdAt: string;
237
+ turn: Turn;
238
+ };
239
+ export type AgentModelCompletedArgs<CONTEXT extends JsonLike> = BaseHookArgs<CONTEXT> & {
240
+ args: AgentModelArgs;
241
+ createdAt: string;
242
+ duration: number;
243
+ result: AgentModelResult;
244
+ /**
245
+ * Un-normalized Vercel AI SDK streamText return. Use to extract
246
+ * SDK-shaped fields (reasoning, sources, steps, files, warnings) that
247
+ * are not part of the canonical AgentModelResult, then stash extracted
248
+ * values in context. Not cloned, not deep-frozen — do not mutate.
249
+ */
250
+ rawResult: AgentRawModelResult;
251
+ turn: Turn;
252
+ };
253
+ export type AgentCallModelArgs<CONTEXT extends JsonLike> = BaseHookArgs<CONTEXT> & {
254
+ args: AgentModelArgs;
255
+ createdAt: string;
256
+ turn: Turn;
257
+ };
258
+ export type AgentCallModelResult = {
259
+ args: AgentModelArgs;
260
+ duration: number;
261
+ pendingToolCalls: AgentToolCall[];
262
+ rawResult: AgentRawModelResult;
263
+ result: AgentModelResult;
264
+ };
265
+ export type AgentStreamUpdateArgs<CONTEXT extends JsonLike> = BaseHookArgs<CONTEXT> & {
266
+ createdAt: string;
267
+ part: TextStreamPart<ToolSet>;
268
+ turn: Turn;
269
+ };
270
+ export type AgentToolCallsStartedArgs<CONTEXT extends JsonLike> = BaseHookArgs<CONTEXT> & {
271
+ createdAt: string;
272
+ result: AgentModelResult;
273
+ toolCalls: readonly ReadonlyAgentToolCall[];
274
+ turn: Turn;
275
+ };
276
+ export type AgentToolCallStartedArgs<CONTEXT extends JsonLike> = BaseHookArgs<CONTEXT> & {
277
+ createdAt: string;
278
+ toolCall: ReadonlyAgentToolCall;
279
+ toolCallId: string;
280
+ toolName: string;
281
+ input: unknown;
282
+ turn: Turn;
283
+ };
284
+ export type AgentToolCallCompletedArgs<CONTEXT extends JsonLike> = BaseHookArgs<CONTEXT> & {
285
+ createdAt: string;
286
+ duration: number;
287
+ toolCallId: string;
288
+ toolName: string;
289
+ input: unknown;
290
+ turn: Turn;
291
+ } & ({
292
+ output: unknown;
293
+ error?: never;
294
+ } | {
295
+ error: unknown;
296
+ output?: never;
297
+ });
298
+ export type AgentCallToolArgs<CONTEXT extends JsonLike> = {
299
+ context: CONTEXT;
300
+ messages: ModelMessage[];
301
+ signal?: AbortSignal;
302
+ toolCall: AgentToolCall;
303
+ tools: ToolSet;
304
+ };
305
+ export type AgentToolCallsCompletedArgs<CONTEXT extends JsonLike> = BaseHookArgs<CONTEXT> & {
306
+ createdAt: string;
307
+ result: AgentModelResult;
308
+ toolCalls: AgentToolCallResponse[];
309
+ turn: Turn;
310
+ };
311
+ export type AgentTurnCompletedArgs<CONTEXT extends JsonLike> = BaseHookArgs<CONTEXT> & {
312
+ createdAt: string;
313
+ duration: number;
314
+ turn: Turn;
315
+ };
316
+ export type AgentRunCompletedArgs<CONTEXT extends JsonLike> = BaseHookArgs<CONTEXT> & {
317
+ createdAt: string;
318
+ duration: number;
319
+ turns: Turn[];
320
+ };
321
+ export type AgentStreamPartEvent = Extract<AgentStreamEvent, {
322
+ type: 'stream_part';
323
+ }>;
324
+ export type AgentMiddlewareMap<CONTEXT extends JsonLike> = {
325
+ callModel?: Array<AgentMiddleware<AgentCallModelArgs<CONTEXT>, AgentCallModelResult>>;
326
+ callTool?: Array<AgentMiddleware<AgentCallToolArgs<CONTEXT>, AgentToolCallResponse>>;
327
+ };
328
+ export type AgentRunFailedArgs<CONTEXT extends JsonLike> = BaseHookArgs<CONTEXT> & {
329
+ createdAt: string;
330
+ error: unknown;
331
+ };
332
+ export type AgentPauseArgs<CONTEXT extends JsonLike> = BaseHookArgs<CONTEXT> & {
333
+ createdAt: string;
334
+ phase: AgentPhase;
335
+ turn?: Turn;
336
+ reason?: string;
337
+ metadata?: JsonLike;
338
+ };
339
+ export type AgentModelRestartedArgs<CONTEXT extends JsonLike> = BaseHookArgs<CONTEXT> & {
340
+ createdAt: string;
341
+ turn: Turn;
342
+ };
343
+ export type AgentRuntime<CONTEXT extends JsonLike> = {
344
+ state: AgentRunState<CONTEXT> | {
345
+ context: CONTEXT;
346
+ runId?: string;
347
+ };
348
+ tools?: ToolSet;
349
+ modelProviders?: AgentModelProviders;
350
+ };
351
+ export type AgentHooks<CONTEXT extends JsonLike> = {
352
+ onRunStarted?: (args: AgentRunStartedArgs<CONTEXT>) => AgentEffectResult<AgentVoidHookResult<CONTEXT>>;
353
+ onTurnStarted?: (args: AgentTurnStartedArgs<CONTEXT>) => AgentEffectResult<AgentVoidHookResult<CONTEXT>>;
354
+ /**
355
+ * Return exact model input for this turn.
356
+ *
357
+ * This is the client's message assembly boundary: load transcript, summaries,
358
+ * memories, retrieved context, or hidden system notes, then choose the exact
359
+ * messages sent to the model for this turn.
360
+ *
361
+ * Core does not append assistant/tool messages to future turns. Completed
362
+ * output is stored in state.turns, and caller code must include any prior
363
+ * turn's response.messages or tool results in the next messages array.
364
+ */
365
+ onTurnPrepared: (args: AgentTurnPreparedArgs<CONTEXT>) => AgentEffectResult<AgentHookResult<AgentTurnPreparedValue, CONTEXT>>;
366
+ onModelStarted?: (args: AgentModelStartedArgs<CONTEXT>) => AgentEffectResult<AgentVoidHookResult<CONTEXT>>;
367
+ /**
368
+ * Observation hook for resumed model phase. Fires after the run has
369
+ * committed back to the model_started phase on resume, before the
370
+ * model_restarted event yields. Void — cannot change run state.
371
+ */
372
+ onModelRestarted?: (args: AgentModelRestartedArgs<CONTEXT>) => AgentEffectResult<void>;
373
+ /**
374
+ * Receives the built AgentModelResult plus rawResult (the un-normalized
375
+ * Vercel AI SDK streamText return). Extract SDK-shaped fields from rawResult
376
+ * here and stash them in context for later hooks.
377
+ */
378
+ onModelCompleted?: (args: AgentModelCompletedArgs<CONTEXT>) => AgentEffectResult<AgentVoidHookResult<CONTEXT>>;
379
+ /**
380
+ * Observation hook for pause. Fires after the paused snapshot is committed,
381
+ * before the pause event yields. Void — cannot change run state.
382
+ */
383
+ onPause?: (args: AgentPauseArgs<CONTEXT>) => AgentEffectResult<void>;
384
+ onStreamUpdate?: (args: AgentStreamUpdateArgs<CONTEXT>) => AgentEffectResult<void>;
385
+ onToolCallsStarted?: (args: AgentToolCallsStartedArgs<CONTEXT>) => AgentEffectResult<AgentHookResult<AgentToolCallsStartedValue, CONTEXT>>;
386
+ onToolCallStarted?: (args: AgentToolCallStartedArgs<CONTEXT>) => AgentEffectResult<AgentHookResult<AgentToolCallStartedValue, CONTEXT>>;
387
+ onToolCallCompleted?: (args: AgentToolCallCompletedArgs<CONTEXT>) => AgentEffectResult<AgentVoidHookResult<CONTEXT>>;
388
+ onToolCallsCompleted?: (args: AgentToolCallsCompletedArgs<CONTEXT>) => AgentEffectResult<AgentVoidHookResult<CONTEXT>>;
389
+ /**
390
+ * Good place to update caller-owned conversation memory from the completed
391
+ * turn's modelResult.response and toolCalls.completed before next
392
+ * onTurnPrepared call.
393
+ */
394
+ onTurnCompleted?: (args: AgentTurnCompletedArgs<CONTEXT>) => AgentEffectResult<AgentVoidHookResult<CONTEXT>>;
395
+ onRunCompleted?: (args: AgentRunCompletedArgs<CONTEXT>) => AgentEffectResult<AgentVoidHookResult<CONTEXT>>;
396
+ onRunFailed?: (args: AgentRunFailedArgs<CONTEXT>) => AgentEffectResult<AgentVoidHookResult<CONTEXT>>;
397
+ };
398
+ export type RunAgentOptions<CONTEXT extends JsonLike> = AgentRuntime<CONTEXT> & {
399
+ maxTurns: number;
400
+ hooks: AgentHooks<CONTEXT>;
401
+ saveState?: AgentSaveState<CONTEXT>;
402
+ middleware?: AgentMiddlewareMap<CONTEXT>;
403
+ signal?: AbortSignal;
404
+ };
405
+ type AgentEventGenerator = AsyncGenerator<AgentStreamEvent, void, void>;
406
+ export declare function runAgent<CONTEXT extends JsonLike>(options: RunAgentOptions<CONTEXT>): AgentEventGenerator;
407
+ export {};