@cuylabs/agent-core 0.8.0 → 0.10.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 +33 -17
- package/dist/chunk-2O4MCSQS.js +780 -0
- package/dist/chunk-2TTOLHBT.js +198 -0
- package/dist/chunk-5FMSGQVX.js +281 -0
- package/dist/chunk-5NVVNXPQ.js +288 -0
- package/dist/{chunk-CAA7FHIH.js → chunk-6HZBHFOL.js} +3 -103
- package/dist/chunk-CJI7PVS2.js +58 -0
- package/dist/{chunk-N6HWIEEA.js → chunk-CMYN2RCB.js} +278 -61
- package/dist/chunk-FII65CN7.js +117 -0
- package/dist/{chunk-IVUJDISU.js → chunk-GFTW23FV.js} +5 -14
- package/dist/chunk-I6PKJ7XQ.js +292 -0
- package/dist/{chunk-BDBZ3SLK.js → chunk-ICZ66572.js} +48 -4
- package/dist/chunk-KYLPMBHD.js +316 -0
- package/dist/chunk-MXAP4UG6.js +2956 -0
- package/dist/{chunk-RZITT45F.js → chunk-N3VX7FEE.js} +39 -6
- package/dist/{chunk-YSLSEQ6B.js → chunk-NDZWXCBZ.js} +218 -95
- package/dist/{chunk-P6YF7USR.js → chunk-Q742PSH3.js} +23 -38
- package/dist/chunk-QAL3OMI3.js +943 -0
- package/dist/{chunk-RFEKJKTO.js → chunk-RN6WZEUF.js} +330 -280
- package/dist/{chunk-ZXAKHMWH.js → chunk-ROTGCYDW.js} +22 -84
- package/dist/chunk-SPBFQXOT.js +0 -0
- package/dist/{chunk-LRHOS4ZN.js → chunk-SPILYYDF.js} +3 -2
- package/dist/chunk-SSFBF3US.js +602 -0
- package/dist/chunk-SZ2XBPTW.js +8 -0
- package/dist/chunk-T4UIX5D7.js +115 -0
- package/dist/chunk-TIHPYVAJ.js +102 -0
- package/dist/{chunk-YUUJK53A.js → chunk-TOTDGK3P.js} +1 -1
- package/dist/chunk-V4RFNEET.js +563 -0
- package/dist/chunk-VOUEJSW6.js +0 -0
- package/dist/{chunk-4BDA7DQY.js → chunk-WBPOZ7CL.js} +673 -273
- package/dist/chunk-X4VN4GIJ.js +185 -0
- package/dist/dispatch/index.d.ts +93 -0
- package/dist/dispatch/index.js +37 -0
- package/dist/events/index.d.ts +93 -0
- package/dist/events/index.js +6 -0
- package/dist/{runtime → execution}/index.d.ts +120 -34
- package/dist/{runtime → execution}/index.js +18 -13
- package/dist/index-BCqEGzBj.d.ts +251 -0
- package/dist/index.d.ts +490 -122
- package/dist/index.js +2104 -615
- package/dist/{errors → inference/errors}/index.d.ts +2 -2
- package/dist/{errors → inference/errors}/index.js +1 -1
- package/dist/inference/index.d.ts +16 -23
- package/dist/inference/index.js +45 -16
- package/dist/instance-BqV2D5pc.d.ts +5723 -0
- package/dist/logger/index.d.ts +50 -0
- package/dist/logger/index.js +11 -0
- package/dist/mcp/index.d.ts +5 -9
- package/dist/mcp/index.js +2 -3
- package/dist/middleware/index.d.ts +10 -149
- package/dist/middleware/index.js +11 -3
- package/dist/model-messages-B4nK9D1-.d.ts +13 -0
- package/dist/models/index.d.ts +23 -18
- package/dist/models/index.js +48 -11
- package/dist/models/reasoning/index.d.ts +4 -0
- package/dist/{reasoning → models/reasoning}/index.js +3 -3
- package/dist/plugin/index.d.ts +458 -0
- package/dist/plugin/index.js +32 -0
- package/dist/profiles/index.d.ts +55 -0
- package/dist/profiles/index.js +30 -0
- package/dist/prompt/index.d.ts +8 -12
- package/dist/prompt/index.js +3 -2
- package/dist/safety/index.d.ts +109 -14
- package/dist/safety/index.js +59 -3
- package/dist/sandbox/index.d.ts +81 -0
- package/dist/sandbox/index.js +1 -0
- package/dist/skill/index.d.ts +10 -8
- package/dist/skill/index.js +3 -3
- package/dist/storage/index.d.ts +12 -4
- package/dist/storage/index.js +1 -1
- package/dist/subagents/index.d.ts +177 -0
- package/dist/subagents/index.js +78 -0
- package/dist/team/index.d.ts +544 -0
- package/dist/team/index.js +41 -0
- package/dist/tool/host/index.d.ts +41 -0
- package/dist/tool/host/index.js +10 -0
- package/dist/tool/index.d.ts +125 -21
- package/dist/tool/index.js +20 -13
- package/dist/{types-VQgymC1N.d.ts → types-Bj_J8u_W.d.ts} +44 -64
- package/dist/{types-CHiPh8U2.d.ts → types-C_LCeYNg.d.ts} +7 -7
- package/dist/types-RSCv7nQ4.d.ts +59 -0
- package/package.json +58 -53
- package/dist/builder-UpOWQMW3.d.ts +0 -34
- package/dist/chunk-7MUFEN4K.js +0 -559
- package/dist/chunk-7VKQ4WPB.js +0 -73
- package/dist/chunk-BFM2YHNM.js +0 -222
- package/dist/chunk-DWYX7ASF.js +0 -26
- package/dist/chunk-KUVSERLJ.js +0 -50
- package/dist/chunk-N7P4PN3O.js +0 -84
- package/dist/chunk-SDSBEQXG.js +0 -157
- package/dist/chunk-SQU2AJHO.js +0 -305
- package/dist/chunk-VBWWUHWI.js +0 -724
- package/dist/chunk-VEKUXUVF.js +0 -41
- package/dist/chunk-VNQBHPCT.js +0 -398
- package/dist/chunk-WWYYNWEW.js +0 -259
- package/dist/context/index.d.ts +0 -259
- package/dist/context/index.js +0 -26
- package/dist/events-CE72w8W4.d.ts +0 -149
- package/dist/host/index.d.ts +0 -45
- package/dist/host/index.js +0 -8
- package/dist/index-CWSchSql.d.ts +0 -1058
- package/dist/messages-BYWGn8TY.d.ts +0 -110
- package/dist/presets/index.d.ts +0 -53
- package/dist/presets/index.js +0 -28
- package/dist/reasoning/index.d.ts +0 -116
- package/dist/registry-DwYqsQkX.d.ts +0 -164
- package/dist/runner-e2YRcUoX.d.ts +0 -786
- package/dist/scope/index.d.ts +0 -10
- package/dist/scope/index.js +0 -14
- package/dist/session-manager-B_CWGTsl.d.ts +0 -274
- package/dist/signal/index.d.ts +0 -28
- package/dist/signal/index.js +0 -6
- package/dist/sub-agent/index.d.ts +0 -23
- package/dist/sub-agent/index.js +0 -15
- package/dist/tool-BHbyUAy3.d.ts +0 -150
- package/dist/tool-DLXAR9Ce.d.ts +0 -145
- package/dist/tracker-DClqYqTj.d.ts +0 -96
- package/dist/tracking/index.d.ts +0 -111
- package/dist/tracking/index.js +0 -20
- package/dist/types-BfNpU8NS.d.ts +0 -270
- package/dist/types-BnpEOYV-.d.ts +0 -50
- package/dist/types-CQL-SvTn.d.ts +0 -29
- package/dist/types-CWm-7rvB.d.ts +0 -55
- package/dist/types-KKDrdU9Y.d.ts +0 -325
- package/dist/types-QA4WhEfz.d.ts +0 -138
- package/dist/types-QKHHQLLq.d.ts +0 -336
- package/dist/types-YuWV4ag7.d.ts +0 -72
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
// src/models/types.ts
|
|
2
|
+
var SourcePriority = /* @__PURE__ */ ((SourcePriority2) => {
|
|
3
|
+
SourcePriority2[SourcePriority2["UserConfig"] = 0] = "UserConfig";
|
|
4
|
+
SourcePriority2[SourcePriority2["LocalCache"] = 1] = "LocalCache";
|
|
5
|
+
SourcePriority2[SourcePriority2["BundledData"] = 2] = "BundledData";
|
|
6
|
+
SourcePriority2[SourcePriority2["PatternMatch"] = 3] = "PatternMatch";
|
|
7
|
+
SourcePriority2[SourcePriority2["RemoteAPI"] = 4] = "RemoteAPI";
|
|
8
|
+
return SourcePriority2;
|
|
9
|
+
})(SourcePriority || {});
|
|
10
|
+
var DEFAULT_RESOLVER_OPTIONS = {
|
|
11
|
+
enableRemoteFetch: false,
|
|
12
|
+
remoteApiUrl: "https://models.dev",
|
|
13
|
+
cachePath: ".agent-core/cache",
|
|
14
|
+
cacheTtlMs: 60 * 60 * 1e3,
|
|
15
|
+
// 1 hour
|
|
16
|
+
networkTimeoutMs: 10 * 1e3,
|
|
17
|
+
// 10 seconds
|
|
18
|
+
modelOverrides: {}
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
// src/models/profiles.ts
|
|
22
|
+
var REASONING_PATTERNS = [
|
|
23
|
+
// OpenAI o-series
|
|
24
|
+
{
|
|
25
|
+
pattern: /^o[134]-?(mini|pro|preview)?$/i,
|
|
26
|
+
provider: "openai",
|
|
27
|
+
capabilities: { reasoning: true, toolCalling: true },
|
|
28
|
+
compatibility: { supportsReasoningEffort: true, thinkingFormat: "openai" },
|
|
29
|
+
confidence: 0.95
|
|
30
|
+
},
|
|
31
|
+
// OpenAI GPT-5.x
|
|
32
|
+
{
|
|
33
|
+
pattern: /gpt-?5(\.\d)?/i,
|
|
34
|
+
provider: "openai",
|
|
35
|
+
capabilities: { reasoning: true, toolCalling: true },
|
|
36
|
+
compatibility: { supportsReasoningEffort: true, thinkingFormat: "openai" },
|
|
37
|
+
confidence: 0.9
|
|
38
|
+
},
|
|
39
|
+
// DeepSeek R1 variants
|
|
40
|
+
{
|
|
41
|
+
pattern: /deepseek[_-]?r1|r1[_-]distill/i,
|
|
42
|
+
capabilities: { reasoning: true, toolCalling: false },
|
|
43
|
+
confidence: 0.95
|
|
44
|
+
},
|
|
45
|
+
// Anthropic Claude with thinking
|
|
46
|
+
{
|
|
47
|
+
pattern: /claude.*thinking|thinking.*claude/i,
|
|
48
|
+
provider: "anthropic",
|
|
49
|
+
capabilities: { reasoning: true, toolCalling: true },
|
|
50
|
+
compatibility: { thinkingFormat: "anthropic" },
|
|
51
|
+
confidence: 0.9
|
|
52
|
+
},
|
|
53
|
+
// Claude 4.x series (reasoning capable)
|
|
54
|
+
{
|
|
55
|
+
pattern: /claude[_-]?(opus|sonnet)[_-]?4/i,
|
|
56
|
+
provider: "anthropic",
|
|
57
|
+
capabilities: { reasoning: true, toolCalling: true },
|
|
58
|
+
compatibility: { thinkingFormat: "anthropic" },
|
|
59
|
+
confidence: 0.85
|
|
60
|
+
},
|
|
61
|
+
// Gemini thinking models
|
|
62
|
+
{
|
|
63
|
+
pattern: /gemini.*thinking|gemini[_-]?2\.5[_-]?pro/i,
|
|
64
|
+
provider: "google",
|
|
65
|
+
capabilities: { reasoning: true, toolCalling: true },
|
|
66
|
+
compatibility: { thinkingFormat: "google" },
|
|
67
|
+
confidence: 0.85
|
|
68
|
+
},
|
|
69
|
+
// Gemini 3.x (future-proofing)
|
|
70
|
+
{
|
|
71
|
+
pattern: /gemini[_-]?3/i,
|
|
72
|
+
provider: "google",
|
|
73
|
+
capabilities: { reasoning: true, toolCalling: true },
|
|
74
|
+
compatibility: { thinkingFormat: "google" },
|
|
75
|
+
confidence: 0.8
|
|
76
|
+
},
|
|
77
|
+
// Grok reasoning models
|
|
78
|
+
{
|
|
79
|
+
pattern: /grok[_-]?\d[_-]?(mini|reasoning)/i,
|
|
80
|
+
provider: "xai",
|
|
81
|
+
capabilities: { reasoning: true, toolCalling: true },
|
|
82
|
+
confidence: 0.85
|
|
83
|
+
},
|
|
84
|
+
// Qwen thinking models
|
|
85
|
+
{
|
|
86
|
+
pattern: /qwen.*thinking|qwen3/i,
|
|
87
|
+
capabilities: { reasoning: true, toolCalling: true },
|
|
88
|
+
confidence: 0.8
|
|
89
|
+
},
|
|
90
|
+
// Generic reasoning/thinking in name
|
|
91
|
+
{
|
|
92
|
+
pattern: /reasoning|thinking/i,
|
|
93
|
+
capabilities: { reasoning: true },
|
|
94
|
+
confidence: 0.7
|
|
95
|
+
}
|
|
96
|
+
];
|
|
97
|
+
var PROVIDER_PATTERNS = [
|
|
98
|
+
{ pattern: /^(gpt|o[134]|chatgpt|davinci)/i, provider: "openai" },
|
|
99
|
+
{ pattern: /^claude/i, provider: "anthropic" },
|
|
100
|
+
{ pattern: /^gemini|^palm/i, provider: "google" },
|
|
101
|
+
{ pattern: /^grok/i, provider: "xai" },
|
|
102
|
+
{ pattern: /^deepseek/i, provider: "deepseek" },
|
|
103
|
+
{ pattern: /^mistral|^mixtral|codestral/i, provider: "mistral" },
|
|
104
|
+
{ pattern: /^llama/i, provider: "meta" },
|
|
105
|
+
{ pattern: /^qwen/i, provider: "alibaba" },
|
|
106
|
+
{ pattern: /^command/i, provider: "cohere" }
|
|
107
|
+
];
|
|
108
|
+
var CONTEXT_WINDOW_PROFILES = [
|
|
109
|
+
// Anthropic Claude 4.x — 200k
|
|
110
|
+
{ pattern: /claude[_-]?(opus|sonnet)[_-]?4/i, tokens: 2e5 },
|
|
111
|
+
// Anthropic Claude 3.5 — 200k
|
|
112
|
+
{ pattern: /claude[_-]?3[._-]?5/i, tokens: 2e5 },
|
|
113
|
+
// Anthropic Claude 3 Opus/Sonnet/Haiku — 200k
|
|
114
|
+
{ pattern: /claude[_-]?3/i, tokens: 2e5 },
|
|
115
|
+
// Anthropic Claude 2 — 100k
|
|
116
|
+
{ pattern: /claude[_-]?2/i, tokens: 1e5 },
|
|
117
|
+
// OpenAI o-series (o1, o3, o4) — 200k
|
|
118
|
+
{ pattern: /^o[134]-?(mini|pro|preview)?$/i, tokens: 2e5 },
|
|
119
|
+
// OpenAI GPT-5.x — 1M
|
|
120
|
+
{ pattern: /gpt-?5/i, tokens: 1e6 },
|
|
121
|
+
// OpenAI GPT-4o — 128k
|
|
122
|
+
{ pattern: /gpt-?4o/i, tokens: 128e3 },
|
|
123
|
+
// OpenAI GPT-4 turbo — 128k
|
|
124
|
+
{ pattern: /gpt-?4[_-]?turbo/i, tokens: 128e3 },
|
|
125
|
+
// OpenAI GPT-4 — 8k (original)
|
|
126
|
+
{ pattern: /gpt-?4(?!o|[_-]?turbo)/i, tokens: 8192 },
|
|
127
|
+
// OpenAI GPT-3.5 turbo — 16k
|
|
128
|
+
{ pattern: /gpt-?3[._-]?5/i, tokens: 16384 },
|
|
129
|
+
// Google Gemini 2.5 Pro — 1M
|
|
130
|
+
{ pattern: /gemini[_-]?2[._-]?5[_-]?pro/i, tokens: 1e6 },
|
|
131
|
+
// Google Gemini 2.x Flash — 1M
|
|
132
|
+
{ pattern: /gemini[_-]?2.*flash/i, tokens: 1e6 },
|
|
133
|
+
// Google Gemini 2.x Pro — 1M
|
|
134
|
+
{ pattern: /gemini[_-]?2[._-]?\d?[_-]?pro/i, tokens: 1e6 },
|
|
135
|
+
// Google Gemini 1.5 Pro/Flash — 1M
|
|
136
|
+
{ pattern: /gemini[_-]?1[._-]?5/i, tokens: 1e6 },
|
|
137
|
+
// xAI Grok 3+ — 128k
|
|
138
|
+
{ pattern: /grok[_-]?\d/i, tokens: 128e3 },
|
|
139
|
+
// Mistral Large — 128k
|
|
140
|
+
{ pattern: /mistral[_-]?large/i, tokens: 128e3 },
|
|
141
|
+
// Mistral Medium — 32k
|
|
142
|
+
{ pattern: /mistral[_-]?medium/i, tokens: 32768 },
|
|
143
|
+
// Codestral — 256k
|
|
144
|
+
{ pattern: /codestral/i, tokens: 256e3 },
|
|
145
|
+
// Mistral generic — 32k
|
|
146
|
+
{ pattern: /mistral|mixtral/i, tokens: 32768 },
|
|
147
|
+
// DeepSeek R1/V3 — 128k
|
|
148
|
+
{ pattern: /deepseek/i, tokens: 128e3 },
|
|
149
|
+
// Qwen 3 — 128k
|
|
150
|
+
{ pattern: /qwen/i, tokens: 128e3 },
|
|
151
|
+
// Meta Llama 3 — 128k
|
|
152
|
+
{ pattern: /llama[_-]?3/i, tokens: 128e3 },
|
|
153
|
+
// Cohere Command R+ — 128k
|
|
154
|
+
{ pattern: /command[_-]?r/i, tokens: 128e3 }
|
|
155
|
+
];
|
|
156
|
+
function inferContextWindow(modelId) {
|
|
157
|
+
const normalized = modelId.toLowerCase();
|
|
158
|
+
for (const { pattern, tokens } of CONTEXT_WINDOW_PROFILES) {
|
|
159
|
+
if (pattern.test(normalized)) {
|
|
160
|
+
return tokens;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
return void 0;
|
|
164
|
+
}
|
|
165
|
+
function inferProvider(modelId) {
|
|
166
|
+
const normalized = modelId.toLowerCase();
|
|
167
|
+
for (const { pattern, provider } of PROVIDER_PATTERNS) {
|
|
168
|
+
if (pattern.test(normalized)) {
|
|
169
|
+
return provider;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
if (modelId.includes("/")) {
|
|
173
|
+
return modelId.split("/")[0];
|
|
174
|
+
}
|
|
175
|
+
return void 0;
|
|
176
|
+
}
|
|
177
|
+
function matchPatterns(modelId, providerHint) {
|
|
178
|
+
const normalized = modelId.toLowerCase();
|
|
179
|
+
for (const rule of REASONING_PATTERNS) {
|
|
180
|
+
if (rule.provider && providerHint && rule.provider !== providerHint) {
|
|
181
|
+
continue;
|
|
182
|
+
}
|
|
183
|
+
const matches = typeof rule.pattern === "string" ? normalized.includes(rule.pattern.toLowerCase()) : rule.pattern.test(normalized);
|
|
184
|
+
if (matches) {
|
|
185
|
+
return { rule, confidence: rule.confidence };
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
return void 0;
|
|
189
|
+
}
|
|
190
|
+
function createDefaultCapabilities() {
|
|
191
|
+
return {
|
|
192
|
+
reasoning: false,
|
|
193
|
+
toolCalling: true,
|
|
194
|
+
temperature: true,
|
|
195
|
+
attachments: false,
|
|
196
|
+
streaming: true,
|
|
197
|
+
inputModalities: ["text"],
|
|
198
|
+
outputModalities: ["text"]
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
var PatternCapabilitySource = class {
|
|
202
|
+
priority = 3 /* PatternMatch */;
|
|
203
|
+
name = "Pattern Matching";
|
|
204
|
+
async lookup(modelId, providerHint) {
|
|
205
|
+
const provider = providerHint || inferProvider(modelId);
|
|
206
|
+
const match = matchPatterns(modelId, provider);
|
|
207
|
+
const baseCapabilities = createDefaultCapabilities();
|
|
208
|
+
if (match) {
|
|
209
|
+
const entry = {
|
|
210
|
+
id: modelId,
|
|
211
|
+
name: modelId,
|
|
212
|
+
provider: match.rule.provider || provider || "unknown",
|
|
213
|
+
capabilities: {
|
|
214
|
+
...baseCapabilities,
|
|
215
|
+
...match.rule.capabilities,
|
|
216
|
+
contextWindow: inferContextWindow(modelId)
|
|
217
|
+
},
|
|
218
|
+
compatibility: match.rule.compatibility
|
|
219
|
+
};
|
|
220
|
+
return {
|
|
221
|
+
entry,
|
|
222
|
+
source: this.priority,
|
|
223
|
+
confident: match.confidence > 0.8
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
return {
|
|
227
|
+
entry: {
|
|
228
|
+
id: modelId,
|
|
229
|
+
name: modelId,
|
|
230
|
+
provider: provider || "unknown",
|
|
231
|
+
capabilities: {
|
|
232
|
+
...baseCapabilities,
|
|
233
|
+
contextWindow: inferContextWindow(modelId)
|
|
234
|
+
}
|
|
235
|
+
},
|
|
236
|
+
source: this.priority,
|
|
237
|
+
confident: false
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
async isAvailable() {
|
|
241
|
+
return true;
|
|
242
|
+
}
|
|
243
|
+
};
|
|
244
|
+
function likelySupportsReasoning(modelId) {
|
|
245
|
+
const match = matchPatterns(modelId);
|
|
246
|
+
return match !== void 0 && match.rule.capabilities.reasoning === true;
|
|
247
|
+
}
|
|
248
|
+
function getProviderCompatibility(modelId, provider) {
|
|
249
|
+
const match = matchPatterns(modelId, provider);
|
|
250
|
+
return match?.rule.compatibility;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
// src/models/identifiers.ts
|
|
254
|
+
function getModelId(model) {
|
|
255
|
+
if (typeof model === "string") return model;
|
|
256
|
+
if (typeof model === "object" && model !== null && "modelId" in model) {
|
|
257
|
+
return String(model.modelId);
|
|
258
|
+
}
|
|
259
|
+
return String(model);
|
|
260
|
+
}
|
|
261
|
+
function getProviderId(model) {
|
|
262
|
+
if (typeof model === "string") {
|
|
263
|
+
if (model.includes("/")) {
|
|
264
|
+
return model.split("/")[0];
|
|
265
|
+
}
|
|
266
|
+
return void 0;
|
|
267
|
+
}
|
|
268
|
+
if (typeof model === "object" && model !== null && "provider" in model) {
|
|
269
|
+
const provider = String(model.provider);
|
|
270
|
+
return provider.split(".")[0];
|
|
271
|
+
}
|
|
272
|
+
return void 0;
|
|
273
|
+
}
|
|
274
|
+
var extractModelId = getModelId;
|
|
275
|
+
function extractProvider(model) {
|
|
276
|
+
const provider = getProviderId(model);
|
|
277
|
+
return provider ?? inferProvider(getModelId(model));
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
export {
|
|
281
|
+
SourcePriority,
|
|
282
|
+
DEFAULT_RESOLVER_OPTIONS,
|
|
283
|
+
inferContextWindow,
|
|
284
|
+
inferProvider,
|
|
285
|
+
PatternCapabilitySource,
|
|
286
|
+
likelySupportsReasoning,
|
|
287
|
+
getProviderCompatibility,
|
|
288
|
+
getModelId,
|
|
289
|
+
getProviderId,
|
|
290
|
+
extractModelId,
|
|
291
|
+
extractProvider
|
|
292
|
+
};
|
|
@@ -9,7 +9,7 @@ function generateEntryId(existingIds) {
|
|
|
9
9
|
}
|
|
10
10
|
return crypto.randomUUID();
|
|
11
11
|
}
|
|
12
|
-
function parseJSONL(content) {
|
|
12
|
+
function parseJSONL(content, logger) {
|
|
13
13
|
const entries = [];
|
|
14
14
|
const lines = content.split("\n");
|
|
15
15
|
for (const line of lines) {
|
|
@@ -18,7 +18,7 @@ function parseJSONL(content) {
|
|
|
18
18
|
try {
|
|
19
19
|
entries.push(JSON.parse(trimmed));
|
|
20
20
|
} catch {
|
|
21
|
-
|
|
21
|
+
logger?.warn("Skipping malformed JSONL line");
|
|
22
22
|
}
|
|
23
23
|
}
|
|
24
24
|
return entries;
|
|
@@ -160,7 +160,6 @@ function getLeafId(entries) {
|
|
|
160
160
|
children.push(e.id);
|
|
161
161
|
childMap.set(e.parentId, children);
|
|
162
162
|
}
|
|
163
|
-
const _allIds = new Set(entries.slice(1).map((e) => e.id));
|
|
164
163
|
const hasChildren = /* @__PURE__ */ new Set();
|
|
165
164
|
for (const children of childMap.values()) {
|
|
166
165
|
for (const child of children) {
|
|
@@ -204,7 +203,8 @@ function buildMessagesFromEntries(entries, leafId) {
|
|
|
204
203
|
let skipUntilId;
|
|
205
204
|
for (const entry of path) {
|
|
206
205
|
if (entry.type === "compaction") {
|
|
207
|
-
|
|
206
|
+
messages.length = 0;
|
|
207
|
+
skipUntilId = entry.firstKeptEntryId !== entry.id ? entry.firstKeptEntryId : void 0;
|
|
208
208
|
messages.push({
|
|
209
209
|
id: entry.id,
|
|
210
210
|
role: "system",
|
|
@@ -291,6 +291,16 @@ async function ensureStorageDirectory(directory) {
|
|
|
291
291
|
}
|
|
292
292
|
function getSessionFilePath(directory, extension, sessionId) {
|
|
293
293
|
const safeId = sessionId.replace(/[^a-zA-Z0-9-_]/g, "_");
|
|
294
|
+
const needsHash = safeId !== sessionId;
|
|
295
|
+
if (needsHash) {
|
|
296
|
+
let hash = 2166136261;
|
|
297
|
+
for (let i = 0; i < sessionId.length; i++) {
|
|
298
|
+
hash ^= sessionId.charCodeAt(i);
|
|
299
|
+
hash = hash * 16777619 >>> 0;
|
|
300
|
+
}
|
|
301
|
+
const suffix = hash.toString(16).padStart(8, "0");
|
|
302
|
+
return join(directory, `${safeId}_${suffix}${extension}`);
|
|
303
|
+
}
|
|
294
304
|
return join(directory, `${safeId}${extension}`);
|
|
295
305
|
}
|
|
296
306
|
async function loadEntriesFromDisk(filePath, sessionId) {
|
|
@@ -615,6 +625,40 @@ var SessionManager = class {
|
|
|
615
625
|
this.currentLeafId = entry.id;
|
|
616
626
|
return entry.id;
|
|
617
627
|
}
|
|
628
|
+
async replaceWithCompaction(options) {
|
|
629
|
+
if (!this.currentSessionId) {
|
|
630
|
+
throw new Error("No session loaded");
|
|
631
|
+
}
|
|
632
|
+
const compactionId = generateEntryId(this.idsCache);
|
|
633
|
+
this.idsCache.add(compactionId);
|
|
634
|
+
let parentId = compactionId;
|
|
635
|
+
const messageEntries = [];
|
|
636
|
+
for (const message of options.messages) {
|
|
637
|
+
const entry = createMessageEntry(message, parentId, this.idsCache);
|
|
638
|
+
messageEntries.push(entry);
|
|
639
|
+
this.idsCache.add(entry.id);
|
|
640
|
+
parentId = entry.id;
|
|
641
|
+
}
|
|
642
|
+
const compactionEntry = {
|
|
643
|
+
type: "compaction",
|
|
644
|
+
id: compactionId,
|
|
645
|
+
parentId: this.currentLeafId,
|
|
646
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
647
|
+
summary: options.summary,
|
|
648
|
+
firstKeptEntryId: messageEntries[0]?.id ?? compactionId,
|
|
649
|
+
tokensBefore: options.tokensBefore,
|
|
650
|
+
tokensAfter: options.tokensAfter,
|
|
651
|
+
...options.readFiles ? { readFiles: options.readFiles } : {},
|
|
652
|
+
...options.modifiedFiles ? { modifiedFiles: options.modifiedFiles } : {}
|
|
653
|
+
};
|
|
654
|
+
await this.storage.appendBatch(this.currentSessionId, [
|
|
655
|
+
compactionEntry,
|
|
656
|
+
...messageEntries
|
|
657
|
+
]);
|
|
658
|
+
this.entriesCache.push(compactionEntry, ...messageEntries);
|
|
659
|
+
this.currentLeafId = messageEntries[messageEntries.length - 1]?.id ?? compactionEntry.id;
|
|
660
|
+
return compactionEntry.id;
|
|
661
|
+
}
|
|
618
662
|
async branch(fromEntryId, summary) {
|
|
619
663
|
if (!this.currentSessionId) {
|
|
620
664
|
throw new Error("No session loaded");
|
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Tool
|
|
3
|
+
} from "./chunk-Q742PSH3.js";
|
|
4
|
+
|
|
5
|
+
// src/tool/registry.ts
|
|
6
|
+
function escapeRegExp(s) {
|
|
7
|
+
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
8
|
+
}
|
|
9
|
+
var ToolRegistry = class {
|
|
10
|
+
tools = /* @__PURE__ */ new Map();
|
|
11
|
+
groups = /* @__PURE__ */ new Map();
|
|
12
|
+
// --------------------------------------------------------------------------
|
|
13
|
+
// Tool registration
|
|
14
|
+
// --------------------------------------------------------------------------
|
|
15
|
+
/**
|
|
16
|
+
* Register a tool. Throws if a tool with the same ID is already registered.
|
|
17
|
+
* Use `set()` for upsert semantics.
|
|
18
|
+
*/
|
|
19
|
+
register(tool) {
|
|
20
|
+
if (this.tools.has(tool.id)) {
|
|
21
|
+
throw new Error(`Tool '${tool.id}' is already registered`);
|
|
22
|
+
}
|
|
23
|
+
this.tools.set(tool.id, tool);
|
|
24
|
+
}
|
|
25
|
+
/** Register multiple tools (throws on duplicates). */
|
|
26
|
+
registerAll(tools) {
|
|
27
|
+
for (const tool of tools) {
|
|
28
|
+
this.register(tool);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
/** Register or replace a tool (upsert). */
|
|
32
|
+
set(tool) {
|
|
33
|
+
this.tools.set(tool.id, tool);
|
|
34
|
+
}
|
|
35
|
+
/** Unregister a tool by ID. Returns `true` if it existed. */
|
|
36
|
+
unregister(id) {
|
|
37
|
+
return this.tools.delete(id);
|
|
38
|
+
}
|
|
39
|
+
/** Get a tool by ID. */
|
|
40
|
+
get(id) {
|
|
41
|
+
return this.tools.get(id);
|
|
42
|
+
}
|
|
43
|
+
/** Check if a tool is registered. */
|
|
44
|
+
has(id) {
|
|
45
|
+
return this.tools.has(id);
|
|
46
|
+
}
|
|
47
|
+
/** Get all tool IDs. */
|
|
48
|
+
ids() {
|
|
49
|
+
return Array.from(this.tools.keys());
|
|
50
|
+
}
|
|
51
|
+
/** Get all tools. */
|
|
52
|
+
all() {
|
|
53
|
+
return Array.from(this.tools.values());
|
|
54
|
+
}
|
|
55
|
+
/** Clear all tools and groups. */
|
|
56
|
+
clear() {
|
|
57
|
+
this.tools.clear();
|
|
58
|
+
this.groups.clear();
|
|
59
|
+
}
|
|
60
|
+
/** Number of registered tools. */
|
|
61
|
+
get size() {
|
|
62
|
+
return this.tools.size;
|
|
63
|
+
}
|
|
64
|
+
// --------------------------------------------------------------------------
|
|
65
|
+
// Group management
|
|
66
|
+
// --------------------------------------------------------------------------
|
|
67
|
+
/**
|
|
68
|
+
* Register a named group of tool IDs.
|
|
69
|
+
* The group name can be used in `resolve()` specs.
|
|
70
|
+
* Tool IDs don't need to be registered yet — resolution is lazy.
|
|
71
|
+
*/
|
|
72
|
+
registerGroup(name, toolIds) {
|
|
73
|
+
this.groups.set(name, toolIds);
|
|
74
|
+
}
|
|
75
|
+
/** Get tools in a group (only returns registered tools). */
|
|
76
|
+
getGroup(name) {
|
|
77
|
+
const ids = this.groups.get(name);
|
|
78
|
+
if (!ids) return void 0;
|
|
79
|
+
return ids.map((id) => this.tools.get(id)).filter((t) => t !== void 0);
|
|
80
|
+
}
|
|
81
|
+
/** Check if a group is registered. */
|
|
82
|
+
hasGroup(name) {
|
|
83
|
+
return this.groups.has(name);
|
|
84
|
+
}
|
|
85
|
+
/** List all group names. */
|
|
86
|
+
listGroups() {
|
|
87
|
+
return Array.from(this.groups.keys());
|
|
88
|
+
}
|
|
89
|
+
// --------------------------------------------------------------------------
|
|
90
|
+
// Deferred loading
|
|
91
|
+
// --------------------------------------------------------------------------
|
|
92
|
+
/**
|
|
93
|
+
* Partition registered tools into eager and deferred sets.
|
|
94
|
+
*
|
|
95
|
+
* Eager tools have their full schemas sent to the LLM on turn 1.
|
|
96
|
+
* Deferred tools are held back — the model discovers them via a
|
|
97
|
+
* search mechanism when needed, saving context window space.
|
|
98
|
+
*
|
|
99
|
+
* @returns `{ eager, deferred }` arrays of tool infos.
|
|
100
|
+
*/
|
|
101
|
+
partition() {
|
|
102
|
+
const eager = [];
|
|
103
|
+
const deferred = [];
|
|
104
|
+
for (const tool of this.tools.values()) {
|
|
105
|
+
if (tool.deferred) {
|
|
106
|
+
deferred.push(tool);
|
|
107
|
+
} else {
|
|
108
|
+
eager.push(tool);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
return { eager, deferred };
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Search deferred tools by keyword with multi-signal weighted scoring.
|
|
115
|
+
*
|
|
116
|
+
* Scoring per term:
|
|
117
|
+
* - Exact tool ID match: +10
|
|
118
|
+
* - Partial tool ID match (substring): +5
|
|
119
|
+
* - Keyword word-boundary match: +4
|
|
120
|
+
* - Keyword substring match: +2
|
|
121
|
+
*
|
|
122
|
+
* @param query - Space-separated search terms
|
|
123
|
+
* @param maxResults - Maximum results to return (default: 5)
|
|
124
|
+
* @returns Matching deferred tools sorted by relevance (highest score first)
|
|
125
|
+
*/
|
|
126
|
+
searchDeferred(query, maxResults = 5) {
|
|
127
|
+
const terms = query.toLowerCase().split(/\s+/).filter(Boolean);
|
|
128
|
+
if (terms.length === 0) return [];
|
|
129
|
+
const { deferred } = this.partition();
|
|
130
|
+
const scored = deferred.map((tool) => {
|
|
131
|
+
let score = 0;
|
|
132
|
+
const id = tool.id.toLowerCase();
|
|
133
|
+
const keywords = (tool.searchKeywords ?? []).join(" ").toLowerCase();
|
|
134
|
+
for (const term of terms) {
|
|
135
|
+
if (id === term) {
|
|
136
|
+
score += 10;
|
|
137
|
+
continue;
|
|
138
|
+
}
|
|
139
|
+
if (id.includes(term)) {
|
|
140
|
+
score += 5;
|
|
141
|
+
continue;
|
|
142
|
+
}
|
|
143
|
+
const wordBoundary = new RegExp(`\\b${escapeRegExp(term)}\\b`);
|
|
144
|
+
if (wordBoundary.test(keywords)) {
|
|
145
|
+
score += 4;
|
|
146
|
+
continue;
|
|
147
|
+
}
|
|
148
|
+
if (keywords.includes(term)) {
|
|
149
|
+
score += 2;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
return { tool, score };
|
|
153
|
+
}).filter(({ score }) => score > 0).sort((a, b) => b.score - a.score);
|
|
154
|
+
return scored.slice(0, maxResults).map(({ tool }) => tool);
|
|
155
|
+
}
|
|
156
|
+
// --------------------------------------------------------------------------
|
|
157
|
+
// Resolution
|
|
158
|
+
// --------------------------------------------------------------------------
|
|
159
|
+
/**
|
|
160
|
+
* Resolve a `ToolSpec` to an array of tools.
|
|
161
|
+
*
|
|
162
|
+
* Supports group names, individual tool IDs, comma-separated strings,
|
|
163
|
+
* exclusions with `-` prefix, booleans, and pass-through arrays.
|
|
164
|
+
*
|
|
165
|
+
* @example
|
|
166
|
+
* ```typescript
|
|
167
|
+
* registry.resolve("read-only"); // group name
|
|
168
|
+
* registry.resolve("read,grep,glob"); // comma-separated IDs
|
|
169
|
+
* registry.resolve("all,-bash"); // all except bash
|
|
170
|
+
* registry.resolve(["read", "grep"]); // array of IDs
|
|
171
|
+
* registry.resolve(true); // all registered tools
|
|
172
|
+
* registry.resolve(false); // empty array
|
|
173
|
+
* ```
|
|
174
|
+
*/
|
|
175
|
+
resolve(spec) {
|
|
176
|
+
if (spec === true) return this.all();
|
|
177
|
+
if (spec === false) return [];
|
|
178
|
+
if (Array.isArray(spec) && spec.length > 0 && typeof spec[0] !== "string") {
|
|
179
|
+
return spec;
|
|
180
|
+
}
|
|
181
|
+
const tokens = Array.isArray(spec) ? spec : spec.split(",").map((s) => s.trim()).filter(Boolean);
|
|
182
|
+
const includes = [];
|
|
183
|
+
const excludes = [];
|
|
184
|
+
for (const token of tokens) {
|
|
185
|
+
if (token.startsWith("-")) {
|
|
186
|
+
excludes.push(token.slice(1));
|
|
187
|
+
} else {
|
|
188
|
+
includes.push(token);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
const result = /* @__PURE__ */ new Map();
|
|
192
|
+
if (includes.length === 0 && excludes.length > 0) {
|
|
193
|
+
for (const [id, tool] of this.tools) {
|
|
194
|
+
result.set(id, tool);
|
|
195
|
+
}
|
|
196
|
+
} else {
|
|
197
|
+
for (const token of includes) {
|
|
198
|
+
if (token === "all") {
|
|
199
|
+
for (const [id, tool] of this.tools) {
|
|
200
|
+
result.set(id, tool);
|
|
201
|
+
}
|
|
202
|
+
} else if (this.groups.has(token)) {
|
|
203
|
+
const ids = this.groups.get(token);
|
|
204
|
+
for (const id of ids) {
|
|
205
|
+
const tool = this.tools.get(id);
|
|
206
|
+
if (tool) result.set(id, tool);
|
|
207
|
+
}
|
|
208
|
+
} else if (this.tools.has(token)) {
|
|
209
|
+
result.set(token, this.tools.get(token));
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
for (const id of excludes) {
|
|
214
|
+
if (this.groups.has(id)) {
|
|
215
|
+
const ids = this.groups.get(id);
|
|
216
|
+
for (const gid of ids) {
|
|
217
|
+
result.delete(gid);
|
|
218
|
+
}
|
|
219
|
+
} else {
|
|
220
|
+
result.delete(id);
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
return Array.from(result.values());
|
|
224
|
+
}
|
|
225
|
+
};
|
|
226
|
+
var defaultRegistry = new ToolRegistry();
|
|
227
|
+
|
|
228
|
+
// src/tool/tool-search.ts
|
|
229
|
+
import { z } from "zod";
|
|
230
|
+
function createToolSearchTool(options) {
|
|
231
|
+
const { registry, maxResults = 5, onMatch } = options;
|
|
232
|
+
return Tool.define("tool_search", {
|
|
233
|
+
description: "Search for additional tools by keyword. Some tools are not loaded by default to save context. Call this when you need a capability that isn't available in your current tool set. Returns matching tool names and descriptions.",
|
|
234
|
+
parameters: z.object({
|
|
235
|
+
query: z.string().describe(
|
|
236
|
+
"Space-separated keywords describing the tool you need (e.g. 'jupyter notebook cells' or 'docker container'). Use 'select:tool_name' to load a specific tool by name, or 'select:foo,bar' for multiple."
|
|
237
|
+
)
|
|
238
|
+
}),
|
|
239
|
+
capabilities: {
|
|
240
|
+
parallelSafe: true,
|
|
241
|
+
readOnly: true,
|
|
242
|
+
riskLevel: "safe"
|
|
243
|
+
},
|
|
244
|
+
execute: async ({ query }, ctx) => {
|
|
245
|
+
if (query.startsWith("select:")) {
|
|
246
|
+
const ids = query.slice(7).split(",").map((s) => s.trim()).filter(Boolean);
|
|
247
|
+
const found = [];
|
|
248
|
+
const missing = [];
|
|
249
|
+
for (const id of ids) {
|
|
250
|
+
const tool = registry.get(id);
|
|
251
|
+
if (tool) {
|
|
252
|
+
found.push(tool);
|
|
253
|
+
} else {
|
|
254
|
+
missing.push(id);
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
if (found.length > 0) onMatch(found);
|
|
258
|
+
const summaries2 = [];
|
|
259
|
+
for (const t of found) {
|
|
260
|
+
try {
|
|
261
|
+
const init = await t.init({ cwd: ctx.cwd });
|
|
262
|
+
summaries2.push(`- **${t.id}**: ${init.description}`);
|
|
263
|
+
} catch {
|
|
264
|
+
summaries2.push(`- **${t.id}**: (description unavailable)`);
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
if (missing.length > 0) {
|
|
268
|
+
summaries2.push(`
|
|
269
|
+
Not found: ${missing.join(", ")}`);
|
|
270
|
+
}
|
|
271
|
+
return {
|
|
272
|
+
title: `Loaded ${found.length} tool(s)`,
|
|
273
|
+
output: found.length > 0 ? summaries2.join("\n") + "\n\nThese tools are now available for use." : `No tools found: ${missing.join(", ")}`,
|
|
274
|
+
metadata: {
|
|
275
|
+
matchCount: found.length,
|
|
276
|
+
toolIds: found.map((t) => t.id)
|
|
277
|
+
}
|
|
278
|
+
};
|
|
279
|
+
}
|
|
280
|
+
const matches = registry.searchDeferred(query, maxResults);
|
|
281
|
+
if (matches.length === 0) {
|
|
282
|
+
return {
|
|
283
|
+
title: `No tools found for "${query}"`,
|
|
284
|
+
output: `No matching tools found for query: "${query}". Try different keywords.`,
|
|
285
|
+
metadata: { matchCount: 0, toolIds: [] }
|
|
286
|
+
};
|
|
287
|
+
}
|
|
288
|
+
const summaries = [];
|
|
289
|
+
for (const tool of matches) {
|
|
290
|
+
try {
|
|
291
|
+
const init = await tool.init({ cwd: ctx.cwd });
|
|
292
|
+
summaries.push(`- **${tool.id}**: ${init.description}`);
|
|
293
|
+
} catch {
|
|
294
|
+
summaries.push(`- **${tool.id}**: (description unavailable)`);
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
onMatch(matches);
|
|
298
|
+
return {
|
|
299
|
+
title: `Found ${matches.length} tool(s)`,
|
|
300
|
+
output: `Found ${matches.length} tool(s) matching "${query}":
|
|
301
|
+
|
|
302
|
+
` + summaries.join("\n") + "\n\nThese tools are now available for use.",
|
|
303
|
+
metadata: {
|
|
304
|
+
matchCount: matches.length,
|
|
305
|
+
toolIds: matches.map((t) => t.id)
|
|
306
|
+
}
|
|
307
|
+
};
|
|
308
|
+
}
|
|
309
|
+
});
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
export {
|
|
313
|
+
ToolRegistry,
|
|
314
|
+
defaultRegistry,
|
|
315
|
+
createToolSearchTool
|
|
316
|
+
};
|