@cuylabs/agent-core 0.3.0 → 0.4.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.
- package/README.md +162 -36
- package/dist/{index-QR704uRr.d.ts → index-BlSTfS-W.d.ts} +4 -6
- package/dist/index.d.ts +2432 -1037
- package/dist/index.js +1571 -61
- package/dist/tool/index.d.ts +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,211 +1,10 @@
|
|
|
1
1
|
import * as ai from 'ai';
|
|
2
2
|
import { LanguageModel, Tool, StreamTextResult, ToolSet, Output, ModelMessage } from 'ai';
|
|
3
|
-
import { T as ToolHost, a as Tool$1, F as FileOperationMeta,
|
|
4
|
-
export { C as CompatibleSchema, D as DirEntry, E as ExecOptions,
|
|
3
|
+
import { T as ToolHost, a as ToolContext, b as Tool$1, F as FileOperationMeta, c as TurnTrackerContext } from './index-BlSTfS-W.js';
|
|
4
|
+
export { C as CompatibleSchema, D as DirEntry, E as ExecOptions, d as ExecResult, e as FileStat, I as InferSchemaOutput, M as MAX_BYTES, f as MAX_LINES, g as TRUNCATE_DIR, h as TRUNCATE_GLOB, i as ToolMetadata, j as ToolRegistry, k as ToolResult, l as ToolSpec, m as TruncateResult, n as defaultRegistry, o as defineTool, p as formatSize, t as truncateOutput } from './index-BlSTfS-W.js';
|
|
5
5
|
import { ProviderOptions } from '@ai-sdk/provider-utils';
|
|
6
6
|
import 'zod';
|
|
7
7
|
|
|
8
|
-
/**
|
|
9
|
-
* Storage Types
|
|
10
|
-
*
|
|
11
|
-
* Core types for session storage with tree structure support.
|
|
12
|
-
* Designed for append-only event sourcing with branching.
|
|
13
|
-
*/
|
|
14
|
-
/**
|
|
15
|
-
* Base interface for all session entries
|
|
16
|
-
* Supports tree structure via id/parentId
|
|
17
|
-
*/
|
|
18
|
-
interface EntryBase {
|
|
19
|
-
/** Unique entry ID (8-char hex) */
|
|
20
|
-
id: string;
|
|
21
|
-
/** Parent entry ID (null for first entry after header) */
|
|
22
|
-
parentId: string | null;
|
|
23
|
-
/** ISO timestamp */
|
|
24
|
-
timestamp: string;
|
|
25
|
-
}
|
|
26
|
-
/**
|
|
27
|
-
* Session header - always first entry in file
|
|
28
|
-
*/
|
|
29
|
-
interface SessionHeader {
|
|
30
|
-
type: "header";
|
|
31
|
-
/** Storage format version */
|
|
32
|
-
version: number;
|
|
33
|
-
/** Session ID */
|
|
34
|
-
id: string;
|
|
35
|
-
/** Working directory */
|
|
36
|
-
cwd: string;
|
|
37
|
-
/** ISO timestamp */
|
|
38
|
-
timestamp: string;
|
|
39
|
-
/** Parent session ID (if forked) */
|
|
40
|
-
parentSessionId?: string;
|
|
41
|
-
/** Session title */
|
|
42
|
-
title?: string;
|
|
43
|
-
}
|
|
44
|
-
/**
|
|
45
|
-
* Serialized message (dates as ISO strings)
|
|
46
|
-
*/
|
|
47
|
-
interface SerializedMessage {
|
|
48
|
-
id: string;
|
|
49
|
-
role: "user" | "assistant" | "tool" | "system";
|
|
50
|
-
content: string;
|
|
51
|
-
createdAt: string;
|
|
52
|
-
system?: string;
|
|
53
|
-
finish?: string;
|
|
54
|
-
tokens?: {
|
|
55
|
-
inputTokens?: number;
|
|
56
|
-
outputTokens?: number;
|
|
57
|
-
totalTokens?: number;
|
|
58
|
-
};
|
|
59
|
-
cost?: number;
|
|
60
|
-
error?: {
|
|
61
|
-
name: string;
|
|
62
|
-
message: string;
|
|
63
|
-
code?: string;
|
|
64
|
-
};
|
|
65
|
-
/** Tool calls for assistant messages with finish=tool-calls */
|
|
66
|
-
toolCalls?: Array<{
|
|
67
|
-
toolCallId: string;
|
|
68
|
-
toolName: string;
|
|
69
|
-
args: unknown;
|
|
70
|
-
}>;
|
|
71
|
-
toolCallId?: string;
|
|
72
|
-
toolName?: string;
|
|
73
|
-
result?: unknown;
|
|
74
|
-
}
|
|
75
|
-
/**
|
|
76
|
-
* Message entry
|
|
77
|
-
*/
|
|
78
|
-
interface MessageEntry extends EntryBase {
|
|
79
|
-
type: "message";
|
|
80
|
-
message: SerializedMessage;
|
|
81
|
-
}
|
|
82
|
-
/**
|
|
83
|
-
* Compaction/summarization entry
|
|
84
|
-
* Replaces old messages with a summary
|
|
85
|
-
*/
|
|
86
|
-
interface CompactionEntry extends EntryBase {
|
|
87
|
-
type: "compaction";
|
|
88
|
-
/** Summary of compacted messages */
|
|
89
|
-
summary: string;
|
|
90
|
-
/** ID of first entry that was kept (not compacted) */
|
|
91
|
-
firstKeptEntryId: string;
|
|
92
|
-
/** Token count before compaction */
|
|
93
|
-
tokensBefore: number;
|
|
94
|
-
/** Token count after compaction */
|
|
95
|
-
tokensAfter: number;
|
|
96
|
-
/** Files that were read during compacted messages */
|
|
97
|
-
readFiles?: string[];
|
|
98
|
-
/** Files that were modified during compacted messages */
|
|
99
|
-
modifiedFiles?: string[];
|
|
100
|
-
}
|
|
101
|
-
/**
|
|
102
|
-
* Session info/metadata update
|
|
103
|
-
*/
|
|
104
|
-
interface MetadataEntry extends EntryBase {
|
|
105
|
-
type: "metadata";
|
|
106
|
-
/** Updated title */
|
|
107
|
-
title?: string;
|
|
108
|
-
/** User-defined name */
|
|
109
|
-
name?: string;
|
|
110
|
-
}
|
|
111
|
-
/**
|
|
112
|
-
* Branch marker - indicates a branch point
|
|
113
|
-
*/
|
|
114
|
-
interface BranchEntry extends EntryBase {
|
|
115
|
-
type: "branch";
|
|
116
|
-
/** ID of the entry we're branching from */
|
|
117
|
-
branchFromId: string;
|
|
118
|
-
/** Optional summary of the branch */
|
|
119
|
-
summary?: string;
|
|
120
|
-
}
|
|
121
|
-
/**
|
|
122
|
-
* Model/config change entry
|
|
123
|
-
*/
|
|
124
|
-
interface ConfigChangeEntry extends EntryBase {
|
|
125
|
-
type: "config_change";
|
|
126
|
-
/** What changed */
|
|
127
|
-
change: "model" | "reasoning_level" | "temperature" | "other";
|
|
128
|
-
/** Previous value */
|
|
129
|
-
from?: string;
|
|
130
|
-
/** New value */
|
|
131
|
-
to: string;
|
|
132
|
-
}
|
|
133
|
-
/**
|
|
134
|
-
* All entry types (excluding header)
|
|
135
|
-
*/
|
|
136
|
-
type SessionEntry = MessageEntry | CompactionEntry | MetadataEntry | BranchEntry | ConfigChangeEntry;
|
|
137
|
-
/**
|
|
138
|
-
* All file entries (including header)
|
|
139
|
-
*/
|
|
140
|
-
type FileEntry = SessionHeader | SessionEntry;
|
|
141
|
-
/**
|
|
142
|
-
* Session summary info (lightweight, for listing)
|
|
143
|
-
*/
|
|
144
|
-
interface SessionInfo {
|
|
145
|
-
/** Session ID */
|
|
146
|
-
id: string;
|
|
147
|
-
/** File path */
|
|
148
|
-
path: string;
|
|
149
|
-
/** Working directory */
|
|
150
|
-
cwd: string;
|
|
151
|
-
/** Session title */
|
|
152
|
-
title?: string;
|
|
153
|
-
/** User-defined name */
|
|
154
|
-
name?: string;
|
|
155
|
-
/** Parent session ID (if forked) */
|
|
156
|
-
parentSessionId?: string;
|
|
157
|
-
/** Creation time */
|
|
158
|
-
createdAt: Date;
|
|
159
|
-
/** Last modified time */
|
|
160
|
-
updatedAt: Date;
|
|
161
|
-
/** Number of message entries */
|
|
162
|
-
messageCount: number;
|
|
163
|
-
/** First user message (preview) */
|
|
164
|
-
firstMessage?: string;
|
|
165
|
-
}
|
|
166
|
-
/**
|
|
167
|
-
* Session storage interface
|
|
168
|
-
* Pluggable backend for session persistence
|
|
169
|
-
*/
|
|
170
|
-
interface SessionStorage {
|
|
171
|
-
/**
|
|
172
|
-
* Create a new session
|
|
173
|
-
*/
|
|
174
|
-
create(header: SessionHeader): Promise<void>;
|
|
175
|
-
/**
|
|
176
|
-
* Append an entry to a session
|
|
177
|
-
*/
|
|
178
|
-
append(sessionId: string, entry: SessionEntry): Promise<void>;
|
|
179
|
-
/**
|
|
180
|
-
* Append multiple entries atomically
|
|
181
|
-
*/
|
|
182
|
-
appendBatch(sessionId: string, entries: SessionEntry[]): Promise<void>;
|
|
183
|
-
/**
|
|
184
|
-
* Read all entries from a session
|
|
185
|
-
*/
|
|
186
|
-
read(sessionId: string): Promise<FileEntry[]>;
|
|
187
|
-
/**
|
|
188
|
-
* Delete a session
|
|
189
|
-
*/
|
|
190
|
-
delete(sessionId: string): Promise<boolean>;
|
|
191
|
-
/**
|
|
192
|
-
* Check if session exists
|
|
193
|
-
*/
|
|
194
|
-
exists(sessionId: string): Promise<boolean>;
|
|
195
|
-
/**
|
|
196
|
-
* List all sessions (lightweight info only)
|
|
197
|
-
*/
|
|
198
|
-
list(): Promise<SessionInfo[]>;
|
|
199
|
-
/**
|
|
200
|
-
* Clear all sessions
|
|
201
|
-
*/
|
|
202
|
-
clear(): Promise<void>;
|
|
203
|
-
}
|
|
204
|
-
/**
|
|
205
|
-
* Current storage format version
|
|
206
|
-
*/
|
|
207
|
-
declare const STORAGE_VERSION = 1;
|
|
208
|
-
|
|
209
8
|
/**
|
|
210
9
|
* Message and token types for @cuylabs/agent-core
|
|
211
10
|
*
|
|
@@ -265,7 +64,6 @@ interface ToolMessage extends MessageBase {
|
|
|
265
64
|
result: unknown;
|
|
266
65
|
/**
|
|
267
66
|
* Timestamp when this tool result was compacted/pruned.
|
|
268
|
-
* Matches OpenCode's part.state.time.compacted pattern.
|
|
269
67
|
* Once set, this message won't be pruned again.
|
|
270
68
|
*/
|
|
271
69
|
compactedAt?: number;
|
|
@@ -316,19 +114,47 @@ interface Session {
|
|
|
316
114
|
parentID?: string;
|
|
317
115
|
}
|
|
318
116
|
|
|
117
|
+
/** Agent status for UI display */
|
|
118
|
+
type AgentStatus = "idle" | "processing" | "thinking" | "reasoning" | "calling-tool" | "waiting-approval" | "error";
|
|
119
|
+
/** Approval request for UI */
|
|
120
|
+
interface ApprovalEvent {
|
|
121
|
+
id: string;
|
|
122
|
+
tool: string;
|
|
123
|
+
args: unknown;
|
|
124
|
+
description: string;
|
|
125
|
+
risk: "safe" | "moderate" | "dangerous";
|
|
126
|
+
}
|
|
319
127
|
/**
|
|
320
|
-
*
|
|
321
|
-
*
|
|
322
|
-
* Defines the canonical StreamChunk union and related types
|
|
323
|
-
* for both AI SDK native and custom stream providers.
|
|
324
|
-
*/
|
|
325
|
-
/**
|
|
326
|
-
* Stream chunk types (AI SDK compatible + custom streams)
|
|
128
|
+
* Events emitted during agent execution
|
|
327
129
|
*
|
|
328
|
-
*
|
|
329
|
-
*
|
|
130
|
+
* These events are designed for UI consumption:
|
|
131
|
+
* - status: Overall agent state for status indicators
|
|
132
|
+
* - approval-request: User confirmation needed
|
|
133
|
+
* - progress: Step counts for progress bars
|
|
330
134
|
*/
|
|
331
|
-
type
|
|
135
|
+
type AgentEvent = {
|
|
136
|
+
type: "status";
|
|
137
|
+
status: AgentStatus;
|
|
138
|
+
} | {
|
|
139
|
+
type: "approval-request";
|
|
140
|
+
request: ApprovalEvent;
|
|
141
|
+
} | {
|
|
142
|
+
type: "approval-resolved";
|
|
143
|
+
id: string;
|
|
144
|
+
action: "allow" | "deny" | "remember";
|
|
145
|
+
} | {
|
|
146
|
+
type: "step-start";
|
|
147
|
+
step: number;
|
|
148
|
+
maxSteps: number;
|
|
149
|
+
} | {
|
|
150
|
+
type: "step-finish";
|
|
151
|
+
step: number;
|
|
152
|
+
usage?: TokenUsage;
|
|
153
|
+
finishReason?: string;
|
|
154
|
+
} | {
|
|
155
|
+
type: "message";
|
|
156
|
+
message: Message;
|
|
157
|
+
} | {
|
|
332
158
|
type: "text-start";
|
|
333
159
|
} | {
|
|
334
160
|
type: "text-delta";
|
|
@@ -346,7 +172,7 @@ type StreamChunk = {
|
|
|
346
172
|
type: "reasoning-end";
|
|
347
173
|
id: string;
|
|
348
174
|
} | {
|
|
349
|
-
type: "tool-
|
|
175
|
+
type: "tool-start";
|
|
350
176
|
toolName: string;
|
|
351
177
|
toolCallId: string;
|
|
352
178
|
input: unknown;
|
|
@@ -354,206 +180,12 @@ type StreamChunk = {
|
|
|
354
180
|
type: "tool-result";
|
|
355
181
|
toolName: string;
|
|
356
182
|
toolCallId: string;
|
|
357
|
-
|
|
183
|
+
result: unknown;
|
|
358
184
|
} | {
|
|
359
185
|
type: "tool-error";
|
|
360
186
|
toolName: string;
|
|
361
187
|
toolCallId: string;
|
|
362
|
-
error:
|
|
363
|
-
} | {
|
|
364
|
-
type: "finish-step";
|
|
365
|
-
usage?: {
|
|
366
|
-
inputTokens?: number;
|
|
367
|
-
outputTokens?: number;
|
|
368
|
-
totalTokens?: number;
|
|
369
|
-
};
|
|
370
|
-
finishReason?: string;
|
|
371
|
-
} | {
|
|
372
|
-
type: "finish";
|
|
373
|
-
totalUsage?: {
|
|
374
|
-
inputTokens?: number;
|
|
375
|
-
outputTokens?: number;
|
|
376
|
-
totalTokens?: number;
|
|
377
|
-
};
|
|
378
|
-
} | {
|
|
379
|
-
type: "error";
|
|
380
|
-
error: unknown;
|
|
381
|
-
} | {
|
|
382
|
-
type: "start-step";
|
|
383
|
-
} | {
|
|
384
|
-
type: "start";
|
|
385
|
-
} | {
|
|
386
|
-
type: "abort";
|
|
387
|
-
} | {
|
|
388
|
-
type: "computer-call";
|
|
389
|
-
callId: string;
|
|
390
|
-
action: unknown;
|
|
391
|
-
pendingSafetyChecks?: unknown[];
|
|
392
|
-
} | {
|
|
393
|
-
type: "step-usage";
|
|
394
|
-
usage: {
|
|
395
|
-
inputTokens: number;
|
|
396
|
-
outputTokens: number;
|
|
397
|
-
totalTokens: number;
|
|
398
|
-
};
|
|
399
|
-
};
|
|
400
|
-
/**
|
|
401
|
-
* Custom stream provider function type.
|
|
402
|
-
*
|
|
403
|
-
* This matches the signature needed for agent-core's LLM module,
|
|
404
|
-
* returning a StreamProviderResult-compatible object.
|
|
405
|
-
*/
|
|
406
|
-
type StreamProvider = (input: StreamProviderInput) => Promise<StreamProviderResult>;
|
|
407
|
-
/**
|
|
408
|
-
* Input for custom stream providers
|
|
409
|
-
*/
|
|
410
|
-
interface StreamProviderInput {
|
|
411
|
-
/** System prompt */
|
|
412
|
-
system: string;
|
|
413
|
-
/** Messages to send */
|
|
414
|
-
messages: Array<{
|
|
415
|
-
role: string;
|
|
416
|
-
content: unknown;
|
|
417
|
-
}>;
|
|
418
|
-
/** Abort signal */
|
|
419
|
-
abortSignal?: AbortSignal;
|
|
420
|
-
/** Max iterations */
|
|
421
|
-
maxSteps?: number;
|
|
422
|
-
}
|
|
423
|
-
/**
|
|
424
|
-
* Result from custom stream providers (AI SDK StreamTextResult compatible)
|
|
425
|
-
*/
|
|
426
|
-
interface StreamProviderResult {
|
|
427
|
-
/** Async iterable of stream chunks */
|
|
428
|
-
fullStream: AsyncIterable<StreamChunk>;
|
|
429
|
-
/** Promise resolving to final text */
|
|
430
|
-
text: Promise<string>;
|
|
431
|
-
/** Promise resolving to usage stats */
|
|
432
|
-
usage: Promise<{
|
|
433
|
-
inputTokens: number;
|
|
434
|
-
outputTokens: number;
|
|
435
|
-
totalTokens: number;
|
|
436
|
-
}>;
|
|
437
|
-
/** Promise resolving to finish reason */
|
|
438
|
-
finishReason: Promise<string>;
|
|
439
|
-
}
|
|
440
|
-
/**
|
|
441
|
-
* Configuration for stream provider factory.
|
|
442
|
-
* Contains everything needed to create a stream provider for a specific model.
|
|
443
|
-
*/
|
|
444
|
-
interface StreamProviderConfig {
|
|
445
|
-
/** API key to use */
|
|
446
|
-
apiKey?: string;
|
|
447
|
-
/** Display dimensions */
|
|
448
|
-
display?: {
|
|
449
|
-
width: number;
|
|
450
|
-
height: number;
|
|
451
|
-
};
|
|
452
|
-
/** Environment type */
|
|
453
|
-
environment?: string;
|
|
454
|
-
/** Enable debug logging */
|
|
455
|
-
debug?: boolean;
|
|
456
|
-
}
|
|
457
|
-
/**
|
|
458
|
-
* Stream provider factory - creates a stream provider for a given model.
|
|
459
|
-
*
|
|
460
|
-
* This is attached to enhanced tools (like computer tools) to allow
|
|
461
|
-
* the Agent to automatically configure the right stream provider
|
|
462
|
-
* when a model requires custom handling (e.g., OpenAI computer-use-preview).
|
|
463
|
-
*/
|
|
464
|
-
type StreamProviderFactory = (modelId: string, config: StreamProviderConfig) => StreamProvider;
|
|
465
|
-
/**
|
|
466
|
-
* Enhanced tools array with additional capabilities.
|
|
467
|
-
*
|
|
468
|
-
* This extends the standard Tool.AnyInfo[] with optional metadata
|
|
469
|
-
* that the Agent can use for automatic configuration.
|
|
470
|
-
*/
|
|
471
|
-
interface EnhancedTools extends Array<unknown> {
|
|
472
|
-
/**
|
|
473
|
-
* Factory to create a stream provider for models that need custom streaming.
|
|
474
|
-
* Called by the Agent when it detects a model that requires special handling.
|
|
475
|
-
*/
|
|
476
|
-
__streamProviderFactory?: StreamProviderFactory;
|
|
477
|
-
/**
|
|
478
|
-
* Model patterns that require the custom stream provider.
|
|
479
|
-
* Used by the Agent to detect when to use the factory.
|
|
480
|
-
* Default patterns: ["computer-use-preview"]
|
|
481
|
-
*/
|
|
482
|
-
__customStreamModels?: string[];
|
|
483
|
-
}
|
|
484
|
-
|
|
485
|
-
/** Agent status for UI display */
|
|
486
|
-
type AgentStatus = "idle" | "processing" | "thinking" | "reasoning" | "calling-tool" | "waiting-approval" | "error";
|
|
487
|
-
/** Approval request for UI */
|
|
488
|
-
interface ApprovalEvent {
|
|
489
|
-
id: string;
|
|
490
|
-
tool: string;
|
|
491
|
-
args: unknown;
|
|
492
|
-
description: string;
|
|
493
|
-
risk: "safe" | "moderate" | "dangerous";
|
|
494
|
-
}
|
|
495
|
-
/**
|
|
496
|
-
* Events emitted during agent execution
|
|
497
|
-
*
|
|
498
|
-
* These events are designed for UI consumption:
|
|
499
|
-
* - status: Overall agent state for status indicators
|
|
500
|
-
* - approval-request: User confirmation needed
|
|
501
|
-
* - progress: Step counts for progress bars
|
|
502
|
-
*/
|
|
503
|
-
type AgentEvent = {
|
|
504
|
-
type: "status";
|
|
505
|
-
status: AgentStatus;
|
|
506
|
-
} | {
|
|
507
|
-
type: "approval-request";
|
|
508
|
-
request: ApprovalEvent;
|
|
509
|
-
} | {
|
|
510
|
-
type: "approval-resolved";
|
|
511
|
-
id: string;
|
|
512
|
-
action: "allow" | "deny" | "remember";
|
|
513
|
-
} | {
|
|
514
|
-
type: "step-start";
|
|
515
|
-
step: number;
|
|
516
|
-
maxSteps: number;
|
|
517
|
-
} | {
|
|
518
|
-
type: "step-finish";
|
|
519
|
-
step: number;
|
|
520
|
-
usage?: TokenUsage;
|
|
521
|
-
finishReason?: string;
|
|
522
|
-
} | {
|
|
523
|
-
type: "message";
|
|
524
|
-
message: Message;
|
|
525
|
-
} | {
|
|
526
|
-
type: "text-start";
|
|
527
|
-
} | {
|
|
528
|
-
type: "text-delta";
|
|
529
|
-
text: string;
|
|
530
|
-
} | {
|
|
531
|
-
type: "text-end";
|
|
532
|
-
} | {
|
|
533
|
-
type: "reasoning-start";
|
|
534
|
-
id: string;
|
|
535
|
-
} | {
|
|
536
|
-
type: "reasoning-delta";
|
|
537
|
-
id: string;
|
|
538
|
-
text: string;
|
|
539
|
-
} | {
|
|
540
|
-
type: "reasoning-end";
|
|
541
|
-
id: string;
|
|
542
|
-
} | {
|
|
543
|
-
type: "tool-start";
|
|
544
|
-
toolName: string;
|
|
545
|
-
toolCallId: string;
|
|
546
|
-
input: unknown;
|
|
547
|
-
} | {
|
|
548
|
-
type: "tool-result";
|
|
549
|
-
toolName: string;
|
|
550
|
-
toolCallId: string;
|
|
551
|
-
result: unknown;
|
|
552
|
-
} | {
|
|
553
|
-
type: "tool-error";
|
|
554
|
-
toolName: string;
|
|
555
|
-
toolCallId: string;
|
|
556
|
-
error: string;
|
|
188
|
+
error: string;
|
|
557
189
|
} | {
|
|
558
190
|
type: "computer-call";
|
|
559
191
|
callId: string;
|
|
@@ -615,304 +247,956 @@ interface StreamInput {
|
|
|
615
247
|
}
|
|
616
248
|
|
|
617
249
|
/**
|
|
618
|
-
*
|
|
250
|
+
* Skill System Types
|
|
619
251
|
*
|
|
620
|
-
*
|
|
621
|
-
*
|
|
252
|
+
* Skills are modular, on-demand knowledge packs that extend an agent's
|
|
253
|
+
* capabilities with specialized instructions, workflows, and resources.
|
|
254
|
+
*
|
|
255
|
+
* Design principles:
|
|
256
|
+
*
|
|
257
|
+
* 1. **Progressive disclosure** — summaries always in context,
|
|
258
|
+
* full content loaded only when needed. Minimizes baseline token cost.
|
|
259
|
+
*
|
|
260
|
+
* 2. **Scoped priority** — project skills override user skills
|
|
261
|
+
* override global skills. Closest scope wins on name collision.
|
|
262
|
+
*
|
|
263
|
+
* 3. **Agent-initiated loading** — the agent decides when to
|
|
264
|
+
* activate a skill by calling the `skill` tool. No guesswork.
|
|
265
|
+
*
|
|
266
|
+
* 4. **Bundled resources** — skills can ship scripts,
|
|
267
|
+
* references, assets, and examples alongside instructions.
|
|
268
|
+
*
|
|
269
|
+
* 5. **Remote sources** — skills can be fetched from URLs,
|
|
270
|
+
* enabling shared skill repositories across teams.
|
|
271
|
+
*
|
|
272
|
+
* The lifecycle:
|
|
273
|
+
*
|
|
274
|
+
* Discovery → Registry → Summary injection → Agent tool call → Full load
|
|
275
|
+
*
|
|
276
|
+
* @packageDocumentation
|
|
622
277
|
*/
|
|
623
278
|
/**
|
|
624
|
-
*
|
|
279
|
+
* Where a skill was discovered, determining its override priority.
|
|
625
280
|
*
|
|
626
|
-
*
|
|
627
|
-
*
|
|
628
|
-
*
|
|
629
|
-
*
|
|
630
|
-
*
|
|
631
|
-
* | `"medium"` | Balanced reasoning |
|
|
632
|
-
* | `"high"` | Deep reasoning |
|
|
633
|
-
* | `"xhigh"` | Maximum reasoning (where supported)|
|
|
281
|
+
* When two skills share the same name, the narrower scope wins:
|
|
282
|
+
* project > user > global > builtin
|
|
283
|
+
*
|
|
284
|
+
* Uses a 4-tier hierarchy with names that are intuitive for
|
|
285
|
+
* library consumers.
|
|
634
286
|
*/
|
|
635
|
-
type
|
|
287
|
+
type SkillScope = "project" | "user" | "global" | "builtin";
|
|
636
288
|
/**
|
|
637
|
-
*
|
|
638
|
-
* {@link getReasoningConfig} / {@link getReasoningConfigSync}.
|
|
289
|
+
* How a skill was obtained — local filesystem or remote URL.
|
|
639
290
|
*/
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
/**
|
|
646
|
-
|
|
291
|
+
type SkillSourceType = "local" | "remote";
|
|
292
|
+
/**
|
|
293
|
+
* Where a skill came from, for provenance tracking.
|
|
294
|
+
*/
|
|
295
|
+
interface SkillSource {
|
|
296
|
+
/** Local or remote origin */
|
|
297
|
+
type: SkillSourceType;
|
|
298
|
+
/** Root directory or URL this skill was discovered under */
|
|
299
|
+
root: string;
|
|
647
300
|
}
|
|
648
|
-
|
|
649
301
|
/**
|
|
650
|
-
*
|
|
302
|
+
* Classification of bundled resources within a skill directory.
|
|
651
303
|
*
|
|
652
|
-
*
|
|
653
|
-
*
|
|
304
|
+
* Resource taxonomy:
|
|
305
|
+
* - `script` — executable code for deterministic tasks (can be run without reading)
|
|
306
|
+
* - `reference` — documentation loaded into context on demand
|
|
307
|
+
* - `asset` — templates, images, fonts used in output (not read into context)
|
|
308
|
+
* - `example` — working code samples for the agent to learn from
|
|
654
309
|
*/
|
|
310
|
+
type SkillResourceType = "script" | "reference" | "asset" | "example";
|
|
655
311
|
/**
|
|
656
|
-
*
|
|
312
|
+
* A file bundled with a skill.
|
|
313
|
+
*
|
|
314
|
+
* Resources are discovered but NOT loaded into memory until the agent
|
|
315
|
+
* explicitly requests them. This is the L3 layer of progressive disclosure.
|
|
657
316
|
*/
|
|
658
|
-
|
|
317
|
+
interface SkillResource {
|
|
318
|
+
/** Path relative to the skill's base directory */
|
|
319
|
+
relativePath: string;
|
|
320
|
+
/** Classified resource type */
|
|
321
|
+
type: SkillResourceType;
|
|
322
|
+
/** Absolute path on disk (for local resources) */
|
|
323
|
+
absolutePath: string;
|
|
324
|
+
}
|
|
659
325
|
/**
|
|
660
|
-
*
|
|
326
|
+
* Lightweight skill metadata parsed from SKILL.md YAML frontmatter.
|
|
327
|
+
*
|
|
328
|
+
* This is the **L1 layer** — always present in the system prompt so the
|
|
329
|
+
* agent knows which skills exist. Kept intentionally small (~100 words each)
|
|
330
|
+
* to minimize baseline context cost.
|
|
331
|
+
*
|
|
332
|
+
* Uses YAML frontmatter in a SKILL.md file — the widely-adopted
|
|
333
|
+
* canonical format for skill definitions.
|
|
661
334
|
*/
|
|
662
|
-
|
|
335
|
+
interface SkillMetadata {
|
|
336
|
+
/** Unique skill identifier (from frontmatter `name`) */
|
|
337
|
+
name: string;
|
|
338
|
+
/**
|
|
339
|
+
* When to use this skill — the single most important field.
|
|
340
|
+
*
|
|
341
|
+
* This description is what the agent reads to decide whether to
|
|
342
|
+
* activate the skill. Should contain trigger phrases that match
|
|
343
|
+
* task types. Written for another LLM to consume, not humans.
|
|
344
|
+
*/
|
|
345
|
+
description: string;
|
|
346
|
+
/** Semantic version (from frontmatter, optional) */
|
|
347
|
+
version?: string;
|
|
348
|
+
/** Scope that determines override priority */
|
|
349
|
+
scope: SkillScope;
|
|
350
|
+
/** How this skill was obtained */
|
|
351
|
+
source: SkillSource;
|
|
352
|
+
/** Absolute path to the SKILL.md file */
|
|
353
|
+
filePath: string;
|
|
354
|
+
/** Directory containing the skill (parent of SKILL.md) */
|
|
355
|
+
baseDir: string;
|
|
356
|
+
/** Optional tags for categorization */
|
|
357
|
+
tags?: string[];
|
|
358
|
+
/**
|
|
359
|
+
* Names of skills this skill depends on.
|
|
360
|
+
* When this skill is loaded, its dependencies are suggested to be loaded too.
|
|
361
|
+
*/
|
|
362
|
+
dependencies?: string[];
|
|
363
|
+
}
|
|
663
364
|
/**
|
|
664
|
-
*
|
|
365
|
+
* Full skill content including the markdown body and resource listing.
|
|
366
|
+
*
|
|
367
|
+
* This is the **L2 layer** — loaded only when the agent calls the skill
|
|
368
|
+
* tool. Contains the actual instructions plus awareness of bundled resources.
|
|
665
369
|
*/
|
|
666
|
-
interface
|
|
667
|
-
/**
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
/** Supported input modalities */
|
|
678
|
-
inputModalities: InputModality[];
|
|
679
|
-
/** Supported output modalities */
|
|
680
|
-
outputModalities: OutputModality[];
|
|
681
|
-
/** Maximum context window in tokens */
|
|
682
|
-
contextWindow?: number;
|
|
683
|
-
/** Maximum output tokens */
|
|
684
|
-
maxOutput?: number;
|
|
685
|
-
}
|
|
686
|
-
/**
|
|
687
|
-
* Provider-specific compatibility flags
|
|
688
|
-
* These handle quirks in different provider implementations
|
|
689
|
-
*/
|
|
690
|
-
interface ProviderCompatibility {
|
|
691
|
-
/** Supports OpenAI-style reasoning_effort parameter */
|
|
692
|
-
supportsReasoningEffort?: boolean;
|
|
693
|
-
/** Supports developer/system role distinction */
|
|
694
|
-
supportsDeveloperRole?: boolean;
|
|
695
|
-
/** Field name for max tokens (varies by provider) */
|
|
696
|
-
maxTokensField?: "max_tokens" | "max_completion_tokens";
|
|
697
|
-
/** Requires thinking as text tags vs structured */
|
|
698
|
-
requiresThinkingTags?: boolean;
|
|
699
|
-
/** Provider-specific thinking format */
|
|
700
|
-
thinkingFormat?: "openai" | "anthropic" | "google" | "zai";
|
|
701
|
-
}
|
|
702
|
-
/**
|
|
703
|
-
* Complete model entry with metadata
|
|
704
|
-
*/
|
|
705
|
-
interface ModelEntry {
|
|
706
|
-
/** Model identifier (e.g., "gpt-4o", "claude-sonnet-4") */
|
|
707
|
-
id: string;
|
|
708
|
-
/** Human-readable model name */
|
|
709
|
-
name: string;
|
|
710
|
-
/** Provider identifier (e.g., "openai", "anthropic") */
|
|
711
|
-
provider: string;
|
|
712
|
-
/** Model capabilities */
|
|
713
|
-
capabilities: ModelCapabilities;
|
|
714
|
-
/** Provider-specific compatibility settings */
|
|
715
|
-
compatibility?: ProviderCompatibility;
|
|
716
|
-
/** Cost per million tokens (input) */
|
|
717
|
-
costInput?: number;
|
|
718
|
-
/** Cost per million tokens (output) */
|
|
719
|
-
costOutput?: number;
|
|
720
|
-
/** When this entry was last updated */
|
|
721
|
-
updatedAt?: string;
|
|
722
|
-
}
|
|
723
|
-
/**
|
|
724
|
-
* Priority levels for capability sources
|
|
725
|
-
*/
|
|
726
|
-
declare enum SourcePriority {
|
|
727
|
-
/** User configuration overrides everything */
|
|
728
|
-
UserConfig = 0,
|
|
729
|
-
/** Local cache from previous fetch */
|
|
730
|
-
LocalCache = 1,
|
|
731
|
-
/** Bundled static data (build-time) */
|
|
732
|
-
BundledData = 2,
|
|
733
|
-
/** Pattern-based inference (fallback) */
|
|
734
|
-
PatternMatch = 3,
|
|
735
|
-
/** Remote API (if network available) */
|
|
736
|
-
RemoteAPI = 4
|
|
737
|
-
}
|
|
738
|
-
/**
|
|
739
|
-
* Options for the capability resolver
|
|
740
|
-
*/
|
|
741
|
-
interface ResolverOptions {
|
|
742
|
-
/** Enable remote API fetching (default: false) */
|
|
743
|
-
enableRemoteFetch?: boolean;
|
|
744
|
-
/** Remote API URL (default: https://models.dev) */
|
|
745
|
-
remoteApiUrl?: string;
|
|
746
|
-
/** Cache directory path */
|
|
747
|
-
cachePath?: string;
|
|
748
|
-
/** Cache TTL in milliseconds (default: 1 hour) */
|
|
749
|
-
cacheTtlMs?: number;
|
|
750
|
-
/** Network timeout in milliseconds (default: 10 seconds) */
|
|
751
|
-
networkTimeoutMs?: number;
|
|
752
|
-
/** Custom user overrides for specific models */
|
|
753
|
-
modelOverrides?: Record<string, Partial<ModelCapabilities>>;
|
|
754
|
-
}
|
|
755
|
-
|
|
756
|
-
/**
|
|
757
|
-
* Extract a model ID string from a LanguageModel instance.
|
|
758
|
-
*/
|
|
759
|
-
declare function getModelId(model: LanguageModel): string;
|
|
760
|
-
/**
|
|
761
|
-
* Extract a provider identifier from a LanguageModel instance.
|
|
762
|
-
*/
|
|
763
|
-
declare function getProviderId(model: LanguageModel): string | undefined;
|
|
764
|
-
|
|
765
|
-
/**
|
|
766
|
-
* Remote Capability Fetching for @cuylabs/agent-core
|
|
767
|
-
*
|
|
768
|
-
* Handles fetching model capabilities from remote APIs (e.g., models.dev).
|
|
769
|
-
* Includes network status detection, timeout handling, and retry logic.
|
|
770
|
-
*/
|
|
771
|
-
|
|
772
|
-
/**
|
|
773
|
-
* Network status information
|
|
774
|
-
*/
|
|
775
|
-
interface NetworkStatus {
|
|
776
|
-
/** Whether we believe the network is available */
|
|
777
|
-
online: boolean;
|
|
778
|
-
/** Last successful fetch timestamp */
|
|
779
|
-
lastSuccess?: number;
|
|
780
|
-
/** Last error if any */
|
|
781
|
-
lastError?: string;
|
|
782
|
-
/** Number of consecutive failures */
|
|
783
|
-
failureCount: number;
|
|
370
|
+
interface SkillContent extends SkillMetadata {
|
|
371
|
+
/**
|
|
372
|
+
* The full markdown body of SKILL.md (everything below the frontmatter).
|
|
373
|
+
* This is the core instructional content injected into the conversation.
|
|
374
|
+
*/
|
|
375
|
+
body: string;
|
|
376
|
+
/**
|
|
377
|
+
* Bundled resources discovered in the skill directory.
|
|
378
|
+
* Listed so the agent knows what's available but not yet loaded.
|
|
379
|
+
*/
|
|
380
|
+
resources: SkillResource[];
|
|
784
381
|
}
|
|
785
382
|
/**
|
|
786
|
-
*
|
|
787
|
-
*/
|
|
788
|
-
declare function getNetworkStatus(): NetworkStatus;
|
|
789
|
-
|
|
790
|
-
/**
|
|
791
|
-
* Model Capability Resolver for @cuylabs/agent-core
|
|
383
|
+
* Configuration for skill discovery and loading.
|
|
792
384
|
*
|
|
793
|
-
*
|
|
794
|
-
*
|
|
795
|
-
* 2. Local cache (fast, persisted)
|
|
796
|
-
* 3. Pattern matching (always available)
|
|
797
|
-
* 4. Remote API (optional, network-dependent)
|
|
798
|
-
*
|
|
799
|
-
* Designed for the Vercel AI SDK v6 ecosystem.
|
|
800
|
-
*/
|
|
801
|
-
|
|
802
|
-
/**
|
|
803
|
-
* Resolution result with source information
|
|
804
|
-
*/
|
|
805
|
-
interface ResolutionResult {
|
|
806
|
-
/** The resolved model entry */
|
|
807
|
-
entry: ModelEntry;
|
|
808
|
-
/** Which source provided the primary result */
|
|
809
|
-
source: SourcePriority;
|
|
810
|
-
/** Whether this is a confident match */
|
|
811
|
-
confident: boolean;
|
|
812
|
-
/** Resolution timing in ms */
|
|
813
|
-
resolveTimeMs: number;
|
|
814
|
-
}
|
|
815
|
-
/**
|
|
816
|
-
* Model Capability Resolver
|
|
385
|
+
* Controls where skills are found, how deep to scan, and which
|
|
386
|
+
* external conventions to support.
|
|
817
387
|
*
|
|
818
|
-
*
|
|
819
|
-
*
|
|
388
|
+
* @example
|
|
389
|
+
* ```typescript
|
|
390
|
+
* const skillConfig: SkillConfig = {
|
|
391
|
+
* // Scan standard locations
|
|
392
|
+
* externalDirs: [".agents", ".claude"],
|
|
393
|
+
* // Add custom skill roots
|
|
394
|
+
* roots: ["./company-skills"],
|
|
395
|
+
* // Limit scan depth for performance
|
|
396
|
+
* maxScanDepth: 4,
|
|
397
|
+
* };
|
|
398
|
+
* ```
|
|
820
399
|
*/
|
|
821
|
-
|
|
822
|
-
private options;
|
|
823
|
-
private cache;
|
|
824
|
-
private sources;
|
|
825
|
-
private initialized;
|
|
826
|
-
private initPromise;
|
|
827
|
-
constructor(options?: Partial<ResolverOptions>);
|
|
828
|
-
/**
|
|
829
|
-
* Initialize the resolver (load cache, optionally fetch remote)
|
|
830
|
-
*/
|
|
831
|
-
initialize(): Promise<void>;
|
|
832
|
-
/**
|
|
833
|
-
* Resolve capabilities for a model
|
|
834
|
-
*/
|
|
835
|
-
resolve(model: LanguageModel): Promise<ResolutionResult>;
|
|
836
|
-
/**
|
|
837
|
-
* Quick check if a model supports reasoning
|
|
838
|
-
* Uses cache/patterns only for speed
|
|
839
|
-
*/
|
|
840
|
-
supportsReasoning(model: LanguageModel): Promise<boolean>;
|
|
400
|
+
interface SkillConfig {
|
|
841
401
|
/**
|
|
842
|
-
*
|
|
402
|
+
* Additional directories to scan for skills (absolute or relative to cwd).
|
|
403
|
+
* Each directory is scanned recursively for SKILL.md files.
|
|
843
404
|
*/
|
|
844
|
-
|
|
405
|
+
roots?: string[];
|
|
845
406
|
/**
|
|
846
|
-
*
|
|
407
|
+
* External skill directory names to scan in project and home directories.
|
|
408
|
+
*
|
|
409
|
+
* These are checked as `<project>/<dir>/skills/` and `~/<dir>/skills/`.
|
|
410
|
+
* Supports `.claude` and `.agents` directory conventions.
|
|
411
|
+
*
|
|
412
|
+
* @default [".agents", ".claude"]
|
|
847
413
|
*/
|
|
848
|
-
|
|
414
|
+
externalDirs?: string[];
|
|
849
415
|
/**
|
|
850
|
-
*
|
|
416
|
+
* Maximum directory depth to scan within each root.
|
|
417
|
+
* Higher values find more deeply nested skills but take longer.
|
|
418
|
+
*
|
|
419
|
+
* @default 4
|
|
851
420
|
*/
|
|
852
|
-
|
|
421
|
+
maxScanDepth?: number;
|
|
853
422
|
/**
|
|
854
|
-
*
|
|
423
|
+
* Maximum file size for SKILL.md files in bytes.
|
|
424
|
+
* Skills larger than this are skipped with a warning.
|
|
425
|
+
*
|
|
426
|
+
* @default 102400 (100KB)
|
|
855
427
|
*/
|
|
856
|
-
|
|
428
|
+
maxFileSize?: number;
|
|
857
429
|
/**
|
|
858
|
-
*
|
|
430
|
+
* Enable fetching skills from remote URLs.
|
|
431
|
+
* When false, `remoteUrls` is ignored.
|
|
432
|
+
*
|
|
433
|
+
* @default false
|
|
859
434
|
*/
|
|
860
|
-
|
|
861
|
-
cacheSize: number;
|
|
862
|
-
cacheLoaded: boolean;
|
|
863
|
-
remoteFetchEnabled: boolean;
|
|
864
|
-
networkOnline: boolean;
|
|
865
|
-
};
|
|
435
|
+
enableRemote?: boolean;
|
|
866
436
|
/**
|
|
867
|
-
*
|
|
437
|
+
* Remote skill index URLs to fetch.
|
|
438
|
+
*
|
|
439
|
+
* Each URL should serve a JSON index listing available skills.
|
|
440
|
+
* See `RemoteSkillIndex` for the expected format.
|
|
441
|
+
*
|
|
442
|
+
* @example
|
|
443
|
+
* ```typescript
|
|
444
|
+
* remoteUrls: ["https://skills.example.com/index.json"]
|
|
445
|
+
* ```
|
|
868
446
|
*/
|
|
869
|
-
|
|
447
|
+
remoteUrls?: string[];
|
|
870
448
|
/**
|
|
871
|
-
*
|
|
872
|
-
*
|
|
449
|
+
* Cache directory for remote skills.
|
|
450
|
+
* Defaults to `~/.cache/cuylabs/skills/`.
|
|
873
451
|
*/
|
|
874
|
-
|
|
452
|
+
remoteCacheDir?: string;
|
|
875
453
|
/**
|
|
876
|
-
*
|
|
454
|
+
* Include built-in skills bundled with agent-core.
|
|
455
|
+
* Currently reserved for future use.
|
|
456
|
+
*
|
|
457
|
+
* @default true
|
|
877
458
|
*/
|
|
878
|
-
|
|
459
|
+
includeBuiltin?: boolean;
|
|
879
460
|
}
|
|
880
461
|
/**
|
|
881
|
-
*
|
|
462
|
+
* Schema for remote skill index JSON files.
|
|
463
|
+
*
|
|
464
|
+
* Hosted at a URL like `https://skills.example.com/index.json`.
|
|
465
|
+
* Enables team-wide or organization-wide skill sharing.
|
|
466
|
+
*
|
|
467
|
+
* @example
|
|
468
|
+
* ```json
|
|
469
|
+
* {
|
|
470
|
+
* "version": 1,
|
|
471
|
+
* "skills": [
|
|
472
|
+
* {
|
|
473
|
+
* "name": "testing",
|
|
474
|
+
* "files": ["SKILL.md", "scripts/run-tests.sh", "references/patterns.md"]
|
|
475
|
+
* }
|
|
476
|
+
* ]
|
|
477
|
+
* }
|
|
478
|
+
* ```
|
|
882
479
|
*/
|
|
883
|
-
|
|
480
|
+
interface RemoteSkillIndex {
|
|
481
|
+
/** Schema version (currently 1) */
|
|
482
|
+
version: number;
|
|
483
|
+
/** List of available skills */
|
|
484
|
+
skills: RemoteSkillEntry[];
|
|
485
|
+
}
|
|
884
486
|
/**
|
|
885
|
-
*
|
|
487
|
+
* A single skill listing in a remote index.
|
|
886
488
|
*/
|
|
887
|
-
|
|
489
|
+
interface RemoteSkillEntry {
|
|
490
|
+
/** Skill name (must match the `name` in SKILL.md frontmatter) */
|
|
491
|
+
name: string;
|
|
492
|
+
/** Relative file paths to download (SKILL.md is required) */
|
|
493
|
+
files: string[];
|
|
494
|
+
}
|
|
495
|
+
/**
|
|
496
|
+
* Result of a full skill discovery pass.
|
|
497
|
+
*/
|
|
498
|
+
interface SkillDiscoveryResult {
|
|
499
|
+
/** All discovered skills (deduplicated, scope-prioritized) */
|
|
500
|
+
skills: SkillMetadata[];
|
|
501
|
+
/** Skills that failed to load with reasons */
|
|
502
|
+
errors: SkillDiscoveryError[];
|
|
503
|
+
/** Total directories scanned */
|
|
504
|
+
dirsScanned: number;
|
|
505
|
+
/** Discovery duration in milliseconds */
|
|
506
|
+
durationMs: number;
|
|
507
|
+
}
|
|
508
|
+
/**
|
|
509
|
+
* An error encountered during skill discovery.
|
|
510
|
+
*/
|
|
511
|
+
interface SkillDiscoveryError {
|
|
512
|
+
/** Path that caused the error */
|
|
513
|
+
path: string;
|
|
514
|
+
/** What went wrong */
|
|
515
|
+
reason: string;
|
|
516
|
+
}
|
|
888
517
|
|
|
889
518
|
/**
|
|
890
|
-
*
|
|
519
|
+
* Prompt Pipeline Types
|
|
891
520
|
*
|
|
892
|
-
*
|
|
893
|
-
*
|
|
894
|
-
* Vercel AI SDK.
|
|
521
|
+
* Types for the layered system prompt architecture.
|
|
522
|
+
* The prompt pipeline composes a system prompt from multiple sources:
|
|
895
523
|
*
|
|
896
|
-
*
|
|
897
|
-
*
|
|
898
|
-
*
|
|
899
|
-
* - **Sync** (`getReasoningConfigSync`, `buildReasoningOptionsSync`) —
|
|
900
|
-
* uses fast pattern-matching only (no network).
|
|
524
|
+
* Base Template → Environment → Instructions → Custom Sections → Per-Turn
|
|
525
|
+
*
|
|
526
|
+
* Each layer is optional, composable, and can be toggled on/off.
|
|
901
527
|
*/
|
|
902
528
|
|
|
903
529
|
/**
|
|
904
|
-
*
|
|
530
|
+
* Model family identifier for prompt template selection.
|
|
905
531
|
*
|
|
906
|
-
*
|
|
907
|
-
*
|
|
532
|
+
* Each family gets a base template optimized for its strengths:
|
|
533
|
+
* - `anthropic`: Claude models — structured sections with XML tags
|
|
534
|
+
* - `openai`: GPT/o-series models — clear directives with markdown
|
|
535
|
+
* - `google`: Gemini models — balanced approach
|
|
536
|
+
* - `deepseek`: DeepSeek models — code-focused emphasis
|
|
537
|
+
* - `default`: Generic template for any model
|
|
908
538
|
*/
|
|
909
|
-
|
|
539
|
+
type ModelFamily = "anthropic" | "openai" | "google" | "deepseek" | "default";
|
|
910
540
|
/**
|
|
911
|
-
*
|
|
912
|
-
*
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
*/
|
|
541
|
+
* Runtime environment information injected into the system prompt.
|
|
542
|
+
* Gives the model awareness of the working context.
|
|
543
|
+
*/
|
|
544
|
+
interface EnvironmentInfo {
|
|
545
|
+
/** Current working directory */
|
|
546
|
+
cwd: string;
|
|
547
|
+
/** Operating system (e.g. "macOS (darwin arm64)") */
|
|
548
|
+
platform: string;
|
|
549
|
+
/** Current date/time formatted string */
|
|
550
|
+
date: string;
|
|
551
|
+
/** User's shell (e.g. "/bin/zsh") */
|
|
552
|
+
shell?: string;
|
|
553
|
+
/** Active git branch, if inside a repo */
|
|
554
|
+
gitBranch?: string;
|
|
555
|
+
/** Whether the working tree is clean */
|
|
556
|
+
gitClean?: boolean;
|
|
557
|
+
/** Git repo root path */
|
|
558
|
+
gitRoot?: string;
|
|
559
|
+
}
|
|
560
|
+
/**
|
|
561
|
+
* An instruction file discovered on disk (e.g. AGENTS.md).
|
|
562
|
+
*
|
|
563
|
+
* Instruction files provide project-specific or workspace-level guidance
|
|
564
|
+
* that gets injected into every prompt. They're discovered by walking up
|
|
565
|
+
* the directory tree from cwd.
|
|
566
|
+
*/
|
|
567
|
+
interface InstructionFile {
|
|
568
|
+
/** Absolute path to the file */
|
|
569
|
+
path: string;
|
|
570
|
+
/** File content (trimmed) */
|
|
571
|
+
content: string;
|
|
572
|
+
/** How the file was discovered */
|
|
573
|
+
source: "project" | "workspace" | "global";
|
|
574
|
+
/** Depth from cwd (0 = same directory) */
|
|
575
|
+
depth: number;
|
|
576
|
+
}
|
|
577
|
+
/**
|
|
578
|
+
* A composable section in the prompt pipeline.
|
|
579
|
+
*
|
|
580
|
+
* Sections are the building blocks of the final system prompt.
|
|
581
|
+
* Each section has a priority that determines its position in the output.
|
|
582
|
+
*
|
|
583
|
+
* Default priority ranges:
|
|
584
|
+
* - 10: Base template
|
|
585
|
+
* - 20: Environment block
|
|
586
|
+
* - 30: Instruction files
|
|
587
|
+
* - 50: Custom sections (default for user-added)
|
|
588
|
+
* - 70: Reserved for future use (e.g. Skills)
|
|
589
|
+
* - 90: Per-turn overrides
|
|
590
|
+
*/
|
|
591
|
+
interface PromptSection {
|
|
592
|
+
/** Unique identifier for this section */
|
|
593
|
+
id: string;
|
|
594
|
+
/** Human-readable label (useful for debugging/logging) */
|
|
595
|
+
label: string;
|
|
596
|
+
/** The text content of this section */
|
|
597
|
+
content: string;
|
|
598
|
+
/** Sort priority — lower values appear earlier (default: 50) */
|
|
599
|
+
priority?: number;
|
|
600
|
+
/** Whether this section is active (default: true) */
|
|
601
|
+
enabled?: boolean;
|
|
602
|
+
}
|
|
603
|
+
/**
|
|
604
|
+
* Context passed to the builder for each prompt build.
|
|
605
|
+
*
|
|
606
|
+
* This provides the runtime information needed to compose
|
|
607
|
+
* the system prompt for a specific conversation turn.
|
|
608
|
+
*/
|
|
609
|
+
interface PromptBuildContext {
|
|
610
|
+
/** Current working directory */
|
|
611
|
+
cwd: string;
|
|
612
|
+
/** The language model being used */
|
|
613
|
+
model: LanguageModel;
|
|
614
|
+
/** Names of available tools (for template customization) */
|
|
615
|
+
toolNames?: string[];
|
|
616
|
+
/** Per-turn additional instructions (from chat options) */
|
|
617
|
+
override?: string;
|
|
618
|
+
/** Current session ID */
|
|
619
|
+
sessionId?: string;
|
|
620
|
+
}
|
|
621
|
+
/**
|
|
622
|
+
* Configuration for the prompt pipeline.
|
|
623
|
+
*
|
|
624
|
+
* Controls which layers are active and how they behave.
|
|
625
|
+
* All options have sensible defaults — an empty config `{}` gives you
|
|
626
|
+
* the full pipeline with auto-detection.
|
|
627
|
+
*
|
|
628
|
+
* @example
|
|
629
|
+
* ```typescript
|
|
630
|
+
* // Minimal — use all defaults
|
|
631
|
+
* const builder = createPromptBuilder();
|
|
632
|
+
*
|
|
633
|
+
* // Custom base template but keep environment + instructions
|
|
634
|
+
* const builder = createPromptBuilder({
|
|
635
|
+
* baseTemplate: "You are a security auditor...",
|
|
636
|
+
* includeEnvironment: true,
|
|
637
|
+
* includeInstructions: true,
|
|
638
|
+
* });
|
|
639
|
+
*
|
|
640
|
+
* // Fully custom — disable auto features, add your own sections
|
|
641
|
+
* const builder = createPromptBuilder({
|
|
642
|
+
* includeEnvironment: false,
|
|
643
|
+
* includeInstructions: false,
|
|
644
|
+
* sections: [
|
|
645
|
+
* { id: "role", label: "Role", content: "You audit code.", priority: 10 },
|
|
646
|
+
* { id: "rules", label: "Rules", content: "Never modify files.", priority: 20 },
|
|
647
|
+
* ],
|
|
648
|
+
* });
|
|
649
|
+
* ```
|
|
650
|
+
*/
|
|
651
|
+
interface PromptConfig {
|
|
652
|
+
/**
|
|
653
|
+
* Override the base template entirely.
|
|
654
|
+
* If set, replaces the model-family-specific template.
|
|
655
|
+
*/
|
|
656
|
+
baseTemplate?: string;
|
|
657
|
+
/**
|
|
658
|
+
* Force a specific model family for template selection.
|
|
659
|
+
* Auto-detected from the model if not provided.
|
|
660
|
+
*/
|
|
661
|
+
modelFamily?: ModelFamily;
|
|
662
|
+
/**
|
|
663
|
+
* Inject runtime environment info (cwd, platform, git, date).
|
|
664
|
+
* @default true
|
|
665
|
+
*/
|
|
666
|
+
includeEnvironment?: boolean;
|
|
667
|
+
/**
|
|
668
|
+
* Discover and include instruction files (AGENTS.md, etc.).
|
|
669
|
+
* @default true
|
|
670
|
+
*/
|
|
671
|
+
includeInstructions?: boolean;
|
|
672
|
+
/**
|
|
673
|
+
* File name patterns to search for when discovering instructions.
|
|
674
|
+
* Searched in each directory walking up from cwd.
|
|
675
|
+
*
|
|
676
|
+
* @default ["AGENTS.md", "CLAUDE.md", "COPILOT.md", ".cuylabs/instructions.md"]
|
|
677
|
+
*/
|
|
678
|
+
instructionPatterns?: string[];
|
|
679
|
+
/**
|
|
680
|
+
* Absolute paths to global instruction files (always included
|
|
681
|
+
* regardless of cwd). Useful for organization-wide rules.
|
|
682
|
+
*/
|
|
683
|
+
globalInstructions?: string[];
|
|
684
|
+
/**
|
|
685
|
+
* Maximum depth to walk up from cwd when searching for instructions.
|
|
686
|
+
* Prevents scanning the entire filesystem.
|
|
687
|
+
* @default 10
|
|
688
|
+
*/
|
|
689
|
+
instructionMaxDepth?: number;
|
|
690
|
+
/**
|
|
691
|
+
* Maximum file size in bytes for instruction files.
|
|
692
|
+
* Files larger than this are skipped to avoid bloating the prompt.
|
|
693
|
+
* @default 51200 (50KB)
|
|
694
|
+
*/
|
|
695
|
+
instructionMaxSize?: number;
|
|
696
|
+
/**
|
|
697
|
+
* Pre-defined sections to include in every prompt build.
|
|
698
|
+
* These are merged with auto-generated sections (template, environment, etc.).
|
|
699
|
+
*/
|
|
700
|
+
sections?: PromptSection[];
|
|
701
|
+
/**
|
|
702
|
+
* Separator between sections in the final composed prompt.
|
|
703
|
+
* @default "\n\n"
|
|
704
|
+
*/
|
|
705
|
+
separator?: string;
|
|
706
|
+
/**
|
|
707
|
+
* Skill discovery and loading configuration.
|
|
708
|
+
*
|
|
709
|
+
* When provided, the prompt pipeline will:
|
|
710
|
+
* 1. Discover SKILL.md files from project, user, and global directories
|
|
711
|
+
* 2. Inject skill summaries at PRIORITY_SKILLS (70) in the system prompt
|
|
712
|
+
* 3. Make `skill` and `skill_resource` tools available to the agent
|
|
713
|
+
*
|
|
714
|
+
* Skills use progressive disclosure:
|
|
715
|
+
* - L1 (summary): always in system prompt — names + descriptions
|
|
716
|
+
* - L2 (content): loaded on demand via `skill` tool
|
|
717
|
+
* - L3 (resources): loaded on demand via `skill_resource` tool
|
|
718
|
+
*
|
|
719
|
+
* @example
|
|
720
|
+
* ```typescript
|
|
721
|
+
* const agent = createAgent({
|
|
722
|
+
* model: anthropic("claude-sonnet-4-20250514"),
|
|
723
|
+
* prompt: {
|
|
724
|
+
* skills: {
|
|
725
|
+
* externalDirs: [".agents", ".claude"],
|
|
726
|
+
* roots: ["./company-skills"],
|
|
727
|
+
* },
|
|
728
|
+
* },
|
|
729
|
+
* });
|
|
730
|
+
* ```
|
|
731
|
+
*/
|
|
732
|
+
skills?: SkillConfig;
|
|
733
|
+
}
|
|
734
|
+
|
|
735
|
+
/**
|
|
736
|
+
* Stream types for @cuylabs/agent-core
|
|
737
|
+
*
|
|
738
|
+
* Defines the canonical StreamChunk union and related types
|
|
739
|
+
* for both AI SDK native and custom stream providers.
|
|
740
|
+
*/
|
|
741
|
+
/**
|
|
742
|
+
* Stream chunk types (AI SDK compatible + custom streams)
|
|
743
|
+
*
|
|
744
|
+
* This is the single canonical definition — used by both the
|
|
745
|
+
* streaming module and custom stream providers.
|
|
746
|
+
*/
|
|
747
|
+
type StreamChunk = {
|
|
748
|
+
type: "text-start";
|
|
749
|
+
} | {
|
|
750
|
+
type: "text-delta";
|
|
751
|
+
text: string;
|
|
752
|
+
} | {
|
|
753
|
+
type: "text-end";
|
|
754
|
+
} | {
|
|
755
|
+
type: "reasoning-start";
|
|
756
|
+
id: string;
|
|
757
|
+
} | {
|
|
758
|
+
type: "reasoning-delta";
|
|
759
|
+
id: string;
|
|
760
|
+
text: string;
|
|
761
|
+
} | {
|
|
762
|
+
type: "reasoning-end";
|
|
763
|
+
id: string;
|
|
764
|
+
} | {
|
|
765
|
+
type: "tool-call";
|
|
766
|
+
toolName: string;
|
|
767
|
+
toolCallId: string;
|
|
768
|
+
input: unknown;
|
|
769
|
+
} | {
|
|
770
|
+
type: "tool-result";
|
|
771
|
+
toolName: string;
|
|
772
|
+
toolCallId: string;
|
|
773
|
+
output: unknown;
|
|
774
|
+
} | {
|
|
775
|
+
type: "tool-error";
|
|
776
|
+
toolName: string;
|
|
777
|
+
toolCallId: string;
|
|
778
|
+
error: unknown;
|
|
779
|
+
} | {
|
|
780
|
+
type: "finish-step";
|
|
781
|
+
usage?: {
|
|
782
|
+
inputTokens?: number;
|
|
783
|
+
outputTokens?: number;
|
|
784
|
+
totalTokens?: number;
|
|
785
|
+
};
|
|
786
|
+
finishReason?: string;
|
|
787
|
+
} | {
|
|
788
|
+
type: "finish";
|
|
789
|
+
totalUsage?: {
|
|
790
|
+
inputTokens?: number;
|
|
791
|
+
outputTokens?: number;
|
|
792
|
+
totalTokens?: number;
|
|
793
|
+
};
|
|
794
|
+
} | {
|
|
795
|
+
type: "error";
|
|
796
|
+
error: unknown;
|
|
797
|
+
} | {
|
|
798
|
+
type: "start-step";
|
|
799
|
+
} | {
|
|
800
|
+
type: "start";
|
|
801
|
+
} | {
|
|
802
|
+
type: "abort";
|
|
803
|
+
} | {
|
|
804
|
+
type: "computer-call";
|
|
805
|
+
callId: string;
|
|
806
|
+
action: unknown;
|
|
807
|
+
pendingSafetyChecks?: unknown[];
|
|
808
|
+
} | {
|
|
809
|
+
type: "step-usage";
|
|
810
|
+
usage: {
|
|
811
|
+
inputTokens: number;
|
|
812
|
+
outputTokens: number;
|
|
813
|
+
totalTokens: number;
|
|
814
|
+
};
|
|
815
|
+
};
|
|
816
|
+
/**
|
|
817
|
+
* Custom stream provider function type.
|
|
818
|
+
*
|
|
819
|
+
* This matches the signature needed for agent-core's LLM module,
|
|
820
|
+
* returning a StreamProviderResult-compatible object.
|
|
821
|
+
*/
|
|
822
|
+
type StreamProvider = (input: StreamProviderInput) => Promise<StreamProviderResult>;
|
|
823
|
+
/**
|
|
824
|
+
* Input for custom stream providers
|
|
825
|
+
*/
|
|
826
|
+
interface StreamProviderInput {
|
|
827
|
+
/** System prompt */
|
|
828
|
+
system: string;
|
|
829
|
+
/** Messages to send */
|
|
830
|
+
messages: Array<{
|
|
831
|
+
role: string;
|
|
832
|
+
content: unknown;
|
|
833
|
+
}>;
|
|
834
|
+
/** Abort signal */
|
|
835
|
+
abortSignal?: AbortSignal;
|
|
836
|
+
/** Max iterations */
|
|
837
|
+
maxSteps?: number;
|
|
838
|
+
}
|
|
839
|
+
/**
|
|
840
|
+
* Result from custom stream providers (AI SDK StreamTextResult compatible)
|
|
841
|
+
*/
|
|
842
|
+
interface StreamProviderResult {
|
|
843
|
+
/** Async iterable of stream chunks */
|
|
844
|
+
fullStream: AsyncIterable<StreamChunk>;
|
|
845
|
+
/** Promise resolving to final text */
|
|
846
|
+
text: Promise<string>;
|
|
847
|
+
/** Promise resolving to usage stats */
|
|
848
|
+
usage: Promise<{
|
|
849
|
+
inputTokens: number;
|
|
850
|
+
outputTokens: number;
|
|
851
|
+
totalTokens: number;
|
|
852
|
+
}>;
|
|
853
|
+
/** Promise resolving to finish reason */
|
|
854
|
+
finishReason: Promise<string>;
|
|
855
|
+
}
|
|
856
|
+
/**
|
|
857
|
+
* Configuration for stream provider factory.
|
|
858
|
+
* Contains everything needed to create a stream provider for a specific model.
|
|
859
|
+
*/
|
|
860
|
+
interface StreamProviderConfig {
|
|
861
|
+
/** API key to use */
|
|
862
|
+
apiKey?: string;
|
|
863
|
+
/** Display dimensions */
|
|
864
|
+
display?: {
|
|
865
|
+
width: number;
|
|
866
|
+
height: number;
|
|
867
|
+
};
|
|
868
|
+
/** Environment type */
|
|
869
|
+
environment?: string;
|
|
870
|
+
/** Enable debug logging */
|
|
871
|
+
debug?: boolean;
|
|
872
|
+
}
|
|
873
|
+
/**
|
|
874
|
+
* Stream provider factory - creates a stream provider for a given model.
|
|
875
|
+
*
|
|
876
|
+
* This is attached to enhanced tools (like computer tools) to allow
|
|
877
|
+
* the Agent to automatically configure the right stream provider
|
|
878
|
+
* when a model requires custom handling (e.g., OpenAI computer-use-preview).
|
|
879
|
+
*/
|
|
880
|
+
type StreamProviderFactory = (modelId: string, config: StreamProviderConfig) => StreamProvider;
|
|
881
|
+
/**
|
|
882
|
+
* Enhanced tools array with additional capabilities.
|
|
883
|
+
*
|
|
884
|
+
* This extends the standard Tool.AnyInfo[] with optional metadata
|
|
885
|
+
* that the Agent can use for automatic configuration.
|
|
886
|
+
*/
|
|
887
|
+
interface EnhancedTools extends Array<unknown> {
|
|
888
|
+
/**
|
|
889
|
+
* Factory to create a stream provider for models that need custom streaming.
|
|
890
|
+
* Called by the Agent when it detects a model that requires special handling.
|
|
891
|
+
*/
|
|
892
|
+
__streamProviderFactory?: StreamProviderFactory;
|
|
893
|
+
/**
|
|
894
|
+
* Model patterns that require the custom stream provider.
|
|
895
|
+
* Used by the Agent to detect when to use the factory.
|
|
896
|
+
* Default patterns: ["computer-use-preview"]
|
|
897
|
+
*/
|
|
898
|
+
__customStreamModels?: string[];
|
|
899
|
+
}
|
|
900
|
+
|
|
901
|
+
/**
|
|
902
|
+
* Reasoning Types & Constants
|
|
903
|
+
*
|
|
904
|
+
* Shared type definitions, level constants, and small helpers
|
|
905
|
+
* used across the reasoning subsystem.
|
|
906
|
+
*/
|
|
907
|
+
/**
|
|
908
|
+
* Standard reasoning / thinking levels.
|
|
909
|
+
*
|
|
910
|
+
* | Level | Description |
|
|
911
|
+
* |------------|------------------------------------|
|
|
912
|
+
* | `"off"` | No reasoning (fastest) |
|
|
913
|
+
* | `"minimal"`| Very light reasoning |
|
|
914
|
+
* | `"low"` | Light reasoning |
|
|
915
|
+
* | `"medium"` | Balanced reasoning |
|
|
916
|
+
* | `"high"` | Deep reasoning |
|
|
917
|
+
* | `"xhigh"` | Maximum reasoning (where supported)|
|
|
918
|
+
*/
|
|
919
|
+
type ReasoningLevel = "off" | "minimal" | "low" | "medium" | "high" | "xhigh";
|
|
920
|
+
/**
|
|
921
|
+
* Provider-specific reasoning configuration returned by
|
|
922
|
+
* {@link getReasoningConfig} / {@link getReasoningConfigSync}.
|
|
923
|
+
*/
|
|
924
|
+
interface ReasoningConfig {
|
|
925
|
+
/** Whether the model supports reasoning at all */
|
|
926
|
+
supportsReasoning: boolean;
|
|
927
|
+
/** Reasoning levels available for this model */
|
|
928
|
+
availableLevels: ReasoningLevel[];
|
|
929
|
+
/** Build provider options for a given level */
|
|
930
|
+
getProviderOptions: (level: ReasoningLevel) => Record<string, unknown> | undefined;
|
|
931
|
+
}
|
|
932
|
+
|
|
933
|
+
/**
|
|
934
|
+
* Model Capability Types for @cuylabs/agent-core
|
|
935
|
+
*
|
|
936
|
+
* Defines the structure for model capabilities that can be sourced from
|
|
937
|
+
* static patterns, local cache, or remote APIs.
|
|
938
|
+
*/
|
|
939
|
+
/**
|
|
940
|
+
* Input modalities a model can accept
|
|
941
|
+
*/
|
|
942
|
+
type InputModality = "text" | "image" | "audio" | "video" | "pdf";
|
|
943
|
+
/**
|
|
944
|
+
* Output modalities a model can produce
|
|
945
|
+
*/
|
|
946
|
+
type OutputModality = "text" | "image" | "audio" | "video";
|
|
947
|
+
/**
|
|
948
|
+
* Comprehensive model capabilities
|
|
949
|
+
*/
|
|
950
|
+
interface ModelCapabilities {
|
|
951
|
+
/** Model supports extended reasoning/thinking */
|
|
952
|
+
reasoning: boolean;
|
|
953
|
+
/** Model supports function/tool calling */
|
|
954
|
+
toolCalling: boolean;
|
|
955
|
+
/** Model supports temperature adjustment */
|
|
956
|
+
temperature: boolean;
|
|
957
|
+
/** Model supports file attachments */
|
|
958
|
+
attachments: boolean;
|
|
959
|
+
/** Model supports streaming responses */
|
|
960
|
+
streaming: boolean;
|
|
961
|
+
/** Supported input modalities */
|
|
962
|
+
inputModalities: InputModality[];
|
|
963
|
+
/** Supported output modalities */
|
|
964
|
+
outputModalities: OutputModality[];
|
|
965
|
+
/** Maximum context window in tokens */
|
|
966
|
+
contextWindow?: number;
|
|
967
|
+
/** Maximum output tokens */
|
|
968
|
+
maxOutput?: number;
|
|
969
|
+
}
|
|
970
|
+
/**
|
|
971
|
+
* Provider-specific compatibility flags
|
|
972
|
+
* These handle quirks in different provider implementations
|
|
973
|
+
*/
|
|
974
|
+
interface ProviderCompatibility {
|
|
975
|
+
/** Supports OpenAI-style reasoning_effort parameter */
|
|
976
|
+
supportsReasoningEffort?: boolean;
|
|
977
|
+
/** Supports developer/system role distinction */
|
|
978
|
+
supportsDeveloperRole?: boolean;
|
|
979
|
+
/** Field name for max tokens (varies by provider) */
|
|
980
|
+
maxTokensField?: "max_tokens" | "max_completion_tokens";
|
|
981
|
+
/** Requires thinking as text tags vs structured */
|
|
982
|
+
requiresThinkingTags?: boolean;
|
|
983
|
+
/** Provider-specific thinking format */
|
|
984
|
+
thinkingFormat?: "openai" | "anthropic" | "google" | "zai";
|
|
985
|
+
}
|
|
986
|
+
/**
|
|
987
|
+
* Complete model entry with metadata
|
|
988
|
+
*/
|
|
989
|
+
interface ModelEntry {
|
|
990
|
+
/** Model identifier (e.g., "gpt-4o", "claude-sonnet-4") */
|
|
991
|
+
id: string;
|
|
992
|
+
/** Human-readable model name */
|
|
993
|
+
name: string;
|
|
994
|
+
/** Provider identifier (e.g., "openai", "anthropic") */
|
|
995
|
+
provider: string;
|
|
996
|
+
/** Model capabilities */
|
|
997
|
+
capabilities: ModelCapabilities;
|
|
998
|
+
/** Provider-specific compatibility settings */
|
|
999
|
+
compatibility?: ProviderCompatibility;
|
|
1000
|
+
/** Cost per million tokens (input) */
|
|
1001
|
+
costInput?: number;
|
|
1002
|
+
/** Cost per million tokens (output) */
|
|
1003
|
+
costOutput?: number;
|
|
1004
|
+
/** When this entry was last updated */
|
|
1005
|
+
updatedAt?: string;
|
|
1006
|
+
}
|
|
1007
|
+
/**
|
|
1008
|
+
* Priority levels for capability sources
|
|
1009
|
+
*/
|
|
1010
|
+
declare enum SourcePriority {
|
|
1011
|
+
/** User configuration overrides everything */
|
|
1012
|
+
UserConfig = 0,
|
|
1013
|
+
/** Local cache from previous fetch */
|
|
1014
|
+
LocalCache = 1,
|
|
1015
|
+
/** Bundled static data (build-time) */
|
|
1016
|
+
BundledData = 2,
|
|
1017
|
+
/** Pattern-based inference (fallback) */
|
|
1018
|
+
PatternMatch = 3,
|
|
1019
|
+
/** Remote API (if network available) */
|
|
1020
|
+
RemoteAPI = 4
|
|
1021
|
+
}
|
|
1022
|
+
/**
|
|
1023
|
+
* Options for the capability resolver
|
|
1024
|
+
*/
|
|
1025
|
+
interface ResolverOptions {
|
|
1026
|
+
/** Enable remote API fetching (default: false) */
|
|
1027
|
+
enableRemoteFetch?: boolean;
|
|
1028
|
+
/** Remote API URL (default: https://models.dev) */
|
|
1029
|
+
remoteApiUrl?: string;
|
|
1030
|
+
/** Cache directory path */
|
|
1031
|
+
cachePath?: string;
|
|
1032
|
+
/** Cache TTL in milliseconds (default: 1 hour) */
|
|
1033
|
+
cacheTtlMs?: number;
|
|
1034
|
+
/** Network timeout in milliseconds (default: 10 seconds) */
|
|
1035
|
+
networkTimeoutMs?: number;
|
|
1036
|
+
/** Custom user overrides for specific models */
|
|
1037
|
+
modelOverrides?: Record<string, Partial<ModelCapabilities>>;
|
|
1038
|
+
}
|
|
1039
|
+
|
|
1040
|
+
/**
|
|
1041
|
+
* Extract a model ID string from a LanguageModel instance.
|
|
1042
|
+
*/
|
|
1043
|
+
declare function getModelId(model: LanguageModel): string;
|
|
1044
|
+
/**
|
|
1045
|
+
* Extract a provider identifier from a LanguageModel instance.
|
|
1046
|
+
*/
|
|
1047
|
+
declare function getProviderId(model: LanguageModel): string | undefined;
|
|
1048
|
+
|
|
1049
|
+
/**
|
|
1050
|
+
* Remote Capability Fetching for @cuylabs/agent-core
|
|
1051
|
+
*
|
|
1052
|
+
* Handles fetching model capabilities from remote APIs (e.g., models.dev).
|
|
1053
|
+
* Includes network status detection, timeout handling, and retry logic.
|
|
1054
|
+
*/
|
|
1055
|
+
|
|
1056
|
+
/**
|
|
1057
|
+
* Network status information
|
|
1058
|
+
*/
|
|
1059
|
+
interface NetworkStatus {
|
|
1060
|
+
/** Whether we believe the network is available */
|
|
1061
|
+
online: boolean;
|
|
1062
|
+
/** Last successful fetch timestamp */
|
|
1063
|
+
lastSuccess?: number;
|
|
1064
|
+
/** Last error if any */
|
|
1065
|
+
lastError?: string;
|
|
1066
|
+
/** Number of consecutive failures */
|
|
1067
|
+
failureCount: number;
|
|
1068
|
+
}
|
|
1069
|
+
/**
|
|
1070
|
+
* Get current network status
|
|
1071
|
+
*/
|
|
1072
|
+
declare function getNetworkStatus(): NetworkStatus;
|
|
1073
|
+
|
|
1074
|
+
/**
|
|
1075
|
+
* Model Capability Resolver for @cuylabs/agent-core
|
|
1076
|
+
*
|
|
1077
|
+
* Main orchestrator that combines multiple capability sources:
|
|
1078
|
+
* 1. User overrides (highest priority)
|
|
1079
|
+
* 2. Local cache (fast, persisted)
|
|
1080
|
+
* 3. Pattern matching (always available)
|
|
1081
|
+
* 4. Remote API (optional, network-dependent)
|
|
1082
|
+
*
|
|
1083
|
+
* Designed for the Vercel AI SDK v6 ecosystem.
|
|
1084
|
+
*/
|
|
1085
|
+
|
|
1086
|
+
/**
|
|
1087
|
+
* Resolution result with source information
|
|
1088
|
+
*/
|
|
1089
|
+
interface ResolutionResult {
|
|
1090
|
+
/** The resolved model entry */
|
|
1091
|
+
entry: ModelEntry;
|
|
1092
|
+
/** Which source provided the primary result */
|
|
1093
|
+
source: SourcePriority;
|
|
1094
|
+
/** Whether this is a confident match */
|
|
1095
|
+
confident: boolean;
|
|
1096
|
+
/** Resolution timing in ms */
|
|
1097
|
+
resolveTimeMs: number;
|
|
1098
|
+
}
|
|
1099
|
+
/**
|
|
1100
|
+
* Model Capability Resolver
|
|
1101
|
+
*
|
|
1102
|
+
* Provides a unified API for querying model capabilities with
|
|
1103
|
+
* automatic fallback through multiple sources.
|
|
1104
|
+
*/
|
|
1105
|
+
declare class ModelCapabilityResolver {
|
|
1106
|
+
private options;
|
|
1107
|
+
private cache;
|
|
1108
|
+
private sources;
|
|
1109
|
+
private initialized;
|
|
1110
|
+
private initPromise;
|
|
1111
|
+
constructor(options?: Partial<ResolverOptions>);
|
|
1112
|
+
/**
|
|
1113
|
+
* Initialize the resolver (load cache, optionally fetch remote)
|
|
1114
|
+
*/
|
|
1115
|
+
initialize(): Promise<void>;
|
|
1116
|
+
/**
|
|
1117
|
+
* Resolve capabilities for a model
|
|
1118
|
+
*/
|
|
1119
|
+
resolve(model: LanguageModel): Promise<ResolutionResult>;
|
|
1120
|
+
/**
|
|
1121
|
+
* Quick check if a model supports reasoning
|
|
1122
|
+
* Uses cache/patterns only for speed
|
|
1123
|
+
*/
|
|
1124
|
+
supportsReasoning(model: LanguageModel): Promise<boolean>;
|
|
1125
|
+
/**
|
|
1126
|
+
* Get capabilities for a model
|
|
1127
|
+
*/
|
|
1128
|
+
getCapabilities(model: LanguageModel): Promise<ModelCapabilities>;
|
|
1129
|
+
/**
|
|
1130
|
+
* Get provider compatibility settings
|
|
1131
|
+
*/
|
|
1132
|
+
getCompatibility(model: LanguageModel): Promise<ProviderCompatibility | undefined>;
|
|
1133
|
+
/**
|
|
1134
|
+
* Force refresh from remote API
|
|
1135
|
+
*/
|
|
1136
|
+
refreshRemote(): Promise<void>;
|
|
1137
|
+
/**
|
|
1138
|
+
* Get current network status
|
|
1139
|
+
*/
|
|
1140
|
+
getNetworkStatus(): NetworkStatus;
|
|
1141
|
+
/**
|
|
1142
|
+
* Get resolver statistics
|
|
1143
|
+
*/
|
|
1144
|
+
getStats(): {
|
|
1145
|
+
cacheSize: number;
|
|
1146
|
+
cacheLoaded: boolean;
|
|
1147
|
+
remoteFetchEnabled: boolean;
|
|
1148
|
+
networkOnline: boolean;
|
|
1149
|
+
};
|
|
1150
|
+
/**
|
|
1151
|
+
* Clear all cached data
|
|
1152
|
+
*/
|
|
1153
|
+
clearCache(): Promise<void>;
|
|
1154
|
+
/**
|
|
1155
|
+
* List all available models
|
|
1156
|
+
* Fetches from remote if cache is empty and remote is enabled
|
|
1157
|
+
*/
|
|
1158
|
+
listModels(): Promise<ModelEntry[]>;
|
|
1159
|
+
/**
|
|
1160
|
+
* List all available models grouped by provider
|
|
1161
|
+
*/
|
|
1162
|
+
listModelsByProvider(): Promise<Record<string, ModelEntry[]>>;
|
|
1163
|
+
}
|
|
1164
|
+
/**
|
|
1165
|
+
* Get the default resolver instance
|
|
1166
|
+
*/
|
|
1167
|
+
declare function getDefaultResolver(): ModelCapabilityResolver;
|
|
1168
|
+
/**
|
|
1169
|
+
* Configure the default resolver with custom options
|
|
1170
|
+
*/
|
|
1171
|
+
declare function configureResolver(options: Partial<ResolverOptions>): void;
|
|
1172
|
+
|
|
1173
|
+
/**
|
|
1174
|
+
* Reasoning Configuration & Option Builders
|
|
1175
|
+
*
|
|
1176
|
+
* Orchestrates capability detection and provider-specific option
|
|
1177
|
+
* building to produce ready-to-use `providerOptions` for the
|
|
1178
|
+
* Vercel AI SDK.
|
|
1179
|
+
*
|
|
1180
|
+
* Two flavours of every function are provided:
|
|
1181
|
+
* - **Async** (`getReasoningConfig`, `buildReasoningOptions`) —
|
|
1182
|
+
* uses the full capability resolver (network + cache).
|
|
1183
|
+
* - **Sync** (`getReasoningConfigSync`, `buildReasoningOptionsSync`) —
|
|
1184
|
+
* uses fast pattern-matching only (no network).
|
|
1185
|
+
*/
|
|
1186
|
+
|
|
1187
|
+
/**
|
|
1188
|
+
* Get the reasoning configuration for a model.
|
|
1189
|
+
*
|
|
1190
|
+
* Uses the full capability resolver (including network lookups)
|
|
1191
|
+
* for the most accurate result.
|
|
1192
|
+
*/
|
|
1193
|
+
declare function getReasoningConfig(model: LanguageModel): Promise<ReasoningConfig>;
|
|
1194
|
+
/**
|
|
1195
|
+
* Synchronous reasoning config using pattern-matching only.
|
|
1196
|
+
*
|
|
1197
|
+
* Faster but less accurate than {@link getReasoningConfig}.
|
|
1198
|
+
* Good for hot paths where async is impractical.
|
|
1199
|
+
*/
|
|
916
1200
|
declare function getReasoningConfigSync(model: LanguageModel): ReasoningConfig;
|
|
917
1201
|
/**
|
|
918
1202
|
* Build `providerOptions` for a reasoning level (async).
|
|
@@ -1159,456 +1443,633 @@ declare function httpServer(url: string, options?: Omit<HttpTransportConfig, "tr
|
|
|
1159
1443
|
declare function sseServer(url: string, options?: Omit<SseTransportConfig, "transport" | "url">): SseTransportConfig;
|
|
1160
1444
|
|
|
1161
1445
|
/**
|
|
1162
|
-
*
|
|
1163
|
-
*
|
|
1164
|
-
* Types for the layered system prompt architecture.
|
|
1165
|
-
* The prompt pipeline composes a system prompt from multiple sources:
|
|
1166
|
-
*
|
|
1167
|
-
* Base Template → Environment → Instructions → Custom Sections → Per-Turn
|
|
1446
|
+
* Agent configuration and state types for @cuylabs/agent-core
|
|
1168
1447
|
*
|
|
1169
|
-
*
|
|
1448
|
+
* Defines AgentConfig (the main config surface), AgentState,
|
|
1449
|
+
* doom-loop types, and compaction configuration.
|
|
1170
1450
|
*/
|
|
1171
1451
|
|
|
1172
1452
|
/**
|
|
1173
|
-
*
|
|
1174
|
-
*
|
|
1175
|
-
* Each family gets a base template optimized for its strengths:
|
|
1176
|
-
* - `anthropic`: Claude models — structured sections with XML tags
|
|
1177
|
-
* - `openai`: GPT/o-series models — clear directives with markdown
|
|
1178
|
-
* - `google`: Gemini models — balanced approach
|
|
1179
|
-
* - `deepseek`: DeepSeek models — code-focused emphasis
|
|
1180
|
-
* - `default`: Generic template for any model
|
|
1181
|
-
*/
|
|
1182
|
-
type ModelFamily = "anthropic" | "openai" | "google" | "deepseek" | "default";
|
|
1183
|
-
/**
|
|
1184
|
-
* Runtime environment information injected into the system prompt.
|
|
1185
|
-
* Gives the model awareness of the working context.
|
|
1453
|
+
* Agent configuration
|
|
1186
1454
|
*/
|
|
1187
|
-
interface
|
|
1188
|
-
/**
|
|
1189
|
-
|
|
1190
|
-
/**
|
|
1191
|
-
|
|
1192
|
-
/**
|
|
1193
|
-
|
|
1194
|
-
/**
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1455
|
+
interface AgentConfig {
|
|
1456
|
+
/** Vercel AI SDK model instance */
|
|
1457
|
+
model: LanguageModel;
|
|
1458
|
+
/** System prompt */
|
|
1459
|
+
systemPrompt?: string;
|
|
1460
|
+
/** Working directory */
|
|
1461
|
+
cwd?: string;
|
|
1462
|
+
/**
|
|
1463
|
+
* Execution environment for tools.
|
|
1464
|
+
*
|
|
1465
|
+
* Controls *where* tools run — local machine, Docker container, SSH host, etc.
|
|
1466
|
+
* When not provided, defaults to `localHost(cwd)` which uses the local
|
|
1467
|
+
* filesystem and shell directly.
|
|
1468
|
+
*
|
|
1469
|
+
* @example
|
|
1470
|
+
* ```typescript
|
|
1471
|
+
* import { localHost } from "@cuylabs/agent-core";
|
|
1472
|
+
*
|
|
1473
|
+
* // Explicit local host (same as default)
|
|
1474
|
+
* const agent = createAgent({ host: localHost("/my/project") });
|
|
1475
|
+
*
|
|
1476
|
+
* // Future: Docker host
|
|
1477
|
+
* // const agent = createAgent({ host: dockerHost("my-container") });
|
|
1478
|
+
* ```
|
|
1479
|
+
*/
|
|
1480
|
+
host?: ToolHost;
|
|
1481
|
+
/** Temperature (0-1) */
|
|
1482
|
+
temperature?: number;
|
|
1483
|
+
/** Top-p sampling */
|
|
1484
|
+
topP?: number;
|
|
1485
|
+
/** Max output tokens */
|
|
1486
|
+
maxOutputTokens?: number;
|
|
1487
|
+
/** Maximum steps (tool call iterations) */
|
|
1488
|
+
maxSteps?: number;
|
|
1489
|
+
/** Reasoning/thinking level for models that support it */
|
|
1490
|
+
reasoningLevel?: ReasoningLevel;
|
|
1491
|
+
/** Require approval for dangerous operations */
|
|
1492
|
+
requireApproval?: boolean;
|
|
1493
|
+
/**
|
|
1494
|
+
* Handler for doom loop detection.
|
|
1495
|
+
*
|
|
1496
|
+
* When the agent detects repeated identical tool calls (default: 3 times),
|
|
1497
|
+
* this handler is called to decide what to do.
|
|
1498
|
+
*
|
|
1499
|
+
* If not provided:
|
|
1500
|
+
* - enforceDoomLoop=true (default): throws DoomLoopError
|
|
1501
|
+
* - enforceDoomLoop=false: logs warning and continues
|
|
1502
|
+
*
|
|
1503
|
+
* @see DoomLoopHandler
|
|
1504
|
+
*/
|
|
1505
|
+
onDoomLoop?: DoomLoopHandler;
|
|
1506
|
+
/**
|
|
1507
|
+
* Strictly enforce doom loop (throw error).
|
|
1508
|
+
* Only used when onDoomLoop is not provided.
|
|
1509
|
+
* Default: true
|
|
1510
|
+
*/
|
|
1511
|
+
enforceDoomLoop?: boolean;
|
|
1512
|
+
/**
|
|
1513
|
+
* Number of identical tool calls before triggering doom loop.
|
|
1514
|
+
* Default: 3
|
|
1515
|
+
*/
|
|
1516
|
+
doomLoopThreshold?: number;
|
|
1517
|
+
/**
|
|
1518
|
+
* Context compaction configuration.
|
|
1519
|
+
* Controls automatic management of the context window.
|
|
1520
|
+
*
|
|
1521
|
+
* @see CompactionConfig
|
|
1522
|
+
*/
|
|
1523
|
+
compaction?: CompactionConfig;
|
|
1524
|
+
/**
|
|
1525
|
+
* Middleware for agent lifecycle hooks.
|
|
1526
|
+
*
|
|
1527
|
+
* Middleware runs in array order for "before" operations and reverse
|
|
1528
|
+
* order for "after" operations. Each middleware is a plain object with
|
|
1529
|
+
* optional hook methods — no classes or registration required.
|
|
1530
|
+
*
|
|
1531
|
+
* Middleware hooks:
|
|
1532
|
+
* - `beforeToolCall` — intercept tool calls (approve/deny)
|
|
1533
|
+
* - `afterToolCall` — transform tool results
|
|
1534
|
+
* - `promptSections` — inject dynamic prompt content
|
|
1535
|
+
* - `onEvent` — observe streaming events
|
|
1536
|
+
* - `onChatStart` / `onChatEnd` — lifecycle callbacks
|
|
1537
|
+
*
|
|
1538
|
+
* @example
|
|
1539
|
+
* ```typescript
|
|
1540
|
+
* const agent = createAgent({
|
|
1541
|
+
* middleware: [
|
|
1542
|
+
* approvalMiddleware({ onRequest: askUser }),
|
|
1543
|
+
* { name: "logger", onEvent: (e) => console.log(e.type) },
|
|
1544
|
+
* ],
|
|
1545
|
+
* });
|
|
1546
|
+
* ```
|
|
1547
|
+
*/
|
|
1548
|
+
middleware?: AgentMiddleware[];
|
|
1549
|
+
/**
|
|
1550
|
+
* Context window size in tokens (for overflow detection).
|
|
1551
|
+
* If not provided, defaults to 128,000 tokens.
|
|
1552
|
+
*
|
|
1553
|
+
* This should match your model's context limit.
|
|
1554
|
+
*/
|
|
1555
|
+
contextWindow?: number;
|
|
1556
|
+
/**
|
|
1557
|
+
* Custom stream provider for specialized models (e.g., OpenAI computer use).
|
|
1558
|
+
*
|
|
1559
|
+
* When provided, this function will be called instead of the default
|
|
1560
|
+
* AI SDK streamText(). This allows packages like @cuylabs/computer-agent
|
|
1561
|
+
* to inject custom streaming implementations without circular dependencies.
|
|
1562
|
+
*
|
|
1563
|
+
* The returned object must have a `fullStream` async iterable that yields
|
|
1564
|
+
* AI SDK compatible chunks (text-delta, tool-call, tool-result, etc.).
|
|
1565
|
+
*/
|
|
1566
|
+
streamProvider?: StreamProvider;
|
|
1567
|
+
/**
|
|
1568
|
+
* MCP (Model Context Protocol) manager for external tool servers.
|
|
1569
|
+
*
|
|
1570
|
+
* When provided, the agent will connect to configured MCP servers
|
|
1571
|
+
* and make their tools available alongside local tools.
|
|
1572
|
+
*
|
|
1573
|
+
* @example
|
|
1574
|
+
* ```typescript
|
|
1575
|
+
* import { createMCPManager } from "@cuylabs/agent-core";
|
|
1576
|
+
*
|
|
1577
|
+
* const mcp = createMCPManager({
|
|
1578
|
+
* filesystem: {
|
|
1579
|
+
* transport: "stdio",
|
|
1580
|
+
* command: "npx",
|
|
1581
|
+
* args: ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"],
|
|
1582
|
+
* },
|
|
1583
|
+
* });
|
|
1584
|
+
*
|
|
1585
|
+
* const agent = createAgent({
|
|
1586
|
+
* model: openai("gpt-4o"),
|
|
1587
|
+
* mcp,
|
|
1588
|
+
* });
|
|
1589
|
+
* ```
|
|
1590
|
+
*/
|
|
1591
|
+
mcp?: MCPManager;
|
|
1592
|
+
/**
|
|
1593
|
+
* Prompt pipeline configuration.
|
|
1594
|
+
*
|
|
1595
|
+
* When provided, enables the layered prompt system that automatically
|
|
1596
|
+
* composes system prompts from:
|
|
1597
|
+
* - Model-family-optimized base templates
|
|
1598
|
+
* - Runtime environment info (cwd, platform, git branch)
|
|
1599
|
+
* - Instruction files (AGENTS.md, CLAUDE.md discovered on disk)
|
|
1600
|
+
* - Custom sections you define
|
|
1601
|
+
* - Per-turn overrides from chat options
|
|
1602
|
+
*
|
|
1603
|
+
* When neither `prompt` nor `systemPrompt` is provided, the pipeline
|
|
1604
|
+
* is enabled with sensible defaults.
|
|
1605
|
+
*
|
|
1606
|
+
* When `systemPrompt` is provided without `prompt`, the flat string
|
|
1607
|
+
* is used directly (backward compatible).
|
|
1608
|
+
*
|
|
1609
|
+
* @example
|
|
1610
|
+
* ```typescript
|
|
1611
|
+
* const agent = createAgent({
|
|
1612
|
+
* model: anthropic("claude-sonnet-4-20250514"),
|
|
1613
|
+
* prompt: {
|
|
1614
|
+
* includeEnvironment: true,
|
|
1615
|
+
* includeInstructions: true,
|
|
1616
|
+
* sections: [
|
|
1617
|
+
* { id: "team", label: "Team Rules", content: "Use strict TypeScript." },
|
|
1618
|
+
* ],
|
|
1619
|
+
* },
|
|
1620
|
+
* });
|
|
1621
|
+
* ```
|
|
1622
|
+
*/
|
|
1623
|
+
prompt?: PromptConfig;
|
|
1202
1624
|
}
|
|
1203
1625
|
/**
|
|
1204
|
-
*
|
|
1205
|
-
*
|
|
1206
|
-
* Instruction files provide project-specific or workspace-level guidance
|
|
1207
|
-
* that gets injected into every prompt. They're discovered by walking up
|
|
1208
|
-
* the directory tree from cwd.
|
|
1626
|
+
* Agent state
|
|
1209
1627
|
*/
|
|
1210
|
-
interface
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
/**
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
depth: number;
|
|
1628
|
+
interface AgentState {
|
|
1629
|
+
model: LanguageModel;
|
|
1630
|
+
systemPrompt: string;
|
|
1631
|
+
cwd: string;
|
|
1632
|
+
isStreaming: boolean;
|
|
1633
|
+
/** Current reasoning level */
|
|
1634
|
+
reasoningLevel: ReasoningLevel;
|
|
1635
|
+
error?: Error;
|
|
1219
1636
|
}
|
|
1220
1637
|
/**
|
|
1221
|
-
*
|
|
1222
|
-
*
|
|
1223
|
-
* Sections are the building blocks of the final system prompt.
|
|
1224
|
-
* Each section has a priority that determines its position in the output.
|
|
1638
|
+
* Doom loop handler response - what to do when a doom loop is detected.
|
|
1225
1639
|
*
|
|
1226
|
-
*
|
|
1227
|
-
* -
|
|
1228
|
-
* -
|
|
1229
|
-
* -
|
|
1230
|
-
* - 50: Custom sections (default for user-added)
|
|
1231
|
-
* - 70: Reserved for future use (e.g. Skills)
|
|
1232
|
-
* - 90: Per-turn overrides
|
|
1640
|
+
* Actions:
|
|
1641
|
+
* - "allow" - Allow this once
|
|
1642
|
+
* - "remember" - Allow and remember for this session
|
|
1643
|
+
* - "deny" - Reject and throw error
|
|
1233
1644
|
*/
|
|
1234
|
-
|
|
1235
|
-
/** Unique identifier for this section */
|
|
1236
|
-
id: string;
|
|
1237
|
-
/** Human-readable label (useful for debugging/logging) */
|
|
1238
|
-
label: string;
|
|
1239
|
-
/** The text content of this section */
|
|
1240
|
-
content: string;
|
|
1241
|
-
/** Sort priority — lower values appear earlier (default: 50) */
|
|
1242
|
-
priority?: number;
|
|
1243
|
-
/** Whether this section is active (default: true) */
|
|
1244
|
-
enabled?: boolean;
|
|
1245
|
-
}
|
|
1645
|
+
type DoomLoopAction = "allow" | "deny" | "remember";
|
|
1246
1646
|
/**
|
|
1247
|
-
*
|
|
1248
|
-
*
|
|
1249
|
-
* This provides the runtime information needed to compose
|
|
1250
|
-
* the system prompt for a specific conversation turn.
|
|
1647
|
+
* Doom loop detection request.
|
|
1648
|
+
* Sent to the handler when repeated tool calls are detected.
|
|
1251
1649
|
*/
|
|
1252
|
-
interface
|
|
1253
|
-
/**
|
|
1254
|
-
|
|
1255
|
-
/**
|
|
1256
|
-
|
|
1257
|
-
/**
|
|
1258
|
-
|
|
1259
|
-
/**
|
|
1260
|
-
|
|
1261
|
-
/** Current session ID */
|
|
1262
|
-
sessionId?: string;
|
|
1650
|
+
interface DoomLoopRequest {
|
|
1651
|
+
/** The tool being called repeatedly */
|
|
1652
|
+
tool: string;
|
|
1653
|
+
/** How many times it's been called with same input */
|
|
1654
|
+
repeatCount: number;
|
|
1655
|
+
/** The input being passed (for context) */
|
|
1656
|
+
input: unknown;
|
|
1657
|
+
/** Session ID */
|
|
1658
|
+
sessionId: string;
|
|
1263
1659
|
}
|
|
1264
1660
|
/**
|
|
1265
|
-
*
|
|
1661
|
+
* Handler for doom loop situations.
|
|
1266
1662
|
*
|
|
1267
|
-
*
|
|
1268
|
-
*
|
|
1269
|
-
*
|
|
1663
|
+
* Return:
|
|
1664
|
+
* - "allow": Continue despite the loop
|
|
1665
|
+
* - "deny": Stop execution and throw error
|
|
1666
|
+
* - "remember": Allow and don't ask again for this tool in this session
|
|
1270
1667
|
*
|
|
1271
1668
|
* @example
|
|
1272
1669
|
* ```typescript
|
|
1273
|
-
*
|
|
1274
|
-
*
|
|
1275
|
-
*
|
|
1276
|
-
*
|
|
1277
|
-
*
|
|
1278
|
-
*
|
|
1279
|
-
*
|
|
1280
|
-
*
|
|
1281
|
-
*
|
|
1282
|
-
*
|
|
1283
|
-
* // Fully custom — disable auto features, add your own sections
|
|
1284
|
-
* const builder = createPromptBuilder({
|
|
1285
|
-
* includeEnvironment: false,
|
|
1286
|
-
* includeInstructions: false,
|
|
1287
|
-
* sections: [
|
|
1288
|
-
* { id: "role", label: "Role", content: "You audit code.", priority: 10 },
|
|
1289
|
-
* { id: "rules", label: "Rules", content: "Never modify files.", priority: 20 },
|
|
1290
|
-
* ],
|
|
1670
|
+
* const agent = createAgent({
|
|
1671
|
+
* model: anthropic("claude-sonnet-4-20250514"),
|
|
1672
|
+
* onDoomLoop: async (req) => {
|
|
1673
|
+
* // Show UI asking user
|
|
1674
|
+
* const action = await showConfirmDialog(
|
|
1675
|
+
* `${req.tool} called ${req.repeatCount} times with same input. Continue?`
|
|
1676
|
+
* );
|
|
1677
|
+
* return action;
|
|
1678
|
+
* },
|
|
1291
1679
|
* });
|
|
1292
1680
|
* ```
|
|
1293
1681
|
*/
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
modelFamily?: ModelFamily;
|
|
1305
|
-
/**
|
|
1306
|
-
* Inject runtime environment info (cwd, platform, git, date).
|
|
1307
|
-
* @default true
|
|
1308
|
-
*/
|
|
1309
|
-
includeEnvironment?: boolean;
|
|
1682
|
+
type DoomLoopHandler = (request: DoomLoopRequest) => Promise<DoomLoopAction>;
|
|
1683
|
+
/**
|
|
1684
|
+
* Configuration for automatic context compaction.
|
|
1685
|
+
*
|
|
1686
|
+
* Features:
|
|
1687
|
+
* - Auto-pruning of old tool outputs
|
|
1688
|
+
* - LLM-based summarization
|
|
1689
|
+
* - Auto-continue after compaction
|
|
1690
|
+
*/
|
|
1691
|
+
interface CompactionConfig {
|
|
1310
1692
|
/**
|
|
1311
|
-
*
|
|
1312
|
-
*
|
|
1693
|
+
* Enable automatic compaction when context overflows.
|
|
1694
|
+
* Default: true
|
|
1313
1695
|
*/
|
|
1314
|
-
|
|
1696
|
+
auto?: boolean;
|
|
1315
1697
|
/**
|
|
1316
|
-
*
|
|
1317
|
-
*
|
|
1318
|
-
*
|
|
1319
|
-
* @default ["AGENTS.md", "CLAUDE.md", "COPILOT.md", ".cuylabs/instructions.md"]
|
|
1698
|
+
* Enable pruning of old tool outputs before summarization.
|
|
1699
|
+
* This is a lightweight operation that removes tool result content.
|
|
1700
|
+
* Default: true
|
|
1320
1701
|
*/
|
|
1321
|
-
|
|
1702
|
+
prune?: boolean;
|
|
1322
1703
|
/**
|
|
1323
|
-
*
|
|
1324
|
-
*
|
|
1704
|
+
* Protect this many recent tokens from pruning.
|
|
1705
|
+
* Default: 40,000
|
|
1325
1706
|
*/
|
|
1326
|
-
|
|
1707
|
+
protectedTokens?: number;
|
|
1327
1708
|
/**
|
|
1328
|
-
*
|
|
1329
|
-
*
|
|
1330
|
-
* @default 10
|
|
1709
|
+
* Minimum tokens to trigger pruning.
|
|
1710
|
+
* Default: 20,000
|
|
1331
1711
|
*/
|
|
1332
|
-
|
|
1712
|
+
pruneMinimum?: number;
|
|
1333
1713
|
/**
|
|
1334
|
-
*
|
|
1335
|
-
*
|
|
1336
|
-
* @default 51200 (50KB)
|
|
1714
|
+
* Custom summarization prompt for compaction.
|
|
1715
|
+
* If not provided, uses default prompt asking for continuation context.
|
|
1337
1716
|
*/
|
|
1338
|
-
|
|
1717
|
+
summaryPrompt?: string;
|
|
1339
1718
|
/**
|
|
1340
|
-
*
|
|
1341
|
-
*
|
|
1719
|
+
* Model to use for summarization (optional).
|
|
1720
|
+
* If not provided, uses the same model as the agent.
|
|
1721
|
+
* You might want to use a cheaper/faster model here.
|
|
1342
1722
|
*/
|
|
1343
|
-
|
|
1723
|
+
summaryModel?: LanguageModel;
|
|
1344
1724
|
/**
|
|
1345
|
-
*
|
|
1346
|
-
*
|
|
1725
|
+
* Auto-continue after compaction with "Continue if you have next steps".
|
|
1726
|
+
* Default: true
|
|
1347
1727
|
*/
|
|
1348
|
-
|
|
1728
|
+
autoContinue?: boolean;
|
|
1349
1729
|
}
|
|
1350
1730
|
|
|
1351
1731
|
/**
|
|
1352
|
-
*
|
|
1732
|
+
* Middleware Types
|
|
1353
1733
|
*
|
|
1354
|
-
* Defines
|
|
1355
|
-
*
|
|
1734
|
+
* Defines the composable middleware interface for agent lifecycle hooks.
|
|
1735
|
+
*
|
|
1736
|
+
* Middleware is just a plain object with optional hook methods — no
|
|
1737
|
+
* base classes, no discovery, no installation. Pass it in code:
|
|
1738
|
+
*
|
|
1739
|
+
* ```typescript
|
|
1740
|
+
* const agent = createAgent({
|
|
1741
|
+
* middleware: [myLoggerMiddleware, myApprovalMiddleware],
|
|
1742
|
+
* });
|
|
1743
|
+
* ```
|
|
1744
|
+
*
|
|
1745
|
+
* Hooks run in array order for "before" operations and reverse order
|
|
1746
|
+
* for "after" operations (like middleware stacks everywhere).
|
|
1356
1747
|
*/
|
|
1357
1748
|
|
|
1358
1749
|
/**
|
|
1359
|
-
*
|
|
1750
|
+
* Action returned by `beforeToolCall` — determines whether
|
|
1751
|
+
* the tool call proceeds or is blocked.
|
|
1360
1752
|
*/
|
|
1361
|
-
interface
|
|
1362
|
-
/**
|
|
1363
|
-
|
|
1364
|
-
/**
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1753
|
+
interface ToolCallDecision {
|
|
1754
|
+
/** Whether to allow or deny the tool call */
|
|
1755
|
+
action: "allow" | "deny";
|
|
1756
|
+
/** Reason for denial — returned to the model as the tool output */
|
|
1757
|
+
reason?: string;
|
|
1758
|
+
}
|
|
1759
|
+
/**
|
|
1760
|
+
* Agent middleware — composable lifecycle hooks.
|
|
1761
|
+
*
|
|
1762
|
+
* All methods are optional. Implement only what you need.
|
|
1763
|
+
*
|
|
1764
|
+
* Ordering:
|
|
1765
|
+
* - `beforeToolCall`: runs in array order, first "deny" wins
|
|
1766
|
+
* - `afterToolCall`: runs in reverse order (innermost first)
|
|
1767
|
+
* - `promptSections`: all run, sections merged
|
|
1768
|
+
* - `onEvent`: all run in parallel (non-blocking)
|
|
1769
|
+
* - `onChatStart` / `onChatEnd`: run in array order, awaited sequentially
|
|
1770
|
+
*
|
|
1771
|
+
* @example
|
|
1772
|
+
* ```typescript
|
|
1773
|
+
* // A simple logging middleware
|
|
1774
|
+
* const logger: AgentMiddleware = {
|
|
1775
|
+
* name: "logger",
|
|
1776
|
+
* beforeToolCall: async (tool, args) => {
|
|
1777
|
+
* console.log(`→ ${tool}`, args);
|
|
1778
|
+
* return { action: "allow" };
|
|
1779
|
+
* },
|
|
1780
|
+
* afterToolCall: async (tool, args, result) => {
|
|
1781
|
+
* console.log(`← ${tool}`, result.title);
|
|
1782
|
+
* return result;
|
|
1783
|
+
* },
|
|
1784
|
+
* };
|
|
1785
|
+
* ```
|
|
1786
|
+
*/
|
|
1787
|
+
interface AgentMiddleware {
|
|
1788
|
+
/** Middleware name (for logging and debugging) */
|
|
1789
|
+
name: string;
|
|
1368
1790
|
/**
|
|
1369
|
-
*
|
|
1791
|
+
* Intercept a tool call before execution.
|
|
1370
1792
|
*
|
|
1371
|
-
*
|
|
1372
|
-
*
|
|
1373
|
-
*
|
|
1374
|
-
*
|
|
1375
|
-
* @example
|
|
1376
|
-
* ```typescript
|
|
1377
|
-
* import { localHost } from "@cuylabs/agent-core";
|
|
1793
|
+
* Return `{ action: "allow" }` to proceed, or `{ action: "deny", reason }` to
|
|
1794
|
+
* block the call. When denied, `reason` is returned to the model as the tool
|
|
1795
|
+
* output so it can adjust its approach.
|
|
1378
1796
|
*
|
|
1379
|
-
*
|
|
1380
|
-
*
|
|
1797
|
+
* Runs in array order. The first middleware that returns "deny" short-circuits
|
|
1798
|
+
* the chain — remaining middleware and the tool itself are skipped.
|
|
1381
1799
|
*
|
|
1382
|
-
*
|
|
1383
|
-
*
|
|
1384
|
-
*
|
|
1800
|
+
* @param tool - Tool name (e.g. "bash", "write_file")
|
|
1801
|
+
* @param args - Parsed tool arguments
|
|
1802
|
+
* @param ctx - Tool execution context (cwd, sessionID, host, etc.)
|
|
1385
1803
|
*/
|
|
1386
|
-
|
|
1387
|
-
/** Temperature (0-1) */
|
|
1388
|
-
temperature?: number;
|
|
1389
|
-
/** Top-p sampling */
|
|
1390
|
-
topP?: number;
|
|
1391
|
-
/** Max output tokens */
|
|
1392
|
-
maxOutputTokens?: number;
|
|
1393
|
-
/** Maximum steps (tool call iterations) */
|
|
1394
|
-
maxSteps?: number;
|
|
1395
|
-
/** Reasoning/thinking level for models that support it */
|
|
1396
|
-
reasoningLevel?: ReasoningLevel;
|
|
1397
|
-
/** Require approval for dangerous operations */
|
|
1398
|
-
requireApproval?: boolean;
|
|
1804
|
+
beforeToolCall?(tool: string, args: unknown, ctx: ToolContext): Promise<ToolCallDecision>;
|
|
1399
1805
|
/**
|
|
1400
|
-
*
|
|
1401
|
-
*
|
|
1402
|
-
* When the agent detects repeated identical tool calls (default: 3 times),
|
|
1403
|
-
* this handler is called to decide what to do.
|
|
1404
|
-
*
|
|
1405
|
-
* If not provided:
|
|
1406
|
-
* - enforceDoomLoop=true (default): throws DoomLoopError
|
|
1407
|
-
* - enforceDoomLoop=false: logs warning and continues
|
|
1806
|
+
* Transform or observe a tool result after execution.
|
|
1408
1807
|
*
|
|
1409
|
-
*
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
/**
|
|
1413
|
-
* Strictly enforce doom loop (throw error).
|
|
1414
|
-
* Only used when onDoomLoop is not provided.
|
|
1415
|
-
* Default: true
|
|
1416
|
-
*/
|
|
1417
|
-
enforceDoomLoop?: boolean;
|
|
1418
|
-
/**
|
|
1419
|
-
* Number of identical tool calls before triggering doom loop.
|
|
1420
|
-
* Default: 3 (like OpenCode's DOOM_LOOP_THRESHOLD)
|
|
1421
|
-
*/
|
|
1422
|
-
doomLoopThreshold?: number;
|
|
1423
|
-
/**
|
|
1424
|
-
* Context compaction configuration.
|
|
1425
|
-
* Controls automatic management of the context window.
|
|
1808
|
+
* Receives the result and must return a result (can be the same object
|
|
1809
|
+
* or a modified copy). Runs in reverse array order so the outermost
|
|
1810
|
+
* middleware sees the final transformed result.
|
|
1426
1811
|
*
|
|
1427
|
-
* @
|
|
1812
|
+
* @param tool - Tool name
|
|
1813
|
+
* @param args - Original tool arguments
|
|
1814
|
+
* @param result - Tool execution result
|
|
1815
|
+
* @param ctx - Tool execution context
|
|
1428
1816
|
*/
|
|
1429
|
-
|
|
1817
|
+
afterToolCall?(tool: string, args: unknown, result: Tool$1.ExecuteResult, ctx: ToolContext): Promise<Tool$1.ExecuteResult>;
|
|
1430
1818
|
/**
|
|
1431
|
-
*
|
|
1432
|
-
* If not provided, defaults to 128,000 tokens.
|
|
1819
|
+
* Inject dynamic prompt sections at build time.
|
|
1433
1820
|
*
|
|
1434
|
-
*
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
/**
|
|
1438
|
-
* Custom stream provider for specialized models (e.g., OpenAI computer use).
|
|
1821
|
+
* Called during `PromptBuilder.build()` for each middleware. Return one
|
|
1822
|
+
* or more sections to inject into the system prompt. Return `undefined`
|
|
1823
|
+
* or an empty array to inject nothing.
|
|
1439
1824
|
*
|
|
1440
|
-
*
|
|
1441
|
-
*
|
|
1442
|
-
*
|
|
1825
|
+
* Sections follow the same priority system as static sections — use
|
|
1826
|
+
* `priority` to control placement relative to base template (10),
|
|
1827
|
+
* environment (20), instructions (30), custom (50), skills (70),
|
|
1828
|
+
* and per-turn overrides (90).
|
|
1443
1829
|
*
|
|
1444
|
-
*
|
|
1445
|
-
* AI SDK compatible chunks (text-delta, tool-call, tool-result, etc.).
|
|
1830
|
+
* @param ctx - Build context with cwd, model, toolNames, sessionId
|
|
1446
1831
|
*/
|
|
1447
|
-
|
|
1832
|
+
promptSections?(ctx: PromptBuildContext): PromptSection | PromptSection[] | undefined;
|
|
1448
1833
|
/**
|
|
1449
|
-
*
|
|
1450
|
-
*
|
|
1451
|
-
* When provided, the agent will connect to configured MCP servers
|
|
1452
|
-
* and make their tools available alongside local tools.
|
|
1834
|
+
* Observe agent events (read-only, non-blocking).
|
|
1453
1835
|
*
|
|
1454
|
-
*
|
|
1455
|
-
*
|
|
1456
|
-
* import { createMCPManager } from "@cuylabs/agent-core";
|
|
1836
|
+
* Fires for every event emitted during `chat()`. Errors thrown by
|
|
1837
|
+
* handlers are caught and logged — they never interrupt the stream.
|
|
1457
1838
|
*
|
|
1458
|
-
*
|
|
1459
|
-
*
|
|
1460
|
-
* transport: "stdio",
|
|
1461
|
-
* command: "npx",
|
|
1462
|
-
* args: ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"],
|
|
1463
|
-
* },
|
|
1464
|
-
* });
|
|
1839
|
+
* This is intentionally synchronous (void return) to prevent
|
|
1840
|
+
* event observers from blocking the streaming pipeline.
|
|
1465
1841
|
*
|
|
1466
|
-
*
|
|
1467
|
-
* model: openai("gpt-4o"),
|
|
1468
|
-
* mcp,
|
|
1469
|
-
* });
|
|
1470
|
-
* ```
|
|
1842
|
+
* @param event - The agent event
|
|
1471
1843
|
*/
|
|
1472
|
-
|
|
1844
|
+
onEvent?(event: AgentEvent): void;
|
|
1473
1845
|
/**
|
|
1474
|
-
*
|
|
1846
|
+
* Called when `chat()` starts, before the LLM stream is created.
|
|
1475
1847
|
*
|
|
1476
|
-
*
|
|
1477
|
-
*
|
|
1478
|
-
*
|
|
1479
|
-
* - Runtime environment info (cwd, platform, git branch)
|
|
1480
|
-
* - Instruction files (AGENTS.md, CLAUDE.md discovered on disk)
|
|
1481
|
-
* - Custom sections you define
|
|
1482
|
-
* - Per-turn overrides from chat options
|
|
1848
|
+
* Use this for setup: initializing loggers, recording start time,
|
|
1849
|
+
* resetting per-turn state, etc. Runs in array order, awaited
|
|
1850
|
+
* sequentially.
|
|
1483
1851
|
*
|
|
1484
|
-
*
|
|
1485
|
-
*
|
|
1852
|
+
* @param sessionId - Session identifier
|
|
1853
|
+
* @param message - The user message being sent
|
|
1854
|
+
*/
|
|
1855
|
+
onChatStart?(sessionId: string, message: string): Promise<void>;
|
|
1856
|
+
/**
|
|
1857
|
+
* Called when `chat()` completes (or errors), after all events
|
|
1858
|
+
* have been yielded.
|
|
1486
1859
|
*
|
|
1487
|
-
*
|
|
1488
|
-
*
|
|
1860
|
+
* Use this for teardown: flushing logs, recording metrics, etc.
|
|
1861
|
+
* Runs in array order, awaited sequentially. Always called, even
|
|
1862
|
+
* if the stream errored.
|
|
1489
1863
|
*
|
|
1490
|
-
* @
|
|
1491
|
-
*
|
|
1492
|
-
* const agent = createAgent({
|
|
1493
|
-
* model: anthropic("claude-sonnet-4-20250514"),
|
|
1494
|
-
* prompt: {
|
|
1495
|
-
* includeEnvironment: true,
|
|
1496
|
-
* includeInstructions: true,
|
|
1497
|
-
* sections: [
|
|
1498
|
-
* { id: "team", label: "Team Rules", content: "Use strict TypeScript." },
|
|
1499
|
-
* ],
|
|
1500
|
-
* },
|
|
1501
|
-
* });
|
|
1502
|
-
* ```
|
|
1864
|
+
* @param sessionId - Session identifier
|
|
1865
|
+
* @param result - Completion info (usage stats and optional error)
|
|
1503
1866
|
*/
|
|
1504
|
-
|
|
1867
|
+
onChatEnd?(sessionId: string, result: {
|
|
1868
|
+
usage?: TokenUsage;
|
|
1869
|
+
error?: Error;
|
|
1870
|
+
}): Promise<void>;
|
|
1871
|
+
}
|
|
1872
|
+
|
|
1873
|
+
/**
|
|
1874
|
+
* Storage Types
|
|
1875
|
+
*
|
|
1876
|
+
* Core types for session storage with tree structure support.
|
|
1877
|
+
* Designed for append-only event sourcing with branching.
|
|
1878
|
+
*/
|
|
1879
|
+
/**
|
|
1880
|
+
* Base interface for all session entries
|
|
1881
|
+
* Supports tree structure via id/parentId
|
|
1882
|
+
*/
|
|
1883
|
+
interface EntryBase {
|
|
1884
|
+
/** Unique entry ID (8-char hex) */
|
|
1885
|
+
id: string;
|
|
1886
|
+
/** Parent entry ID (null for first entry after header) */
|
|
1887
|
+
parentId: string | null;
|
|
1888
|
+
/** ISO timestamp */
|
|
1889
|
+
timestamp: string;
|
|
1890
|
+
}
|
|
1891
|
+
/**
|
|
1892
|
+
* Session header - always first entry in file
|
|
1893
|
+
*/
|
|
1894
|
+
interface SessionHeader {
|
|
1895
|
+
type: "header";
|
|
1896
|
+
/** Storage format version */
|
|
1897
|
+
version: number;
|
|
1898
|
+
/** Session ID */
|
|
1899
|
+
id: string;
|
|
1900
|
+
/** Working directory */
|
|
1901
|
+
cwd: string;
|
|
1902
|
+
/** ISO timestamp */
|
|
1903
|
+
timestamp: string;
|
|
1904
|
+
/** Parent session ID (if forked) */
|
|
1905
|
+
parentSessionId?: string;
|
|
1906
|
+
/** Session title */
|
|
1907
|
+
title?: string;
|
|
1908
|
+
}
|
|
1909
|
+
/**
|
|
1910
|
+
* Serialized message (dates as ISO strings)
|
|
1911
|
+
*/
|
|
1912
|
+
interface SerializedMessage {
|
|
1913
|
+
id: string;
|
|
1914
|
+
role: "user" | "assistant" | "tool" | "system";
|
|
1915
|
+
content: string;
|
|
1916
|
+
createdAt: string;
|
|
1917
|
+
system?: string;
|
|
1918
|
+
finish?: string;
|
|
1919
|
+
tokens?: {
|
|
1920
|
+
inputTokens?: number;
|
|
1921
|
+
outputTokens?: number;
|
|
1922
|
+
totalTokens?: number;
|
|
1923
|
+
};
|
|
1924
|
+
cost?: number;
|
|
1925
|
+
error?: {
|
|
1926
|
+
name: string;
|
|
1927
|
+
message: string;
|
|
1928
|
+
code?: string;
|
|
1929
|
+
};
|
|
1930
|
+
/** Tool calls for assistant messages with finish=tool-calls */
|
|
1931
|
+
toolCalls?: Array<{
|
|
1932
|
+
toolCallId: string;
|
|
1933
|
+
toolName: string;
|
|
1934
|
+
args: unknown;
|
|
1935
|
+
}>;
|
|
1936
|
+
toolCallId?: string;
|
|
1937
|
+
toolName?: string;
|
|
1938
|
+
result?: unknown;
|
|
1939
|
+
}
|
|
1940
|
+
/**
|
|
1941
|
+
* Message entry
|
|
1942
|
+
*/
|
|
1943
|
+
interface MessageEntry extends EntryBase {
|
|
1944
|
+
type: "message";
|
|
1945
|
+
message: SerializedMessage;
|
|
1946
|
+
}
|
|
1947
|
+
/**
|
|
1948
|
+
* Compaction/summarization entry
|
|
1949
|
+
* Replaces old messages with a summary
|
|
1950
|
+
*/
|
|
1951
|
+
interface CompactionEntry extends EntryBase {
|
|
1952
|
+
type: "compaction";
|
|
1953
|
+
/** Summary of compacted messages */
|
|
1954
|
+
summary: string;
|
|
1955
|
+
/** ID of first entry that was kept (not compacted) */
|
|
1956
|
+
firstKeptEntryId: string;
|
|
1957
|
+
/** Token count before compaction */
|
|
1958
|
+
tokensBefore: number;
|
|
1959
|
+
/** Token count after compaction */
|
|
1960
|
+
tokensAfter: number;
|
|
1961
|
+
/** Files that were read during compacted messages */
|
|
1962
|
+
readFiles?: string[];
|
|
1963
|
+
/** Files that were modified during compacted messages */
|
|
1964
|
+
modifiedFiles?: string[];
|
|
1965
|
+
}
|
|
1966
|
+
/**
|
|
1967
|
+
* Session info/metadata update
|
|
1968
|
+
*/
|
|
1969
|
+
interface MetadataEntry extends EntryBase {
|
|
1970
|
+
type: "metadata";
|
|
1971
|
+
/** Updated title */
|
|
1972
|
+
title?: string;
|
|
1973
|
+
/** User-defined name */
|
|
1974
|
+
name?: string;
|
|
1975
|
+
}
|
|
1976
|
+
/**
|
|
1977
|
+
* Branch marker - indicates a branch point
|
|
1978
|
+
*/
|
|
1979
|
+
interface BranchEntry extends EntryBase {
|
|
1980
|
+
type: "branch";
|
|
1981
|
+
/** ID of the entry we're branching from */
|
|
1982
|
+
branchFromId: string;
|
|
1983
|
+
/** Optional summary of the branch */
|
|
1984
|
+
summary?: string;
|
|
1505
1985
|
}
|
|
1506
1986
|
/**
|
|
1507
|
-
*
|
|
1987
|
+
* Model/config change entry
|
|
1508
1988
|
*/
|
|
1509
|
-
interface
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1989
|
+
interface ConfigChangeEntry extends EntryBase {
|
|
1990
|
+
type: "config_change";
|
|
1991
|
+
/** What changed */
|
|
1992
|
+
change: "model" | "reasoning_level" | "temperature" | "other";
|
|
1993
|
+
/** Previous value */
|
|
1994
|
+
from?: string;
|
|
1995
|
+
/** New value */
|
|
1996
|
+
to: string;
|
|
1517
1997
|
}
|
|
1518
1998
|
/**
|
|
1519
|
-
*
|
|
1520
|
-
*
|
|
1521
|
-
* Aligned with OpenCode's PermissionNext.Reply:
|
|
1522
|
-
* - "once" (OpenCode) → "allow" - Allow this once
|
|
1523
|
-
* - "always" (OpenCode) → "remember" - Allow and remember for this session
|
|
1524
|
-
* - "reject" (OpenCode) → "deny" - Reject and throw error
|
|
1999
|
+
* All entry types (excluding header)
|
|
1525
2000
|
*/
|
|
1526
|
-
type
|
|
2001
|
+
type SessionEntry = MessageEntry | CompactionEntry | MetadataEntry | BranchEntry | ConfigChangeEntry;
|
|
1527
2002
|
/**
|
|
1528
|
-
*
|
|
1529
|
-
* Sent to the handler when repeated tool calls are detected.
|
|
2003
|
+
* All file entries (including header)
|
|
1530
2004
|
*/
|
|
1531
|
-
|
|
1532
|
-
/** The tool being called repeatedly */
|
|
1533
|
-
tool: string;
|
|
1534
|
-
/** How many times it's been called with same input */
|
|
1535
|
-
repeatCount: number;
|
|
1536
|
-
/** The input being passed (for context) */
|
|
1537
|
-
input: unknown;
|
|
1538
|
-
/** Session ID */
|
|
1539
|
-
sessionId: string;
|
|
1540
|
-
}
|
|
2005
|
+
type FileEntry = SessionHeader | SessionEntry;
|
|
1541
2006
|
/**
|
|
1542
|
-
*
|
|
1543
|
-
*
|
|
1544
|
-
* Return:
|
|
1545
|
-
* - "allow": Continue despite the loop (like OpenCode's "once")
|
|
1546
|
-
* - "deny": Stop execution and throw error (like OpenCode's "reject")
|
|
1547
|
-
* - "remember": Allow and don't ask again for this tool in this session (like OpenCode's "always")
|
|
1548
|
-
*
|
|
1549
|
-
* @example
|
|
1550
|
-
* ```typescript
|
|
1551
|
-
* const agent = createAgent({
|
|
1552
|
-
* model: anthropic("claude-sonnet-4-20250514"),
|
|
1553
|
-
* onDoomLoop: async (req) => {
|
|
1554
|
-
* // Show UI asking user
|
|
1555
|
-
* const action = await showConfirmDialog(
|
|
1556
|
-
* `${req.tool} called ${req.repeatCount} times with same input. Continue?`
|
|
1557
|
-
* );
|
|
1558
|
-
* return action;
|
|
1559
|
-
* },
|
|
1560
|
-
* });
|
|
1561
|
-
* ```
|
|
2007
|
+
* Session summary info (lightweight, for listing)
|
|
1562
2008
|
*/
|
|
1563
|
-
|
|
2009
|
+
interface SessionInfo {
|
|
2010
|
+
/** Session ID */
|
|
2011
|
+
id: string;
|
|
2012
|
+
/** File path */
|
|
2013
|
+
path: string;
|
|
2014
|
+
/** Working directory */
|
|
2015
|
+
cwd: string;
|
|
2016
|
+
/** Session title */
|
|
2017
|
+
title?: string;
|
|
2018
|
+
/** User-defined name */
|
|
2019
|
+
name?: string;
|
|
2020
|
+
/** Parent session ID (if forked) */
|
|
2021
|
+
parentSessionId?: string;
|
|
2022
|
+
/** Creation time */
|
|
2023
|
+
createdAt: Date;
|
|
2024
|
+
/** Last modified time */
|
|
2025
|
+
updatedAt: Date;
|
|
2026
|
+
/** Number of message entries */
|
|
2027
|
+
messageCount: number;
|
|
2028
|
+
/** First user message (preview) */
|
|
2029
|
+
firstMessage?: string;
|
|
2030
|
+
}
|
|
1564
2031
|
/**
|
|
1565
|
-
*
|
|
1566
|
-
*
|
|
1567
|
-
* Aligned with OpenCode's SessionCompaction:
|
|
1568
|
-
* - Auto-pruning of old tool outputs
|
|
1569
|
-
* - LLM-based summarization
|
|
1570
|
-
* - Auto-continue after compaction
|
|
2032
|
+
* Session storage interface
|
|
2033
|
+
* Pluggable backend for session persistence
|
|
1571
2034
|
*/
|
|
1572
|
-
interface
|
|
2035
|
+
interface SessionStorage {
|
|
1573
2036
|
/**
|
|
1574
|
-
*
|
|
1575
|
-
* Default: true (matches OpenCode's default)
|
|
2037
|
+
* Create a new session
|
|
1576
2038
|
*/
|
|
1577
|
-
|
|
2039
|
+
create(header: SessionHeader): Promise<void>;
|
|
1578
2040
|
/**
|
|
1579
|
-
*
|
|
1580
|
-
* This is a lightweight operation that removes tool result content.
|
|
1581
|
-
* Default: true
|
|
2041
|
+
* Append an entry to a session
|
|
1582
2042
|
*/
|
|
1583
|
-
|
|
2043
|
+
append(sessionId: string, entry: SessionEntry): Promise<void>;
|
|
1584
2044
|
/**
|
|
1585
|
-
*
|
|
1586
|
-
* Default: 40,000 (like OpenCode's PRUNE_PROTECT)
|
|
2045
|
+
* Append multiple entries atomically
|
|
1587
2046
|
*/
|
|
1588
|
-
|
|
2047
|
+
appendBatch(sessionId: string, entries: SessionEntry[]): Promise<void>;
|
|
1589
2048
|
/**
|
|
1590
|
-
*
|
|
1591
|
-
* Default: 20,000 (like OpenCode's PRUNE_MINIMUM)
|
|
2049
|
+
* Read all entries from a session
|
|
1592
2050
|
*/
|
|
1593
|
-
|
|
2051
|
+
read(sessionId: string): Promise<FileEntry[]>;
|
|
1594
2052
|
/**
|
|
1595
|
-
*
|
|
1596
|
-
* If not provided, uses default prompt asking for continuation context.
|
|
2053
|
+
* Delete a session
|
|
1597
2054
|
*/
|
|
1598
|
-
|
|
2055
|
+
delete(sessionId: string): Promise<boolean>;
|
|
1599
2056
|
/**
|
|
1600
|
-
*
|
|
1601
|
-
* If not provided, uses the same model as the agent.
|
|
1602
|
-
* You might want to use a cheaper/faster model here.
|
|
2057
|
+
* Check if session exists
|
|
1603
2058
|
*/
|
|
1604
|
-
|
|
2059
|
+
exists(sessionId: string): Promise<boolean>;
|
|
1605
2060
|
/**
|
|
1606
|
-
*
|
|
1607
|
-
* Like OpenCode's behavior.
|
|
1608
|
-
* Default: true
|
|
2061
|
+
* List all sessions (lightweight info only)
|
|
1609
2062
|
*/
|
|
1610
|
-
|
|
2063
|
+
list(): Promise<SessionInfo[]>;
|
|
2064
|
+
/**
|
|
2065
|
+
* Clear all sessions
|
|
2066
|
+
*/
|
|
2067
|
+
clear(): Promise<void>;
|
|
1611
2068
|
}
|
|
2069
|
+
/**
|
|
2070
|
+
* Current storage format version
|
|
2071
|
+
*/
|
|
2072
|
+
declare const STORAGE_VERSION = 1;
|
|
1612
2073
|
|
|
1613
2074
|
/**
|
|
1614
2075
|
* Session Manager
|
|
@@ -1900,7 +2361,7 @@ declare class FileStorage implements SessionStorage {
|
|
|
1900
2361
|
* - Windows: %APPDATA%/cuylabs/
|
|
1901
2362
|
*
|
|
1902
2363
|
* Project identification:
|
|
1903
|
-
* - Uses git root commit hash
|
|
2364
|
+
* - Uses git root commit hash for git repos
|
|
1904
2365
|
* - Falls back to encoded path for non-git directories
|
|
1905
2366
|
*/
|
|
1906
2367
|
/**
|
|
@@ -2063,6 +2524,8 @@ declare const Presets: {
|
|
|
2063
2524
|
readonly review: Preset;
|
|
2064
2525
|
readonly quick: Preset;
|
|
2065
2526
|
readonly careful: Preset;
|
|
2527
|
+
readonly code: Preset;
|
|
2528
|
+
readonly watch: Preset;
|
|
2066
2529
|
};
|
|
2067
2530
|
/**
|
|
2068
2531
|
* Create a custom preset with defaults
|
|
@@ -2079,8 +2542,6 @@ declare function createPreset(options: Partial<Preset> & {
|
|
|
2079
2542
|
* granular per-turn tracking with minimal overhead - only touched files
|
|
2080
2543
|
* are captured.
|
|
2081
2544
|
*
|
|
2082
|
-
* Inspired by OpenCode's Snapshot system and Codex's TurnDiffTracker.
|
|
2083
|
-
*
|
|
2084
2545
|
* @example
|
|
2085
2546
|
* ```typescript
|
|
2086
2547
|
* const tracker = createTurnTracker({ cwd: '/project' });
|
|
@@ -2388,9 +2849,9 @@ declare function summarizeEnvironment(info: EnvironmentInfo): string;
|
|
|
2388
2849
|
* effectively take precedence in case of conflicting guidance.
|
|
2389
2850
|
*
|
|
2390
2851
|
* Compatible with:
|
|
2391
|
-
* -
|
|
2392
|
-
* -
|
|
2393
|
-
* -
|
|
2852
|
+
* - AGENTS.md convention
|
|
2853
|
+
* - CLAUDE.md convention
|
|
2854
|
+
* - COPILOT.md convention
|
|
2394
2855
|
* - CuyLabs' own .cuylabs/instructions.md
|
|
2395
2856
|
*/
|
|
2396
2857
|
|
|
@@ -2475,6 +2936,242 @@ declare function loadGlobalInstructions(paths: string[], maxSize?: number): Prom
|
|
|
2475
2936
|
*/
|
|
2476
2937
|
declare function formatInstructions(files: InstructionFile[], basePath?: string): string;
|
|
2477
2938
|
|
|
2939
|
+
/**
|
|
2940
|
+
* Skill Registry — in-memory store for discovered skills
|
|
2941
|
+
*
|
|
2942
|
+
* The registry is the central coordination point for the skill system.
|
|
2943
|
+
* It holds discovered metadata (L1), handles on-demand content loading
|
|
2944
|
+
* (L2/L3), provides the prompt summary for injection, and manages
|
|
2945
|
+
* the lifecycle of skill state.
|
|
2946
|
+
*
|
|
2947
|
+
* ```
|
|
2948
|
+
* discoverSkills() → SkillRegistry → promptSummary (L1 → system prompt)
|
|
2949
|
+
* → loadSkill() (L2 → tool response)
|
|
2950
|
+
* → loadResource (L3 → tool response)
|
|
2951
|
+
* ```
|
|
2952
|
+
*
|
|
2953
|
+
* The registry is designed to be created once per agent and shared
|
|
2954
|
+
* across the agent's lifetime, including across forked sub-agents.
|
|
2955
|
+
*
|
|
2956
|
+
* @example
|
|
2957
|
+
* ```typescript
|
|
2958
|
+
* const registry = await createSkillRegistry("/path/to/project", {
|
|
2959
|
+
* externalDirs: [".agents", ".claude"],
|
|
2960
|
+
* });
|
|
2961
|
+
*
|
|
2962
|
+
* // L1: summary goes into system prompt
|
|
2963
|
+
* const summary = registry.formatSummary();
|
|
2964
|
+
*
|
|
2965
|
+
* // L2: agent calls skill tool → full content loaded
|
|
2966
|
+
* const content = await registry.loadContent("testing");
|
|
2967
|
+
*
|
|
2968
|
+
* // L3: agent reads a bundled reference
|
|
2969
|
+
* const ref = await registry.loadResource("testing", "references/patterns.md");
|
|
2970
|
+
* ```
|
|
2971
|
+
*/
|
|
2972
|
+
|
|
2973
|
+
/**
|
|
2974
|
+
* In-memory registry of discovered skills with lazy content loading.
|
|
2975
|
+
*
|
|
2976
|
+
* Holds L1 metadata for all skills. Content (L2) and resources (L3)
|
|
2977
|
+
* are loaded on demand and cached for the registry's lifetime.
|
|
2978
|
+
*/
|
|
2979
|
+
declare class SkillRegistry {
|
|
2980
|
+
/** All discovered skill metadata indexed by name */
|
|
2981
|
+
private readonly skills;
|
|
2982
|
+
/** Cached full content for skills that have been loaded */
|
|
2983
|
+
private readonly contentCache;
|
|
2984
|
+
/** Discovery metadata */
|
|
2985
|
+
readonly discoveryResult: SkillDiscoveryResult;
|
|
2986
|
+
constructor(discoveryResult: SkillDiscoveryResult);
|
|
2987
|
+
/** Get a skill's metadata by name. Returns undefined if not found. */
|
|
2988
|
+
get(name: string): SkillMetadata | undefined;
|
|
2989
|
+
/** Check if a skill exists by name. */
|
|
2990
|
+
has(name: string): boolean;
|
|
2991
|
+
/** Get all skill metadata entries. */
|
|
2992
|
+
list(): SkillMetadata[];
|
|
2993
|
+
/** Number of registered skills. */
|
|
2994
|
+
get size(): number;
|
|
2995
|
+
/** Skill names as an array. */
|
|
2996
|
+
get names(): string[];
|
|
2997
|
+
/**
|
|
2998
|
+
* Load a skill's full content (L2: body + resource listing).
|
|
2999
|
+
*
|
|
3000
|
+
* Results are cached — subsequent calls return the cached content
|
|
3001
|
+
* without re-reading the filesystem.
|
|
3002
|
+
*
|
|
3003
|
+
* @param name Skill name
|
|
3004
|
+
* @returns Full skill content, or null if the skill doesn't exist
|
|
3005
|
+
*/
|
|
3006
|
+
loadContent(name: string): Promise<SkillContent | null>;
|
|
3007
|
+
/**
|
|
3008
|
+
* Load a specific bundled resource from a skill (L3).
|
|
3009
|
+
*
|
|
3010
|
+
* The skill's content must be loaded first (via `loadContent`)
|
|
3011
|
+
* so the resource listing is available.
|
|
3012
|
+
*
|
|
3013
|
+
* @param skillName Skill name
|
|
3014
|
+
* @param relativePath Relative path to the resource within the skill dir
|
|
3015
|
+
* @returns Resource file content as UTF-8 string
|
|
3016
|
+
* @throws If the skill or resource doesn't exist
|
|
3017
|
+
*/
|
|
3018
|
+
loadResource(skillName: string, relativePath: string): Promise<string>;
|
|
3019
|
+
/**
|
|
3020
|
+
* Get the list of resources for a loaded skill.
|
|
3021
|
+
*
|
|
3022
|
+
* @param name Skill name
|
|
3023
|
+
* @returns Resource list, or empty array if skill isn't loaded yet
|
|
3024
|
+
*/
|
|
3025
|
+
getResources(name: string): SkillResource[];
|
|
3026
|
+
/**
|
|
3027
|
+
* Format a summary of all available skills for injection into the system prompt.
|
|
3028
|
+
*
|
|
3029
|
+
* This is the L1 layer — the agent sees names and descriptions of all
|
|
3030
|
+
* available skills, enabling it to decide which to activate via tool calls.
|
|
3031
|
+
*
|
|
3032
|
+
* The output format uses XML tags (consistent with the instruction format
|
|
3033
|
+
* in `formatInstructions`) for clear delineation in the prompt.
|
|
3034
|
+
*
|
|
3035
|
+
* Returns empty string if no skills are available.
|
|
3036
|
+
*
|
|
3037
|
+
* @example Output:
|
|
3038
|
+
* ```xml
|
|
3039
|
+
* <available-skills>
|
|
3040
|
+
*
|
|
3041
|
+
* You have access to the following skills. To activate a skill and load its
|
|
3042
|
+
* full instructions, call the `skill` tool with the skill's name.
|
|
3043
|
+
*
|
|
3044
|
+
* <skill name="testing" scope="project">
|
|
3045
|
+
* Write comprehensive test suites with vitest, covering unit, integration,
|
|
3046
|
+
* and snapshot testing patterns.
|
|
3047
|
+
* </skill>
|
|
3048
|
+
*
|
|
3049
|
+
* <skill name="frontend-design" scope="user">
|
|
3050
|
+
* Create distinctive, production-grade frontend interfaces with high design quality.
|
|
3051
|
+
* </skill>
|
|
3052
|
+
*
|
|
3053
|
+
* </available-skills>
|
|
3054
|
+
* ```
|
|
3055
|
+
*/
|
|
3056
|
+
formatSummary(): string;
|
|
3057
|
+
/**
|
|
3058
|
+
* Format the full content of a loaded skill for a tool response.
|
|
3059
|
+
*
|
|
3060
|
+
* Wraps the skill body in XML with metadata, and lists bundled resources
|
|
3061
|
+
* so the agent knows what's available at L3.
|
|
3062
|
+
*
|
|
3063
|
+
* @param content Previously loaded skill content
|
|
3064
|
+
* @returns Formatted string for tool response
|
|
3065
|
+
*/
|
|
3066
|
+
formatContent(content: SkillContent): string;
|
|
3067
|
+
/** Clear the content cache, forcing reloads on next access. */
|
|
3068
|
+
clearContentCache(): void;
|
|
3069
|
+
/** Check if a skill's content has been loaded and cached. */
|
|
3070
|
+
isContentLoaded(name: string): boolean;
|
|
3071
|
+
}
|
|
3072
|
+
/**
|
|
3073
|
+
* Create a skill registry by discovering all available skills.
|
|
3074
|
+
*
|
|
3075
|
+
* This is the recommended way to initialize the skill system.
|
|
3076
|
+
* It runs discovery, deduplicates by scope priority, and returns
|
|
3077
|
+
* a ready-to-use registry.
|
|
3078
|
+
*
|
|
3079
|
+
* @param cwd Current working directory
|
|
3080
|
+
* @param config Skill configuration
|
|
3081
|
+
* @returns A populated SkillRegistry
|
|
3082
|
+
*
|
|
3083
|
+
* @example
|
|
3084
|
+
* ```typescript
|
|
3085
|
+
* const registry = await createSkillRegistry("/path/to/project", {
|
|
3086
|
+
* externalDirs: [".agents", ".claude"],
|
|
3087
|
+
* roots: ["./company-skills"],
|
|
3088
|
+
* });
|
|
3089
|
+
*
|
|
3090
|
+
* console.log(`Found ${registry.size} skills`);
|
|
3091
|
+
* console.log(registry.formatSummary());
|
|
3092
|
+
* ```
|
|
3093
|
+
*/
|
|
3094
|
+
declare function createSkillRegistry(cwd: string, config?: SkillConfig): Promise<SkillRegistry>;
|
|
3095
|
+
/**
|
|
3096
|
+
* Create an empty skill registry (for agents that don't use skills).
|
|
3097
|
+
*/
|
|
3098
|
+
declare function emptySkillRegistry(): SkillRegistry;
|
|
3099
|
+
|
|
3100
|
+
/**
|
|
3101
|
+
* Middleware Runner
|
|
3102
|
+
*
|
|
3103
|
+
* Executes middleware hooks in the correct order with proper
|
|
3104
|
+
* error handling and short-circuit semantics.
|
|
3105
|
+
*
|
|
3106
|
+
* This is the internal engine — consumers never see it.
|
|
3107
|
+
* They interact with middleware through AgentConfig.middleware.
|
|
3108
|
+
*/
|
|
3109
|
+
|
|
3110
|
+
/**
|
|
3111
|
+
* Middleware runner — holds an ordered list of middleware and
|
|
3112
|
+
* exposes methods to run each hook type with correct semantics.
|
|
3113
|
+
*
|
|
3114
|
+
* Immutable after construction. Fork creates a new runner
|
|
3115
|
+
* (with inherited + additional middleware).
|
|
3116
|
+
*/
|
|
3117
|
+
declare class MiddlewareRunner {
|
|
3118
|
+
private readonly stack;
|
|
3119
|
+
constructor(middleware?: AgentMiddleware[]);
|
|
3120
|
+
/** Number of registered middleware */
|
|
3121
|
+
get count(): number;
|
|
3122
|
+
/** Whether any middleware is registered */
|
|
3123
|
+
get hasMiddleware(): boolean;
|
|
3124
|
+
/** Get the middleware list (for fork inheritance) */
|
|
3125
|
+
getMiddleware(): readonly AgentMiddleware[];
|
|
3126
|
+
/**
|
|
3127
|
+
* Run all `beforeToolCall` hooks in order.
|
|
3128
|
+
*
|
|
3129
|
+
* Returns `{ action: "allow" }` if all middleware allow (or have no hook).
|
|
3130
|
+
* Returns `{ action: "deny", reason }` on first denial — remaining
|
|
3131
|
+
* middleware are skipped.
|
|
3132
|
+
*/
|
|
3133
|
+
runBeforeToolCall(tool: string, args: unknown, ctx: ToolContext): Promise<ToolCallDecision>;
|
|
3134
|
+
/**
|
|
3135
|
+
* Run all `afterToolCall` hooks in reverse order.
|
|
3136
|
+
*
|
|
3137
|
+
* Each hook receives the result from the previous hook (or the
|
|
3138
|
+
* original tool result for the first hook). Errors are caught
|
|
3139
|
+
* and logged — the original result passes through.
|
|
3140
|
+
*/
|
|
3141
|
+
runAfterToolCall(tool: string, args: unknown, result: Tool$1.ExecuteResult, ctx: ToolContext): Promise<Tool$1.ExecuteResult>;
|
|
3142
|
+
/**
|
|
3143
|
+
* Collect prompt sections from all middleware.
|
|
3144
|
+
*
|
|
3145
|
+
* Returns a flat array of sections. Each middleware can return a single
|
|
3146
|
+
* section, an array of sections, or undefined/empty.
|
|
3147
|
+
*/
|
|
3148
|
+
collectPromptSections(ctx: PromptBuildContext): PromptSection[];
|
|
3149
|
+
/**
|
|
3150
|
+
* Broadcast an event to all middleware observers.
|
|
3151
|
+
*
|
|
3152
|
+
* Non-blocking — errors are caught and logged. This never
|
|
3153
|
+
* slows down the streaming pipeline.
|
|
3154
|
+
*/
|
|
3155
|
+
emitEvent(event: AgentEvent): void;
|
|
3156
|
+
/**
|
|
3157
|
+
* Run all `onChatStart` hooks in order.
|
|
3158
|
+
*
|
|
3159
|
+
* Errors are caught and logged — a broken logger should not
|
|
3160
|
+
* prevent the chat from starting.
|
|
3161
|
+
*/
|
|
3162
|
+
runChatStart(sessionId: string, message: string): Promise<void>;
|
|
3163
|
+
/**
|
|
3164
|
+
* Run all `onChatEnd` hooks in order.
|
|
3165
|
+
*
|
|
3166
|
+
* Always called, even when the stream errored. Errors in handlers
|
|
3167
|
+
* are caught and logged.
|
|
3168
|
+
*/
|
|
3169
|
+
runChatEnd(sessionId: string, result: {
|
|
3170
|
+
usage?: TokenUsage;
|
|
3171
|
+
error?: Error;
|
|
3172
|
+
}): Promise<void>;
|
|
3173
|
+
}
|
|
3174
|
+
|
|
2478
3175
|
/**
|
|
2479
3176
|
* PromptBuilder — The pipeline orchestrator
|
|
2480
3177
|
*
|
|
@@ -2489,7 +3186,7 @@ declare function formatInstructions(files: InstructionFile[], basePath?: string)
|
|
|
2489
3186
|
* ├──────────────────┤
|
|
2490
3187
|
* │ Custom Sections │ priority 50 — user-defined content
|
|
2491
3188
|
* ├──────────────────┤
|
|
2492
|
-
* │
|
|
3189
|
+
* │ Skills Summary │ priority 70 — L1 skill names + descriptions
|
|
2493
3190
|
* ├──────────────────┤
|
|
2494
3191
|
* │ Per-Turn Override │ priority 90 — session-specific context
|
|
2495
3192
|
* └──────────────────┘
|
|
@@ -2522,7 +3219,7 @@ declare const PRIORITY_ENVIRONMENT = 20;
|
|
|
2522
3219
|
declare const PRIORITY_INSTRUCTIONS = 30;
|
|
2523
3220
|
/** Priority for custom user-defined sections (default) */
|
|
2524
3221
|
declare const PRIORITY_CUSTOM = 50;
|
|
2525
|
-
/** Priority
|
|
3222
|
+
/** Priority for skill summary injection (L1 names + descriptions) */
|
|
2526
3223
|
declare const PRIORITY_SKILLS = 70;
|
|
2527
3224
|
/** Priority for per-turn override content */
|
|
2528
3225
|
declare const PRIORITY_OVERRIDE = 90;
|
|
@@ -2562,6 +3259,8 @@ declare class PromptBuilder {
|
|
|
2562
3259
|
private envCache?;
|
|
2563
3260
|
/** Cached instruction files */
|
|
2564
3261
|
private instructionCache?;
|
|
3262
|
+
/** Cached skill registry */
|
|
3263
|
+
private skillRegistryCache?;
|
|
2565
3264
|
constructor(config?: PromptConfig);
|
|
2566
3265
|
/**
|
|
2567
3266
|
* Build the complete system prompt from all active layers.
|
|
@@ -2573,9 +3272,10 @@ declare class PromptBuilder {
|
|
|
2573
3272
|
* with the configured separator.
|
|
2574
3273
|
*
|
|
2575
3274
|
* @param context - Build context with cwd, model, and optional override
|
|
3275
|
+
* @param middleware - Optional middleware runner to collect dynamic sections from
|
|
2576
3276
|
* @returns The composed system prompt string
|
|
2577
3277
|
*/
|
|
2578
|
-
build(context: PromptBuildContext): Promise<string>;
|
|
3278
|
+
build(context: PromptBuildContext, middleware?: MiddlewareRunner): Promise<string>;
|
|
2579
3279
|
/**
|
|
2580
3280
|
* Add or replace a custom section.
|
|
2581
3281
|
*
|
|
@@ -2630,6 +3330,16 @@ declare class PromptBuilder {
|
|
|
2630
3330
|
* - You want to force a refresh on the next build()
|
|
2631
3331
|
*/
|
|
2632
3332
|
clearCache(): void;
|
|
3333
|
+
/**
|
|
3334
|
+
* Get the skill registry for the current working directory.
|
|
3335
|
+
*
|
|
3336
|
+
* Runs skill discovery on first call and caches the result.
|
|
3337
|
+
* Consumers can use this to get the registry for creating skill tools.
|
|
3338
|
+
*
|
|
3339
|
+
* @param cwd Working directory for skill discovery
|
|
3340
|
+
* @returns The skill registry (may be empty if no skills config)
|
|
3341
|
+
*/
|
|
3342
|
+
getSkillRegistry(cwd: string): Promise<SkillRegistry>;
|
|
2633
3343
|
/**
|
|
2634
3344
|
* Get the model family that would be used for a given model.
|
|
2635
3345
|
* Useful for debugging template selection.
|
|
@@ -2698,8 +3408,8 @@ declare function createPromptBuilder(config?: PromptConfig): PromptBuilder;
|
|
|
2698
3408
|
* Uses Vercel AI SDK v6's `prepareStep` hook for zero-overhead
|
|
2699
3409
|
* integration at step boundaries (between LLM calls in a multi-step turn).
|
|
2700
3410
|
*
|
|
2701
|
-
* Instead of polling a queue after each tool execution
|
|
2702
|
-
*
|
|
3411
|
+
* Instead of polling a queue after each tool execution, this leverages
|
|
3412
|
+
* the SDK's native step lifecycle. The
|
|
2703
3413
|
* `prepareStep` callback fires before every LLM call, giving us a
|
|
2704
3414
|
* natural injection point with no custom loop machinery.
|
|
2705
3415
|
*
|
|
@@ -2933,6 +3643,8 @@ declare class Agent {
|
|
|
2933
3643
|
private interventionCtrl;
|
|
2934
3644
|
/** Execution environment for tool operations */
|
|
2935
3645
|
private host;
|
|
3646
|
+
/** Middleware runner for lifecycle hooks */
|
|
3647
|
+
private middlewareRunner;
|
|
2936
3648
|
constructor(config: AgentConfig & {
|
|
2937
3649
|
tools?: Tool$1.AnyInfo[];
|
|
2938
3650
|
sessionManager?: SessionManager;
|
|
@@ -2999,11 +3711,6 @@ declare class Agent {
|
|
|
2999
3711
|
chat(sessionId: string, message: string, options?: {
|
|
3000
3712
|
abort?: AbortSignal;
|
|
3001
3713
|
system?: string;
|
|
3002
|
-
onApproval?: (request: {
|
|
3003
|
-
tool: string;
|
|
3004
|
-
args: unknown;
|
|
3005
|
-
description: string;
|
|
3006
|
-
}) => Promise<"allow" | "deny">;
|
|
3007
3714
|
}): AsyncGenerator<AgentEvent>;
|
|
3008
3715
|
/**
|
|
3009
3716
|
* Ensure a session is loaded or created
|
|
@@ -3305,6 +4012,10 @@ declare class Agent {
|
|
|
3305
4012
|
reasoningLevel?: ReasoningLevel;
|
|
3306
4013
|
/** Apply a preset configuration */
|
|
3307
4014
|
preset?: Preset;
|
|
4015
|
+
/** Override middleware (if not provided, inherits parent's middleware) */
|
|
4016
|
+
middleware?: AgentMiddleware[];
|
|
4017
|
+
/** Additional middleware appended after inherited middleware */
|
|
4018
|
+
additionalMiddleware?: AgentMiddleware[];
|
|
3308
4019
|
}): Agent;
|
|
3309
4020
|
/**
|
|
3310
4021
|
* Create a sub-agent with a preset configuration.
|
|
@@ -3628,6 +4339,13 @@ interface LLMStreamInput {
|
|
|
3628
4339
|
* Only works with the standard AI SDK path (not custom stream providers).
|
|
3629
4340
|
*/
|
|
3630
4341
|
intervention?: InterventionController;
|
|
4342
|
+
/**
|
|
4343
|
+
* Middleware runner for lifecycle hooks.
|
|
4344
|
+
*
|
|
4345
|
+
* When provided, tool calls are wrapped with before/after hooks
|
|
4346
|
+
* from registered middleware.
|
|
4347
|
+
*/
|
|
4348
|
+
middleware?: MiddlewareRunner;
|
|
3631
4349
|
}
|
|
3632
4350
|
/**
|
|
3633
4351
|
* Step information
|
|
@@ -3660,7 +4378,7 @@ declare namespace LLM {
|
|
|
3660
4378
|
* @param turnTracker - Optional turn tracker for automatic file baseline capture
|
|
3661
4379
|
* @param host - Optional execution environment for tools
|
|
3662
4380
|
*/
|
|
3663
|
-
function buildToolSet(tools: Record<string, Tool$1.Info>, cwd: string, sessionID: string, messageID: string, abort: AbortSignal, turnTracker?: TurnTrackerContext, host?: ToolHost): Promise<ToolSet>;
|
|
4381
|
+
function buildToolSet(tools: Record<string, Tool$1.Info>, cwd: string, sessionID: string, messageID: string, abort: AbortSignal, turnTracker?: TurnTrackerContext, host?: ToolHost, middleware?: MiddlewareRunner): Promise<ToolSet>;
|
|
3664
4382
|
/**
|
|
3665
4383
|
* Create a stream for LLM completion with retry support
|
|
3666
4384
|
*/
|
|
@@ -4087,7 +4805,7 @@ declare function findCutPoint(messages: Message[], protectedTokens?: number): nu
|
|
|
4087
4805
|
/**
|
|
4088
4806
|
* Prune old, large tool results from the conversation.
|
|
4089
4807
|
*
|
|
4090
|
-
*
|
|
4808
|
+
* Prune strategy:
|
|
4091
4809
|
* - Walks backwards through messages
|
|
4092
4810
|
* - Protects recent outputs (within {@link protectedTokens})
|
|
4093
4811
|
* - Skips protected tools (e.g. "skill")
|
|
@@ -4208,17 +4926,80 @@ declare class ContextManager {
|
|
|
4208
4926
|
/**
|
|
4209
4927
|
* Get a snapshot of token statistics.
|
|
4210
4928
|
*
|
|
4211
|
-
* Useful for dashboards, logging, or deciding whether to prune.
|
|
4929
|
+
* Useful for dashboards, logging, or deciding whether to prune.
|
|
4930
|
+
*/
|
|
4931
|
+
getStats(messages: (Message | ModelMessage)[]): {
|
|
4932
|
+
tokens: number;
|
|
4933
|
+
limit: number;
|
|
4934
|
+
available: number;
|
|
4935
|
+
utilizationPercent: number;
|
|
4936
|
+
isOverflowing: boolean;
|
|
4937
|
+
shouldPrune: boolean;
|
|
4938
|
+
};
|
|
4939
|
+
}
|
|
4940
|
+
|
|
4941
|
+
/**
|
|
4942
|
+
* Approval Middleware
|
|
4943
|
+
*
|
|
4944
|
+
* Wraps the existing approval system as an AgentMiddleware.
|
|
4945
|
+
* This is how approval finally gets wired into the tool execution
|
|
4946
|
+
* pipeline — no more dead code.
|
|
4947
|
+
*
|
|
4948
|
+
* @example
|
|
4949
|
+
* ```typescript
|
|
4950
|
+
* import { createAgent, approvalMiddleware } from "@cuylabs/agent-core";
|
|
4951
|
+
*
|
|
4952
|
+
* const agent = createAgent({
|
|
4953
|
+
* model: anthropic("claude-sonnet-4-20250514"),
|
|
4954
|
+
* tools: [read, write, bash],
|
|
4955
|
+
* middleware: [
|
|
4956
|
+
* approvalMiddleware({
|
|
4957
|
+
* rules: [
|
|
4958
|
+
* { pattern: "src/*", tool: "read_file", action: "allow" },
|
|
4959
|
+
* ],
|
|
4960
|
+
* onRequest: async (req) => {
|
|
4961
|
+
* // Prompt user in your UI
|
|
4962
|
+
* return await askUser(req);
|
|
4963
|
+
* },
|
|
4964
|
+
* }),
|
|
4965
|
+
* ],
|
|
4966
|
+
* });
|
|
4967
|
+
* ```
|
|
4968
|
+
*/
|
|
4969
|
+
|
|
4970
|
+
/**
|
|
4971
|
+
* Configuration for the approval middleware.
|
|
4972
|
+
*
|
|
4973
|
+
* Extends the existing ApprovalConfig with middleware-specific options.
|
|
4974
|
+
*/
|
|
4975
|
+
interface ApprovalMiddlewareConfig extends ApprovalConfig {
|
|
4976
|
+
/**
|
|
4977
|
+
* Custom risk classification for tools.
|
|
4978
|
+
*
|
|
4979
|
+
* Overrides the built-in risk map. Tools not listed here
|
|
4980
|
+
* fall back to the default classification.
|
|
4981
|
+
*
|
|
4982
|
+
* @example
|
|
4983
|
+
* ```typescript
|
|
4984
|
+
* customRisks: {
|
|
4985
|
+
* "my_deploy_tool": "dangerous",
|
|
4986
|
+
* "my_lint_tool": "safe",
|
|
4987
|
+
* }
|
|
4988
|
+
* ```
|
|
4212
4989
|
*/
|
|
4213
|
-
|
|
4214
|
-
tokens: number;
|
|
4215
|
-
limit: number;
|
|
4216
|
-
available: number;
|
|
4217
|
-
utilizationPercent: number;
|
|
4218
|
-
isOverflowing: boolean;
|
|
4219
|
-
shouldPrune: boolean;
|
|
4220
|
-
};
|
|
4990
|
+
customRisks?: Record<string, RiskLevel>;
|
|
4221
4991
|
}
|
|
4992
|
+
/**
|
|
4993
|
+
* Create an approval middleware from an ApprovalConfig.
|
|
4994
|
+
*
|
|
4995
|
+
* This bridges the existing `createApprovalHandler` into the middleware
|
|
4996
|
+
* system. The `beforeToolCall` hook checks rules, classifies risk,
|
|
4997
|
+
* and calls the approval handler when needed.
|
|
4998
|
+
*
|
|
4999
|
+
* @param config - Approval configuration (rules, handler, timeout, etc.)
|
|
5000
|
+
* @returns An AgentMiddleware that gates tool execution
|
|
5001
|
+
*/
|
|
5002
|
+
declare function approvalMiddleware(config?: ApprovalMiddlewareConfig): AgentMiddleware;
|
|
4222
5003
|
|
|
4223
5004
|
/**
|
|
4224
5005
|
* LocalHost — executes tools on the local machine.
|
|
@@ -4387,6 +5168,620 @@ interface DockerHostOptions {
|
|
|
4387
5168
|
*/
|
|
4388
5169
|
declare function dockerHost(options: DockerHostOptions): Promise<ToolHost>;
|
|
4389
5170
|
|
|
5171
|
+
/**
|
|
5172
|
+
* Skill Loader — parses SKILL.md files with YAML frontmatter
|
|
5173
|
+
*
|
|
5174
|
+
* Handles the core I/O of reading a SKILL.md file and extracting:
|
|
5175
|
+
* - YAML frontmatter → SkillMetadata (L1)
|
|
5176
|
+
* - Markdown body → SkillContent (L2)
|
|
5177
|
+
* - Directory scan → SkillResource[] (L3)
|
|
5178
|
+
*
|
|
5179
|
+
* The frontmatter format follows the widely-adopted SKILL.md convention:
|
|
5180
|
+
*
|
|
5181
|
+
* ```markdown
|
|
5182
|
+
* ---
|
|
5183
|
+
* name: my-skill
|
|
5184
|
+
* description: When to use this skill...
|
|
5185
|
+
* version: 1.0.0
|
|
5186
|
+
* tags: [testing, typescript]
|
|
5187
|
+
* dependencies: [another-skill]
|
|
5188
|
+
* ---
|
|
5189
|
+
*
|
|
5190
|
+
* # Skill Instructions
|
|
5191
|
+
*
|
|
5192
|
+
* The full markdown body with instructions for the agent...
|
|
5193
|
+
* ```
|
|
5194
|
+
*
|
|
5195
|
+
* We parse YAML manually (no external dependency) since frontmatter
|
|
5196
|
+
* is simple key-value pairs. This keeps agent-core dependency-free.
|
|
5197
|
+
*/
|
|
5198
|
+
|
|
5199
|
+
/** The canonical skill definition filename */
|
|
5200
|
+
declare const SKILL_FILENAME = "SKILL.md";
|
|
5201
|
+
/** Maximum file size for SKILL.md (100KB) */
|
|
5202
|
+
declare const DEFAULT_SKILL_MAX_SIZE = 102400;
|
|
5203
|
+
/**
|
|
5204
|
+
* Parse YAML frontmatter from a markdown file content string.
|
|
5205
|
+
*
|
|
5206
|
+
* Handles the `---` delimited frontmatter block at the start of the file.
|
|
5207
|
+
* Returns the parsed key-value pairs and the remaining markdown body.
|
|
5208
|
+
*
|
|
5209
|
+
* We intentionally avoid a YAML library dependency — skill frontmatter
|
|
5210
|
+
* is simple enough that a lightweight parser covers all real-world cases.
|
|
5211
|
+
*/
|
|
5212
|
+
declare function parseFrontmatter(raw: string): {
|
|
5213
|
+
data: Record<string, unknown>;
|
|
5214
|
+
body: string;
|
|
5215
|
+
};
|
|
5216
|
+
/**
|
|
5217
|
+
* Load skill metadata from a SKILL.md file path.
|
|
5218
|
+
*
|
|
5219
|
+
* This is the lightweight L1 load — reads just enough to populate the
|
|
5220
|
+
* skill summary that goes into the system prompt. Does NOT load the
|
|
5221
|
+
* full body content or scan for resources.
|
|
5222
|
+
*
|
|
5223
|
+
* @param filePath Absolute path to a SKILL.md file
|
|
5224
|
+
* @param scope The scope this skill belongs to
|
|
5225
|
+
* @param source How this skill was discovered
|
|
5226
|
+
* @param maxSize Maximum file size (skips oversized files)
|
|
5227
|
+
* @returns Parsed metadata, or null if the file is invalid/missing
|
|
5228
|
+
*/
|
|
5229
|
+
declare function loadSkillMetadata(filePath: string, scope: SkillScope, source: SkillSource, maxSize?: number): Promise<SkillMetadata | null>;
|
|
5230
|
+
/**
|
|
5231
|
+
* Load the full skill content including body and resources.
|
|
5232
|
+
*
|
|
5233
|
+
* This is the L2+L3 load — called when the agent activates a skill.
|
|
5234
|
+
* Reads the full markdown body and scans for bundled resource files.
|
|
5235
|
+
*
|
|
5236
|
+
* @param metadata Previously loaded skill metadata (L1)
|
|
5237
|
+
* @returns Full skill content with body and resource listing
|
|
5238
|
+
*/
|
|
5239
|
+
declare function loadSkillContent(metadata: SkillMetadata): Promise<SkillContent>;
|
|
5240
|
+
/**
|
|
5241
|
+
* Load a specific resource file's content.
|
|
5242
|
+
*
|
|
5243
|
+
* This is the deepest level of progressive disclosure — called only
|
|
5244
|
+
* when the agent explicitly requests a bundled file.
|
|
5245
|
+
*
|
|
5246
|
+
* @param resource The resource to read
|
|
5247
|
+
* @returns File content as UTF-8 string
|
|
5248
|
+
* @throws If the file doesn't exist or can't be read
|
|
5249
|
+
*/
|
|
5250
|
+
declare function loadResourceContent(resource: SkillResource): Promise<string>;
|
|
5251
|
+
/**
|
|
5252
|
+
* Infer the resource type from a file's location and extension.
|
|
5253
|
+
*
|
|
5254
|
+
* Used for files that aren't in a typed subdirectory.
|
|
5255
|
+
* Falls back to "reference" for unknown types.
|
|
5256
|
+
*/
|
|
5257
|
+
declare function inferResourceType(filePath: string): SkillResourceType;
|
|
5258
|
+
|
|
5259
|
+
/**
|
|
5260
|
+
* Skill Discovery — finds SKILL.md files across the filesystem
|
|
5261
|
+
*
|
|
5262
|
+
* Scans multiple roots with scope-based priority to build a complete
|
|
5263
|
+
* picture of available skills. Combines the best discovery patterns:
|
|
5264
|
+
*
|
|
5265
|
+
* - **Hierarchical walk**: scans `.agents/skills/` directories
|
|
5266
|
+
* between project root and cwd, so subdirectory skills override parents
|
|
5267
|
+
* - **Multi-source approach**: project dirs, user home dirs,
|
|
5268
|
+
* external convention dirs (.claude, .agents), config-specified paths
|
|
5269
|
+
* - **Standard layout**: `skills/<name>/SKILL.md` directory structure
|
|
5270
|
+
*
|
|
5271
|
+
* Discovery roots are scanned in order of increasing priority:
|
|
5272
|
+
*
|
|
5273
|
+
* 1. Built-in skills (lowest priority, reserved for future)
|
|
5274
|
+
* 2. Global config paths (user-specified `roots`)
|
|
5275
|
+
* 3. User home directory (`~/.agents/skills/`, `~/.claude/skills/`)
|
|
5276
|
+
* 4. Project tree walk (from git root to cwd)
|
|
5277
|
+
* 5. Project local (`.agents/skills/`, `.claude/skills/` in cwd)
|
|
5278
|
+
*
|
|
5279
|
+
* When two skills have the same name, the higher-priority root wins.
|
|
5280
|
+
*/
|
|
5281
|
+
|
|
5282
|
+
/** Default external dirs to scan for skills (standard conventions) */
|
|
5283
|
+
declare const DEFAULT_EXTERNAL_DIRS: string[];
|
|
5284
|
+
/** Default max scan depth within each root */
|
|
5285
|
+
declare const DEFAULT_MAX_SCAN_DEPTH = 4;
|
|
5286
|
+
/**
|
|
5287
|
+
* Discover all skills from configured roots and conventions.
|
|
5288
|
+
*
|
|
5289
|
+
* This is the main discovery function. It scans all roots, loads
|
|
5290
|
+
* metadata for each SKILL.md found, and returns deduplicated results
|
|
5291
|
+
* with scope-based priority (narrower scope wins).
|
|
5292
|
+
*
|
|
5293
|
+
* @param cwd Current working directory
|
|
5294
|
+
* @param config Skill configuration (roots, external dirs, etc.)
|
|
5295
|
+
* @returns Discovery result with skills, errors, and timing
|
|
5296
|
+
*
|
|
5297
|
+
* @example
|
|
5298
|
+
* ```typescript
|
|
5299
|
+
* const result = await discoverSkills("/path/to/project", {
|
|
5300
|
+
* externalDirs: [".agents", ".claude"],
|
|
5301
|
+
* roots: ["./extra-skills"],
|
|
5302
|
+
* maxScanDepth: 4,
|
|
5303
|
+
* });
|
|
5304
|
+
*
|
|
5305
|
+
* console.log(`Found ${result.skills.length} skills in ${result.durationMs}ms`);
|
|
5306
|
+
* for (const skill of result.skills) {
|
|
5307
|
+
* console.log(` ${skill.name} (${skill.scope}): ${skill.description}`);
|
|
5308
|
+
* }
|
|
5309
|
+
* ```
|
|
5310
|
+
*/
|
|
5311
|
+
declare function discoverSkills(cwd: string, config?: SkillConfig): Promise<SkillDiscoveryResult>;
|
|
5312
|
+
|
|
5313
|
+
/**
|
|
5314
|
+
* Skill Tools — built-in tools for agent-initiated skill loading
|
|
5315
|
+
*
|
|
5316
|
+
* Provides two tools that enable the agent to activate skills on demand:
|
|
5317
|
+
*
|
|
5318
|
+
* 1. **`skill`** — Load a skill's full instructions (L2).
|
|
5319
|
+
* The agent calls this when it recognizes a task matching a skill's
|
|
5320
|
+
* description. Returns the complete skill body with resource listings.
|
|
5321
|
+
*
|
|
5322
|
+
* 2. **`skill_resource`** — Read a specific bundled resource (L3).
|
|
5323
|
+
* After loading a skill, the agent can read scripts, references,
|
|
5324
|
+
* examples, or assets bundled with it.
|
|
5325
|
+
*
|
|
5326
|
+
* These tools expose skills as regular tools the agent can call,
|
|
5327
|
+
* using progressive disclosure so context is used efficiently.
|
|
5328
|
+
*
|
|
5329
|
+
* The tool descriptions are dynamic — they list all available skill names
|
|
5330
|
+
* and descriptions so the agent knows what's available without needing
|
|
5331
|
+
* a separate discovery step.
|
|
5332
|
+
*
|
|
5333
|
+
* @example
|
|
5334
|
+
* ```typescript
|
|
5335
|
+
* import { createSkillTools, createSkillRegistry } from "@cuylabs/agent-core";
|
|
5336
|
+
*
|
|
5337
|
+
* const registry = await createSkillRegistry(cwd, skillConfig);
|
|
5338
|
+
* const tools = createSkillTools(registry);
|
|
5339
|
+
*
|
|
5340
|
+
* const agent = createAgent({
|
|
5341
|
+
* model: anthropic("claude-sonnet-4-20250514"),
|
|
5342
|
+
* tools: [...myTools, ...tools],
|
|
5343
|
+
* });
|
|
5344
|
+
* ```
|
|
5345
|
+
*/
|
|
5346
|
+
|
|
5347
|
+
/**
|
|
5348
|
+
* Create the built-in `skill` tool that lets the agent load skill instructions.
|
|
5349
|
+
*
|
|
5350
|
+
* The tool's description is dynamically generated to include all available
|
|
5351
|
+
* skill names and summaries, so the agent knows exactly what's available.
|
|
5352
|
+
*
|
|
5353
|
+
* @param registry The skill registry to load from
|
|
5354
|
+
* @returns A Tool.Info for the `skill` tool
|
|
5355
|
+
*/
|
|
5356
|
+
declare function createSkillTool(registry: SkillRegistry): Tool$1.AnyInfo;
|
|
5357
|
+
/**
|
|
5358
|
+
* Create the built-in `skill_resource` tool for reading bundled files.
|
|
5359
|
+
*
|
|
5360
|
+
* This is the L3 layer — the agent calls this to read specific scripts,
|
|
5361
|
+
* references, examples, or assets bundled with a skill.
|
|
5362
|
+
*
|
|
5363
|
+
* @param registry The skill registry to load from
|
|
5364
|
+
* @returns A Tool.Info for the `skill_resource` tool
|
|
5365
|
+
*/
|
|
5366
|
+
declare function createSkillResourceTool(registry: SkillRegistry): Tool$1.AnyInfo;
|
|
5367
|
+
/**
|
|
5368
|
+
* Create both skill tools (skill + skill_resource) for an agent.
|
|
5369
|
+
*
|
|
5370
|
+
* Returns an empty array if the registry has no skills, so the tools
|
|
5371
|
+
* don't clutter the agent's tool list when skills aren't in use.
|
|
5372
|
+
*
|
|
5373
|
+
* @param registry The skill registry
|
|
5374
|
+
* @returns Array of Tool.AnyInfo (0 or 2 tools)
|
|
5375
|
+
*
|
|
5376
|
+
* @example
|
|
5377
|
+
* ```typescript
|
|
5378
|
+
* const registry = await createSkillRegistry(cwd, config);
|
|
5379
|
+
* const skillTools = createSkillTools(registry);
|
|
5380
|
+
*
|
|
5381
|
+
* const agent = createAgent({
|
|
5382
|
+
* model: myModel,
|
|
5383
|
+
* tools: [...codeTools, ...skillTools],
|
|
5384
|
+
* });
|
|
5385
|
+
* ```
|
|
5386
|
+
*/
|
|
5387
|
+
declare function createSkillTools(registry: SkillRegistry): Tool$1.AnyInfo[];
|
|
5388
|
+
|
|
5389
|
+
/**
|
|
5390
|
+
* Sub-Agent Types
|
|
5391
|
+
*
|
|
5392
|
+
* Type definitions for the sub-agent system: profiles, lifecycle status,
|
|
5393
|
+
* handles, and configuration.
|
|
5394
|
+
*
|
|
5395
|
+
* Following PowerShell verb-noun naming (Invoke-Agent, Get-Agent, Stop-Agent).
|
|
5396
|
+
*
|
|
5397
|
+
* Designed for agent-core's composable library architecture.
|
|
5398
|
+
*
|
|
5399
|
+
* Key design decisions:
|
|
5400
|
+
*
|
|
5401
|
+
* 1. **Library-first**: Unlike CLI-embedded tools, these
|
|
5402
|
+
* are importable building blocks. The consumer creates them with
|
|
5403
|
+
* `createSubAgentTools(parent)` and opts in — nothing auto-registered.
|
|
5404
|
+
*
|
|
5405
|
+
* 2. **Agent profiles over role configs**: Instead of TOML files or markdown
|
|
5406
|
+
* agents, we use composable `AgentProfile` objects that wrap existing
|
|
5407
|
+
* `Preset` + extra metadata the LLM can read.
|
|
5408
|
+
*
|
|
5409
|
+
* 3. **Progressive lifecycle**: Start with synchronous `invoke_agent` (simplest),
|
|
5410
|
+
* add `wait_agent`/`close_agent` only when async profiles exist.
|
|
5411
|
+
*
|
|
5412
|
+
* 4. **Depth safety**: Hard limit on nesting with configurable max depth.
|
|
5413
|
+
*
|
|
5414
|
+
* @packageDocumentation
|
|
5415
|
+
*/
|
|
5416
|
+
|
|
5417
|
+
/**
|
|
5418
|
+
* An agent profile defines a specialized sub-agent personality.
|
|
5419
|
+
*
|
|
5420
|
+
* Profiles combine a `Preset` (tool filtering, temperature, etc.) with
|
|
5421
|
+
* LLM-facing metadata (name, description, examples) so the model knows
|
|
5422
|
+
* when and how to delegate.
|
|
5423
|
+
*
|
|
5424
|
+
* Profiles define specialized sub-agent personalities with roles
|
|
5425
|
+
* like explorer, worker, planner, and reviewer.
|
|
5426
|
+
*
|
|
5427
|
+
* @example
|
|
5428
|
+
* ```typescript
|
|
5429
|
+
* const explorer: AgentProfile = {
|
|
5430
|
+
* name: "explorer",
|
|
5431
|
+
* description: "Fast, read-only codebase exploration. Use when you need to find files, search code, or understand project structure.",
|
|
5432
|
+
* preset: Presets.explore,
|
|
5433
|
+
* maxSteps: 30,
|
|
5434
|
+
* };
|
|
5435
|
+
* ```
|
|
5436
|
+
*/
|
|
5437
|
+
interface AgentProfile {
|
|
5438
|
+
/** Unique identifier used in tool calls (lowercase, no spaces) */
|
|
5439
|
+
name: string;
|
|
5440
|
+
/**
|
|
5441
|
+
* When to use this sub-agent — written for the LLM to consume.
|
|
5442
|
+
*
|
|
5443
|
+
* This is the most important field. The parent LLM reads this to decide
|
|
5444
|
+
* whether to delegate. Include clear trigger phrases.
|
|
5445
|
+
*/
|
|
5446
|
+
description: string;
|
|
5447
|
+
/**
|
|
5448
|
+
* Preset to apply (tool filtering, temperature, system prompt, etc.).
|
|
5449
|
+
* If omitted, inherits the parent agent's configuration.
|
|
5450
|
+
*/
|
|
5451
|
+
preset?: Preset;
|
|
5452
|
+
/**
|
|
5453
|
+
* Override system prompt for this profile.
|
|
5454
|
+
* Takes precedence over preset's systemPrompt.
|
|
5455
|
+
* Use `{basePrompt}` to include the parent's system prompt.
|
|
5456
|
+
*/
|
|
5457
|
+
systemPrompt?: string;
|
|
5458
|
+
/**
|
|
5459
|
+
* Override model for this profile.
|
|
5460
|
+
* Useful for using cheaper/faster models for simple tasks.
|
|
5461
|
+
*/
|
|
5462
|
+
model?: LanguageModel;
|
|
5463
|
+
/** Max steps for this sub-agent (default: parent's maxSteps) */
|
|
5464
|
+
maxSteps?: number;
|
|
5465
|
+
/**
|
|
5466
|
+
* Additional middleware appended to the parent's middleware stack.
|
|
5467
|
+
* Useful for adding logging or guardrails specific to this profile.
|
|
5468
|
+
*/
|
|
5469
|
+
additionalMiddleware?: AgentMiddleware[];
|
|
5470
|
+
/**
|
|
5471
|
+
* Additional tools beyond what the preset allows.
|
|
5472
|
+
* These are merged with the preset-filtered tools.
|
|
5473
|
+
*/
|
|
5474
|
+
additionalTools?: Tool$1.AnyInfo[];
|
|
5475
|
+
/**
|
|
5476
|
+
* Whether this sub-agent can itself spawn further sub-agents.
|
|
5477
|
+
* When false, the `invoke_agent` tool is removed from the child.
|
|
5478
|
+
*
|
|
5479
|
+
* @default false — sub-agents cannot nest by default (safe default)
|
|
5480
|
+
*/
|
|
5481
|
+
canSpawn?: boolean;
|
|
5482
|
+
}
|
|
5483
|
+
/**
|
|
5484
|
+
* Lifecycle status of a running or completed sub-agent.
|
|
5485
|
+
*
|
|
5486
|
+
* Simplified lifecycle for the fire-and-forget-with-optional-wait model.
|
|
5487
|
+
*/
|
|
5488
|
+
type SubAgentStatus = {
|
|
5489
|
+
state: "running";
|
|
5490
|
+
} | {
|
|
5491
|
+
state: "completed";
|
|
5492
|
+
response: string;
|
|
5493
|
+
usage: SubAgentUsage;
|
|
5494
|
+
} | {
|
|
5495
|
+
state: "errored";
|
|
5496
|
+
error: string;
|
|
5497
|
+
} | {
|
|
5498
|
+
state: "cancelled";
|
|
5499
|
+
};
|
|
5500
|
+
/**
|
|
5501
|
+
* Token usage tracking for a sub-agent run.
|
|
5502
|
+
*/
|
|
5503
|
+
interface SubAgentUsage {
|
|
5504
|
+
inputTokens: number;
|
|
5505
|
+
outputTokens: number;
|
|
5506
|
+
totalTokens: number;
|
|
5507
|
+
}
|
|
5508
|
+
/**
|
|
5509
|
+
* A handle to a running or completed sub-agent.
|
|
5510
|
+
*
|
|
5511
|
+
* Returned by async invocations. Allows the parent to wait for completion,
|
|
5512
|
+
* check status, or cancel.
|
|
5513
|
+
*/
|
|
5514
|
+
interface SubAgentHandle {
|
|
5515
|
+
/** Unique ID for this sub-agent invocation */
|
|
5516
|
+
id: string;
|
|
5517
|
+
/** Human-readable name (from profile or auto-generated) */
|
|
5518
|
+
name: string;
|
|
5519
|
+
/** Session ID of the child agent's session */
|
|
5520
|
+
sessionId: string;
|
|
5521
|
+
/** Current status */
|
|
5522
|
+
status: SubAgentStatus;
|
|
5523
|
+
/** The promise that resolves when the sub-agent completes */
|
|
5524
|
+
promise: Promise<SubAgentCompletedResult>;
|
|
5525
|
+
/** Abort controller to cancel this sub-agent */
|
|
5526
|
+
abort: AbortController;
|
|
5527
|
+
}
|
|
5528
|
+
/**
|
|
5529
|
+
* The final result of a completed sub-agent.
|
|
5530
|
+
*/
|
|
5531
|
+
interface SubAgentCompletedResult {
|
|
5532
|
+
/** Final response text */
|
|
5533
|
+
response: string;
|
|
5534
|
+
/** Session ID (for audit/inspection) */
|
|
5535
|
+
sessionId: string;
|
|
5536
|
+
/** Token usage */
|
|
5537
|
+
usage: SubAgentUsage;
|
|
5538
|
+
/** Tool calls the sub-agent made */
|
|
5539
|
+
toolCalls: Array<{
|
|
5540
|
+
name: string;
|
|
5541
|
+
result: unknown;
|
|
5542
|
+
}>;
|
|
5543
|
+
}
|
|
5544
|
+
/**
|
|
5545
|
+
* Configuration for `createSubAgentTools()`.
|
|
5546
|
+
*
|
|
5547
|
+
* Controls which profiles are available, concurrency limits,
|
|
5548
|
+
* depth limits, and whether async mode is enabled.
|
|
5549
|
+
*/
|
|
5550
|
+
interface SubAgentToolConfig {
|
|
5551
|
+
/**
|
|
5552
|
+
* Available sub-agent profiles.
|
|
5553
|
+
* Each profile defines a specialized persona the LLM can invoke.
|
|
5554
|
+
* At least one profile is required.
|
|
5555
|
+
*/
|
|
5556
|
+
profiles: AgentProfile[];
|
|
5557
|
+
/**
|
|
5558
|
+
* Maximum concurrent sub-agents (across all profiles).
|
|
5559
|
+
* @default 6
|
|
5560
|
+
*/
|
|
5561
|
+
maxConcurrent?: number;
|
|
5562
|
+
/**
|
|
5563
|
+
* Maximum nesting depth for recursive sub-agent spawning.
|
|
5564
|
+
* Depth 0 = no spawning, 1 = one level of sub-agents, etc.
|
|
5565
|
+
*
|
|
5566
|
+
* When a sub-agent reaches the depth limit, the `invoke_agent`
|
|
5567
|
+
* tool is automatically removed from its tool set.
|
|
5568
|
+
*
|
|
5569
|
+
* @default 2
|
|
5570
|
+
*/
|
|
5571
|
+
maxDepth?: number;
|
|
5572
|
+
/**
|
|
5573
|
+
* Current depth (internal — incremented when creating child tools).
|
|
5574
|
+
* Users should not set this directly.
|
|
5575
|
+
*
|
|
5576
|
+
* @internal
|
|
5577
|
+
*/
|
|
5578
|
+
currentDepth?: number;
|
|
5579
|
+
/**
|
|
5580
|
+
* Enable async mode with `wait_agent` and `close_agent` tools.
|
|
5581
|
+
*
|
|
5582
|
+
* When false (default), `invoke_agent` blocks until the sub-agent
|
|
5583
|
+
* completes and returns the result directly — simpler but sequential.
|
|
5584
|
+
*
|
|
5585
|
+
* When true, `invoke_agent` returns immediately with an agent ID,
|
|
5586
|
+
* and the LLM must call `wait_agent` to collect results. This enables
|
|
5587
|
+
* parallel sub-agent execution.
|
|
5588
|
+
*
|
|
5589
|
+
* @default false
|
|
5590
|
+
*/
|
|
5591
|
+
async?: boolean;
|
|
5592
|
+
/**
|
|
5593
|
+
* Title prefix for sub-agent sessions.
|
|
5594
|
+
* @default "Sub-agent"
|
|
5595
|
+
*/
|
|
5596
|
+
sessionTitlePrefix?: string;
|
|
5597
|
+
}
|
|
5598
|
+
/** Default maximum concurrent sub-agents */
|
|
5599
|
+
declare const DEFAULT_MAX_CONCURRENT = 6;
|
|
5600
|
+
/** Default maximum nesting depth */
|
|
5601
|
+
declare const DEFAULT_MAX_SPAWN_DEPTH = 2;
|
|
5602
|
+
/** Default session title prefix */
|
|
5603
|
+
declare const DEFAULT_SESSION_TITLE_PREFIX = "Sub-agent";
|
|
5604
|
+
|
|
5605
|
+
/**
|
|
5606
|
+
* Sub-Agent Tracker — in-memory state for active sub-agents
|
|
5607
|
+
*
|
|
5608
|
+
* Manages the lifecycle of running sub-agents: slots, handles,
|
|
5609
|
+
* concurrency limits, and depth enforcement.
|
|
5610
|
+
*
|
|
5611
|
+
* Handles spawn slot reservation and depth checking, designed for
|
|
5612
|
+
* single-process TypeScript/async usage.
|
|
5613
|
+
*
|
|
5614
|
+
* @packageDocumentation
|
|
5615
|
+
*/
|
|
5616
|
+
|
|
5617
|
+
/**
|
|
5618
|
+
* Tracks active sub-agent handles and enforces concurrency/depth limits.
|
|
5619
|
+
*
|
|
5620
|
+
* One tracker is created per `createSubAgentTools()` call and shared
|
|
5621
|
+
* across all sub-agent tool instances for that parent agent.
|
|
5622
|
+
*/
|
|
5623
|
+
declare class SubAgentTracker {
|
|
5624
|
+
/** Active sub-agent handles by ID */
|
|
5625
|
+
private readonly handles;
|
|
5626
|
+
/** Maximum concurrent sub-agents */
|
|
5627
|
+
readonly maxConcurrent: number;
|
|
5628
|
+
/** Maximum nesting depth */
|
|
5629
|
+
readonly maxDepth: number;
|
|
5630
|
+
/** Current depth in the spawn hierarchy */
|
|
5631
|
+
readonly currentDepth: number;
|
|
5632
|
+
constructor(config?: Partial<SubAgentToolConfig>);
|
|
5633
|
+
/** Number of currently active (running) sub-agents */
|
|
5634
|
+
get activeCount(): number;
|
|
5635
|
+
/** Total tracked handles (including completed) */
|
|
5636
|
+
get totalCount(): number;
|
|
5637
|
+
/**
|
|
5638
|
+
* Check if a new sub-agent can be spawned.
|
|
5639
|
+
* Returns an error message if not, undefined if OK.
|
|
5640
|
+
*/
|
|
5641
|
+
canSpawn(): string | undefined;
|
|
5642
|
+
/** Whether the current depth allows further spawning */
|
|
5643
|
+
get canNest(): boolean;
|
|
5644
|
+
/** Register a new sub-agent handle */
|
|
5645
|
+
register(handle: SubAgentHandle): void;
|
|
5646
|
+
/** Get a handle by ID */
|
|
5647
|
+
get(id: string): SubAgentHandle | undefined;
|
|
5648
|
+
/** Update a handle's status */
|
|
5649
|
+
updateStatus(id: string, status: SubAgentStatus): void;
|
|
5650
|
+
/** Get all handles */
|
|
5651
|
+
list(): SubAgentHandle[];
|
|
5652
|
+
/** Get all running handles */
|
|
5653
|
+
running(): SubAgentHandle[];
|
|
5654
|
+
/** Get all completed handles */
|
|
5655
|
+
completed(): SubAgentHandle[];
|
|
5656
|
+
/**
|
|
5657
|
+
* Cancel a running sub-agent.
|
|
5658
|
+
* Signals the abort controller and updates status.
|
|
5659
|
+
*/
|
|
5660
|
+
cancel(id: string): boolean;
|
|
5661
|
+
/**
|
|
5662
|
+
* Cancel all running sub-agents.
|
|
5663
|
+
*/
|
|
5664
|
+
cancelAll(): void;
|
|
5665
|
+
/**
|
|
5666
|
+
* Wait for a specific sub-agent to complete.
|
|
5667
|
+
* Returns the result or throws if not found.
|
|
5668
|
+
*/
|
|
5669
|
+
wait(id: string, timeoutMs?: number): Promise<SubAgentCompletedResult>;
|
|
5670
|
+
/**
|
|
5671
|
+
* Wait for any one of the given sub-agents to complete.
|
|
5672
|
+
* Returns the first result.
|
|
5673
|
+
*/
|
|
5674
|
+
waitAny(ids: string[], timeoutMs?: number): Promise<{
|
|
5675
|
+
id: string;
|
|
5676
|
+
result: SubAgentCompletedResult;
|
|
5677
|
+
} | {
|
|
5678
|
+
timedOut: true;
|
|
5679
|
+
}>;
|
|
5680
|
+
/**
|
|
5681
|
+
* Create a child tracker configuration for a nested sub-agent.
|
|
5682
|
+
* Increments the depth counter.
|
|
5683
|
+
*/
|
|
5684
|
+
childConfig(): Partial<SubAgentToolConfig>;
|
|
5685
|
+
}
|
|
5686
|
+
|
|
5687
|
+
/**
|
|
5688
|
+
* Sub-Agent Tools — LLM-callable tools for delegating work to specialized agents
|
|
5689
|
+
*
|
|
5690
|
+
* Provides three tools following PowerShell verb-noun naming:
|
|
5691
|
+
*
|
|
5692
|
+
* 1. **`invoke_agent`** — Spawn a sub-agent for a focused task.
|
|
5693
|
+
* In sync mode, blocks until completion and returns the result.
|
|
5694
|
+
* In async mode, returns an agent ID immediately.
|
|
5695
|
+
*
|
|
5696
|
+
* 2. **`wait_agent`** — Wait for one or more async sub-agents to complete.
|
|
5697
|
+
* Supports timeout. Only available in async mode.
|
|
5698
|
+
*
|
|
5699
|
+
* 3. **`close_agent`** — Cancel a running sub-agent.
|
|
5700
|
+
* Only available in async mode.
|
|
5701
|
+
*
|
|
5702
|
+
* These tools bridge agent-core's existing `fork().run()` primitives
|
|
5703
|
+
* into the LLM's tool-calling interface, letting the model itself
|
|
5704
|
+
* decide when to delegate.
|
|
5705
|
+
*
|
|
5706
|
+
* Key differentiators from competitors:
|
|
5707
|
+
* - **Library-first**: Created via `createSubAgentTools(parent)`, not auto-registered
|
|
5708
|
+
* - **Profile-based**: Sub-agent types defined as composable `AgentProfile` objects
|
|
5709
|
+
* - **Depth-safe**: Automatic depth limiting removes `invoke_agent` at max depth
|
|
5710
|
+
* - **Dual-mode**: Sync (simple) or async (parallel) — consumer chooses
|
|
5711
|
+
*
|
|
5712
|
+
* @example
|
|
5713
|
+
* ```typescript
|
|
5714
|
+
* import { createSubAgentTools, createAgent, Presets } from "@cuylabs/agent-core";
|
|
5715
|
+
*
|
|
5716
|
+
* const agent = createAgent({ model, tools: codeTools });
|
|
5717
|
+
* const subAgentTools = createSubAgentTools(agent, {
|
|
5718
|
+
* profiles: [
|
|
5719
|
+
* { name: "explorer", description: "Fast read-only search", preset: Presets.explore },
|
|
5720
|
+
* { name: "reviewer", description: "Thorough code review", preset: Presets.review },
|
|
5721
|
+
* ],
|
|
5722
|
+
* });
|
|
5723
|
+
*
|
|
5724
|
+
* const fullAgent = createAgent({
|
|
5725
|
+
* model,
|
|
5726
|
+
* tools: [...codeTools, ...subAgentTools],
|
|
5727
|
+
* });
|
|
5728
|
+
* ```
|
|
5729
|
+
*
|
|
5730
|
+
* @packageDocumentation
|
|
5731
|
+
*/
|
|
5732
|
+
|
|
5733
|
+
/**
|
|
5734
|
+
* Create the sub-agent tools for an agent.
|
|
5735
|
+
*
|
|
5736
|
+
* Returns an array of tools that the LLM can call to delegate tasks:
|
|
5737
|
+
* - `invoke_agent` — always included
|
|
5738
|
+
* - `wait_agent` — only in async mode
|
|
5739
|
+
* - `close_agent` — only in async mode
|
|
5740
|
+
*
|
|
5741
|
+
* These tools use the parent agent's `fork().run()` under the hood,
|
|
5742
|
+
* so sub-agents inherit the parent's storage, host, MCP connections,
|
|
5743
|
+
* and (optionally) middleware.
|
|
5744
|
+
*
|
|
5745
|
+
* @param parent The parent agent that sub-agents will be forked from
|
|
5746
|
+
* @param config Sub-agent configuration (profiles, limits, mode)
|
|
5747
|
+
* @returns Array of Tool.AnyInfo to add to the agent's tools
|
|
5748
|
+
*
|
|
5749
|
+
* @example
|
|
5750
|
+
* ```typescript
|
|
5751
|
+
* import {
|
|
5752
|
+
* createAgent,
|
|
5753
|
+
* createSubAgentTools,
|
|
5754
|
+
* Presets,
|
|
5755
|
+
* } from "@cuylabs/agent-core";
|
|
5756
|
+
*
|
|
5757
|
+
* const parent = createAgent({ model, tools: codeTools });
|
|
5758
|
+
*
|
|
5759
|
+
* // Sync mode (simple — invoke blocks until done)
|
|
5760
|
+
* const subTools = createSubAgentTools(parent, {
|
|
5761
|
+
* profiles: [
|
|
5762
|
+
* { name: "explorer", description: "Read-only search", preset: Presets.explore },
|
|
5763
|
+
* { name: "reviewer", description: "Code review", preset: Presets.review },
|
|
5764
|
+
* ],
|
|
5765
|
+
* });
|
|
5766
|
+
*
|
|
5767
|
+
* // Async mode (parallel — invoke returns ID, wait collects result)
|
|
5768
|
+
* const asyncSubTools = createSubAgentTools(parent, {
|
|
5769
|
+
* profiles: [
|
|
5770
|
+
* { name: "explorer", description: "Read-only search", preset: Presets.explore },
|
|
5771
|
+
* { name: "worker", description: "Implementation", preset: Presets.careful },
|
|
5772
|
+
* ],
|
|
5773
|
+
* async: true,
|
|
5774
|
+
* maxConcurrent: 4,
|
|
5775
|
+
* });
|
|
5776
|
+
*
|
|
5777
|
+
* const agent = createAgent({
|
|
5778
|
+
* model,
|
|
5779
|
+
* tools: [...codeTools, ...subTools],
|
|
5780
|
+
* });
|
|
5781
|
+
* ```
|
|
5782
|
+
*/
|
|
5783
|
+
declare function createSubAgentTools(parent: Agent, config: SubAgentToolConfig): Tool$1.AnyInfo[];
|
|
5784
|
+
|
|
4390
5785
|
type AdapterKind = "openai" | "anthropic" | "google" | "openai-compatible";
|
|
4391
5786
|
type AdapterSettings = {
|
|
4392
5787
|
apiKey?: string;
|
|
@@ -4416,4 +5811,4 @@ type Resolver = (key: string) => Promise<LanguageModel>;
|
|
|
4416
5811
|
type SyncResolver = (key: string) => LanguageModel;
|
|
4417
5812
|
declare function createResolver(directory: Directory): Resolver;
|
|
4418
5813
|
|
|
4419
|
-
export { type AdapterSettings, Agent, type AgentConfig, type AgentEvent, type AgentState, type AgentStatus, type AnyStreamResult, type AppliedPreset, type ApprovalAction, type ApprovalConfig, ApprovalDeniedError, type ApprovalEvent, type ApprovalHandler, type ApprovalRequest, type ApprovalRule, ApprovalTimeoutError, type AssistantMessage, type BranchEntry, type ChangeSet, type Checkpoint, type CheckpointConfig, type CheckpointManager, type CompactionConfig, type CompactionEntry, type ContextLimits, ContextManager, ContextOverflowError, type CreateSessionOptions, type CustomStreamProvider, type CustomStreamResult, DEFAULT_CONTEXT_LIMITS, DEFAULT_INSTRUCTION_PATTERNS, DEFAULT_MAX_DEPTH, DEFAULT_MAX_FILE_SIZE, DEFAULT_RETRY_CONFIG, type DockerHostOptions, type DoomLoopAction, DoomLoopError, type DoomLoopHandler, type DoomLoopRequest, type EngineSpec, type EnhancedTools, type EnvironmentInfo, type ErrorCategory, type FileBaseline, type FileChange, type FileEntry, FileOperationMeta, FileStorage, type FileStorageOptions, type HttpTransportConfig, type InstructionFile, InterventionController, LLM, LLMError, type LLMErrorOptions, type LLMStreamInput, type LLMStreamResult, type MCPConfig, type MCPManager, type MCPPrompt, type MCPResource, type MCPServerConfig, type MCPServerStatus, MemoryStorage, type Message, type MessageBase, type MessageEntry, type MessageError, type MessageRole, type MetadataEntry, type ModelCapabilities, ModelCapabilityResolver, type Directory as ModelDirectory, type ModelEntry, type ModelFamily, type Resolver as ModelResolver, type ModelSpec, type NetworkStatus, OUTPUT_TOKEN_MAX, type OnInterventionApplied, PRIORITY_BASE, PRIORITY_CUSTOM, PRIORITY_ENVIRONMENT, PRIORITY_INSTRUCTIONS, PRIORITY_OVERRIDE, PRIORITY_SKILLS, type PendingIntervention, type Preset, Presets, type ProcessorOptions, type ProcessorOutput, type ProcessorResult, type PromptBuildContext, PromptBuilder, type PromptConfig, type PromptSection, type ProviderCompatibility, type PruneContextOptions, type PruneResult, type ReasoningConfig, type ReasoningLevel, type ResolverOptions, type ResponseHeaders, type RetryConfig, type RetryHandlerOptions, type RetryState, type RiskLevel, STORAGE_VERSION, type Session, type SessionContext, type SessionEntry, type SessionHeader, type SessionInfo, SessionManager, type SessionStorage, type SseTransportConfig, type StdioTransportConfig, type StepInfo, type StreamChunk, type StreamInput, type StreamProvider, type StreamProviderConfig, type StreamProviderFactory, type StreamProviderInput, type StreamProviderResult, type SubAgentResult, type SummarizationOptions, type SyncResolver, type SystemMessage, type TokenUsage, Tool$1 as Tool, ToolHost, type ToolMessage, type TrackedToolMetadata, TurnChangeTracker, type TurnFileChange, type TurnSummary, type TurnTrackerConfig, TurnTrackerContext, type UndoResult, type UserMessage, applyPreset, buildMessagesFromEntries, buildReasoningOptions, buildReasoningOptionsSync, calculateDelay, clearCheckpoints, configureDefaultSessionManager, configureResolver, createAgent, createApprovalHandler, createCheckpointManager, createMCPManager, createPreset, createPromptBuilder, createResolver, createRetryHandler, createRetryState, createTurnTracker, defineServer, deserializeMessage, detectModelFamily, discoverInstructions, dockerHost, estimateConversationTokens, estimateMessageTokens, estimateTokens, extractFilePathsFromArgs, filterTools, findCutPoint, formatEnvironment, formatInstructions, gatherEnvironment, generateEntryId, generateSummary, getAvailableFamilies, getDataDir, getDefaultResolver, getDefaultSessionManager, getErrorCategory, getLeafId, getModelId, getNetworkStatus, getProjectSessionsDir, getProviderId, getReasoningConfig, getReasoningConfigSync, getRetryDelay, getSessionsDir, getTemplate, getToolRisk, httpServer, isContextOverflowing, isRetryable, isRetryableCategory, loadGlobalInstructions, localHost, mergePresets, parseJSONL, processStream, pruneContext, pruneToolResults, runConcurrent, serializeMessage, shouldCaptureBaseline, shouldPruneContext, shouldRetry, sleep, sseServer, stdioServer, summarizeEnvironment, supportsReasoning, supportsReasoningSync, toJSONL, withFileTracking, withRetry };
|
|
5814
|
+
export { type AdapterSettings, Agent, type AgentConfig, type AgentEvent, type AgentMiddleware, type AgentProfile, type AgentState, type AgentStatus, type AnyStreamResult, type AppliedPreset, type ApprovalAction, type ApprovalConfig, ApprovalDeniedError, type ApprovalEvent, type ApprovalHandler, type ApprovalMiddlewareConfig, type ApprovalRequest, type ApprovalRule, ApprovalTimeoutError, type AssistantMessage, type BranchEntry, type ChangeSet, type Checkpoint, type CheckpointConfig, type CheckpointManager, type CompactionConfig, type CompactionEntry, type ContextLimits, ContextManager, ContextOverflowError, type CreateSessionOptions, type CustomStreamProvider, type CustomStreamResult, DEFAULT_CONTEXT_LIMITS, DEFAULT_EXTERNAL_DIRS, DEFAULT_INSTRUCTION_PATTERNS, DEFAULT_MAX_CONCURRENT, DEFAULT_MAX_DEPTH, DEFAULT_MAX_FILE_SIZE, DEFAULT_MAX_SCAN_DEPTH, DEFAULT_MAX_SPAWN_DEPTH, DEFAULT_RETRY_CONFIG, DEFAULT_SESSION_TITLE_PREFIX, DEFAULT_SKILL_MAX_SIZE, type DockerHostOptions, type DoomLoopAction, DoomLoopError, type DoomLoopHandler, type DoomLoopRequest, type EngineSpec, type EnhancedTools, type EnvironmentInfo, type ErrorCategory, type FileBaseline, type FileChange, type FileEntry, FileOperationMeta, FileStorage, type FileStorageOptions, type HttpTransportConfig, type InstructionFile, InterventionController, LLM, LLMError, type LLMErrorOptions, type LLMStreamInput, type LLMStreamResult, type MCPConfig, type MCPManager, type MCPPrompt, type MCPResource, type MCPServerConfig, type MCPServerStatus, MemoryStorage, type Message, type MessageBase, type MessageEntry, type MessageError, type MessageRole, type MetadataEntry, MiddlewareRunner, type ModelCapabilities, ModelCapabilityResolver, type Directory as ModelDirectory, type ModelEntry, type ModelFamily, type Resolver as ModelResolver, type ModelSpec, type NetworkStatus, OUTPUT_TOKEN_MAX, type OnInterventionApplied, PRIORITY_BASE, PRIORITY_CUSTOM, PRIORITY_ENVIRONMENT, PRIORITY_INSTRUCTIONS, PRIORITY_OVERRIDE, PRIORITY_SKILLS, type PendingIntervention, type Preset, Presets, type ProcessorOptions, type ProcessorOutput, type ProcessorResult, type PromptBuildContext, PromptBuilder, type PromptConfig, type PromptSection, type ProviderCompatibility, type PruneContextOptions, type PruneResult, type ReasoningConfig, type ReasoningLevel, type RemoteSkillEntry, type RemoteSkillIndex, type ResolverOptions, type ResponseHeaders, type RetryConfig, type RetryHandlerOptions, type RetryState, type RiskLevel, SKILL_FILENAME, STORAGE_VERSION, type Session, type SessionContext, type SessionEntry, type SessionHeader, type SessionInfo, SessionManager, type SessionStorage, type SkillConfig, type SkillContent, type SkillDiscoveryError, type SkillDiscoveryResult, type SkillMetadata, SkillRegistry, type SkillResource, type SkillResourceType, type SkillScope, type SkillSource, type SkillSourceType, type SseTransportConfig, type StdioTransportConfig, type StepInfo, type StreamChunk, type StreamInput, type StreamProvider, type StreamProviderConfig, type StreamProviderFactory, type StreamProviderInput, type StreamProviderResult, type SubAgentCompletedResult, type SubAgentHandle, type SubAgentResult, type SubAgentStatus, type SubAgentToolConfig, SubAgentTracker, type SubAgentUsage, type SummarizationOptions, type SyncResolver, type SystemMessage, type TokenUsage, Tool$1 as Tool, type ToolCallDecision, ToolContext, ToolHost, type ToolMessage, type TrackedToolMetadata, TurnChangeTracker, type TurnFileChange, type TurnSummary, type TurnTrackerConfig, TurnTrackerContext, type UndoResult, type UserMessage, applyPreset, approvalMiddleware, buildMessagesFromEntries, buildReasoningOptions, buildReasoningOptionsSync, calculateDelay, clearCheckpoints, configureDefaultSessionManager, configureResolver, createAgent, createApprovalHandler, createCheckpointManager, createMCPManager, createPreset, createPromptBuilder, createResolver, createRetryHandler, createRetryState, createSkillRegistry, createSkillResourceTool, createSkillTool, createSkillTools, createSubAgentTools, createTurnTracker, defineServer, deserializeMessage, detectModelFamily, discoverInstructions, discoverSkills, dockerHost, emptySkillRegistry, estimateConversationTokens, estimateMessageTokens, estimateTokens, extractFilePathsFromArgs, filterTools, findCutPoint, formatEnvironment, formatInstructions, gatherEnvironment, generateEntryId, generateSummary, getAvailableFamilies, getDataDir, getDefaultResolver, getDefaultSessionManager, getErrorCategory, getLeafId, getModelId, getNetworkStatus, getProjectSessionsDir, getProviderId, getReasoningConfig, getReasoningConfigSync, getRetryDelay, getSessionsDir, getTemplate, getToolRisk, httpServer, inferResourceType, isContextOverflowing, isRetryable, isRetryableCategory, loadGlobalInstructions, loadResourceContent, loadSkillContent, loadSkillMetadata, localHost, mergePresets, parseFrontmatter, parseJSONL, processStream, pruneContext, pruneToolResults, runConcurrent, serializeMessage, shouldCaptureBaseline, shouldPruneContext, shouldRetry, sleep, sseServer, stdioServer, summarizeEnvironment, supportsReasoning, supportsReasoningSync, toJSONL, withFileTracking, withRetry };
|