@nuvin/nuvin-core 1.1.1 → 1.2.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/dist/VERSION +2 -2
- package/dist/index.d.ts +48 -12
- package/dist/index.js +141 -47
- package/package.json +1 -1
package/dist/VERSION
CHANGED
package/dist/index.d.ts
CHANGED
|
@@ -19,6 +19,11 @@ type AgentTemplate = {
|
|
|
19
19
|
shareContext?: boolean;
|
|
20
20
|
metadata?: Record<string, unknown>;
|
|
21
21
|
};
|
|
22
|
+
/**
|
|
23
|
+
* CompleteAgent is an AgentTemplate with all required fields populated
|
|
24
|
+
* Used for registered agents that have gone through applyDefaults()
|
|
25
|
+
*/
|
|
26
|
+
type CompleteAgent = Required<Pick<AgentTemplate, 'id' | 'name' | 'description' | 'systemPrompt' | 'tools' | 'temperature' | 'maxTokens'>> & Pick<AgentTemplate, 'provider' | 'model' | 'topP' | 'timeoutMs' | 'shareContext' | 'metadata'>;
|
|
22
27
|
/**
|
|
23
28
|
* Specialist Agent Configuration (Internal - used by AgentManager)
|
|
24
29
|
*/
|
|
@@ -135,7 +140,7 @@ declare class AgentRegistry {
|
|
|
135
140
|
*/
|
|
136
141
|
applyDefaults(partial: Partial<AgentTemplate> & {
|
|
137
142
|
systemPrompt: string;
|
|
138
|
-
}):
|
|
143
|
+
}): CompleteAgent;
|
|
139
144
|
/**
|
|
140
145
|
* Load agents from memory persistence
|
|
141
146
|
*/
|
|
@@ -161,7 +166,7 @@ declare class AgentRegistry {
|
|
|
161
166
|
/**
|
|
162
167
|
* Save agent to file
|
|
163
168
|
*/
|
|
164
|
-
saveToFile(agent:
|
|
169
|
+
saveToFile(agent: CompleteAgent): Promise<void>;
|
|
165
170
|
/**
|
|
166
171
|
* Delete agent from file
|
|
167
172
|
*/
|
|
@@ -177,11 +182,11 @@ declare class AgentRegistry {
|
|
|
177
182
|
/**
|
|
178
183
|
* Get an agent template by ID
|
|
179
184
|
*/
|
|
180
|
-
get(agentId: string):
|
|
185
|
+
get(agentId: string): CompleteAgent | undefined;
|
|
181
186
|
/**
|
|
182
187
|
* List all registered agent templates
|
|
183
188
|
*/
|
|
184
|
-
list():
|
|
189
|
+
list(): CompleteAgent[];
|
|
185
190
|
/**
|
|
186
191
|
* Check if an agent exists
|
|
187
192
|
*/
|
|
@@ -232,6 +237,7 @@ type ChatMessage = {
|
|
|
232
237
|
tool_calls?: ToolCall[];
|
|
233
238
|
tool_call_id?: string;
|
|
234
239
|
name?: string;
|
|
240
|
+
[key: string]: unknown;
|
|
235
241
|
};
|
|
236
242
|
type CompletionParams = {
|
|
237
243
|
messages: ChatMessage[];
|
|
@@ -259,6 +265,7 @@ type CompletionParams = {
|
|
|
259
265
|
usage?: {
|
|
260
266
|
include?: boolean;
|
|
261
267
|
};
|
|
268
|
+
[key: string]: unknown;
|
|
262
269
|
};
|
|
263
270
|
type UsageData = {
|
|
264
271
|
prompt_tokens?: number;
|
|
@@ -281,6 +288,7 @@ type CompletionResult = {
|
|
|
281
288
|
content: string;
|
|
282
289
|
tool_calls?: ToolCall[];
|
|
283
290
|
usage?: UsageData;
|
|
291
|
+
[key: string]: unknown;
|
|
284
292
|
};
|
|
285
293
|
type Message = {
|
|
286
294
|
id: string;
|
|
@@ -291,6 +299,7 @@ type Message = {
|
|
|
291
299
|
tool_call_id?: string;
|
|
292
300
|
name?: string;
|
|
293
301
|
usage?: UsageData;
|
|
302
|
+
[key: string]: unknown;
|
|
294
303
|
};
|
|
295
304
|
type MessageResponse = {
|
|
296
305
|
id: string;
|
|
@@ -330,6 +339,10 @@ interface LLMPort {
|
|
|
330
339
|
onToolCallDelta?: (tc: ToolCall) => void;
|
|
331
340
|
onStreamFinish?: (finishReason?: string, usage?: UsageData) => void;
|
|
332
341
|
}, signal?: AbortSignal): Promise<CompletionResult>;
|
|
342
|
+
getModels?(signal?: AbortSignal): Promise<Array<{
|
|
343
|
+
id: string;
|
|
344
|
+
[key: string]: unknown;
|
|
345
|
+
}>>;
|
|
333
346
|
}
|
|
334
347
|
type LLMConfig = {
|
|
335
348
|
provider?: string;
|
|
@@ -922,7 +935,7 @@ declare class DefaultSpecialistAgentFactory implements SpecialistAgentFactory {
|
|
|
922
935
|
systemContextProvider?: SystemContextProvider;
|
|
923
936
|
agentListProvider?: AgentListProvider;
|
|
924
937
|
idGenerator?: IdGenerator;
|
|
925
|
-
});
|
|
938
|
+
} | undefined);
|
|
926
939
|
create(input: SpecialistAgentFactoryInput): SpecialistAgentConfig;
|
|
927
940
|
}
|
|
928
941
|
|
|
@@ -938,7 +951,7 @@ declare class AgentManager {
|
|
|
938
951
|
private llmResolver;
|
|
939
952
|
private activeAgents;
|
|
940
953
|
private eventCollectors;
|
|
941
|
-
constructor(delegatingConfig: AgentConfig, delegatingTools: ToolPort, llmFactory?: LLMFactory, eventCallback?: (event: AgentEvent) => void, configResolver?: () => Partial<AgentConfig>);
|
|
954
|
+
constructor(delegatingConfig: AgentConfig, delegatingTools: ToolPort, llmFactory?: LLMFactory | undefined, eventCallback?: ((event: AgentEvent) => void) | undefined, configResolver?: (() => Partial<AgentConfig>) | undefined);
|
|
942
955
|
/**
|
|
943
956
|
* Create and execute a specialist agent for a specific task
|
|
944
957
|
*/
|
|
@@ -970,7 +983,7 @@ declare class AgentManagerCommandRunner implements AgentCommandRunner {
|
|
|
970
983
|
private readonly delegatingTools;
|
|
971
984
|
private readonly llmFactory?;
|
|
972
985
|
private readonly configResolver?;
|
|
973
|
-
constructor(delegatingConfig: AgentConfig, delegatingTools: ToolPort, llmFactory?: LLMFactory, configResolver?: () => Partial<AgentConfig>);
|
|
986
|
+
constructor(delegatingConfig: AgentConfig, delegatingTools: ToolPort, llmFactory?: LLMFactory | undefined, configResolver?: (() => Partial<AgentConfig>) | undefined);
|
|
974
987
|
run(config: Parameters<AgentManager['executeTask']>[0], context?: ToolExecutionContext): Promise<SpecialistAgentResult>;
|
|
975
988
|
}
|
|
976
989
|
|
|
@@ -995,7 +1008,7 @@ declare class DefaultDelegationResultFormatter implements DelegationResultFormat
|
|
|
995
1008
|
status: "success" | "error" | "timeout";
|
|
996
1009
|
executionTimeMs: number;
|
|
997
1010
|
toolCallsExecuted: number;
|
|
998
|
-
tokensUsed: number;
|
|
1011
|
+
tokensUsed: number | undefined;
|
|
999
1012
|
};
|
|
1000
1013
|
};
|
|
1001
1014
|
formatError(error: unknown): string;
|
|
@@ -1157,9 +1170,9 @@ declare class GithubAuthTransport implements HttpTransport {
|
|
|
1157
1170
|
}
|
|
1158
1171
|
|
|
1159
1172
|
declare class LLMError extends Error {
|
|
1160
|
-
readonly statusCode?: number;
|
|
1173
|
+
readonly statusCode?: number | undefined;
|
|
1161
1174
|
readonly isRetryable: boolean;
|
|
1162
|
-
constructor(message: string, statusCode?: number, isRetryable?: boolean, cause?: unknown);
|
|
1175
|
+
constructor(message: string, statusCode?: number | undefined, isRetryable?: boolean, cause?: unknown);
|
|
1163
1176
|
}
|
|
1164
1177
|
declare abstract class BaseLLM implements LLMPort {
|
|
1165
1178
|
protected transport: HttpTransport | null;
|
|
@@ -1169,7 +1182,7 @@ declare abstract class BaseLLM implements LLMPort {
|
|
|
1169
1182
|
enablePromptCaching?: boolean;
|
|
1170
1183
|
});
|
|
1171
1184
|
protected abstract createTransport(): HttpTransport;
|
|
1172
|
-
|
|
1185
|
+
protected getTransport(): HttpTransport;
|
|
1173
1186
|
protected applyCacheControl(params: CompletionParams): CompletionParams;
|
|
1174
1187
|
generateCompletion(params: CompletionParams, signal?: AbortSignal): Promise<CompletionResult>;
|
|
1175
1188
|
streamCompletion(params: CompletionParams, handlers?: {
|
|
@@ -1185,10 +1198,32 @@ type GithubOptions = {
|
|
|
1185
1198
|
apiUrl?: string;
|
|
1186
1199
|
httpLogFile?: string;
|
|
1187
1200
|
};
|
|
1201
|
+
type GithubModel = {
|
|
1202
|
+
id: string;
|
|
1203
|
+
name: string;
|
|
1204
|
+
capable_endpoints?: string[];
|
|
1205
|
+
supported_endpoints?: string[];
|
|
1206
|
+
capabilities: {
|
|
1207
|
+
family: string;
|
|
1208
|
+
type: string;
|
|
1209
|
+
limits?: {
|
|
1210
|
+
max_context_window_tokens?: number;
|
|
1211
|
+
max_output_tokens?: number;
|
|
1212
|
+
};
|
|
1213
|
+
};
|
|
1214
|
+
};
|
|
1188
1215
|
declare class GithubLLM extends BaseLLM implements LLMPort {
|
|
1189
1216
|
private readonly opts;
|
|
1190
1217
|
constructor(opts?: GithubOptions);
|
|
1191
1218
|
protected createTransport(): GithubAuthTransport;
|
|
1219
|
+
getModels(signal?: AbortSignal): Promise<GithubModel[]>;
|
|
1220
|
+
private handleError;
|
|
1221
|
+
generateCompletion(params: CompletionParams, signal?: AbortSignal): Promise<CompletionResult>;
|
|
1222
|
+
streamCompletion(params: CompletionParams, handlers?: {
|
|
1223
|
+
onChunk?: (delta: string, usage?: UsageData) => void;
|
|
1224
|
+
onToolCallDelta?: (tc: ToolCall) => void;
|
|
1225
|
+
onStreamFinish?: (finishReason?: string, usage?: UsageData) => void;
|
|
1226
|
+
}, signal?: AbortSignal): Promise<CompletionResult>;
|
|
1192
1227
|
}
|
|
1193
1228
|
|
|
1194
1229
|
type AnthropicAISDKOptions = {
|
|
@@ -1328,6 +1363,7 @@ declare function loadMCPConfig(filePath?: string): Promise<MCPConfig | null>;
|
|
|
1328
1363
|
declare class PersistingConsoleEventPort implements EventPort {
|
|
1329
1364
|
private memory;
|
|
1330
1365
|
private maxPerConversation;
|
|
1366
|
+
private writeQueue;
|
|
1331
1367
|
constructor(opts?: {
|
|
1332
1368
|
memory?: MemoryPort<AgentEvent>;
|
|
1333
1369
|
filename?: string;
|
|
@@ -1342,4 +1378,4 @@ declare function resolveBackspaces(s: string): string;
|
|
|
1342
1378
|
declare function stripAnsiAndControls(s: string): string;
|
|
1343
1379
|
declare function canonicalizeTerminalPaste(raw: string): string;
|
|
1344
1380
|
|
|
1345
|
-
export { AGENT_CREATOR_SYSTEM_PROMPT, type AgentAwareToolPort, type AgentCatalog, type AgentConfig, type AgentEvent, AgentEventTypes, AgentFilePersistence, AgentManager, AgentManagerCommandRunner, AgentOrchestrator, AgentRegistry, type AgentTemplate, AnthropicAISDKLLM, type AssignParams, BashTool, CompositeToolPort, type Conversation, ConversationContext, type ConversationMetadata, type ConversationSnapshot, ConversationStore, CoreMCPClient, DefaultDelegationPolicy, DefaultDelegationResultFormatter, DefaultDelegationService, DefaultSpecialistAgentFactory, type DelegationService, type DelegationServiceConfig, DelegationServiceFactory, ErrorReason, type FolderTreeOptions, GithubLLM, InMemoryMemory, InMemoryMetadata, JsonFileMemoryPersistence, type LLMConfig, LLMError, type LLMFactory, type LLMOptions, type LLMPort, LLMResolver, type MCPConfig, type MCPServerConfig, MCPToolPort, type MemoryPort, MemoryPortMetadataAdapter, type Message, type MessageContent, type MessageContentPart, type MetadataPort, NoopReminders, type OrchestratorAwareToolPort, PersistedMemory, PersistingConsoleEventPort, RuntimeEnv, type SendMessageOptions, SimpleContextBuilder, SimpleCost, SimpleId, type SpecialistAgentConfig, type SpecialistAgentResult, SystemClock, type ToolApprovalDecision, type ToolCall, type ToolExecutionResult, type ToolPort, ToolRegistry, type UserAttachment, type UserMessagePayload, buildAgentCreationPrompt, buildInjectedSystem, canonicalizeTerminalPaste, createLLM, generateFolderTree, getAvailableProviders, loadMCPConfig, normalizeNewlines, renderTemplate, resolveBackspaces, resolveCarriageReturns, stripAnsiAndControls, supportsGetModels };
|
|
1381
|
+
export { AGENT_CREATOR_SYSTEM_PROMPT, type AgentAwareToolPort, type AgentCatalog, type AgentConfig, type AgentEvent, AgentEventTypes, AgentFilePersistence, AgentManager, AgentManagerCommandRunner, AgentOrchestrator, AgentRegistry, type AgentTemplate, AnthropicAISDKLLM, type AssignParams, BashTool, type CompleteAgent, CompositeToolPort, type Conversation, ConversationContext, type ConversationMetadata, type ConversationSnapshot, ConversationStore, CoreMCPClient, DefaultDelegationPolicy, DefaultDelegationResultFormatter, DefaultDelegationService, DefaultSpecialistAgentFactory, type DelegationService, type DelegationServiceConfig, DelegationServiceFactory, ErrorReason, type FolderTreeOptions, GithubLLM, InMemoryMemory, InMemoryMetadata, JsonFileMemoryPersistence, type LLMConfig, LLMError, type LLMFactory, type LLMOptions, type LLMPort, LLMResolver, type MCPConfig, type MCPServerConfig, MCPToolPort, type MemoryPort, MemoryPortMetadataAdapter, type Message, type MessageContent, type MessageContentPart, type MetadataPort, NoopReminders, type OrchestratorAwareToolPort, PersistedMemory, PersistingConsoleEventPort, RuntimeEnv, type SendMessageOptions, SimpleContextBuilder, SimpleCost, SimpleId, type SpecialistAgentConfig, type SpecialistAgentResult, SystemClock, type ToolApprovalDecision, type ToolCall, type ToolExecutionResult, type ToolPort, ToolRegistry, type UserAttachment, type UserMessagePayload, buildAgentCreationPrompt, buildInjectedSystem, canonicalizeTerminalPaste, createLLM, generateFolderTree, getAvailableProviders, loadMCPConfig, normalizeNewlines, renderTemplate, resolveBackspaces, resolveCarriageReturns, stripAnsiAndControls, supportsGetModels };
|
package/dist/index.js
CHANGED
|
@@ -450,7 +450,13 @@ var AgentOrchestrator = class {
|
|
|
450
450
|
});
|
|
451
451
|
}
|
|
452
452
|
await this.deps.memory.append(convo, [assistantMsg, ...toolResultMsgs]);
|
|
453
|
-
|
|
453
|
+
const { usage: _usage, ...extraField } = result;
|
|
454
|
+
accumulatedMessages.push({
|
|
455
|
+
...extraField,
|
|
456
|
+
role: "assistant",
|
|
457
|
+
content: result.content ?? null,
|
|
458
|
+
tool_calls: approvedCalls
|
|
459
|
+
});
|
|
454
460
|
for (const tr of toolResults) {
|
|
455
461
|
const contentStr = tr.status === "error" ? String(tr.result) : typeof tr.result === "string" ? tr.result : JSON.stringify(tr.result);
|
|
456
462
|
accumulatedMessages.push({ role: "tool", content: contentStr, tool_call_id: tr.id, name: tr.name });
|
|
@@ -638,9 +644,18 @@ var SimpleContextBuilder = class {
|
|
|
638
644
|
transformed.push({ role: "user", content: providerContent ?? "" });
|
|
639
645
|
} else if (m.role === "assistant") {
|
|
640
646
|
if (m.tool_calls && m.tool_calls.length > 0) {
|
|
641
|
-
transformed.push({
|
|
647
|
+
transformed.push({
|
|
648
|
+
...m,
|
|
649
|
+
role: "assistant",
|
|
650
|
+
content: providerContent ?? null,
|
|
651
|
+
tool_calls: m.tool_calls
|
|
652
|
+
});
|
|
642
653
|
} else {
|
|
643
|
-
transformed.push({
|
|
654
|
+
transformed.push({
|
|
655
|
+
...m,
|
|
656
|
+
role: "assistant",
|
|
657
|
+
content: providerContent ?? ""
|
|
658
|
+
});
|
|
644
659
|
}
|
|
645
660
|
} else if (m.role === "tool") {
|
|
646
661
|
if (m.tool_call_id) {
|
|
@@ -2384,8 +2399,12 @@ var BashTool = class {
|
|
|
2384
2399
|
}
|
|
2385
2400
|
arr.push(chunk);
|
|
2386
2401
|
};
|
|
2387
|
-
child.stdout
|
|
2388
|
-
|
|
2402
|
+
if (child.stdout) {
|
|
2403
|
+
child.stdout.on("data", (d) => capPush(stdout, d));
|
|
2404
|
+
}
|
|
2405
|
+
if (child.stderr) {
|
|
2406
|
+
child.stderr.on("data", (d) => capPush(stderr, d));
|
|
2407
|
+
}
|
|
2389
2408
|
const exit = new Promise((res) => {
|
|
2390
2409
|
child.on("close", (code, signal2) => res({ code, signal: signal2 }));
|
|
2391
2410
|
});
|
|
@@ -2643,8 +2662,10 @@ var AgentRegistry = class {
|
|
|
2643
2662
|
this.filePersistence = options?.filePersistence;
|
|
2644
2663
|
for (const agent of defaultAgents) {
|
|
2645
2664
|
const complete = this.applyDefaults(agent);
|
|
2646
|
-
|
|
2647
|
-
|
|
2665
|
+
if (complete.id) {
|
|
2666
|
+
this.agents.set(complete.id, complete);
|
|
2667
|
+
this.defaultAgentIds.add(complete.id);
|
|
2668
|
+
}
|
|
2648
2669
|
}
|
|
2649
2670
|
this.loadingPromise = this.loadAgents();
|
|
2650
2671
|
}
|
|
@@ -2726,7 +2747,7 @@ var AgentRegistry = class {
|
|
|
2726
2747
|
for (const agent of loadedAgents) {
|
|
2727
2748
|
if (this.validateTemplate(agent)) {
|
|
2728
2749
|
const complete = this.applyDefaults(agent);
|
|
2729
|
-
if (!this.defaultAgentIds.has(complete.id)) {
|
|
2750
|
+
if (complete.id && !this.defaultAgentIds.has(complete.id)) {
|
|
2730
2751
|
this.agents.set(complete.id, complete);
|
|
2731
2752
|
}
|
|
2732
2753
|
}
|
|
@@ -2775,9 +2796,6 @@ var AgentRegistry = class {
|
|
|
2775
2796
|
if (!this.filePersistence) {
|
|
2776
2797
|
throw new Error("File persistence not configured");
|
|
2777
2798
|
}
|
|
2778
|
-
if (!agent.id) {
|
|
2779
|
-
throw new Error("Cannot save agent without ID");
|
|
2780
|
-
}
|
|
2781
2799
|
if (this.defaultAgentIds.has(agent.id)) {
|
|
2782
2800
|
throw new Error(`Cannot save default agent "${agent.id}" to file`);
|
|
2783
2801
|
}
|
|
@@ -2999,8 +3017,8 @@ var AgentManager = class {
|
|
|
2999
3017
|
this.llmFactory = llmFactory;
|
|
3000
3018
|
this.eventCallback = eventCallback;
|
|
3001
3019
|
this.configResolver = configResolver;
|
|
3002
|
-
if (llmFactory) {
|
|
3003
|
-
this.llmResolver = new LLMResolver(llmFactory);
|
|
3020
|
+
if (this.llmFactory) {
|
|
3021
|
+
this.llmResolver = new LLMResolver(this.llmFactory);
|
|
3004
3022
|
}
|
|
3005
3023
|
}
|
|
3006
3024
|
llmResolver = null;
|
|
@@ -3178,7 +3196,9 @@ var AgentManager = class {
|
|
|
3178
3196
|
*/
|
|
3179
3197
|
resolveLLM(config) {
|
|
3180
3198
|
if (!this.llmResolver) {
|
|
3181
|
-
throw new Error(
|
|
3199
|
+
throw new Error(
|
|
3200
|
+
"AgentManager requires LLMFactory to create sub-agents. Please provide llmFactory in constructor."
|
|
3201
|
+
);
|
|
3182
3202
|
}
|
|
3183
3203
|
return this.llmResolver.resolve(config);
|
|
3184
3204
|
}
|
|
@@ -3411,9 +3431,7 @@ var ToolRegistry = class {
|
|
|
3411
3431
|
const delegationService = factory.create({
|
|
3412
3432
|
agentRegistry: this.agentRegistry,
|
|
3413
3433
|
commandRunner,
|
|
3414
|
-
agentListProvider: () => this.agentRegistry.list().
|
|
3415
|
-
(agent) => typeof agent.id === "string" && typeof agent.name === "string" && typeof agent.description === "string"
|
|
3416
|
-
).map((agent) => ({
|
|
3434
|
+
agentListProvider: () => this.agentRegistry.list().map((agent) => ({
|
|
3417
3435
|
id: agent.id,
|
|
3418
3436
|
name: agent.name,
|
|
3419
3437
|
description: agent.description
|
|
@@ -3685,9 +3703,7 @@ var AgentFilePersistence = class {
|
|
|
3685
3703
|
fs8.unlinkSync(filePath);
|
|
3686
3704
|
}
|
|
3687
3705
|
} catch (error) {
|
|
3688
|
-
throw new Error(
|
|
3689
|
-
`Failed to delete agent ${agentId}: ${error instanceof Error ? error.message : String(error)}`
|
|
3690
|
-
);
|
|
3706
|
+
throw new Error(`Failed to delete agent ${agentId}: ${error instanceof Error ? error.message : String(error)}`);
|
|
3691
3707
|
}
|
|
3692
3708
|
}
|
|
3693
3709
|
/**
|
|
@@ -3716,6 +3732,7 @@ var AgentFilePersistence = class {
|
|
|
3716
3732
|
function mergeChoices(choices) {
|
|
3717
3733
|
const contentParts = [];
|
|
3718
3734
|
const mergedToolCalls = [];
|
|
3735
|
+
const extraFields = {};
|
|
3719
3736
|
const collectText = (value) => {
|
|
3720
3737
|
if (typeof value === "string") {
|
|
3721
3738
|
const trimmed = value.trim();
|
|
@@ -3736,10 +3753,20 @@ function mergeChoices(choices) {
|
|
|
3736
3753
|
if (!msg) continue;
|
|
3737
3754
|
collectText(msg.content);
|
|
3738
3755
|
if (Array.isArray(msg.tool_calls)) mergedToolCalls.push(...msg.tool_calls);
|
|
3756
|
+
const knownKeys = ["content", "tool_calls", "role"];
|
|
3757
|
+
for (const key of Object.keys(msg)) {
|
|
3758
|
+
if (!knownKeys.includes(key)) {
|
|
3759
|
+
extraFields[key] = msg[key];
|
|
3760
|
+
}
|
|
3761
|
+
}
|
|
3739
3762
|
}
|
|
3740
3763
|
const content = contentParts.join("\n\n");
|
|
3741
3764
|
const tool_calls = mergedToolCalls.length ? mergedToolCalls : void 0;
|
|
3742
|
-
return {
|
|
3765
|
+
return {
|
|
3766
|
+
content,
|
|
3767
|
+
...tool_calls ? { tool_calls } : {},
|
|
3768
|
+
...extraFields
|
|
3769
|
+
};
|
|
3743
3770
|
}
|
|
3744
3771
|
function normalizeUsage(usage) {
|
|
3745
3772
|
if (!usage) return void 0;
|
|
@@ -3900,6 +3927,7 @@ var BaseLLM = class {
|
|
|
3900
3927
|
const mergedToolCalls = [];
|
|
3901
3928
|
let usage;
|
|
3902
3929
|
let lastFinishReason;
|
|
3930
|
+
const extraFields = {};
|
|
3903
3931
|
const flushEvent = (rawEvent) => {
|
|
3904
3932
|
const lines = rawEvent.split("\n");
|
|
3905
3933
|
const dataLines = [];
|
|
@@ -3927,7 +3955,7 @@ var BaseLLM = class {
|
|
|
3927
3955
|
}
|
|
3928
3956
|
for (const ch of choices) {
|
|
3929
3957
|
const delta = ch.delta ?? ch.message ?? {};
|
|
3930
|
-
const textDelta = delta.content
|
|
3958
|
+
const textDelta = delta.content ?? void 0;
|
|
3931
3959
|
if (typeof textDelta === "string" && textDelta.length > 0) {
|
|
3932
3960
|
if (content === "") {
|
|
3933
3961
|
const trimmedDelta = textDelta.replace(/^\n+/, "");
|
|
@@ -3940,6 +3968,16 @@ var BaseLLM = class {
|
|
|
3940
3968
|
handlers.onChunk?.(textDelta);
|
|
3941
3969
|
}
|
|
3942
3970
|
}
|
|
3971
|
+
const knownKeys = ["role", "content", "tool_calls"];
|
|
3972
|
+
for (const key of Object.keys(delta)) {
|
|
3973
|
+
if (knownKeys.includes(key)) continue;
|
|
3974
|
+
const val = delta[key];
|
|
3975
|
+
if (typeof val === "string") {
|
|
3976
|
+
extraFields[key] = (extraFields[key] || "") + val;
|
|
3977
|
+
} else if (val !== void 0 && val !== null) {
|
|
3978
|
+
extraFields[key] = val;
|
|
3979
|
+
}
|
|
3980
|
+
}
|
|
3943
3981
|
const toolDeltas = Array.isArray(delta.tool_calls) ? delta.tool_calls : [];
|
|
3944
3982
|
for (const td of toolDeltas) {
|
|
3945
3983
|
let toolCall;
|
|
@@ -3947,6 +3985,7 @@ var BaseLLM = class {
|
|
|
3947
3985
|
toolCall = mergedToolCalls.find((tc) => tc.id === td.id);
|
|
3948
3986
|
if (!toolCall) {
|
|
3949
3987
|
toolCall = {
|
|
3988
|
+
...td,
|
|
3950
3989
|
id: td.id,
|
|
3951
3990
|
type: "function",
|
|
3952
3991
|
function: { name: td.function?.name ?? "", arguments: "" }
|
|
@@ -3993,7 +4032,12 @@ var BaseLLM = class {
|
|
|
3993
4032
|
if (buffer.trim()) flushEvent(buffer);
|
|
3994
4033
|
content = content.replace(/^\n+/, "");
|
|
3995
4034
|
const tool_calls = mergedToolCalls.length ? mergedToolCalls : void 0;
|
|
3996
|
-
return {
|
|
4035
|
+
return {
|
|
4036
|
+
content,
|
|
4037
|
+
...tool_calls ? { tool_calls } : {},
|
|
4038
|
+
...usage ? { usage } : {},
|
|
4039
|
+
...extraFields
|
|
4040
|
+
};
|
|
3997
4041
|
}
|
|
3998
4042
|
};
|
|
3999
4043
|
|
|
@@ -4363,8 +4407,9 @@ var GithubAuthTransport = class {
|
|
|
4363
4407
|
method: "GET",
|
|
4364
4408
|
headers: {
|
|
4365
4409
|
Authorization: `Bearer ${this.accessToken}`,
|
|
4366
|
-
"user-agent": "GitHubCopilotChat/0.
|
|
4367
|
-
"editor-version": "vscode/1.
|
|
4410
|
+
"user-agent": "GitHubCopilotChat/0.33.1",
|
|
4411
|
+
"editor-version": "vscode/1.106.1",
|
|
4412
|
+
"x-github-api-version": "2025-10-01",
|
|
4368
4413
|
accept: "application/json"
|
|
4369
4414
|
},
|
|
4370
4415
|
signal
|
|
@@ -4393,7 +4438,7 @@ var GithubAuthTransport = class {
|
|
|
4393
4438
|
if (!Array.isArray(messages.messages)) return false;
|
|
4394
4439
|
return messages.messages.some((msg) => isVisionMessage(msg));
|
|
4395
4440
|
}
|
|
4396
|
-
makeAuthHeaders(
|
|
4441
|
+
makeAuthHeaders(headers, body) {
|
|
4397
4442
|
const base = headers ? { ...headers } : {};
|
|
4398
4443
|
if (this.apiKey) base.Authorization = `Bearer ${this.apiKey}`;
|
|
4399
4444
|
base["editor-version"] = base["editor-version"] || "vscode/1.104.2";
|
|
@@ -4431,11 +4476,11 @@ var GithubAuthTransport = class {
|
|
|
4431
4476
|
await this.exchangeToken(signal);
|
|
4432
4477
|
}
|
|
4433
4478
|
const fullUrl = this.buildFullUrl(url);
|
|
4434
|
-
let res = await this.inner.get(fullUrl, this.makeAuthHeaders(
|
|
4479
|
+
let res = await this.inner.get(fullUrl, this.makeAuthHeaders(headers), signal);
|
|
4435
4480
|
if (res.status === 401 && this.accessToken) {
|
|
4436
4481
|
await this.exchangeToken(signal);
|
|
4437
4482
|
const retryUrl = this.buildFullUrl(url);
|
|
4438
|
-
res = await this.inner.get(retryUrl, this.makeAuthHeaders(
|
|
4483
|
+
res = await this.inner.get(retryUrl, this.makeAuthHeaders(headers), signal);
|
|
4439
4484
|
}
|
|
4440
4485
|
return res;
|
|
4441
4486
|
}
|
|
@@ -4444,25 +4489,26 @@ var GithubAuthTransport = class {
|
|
|
4444
4489
|
await this.exchangeToken(signal);
|
|
4445
4490
|
}
|
|
4446
4491
|
const fullUrl = this.buildFullUrl(url);
|
|
4447
|
-
let res = await this.inner.postJson(fullUrl, body, this.makeAuthHeaders(
|
|
4492
|
+
let res = await this.inner.postJson(fullUrl, body, this.makeAuthHeaders(headers, body), signal);
|
|
4448
4493
|
if (res.status === 401 && this.accessToken) {
|
|
4449
4494
|
await this.exchangeToken(signal);
|
|
4450
4495
|
const retryUrl = this.buildFullUrl(url);
|
|
4451
|
-
res = await this.inner.postJson(retryUrl, body, this.makeAuthHeaders(
|
|
4496
|
+
res = await this.inner.postJson(retryUrl, body, this.makeAuthHeaders(headers, body), signal);
|
|
4452
4497
|
}
|
|
4453
4498
|
return res;
|
|
4454
4499
|
}
|
|
4455
4500
|
async postStream(url, body, headers, signal) {
|
|
4456
|
-
|
|
4501
|
+
let hdrs = this.makeAuthHeaders({ Accept: "text/event-stream", ...headers || {} }, body);
|
|
4502
|
+
if ((!this.apiKey || !hdrs.Authorization) && this.accessToken) {
|
|
4457
4503
|
await this.exchangeToken(signal);
|
|
4504
|
+
hdrs = this.makeAuthHeaders({ Accept: "text/event-stream", ...headers || {} }, body);
|
|
4458
4505
|
}
|
|
4459
4506
|
const fullUrl = this.buildFullUrl(url);
|
|
4460
|
-
const hdrs = this.makeAuthHeaders(fullUrl, { Accept: "text/event-stream", ...headers || {} }, body);
|
|
4461
4507
|
let res = await this.inner.postStream(fullUrl, body, hdrs, signal);
|
|
4462
4508
|
if (res.status === 401 && this.accessToken) {
|
|
4463
4509
|
await this.exchangeToken(signal);
|
|
4464
4510
|
const retryUrl = this.buildFullUrl(url);
|
|
4465
|
-
res = await this.inner.postStream(retryUrl, body, this.makeAuthHeaders(
|
|
4511
|
+
res = await this.inner.postStream(retryUrl, body, this.makeAuthHeaders(hdrs, body), signal);
|
|
4466
4512
|
}
|
|
4467
4513
|
return res;
|
|
4468
4514
|
}
|
|
@@ -4551,6 +4597,49 @@ var GithubLLM = class extends BaseLLM {
|
|
|
4551
4597
|
accessToken: this.opts.accessToken
|
|
4552
4598
|
});
|
|
4553
4599
|
}
|
|
4600
|
+
async getModels(signal) {
|
|
4601
|
+
const res = await this.getTransport().get("/models", void 0, signal);
|
|
4602
|
+
if (!res.ok) {
|
|
4603
|
+
const text = await res.text();
|
|
4604
|
+
throw new LLMError(text || `Failed to fetch models: ${res.status}`, res.status);
|
|
4605
|
+
}
|
|
4606
|
+
const body = await res.json();
|
|
4607
|
+
return body.data;
|
|
4608
|
+
}
|
|
4609
|
+
handleError(error, model) {
|
|
4610
|
+
if (error instanceof LLMError) {
|
|
4611
|
+
try {
|
|
4612
|
+
const errorBody = JSON.parse(error.message);
|
|
4613
|
+
if (errorBody?.error?.code === "unsupported_api_for_model") {
|
|
4614
|
+
throw new LLMError(
|
|
4615
|
+
`The model '${model}' is not supported for chat completions. Please select a different model using '/model'.`,
|
|
4616
|
+
error.statusCode,
|
|
4617
|
+
false
|
|
4618
|
+
// Not retryable
|
|
4619
|
+
);
|
|
4620
|
+
}
|
|
4621
|
+
} catch (e) {
|
|
4622
|
+
if (e instanceof LLMError && e.message.includes("not supported")) {
|
|
4623
|
+
throw e;
|
|
4624
|
+
}
|
|
4625
|
+
}
|
|
4626
|
+
}
|
|
4627
|
+
throw error;
|
|
4628
|
+
}
|
|
4629
|
+
async generateCompletion(params, signal) {
|
|
4630
|
+
try {
|
|
4631
|
+
return await super.generateCompletion(params, signal);
|
|
4632
|
+
} catch (error) {
|
|
4633
|
+
this.handleError(error, params.model);
|
|
4634
|
+
}
|
|
4635
|
+
}
|
|
4636
|
+
async streamCompletion(params, handlers, signal) {
|
|
4637
|
+
try {
|
|
4638
|
+
return await super.streamCompletion(params, handlers, signal);
|
|
4639
|
+
} catch (error) {
|
|
4640
|
+
this.handleError(error, params.model);
|
|
4641
|
+
}
|
|
4642
|
+
}
|
|
4554
4643
|
};
|
|
4555
4644
|
|
|
4556
4645
|
// llm-providers/llm-anthropic-aisdk.ts
|
|
@@ -4601,9 +4690,11 @@ var AnthropicAISDKLLM = class {
|
|
|
4601
4690
|
}
|
|
4602
4691
|
updateCredentials(result) {
|
|
4603
4692
|
if (result.type === "success" && result.access && result.refresh && result.expires) {
|
|
4604
|
-
this.opts.oauth
|
|
4605
|
-
|
|
4606
|
-
|
|
4693
|
+
if (this.opts.oauth) {
|
|
4694
|
+
this.opts.oauth.access = result.access;
|
|
4695
|
+
this.opts.oauth.refresh = result.refresh;
|
|
4696
|
+
this.opts.oauth.expires = result.expires;
|
|
4697
|
+
}
|
|
4607
4698
|
this.opts.onTokenUpdate?.({
|
|
4608
4699
|
access: result.access,
|
|
4609
4700
|
refresh: result.refresh,
|
|
@@ -5405,7 +5496,7 @@ function normalizeMCPConfig(raw) {
|
|
|
5405
5496
|
return { mcpServers: servers };
|
|
5406
5497
|
}
|
|
5407
5498
|
}
|
|
5408
|
-
if (asRecord.config && typeof asRecord.config === "object") {
|
|
5499
|
+
if ("config" in asRecord && asRecord.config && typeof asRecord.config === "object") {
|
|
5409
5500
|
const nested = asRecord.config;
|
|
5410
5501
|
if (isValidConfig(nested)) {
|
|
5411
5502
|
const servers = nested.mcpServers;
|
|
@@ -5434,23 +5525,26 @@ function isValidConfig(value) {
|
|
|
5434
5525
|
|
|
5435
5526
|
// events.ts
|
|
5436
5527
|
var PersistingConsoleEventPort = class {
|
|
5437
|
-
// private console = new ConsoleEventPort();
|
|
5438
5528
|
memory;
|
|
5439
5529
|
maxPerConversation;
|
|
5530
|
+
writeQueue = Promise.resolve();
|
|
5440
5531
|
constructor(opts) {
|
|
5441
5532
|
this.memory = opts?.memory ?? new PersistedMemory(new JsonFileMemoryPersistence(opts?.filename || "events.json"));
|
|
5442
5533
|
this.maxPerConversation = opts?.maxPerConversation ?? 500;
|
|
5443
5534
|
}
|
|
5444
5535
|
async emit(event) {
|
|
5445
|
-
|
|
5446
|
-
|
|
5447
|
-
|
|
5448
|
-
|
|
5449
|
-
|
|
5450
|
-
|
|
5451
|
-
|
|
5452
|
-
|
|
5453
|
-
|
|
5536
|
+
this.writeQueue = this.writeQueue.then(async () => {
|
|
5537
|
+
try {
|
|
5538
|
+
const key = event?.conversationId ?? "default";
|
|
5539
|
+
const existing = await this.memory.get(key);
|
|
5540
|
+
const next = [...existing, { ...event }];
|
|
5541
|
+
const max = this.maxPerConversation;
|
|
5542
|
+
const trimmed = max > 0 && next.length > max ? next.slice(next.length - max) : next;
|
|
5543
|
+
await this.memory.set(key, trimmed);
|
|
5544
|
+
} catch {
|
|
5545
|
+
}
|
|
5546
|
+
});
|
|
5547
|
+
return this.writeQueue;
|
|
5454
5548
|
}
|
|
5455
5549
|
};
|
|
5456
5550
|
export {
|