agent-framework-js 0.2.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/CHANGELOG.md +45 -0
- package/README.md +6 -0
- package/dist/agents/index.cjs +7 -7
- package/dist/agents/index.d.cts +6 -6
- package/dist/agents/index.d.ts +6 -6
- package/dist/agents/index.js +2 -2
- package/dist/{chunk-245NZAGV.cjs → chunk-2WBJEXNY.cjs} +4 -4
- package/dist/{chunk-245NZAGV.cjs.map → chunk-2WBJEXNY.cjs.map} +1 -1
- package/dist/{chunk-IGIFX6QO.js → chunk-3KU76DCP.js} +4 -4
- package/dist/{chunk-IGIFX6QO.js.map → chunk-3KU76DCP.js.map} +1 -1
- package/dist/{chunk-S5776DOL.js → chunk-55NB43FN.js} +3 -3
- package/dist/{chunk-S5776DOL.js.map → chunk-55NB43FN.js.map} +1 -1
- package/dist/{chunk-UIXNKPLQ.cjs → chunk-5KC6X2T5.cjs} +7 -7
- package/dist/{chunk-UIXNKPLQ.cjs.map → chunk-5KC6X2T5.cjs.map} +1 -1
- package/dist/{chunk-NURRGYIU.cjs → chunk-FDCTSJMB.cjs} +13 -11
- package/dist/chunk-FDCTSJMB.cjs.map +1 -0
- package/dist/{chunk-ILBKDEEL.cjs → chunk-I55OVD23.cjs} +2 -2
- package/dist/chunk-I55OVD23.cjs.map +1 -0
- package/dist/{chunk-U64OEHG6.cjs → chunk-JLPLGU7O.cjs} +131 -21
- package/dist/chunk-JLPLGU7O.cjs.map +1 -0
- package/dist/{chunk-WEKU7735.js → chunk-KOPGBIES.js} +6 -4
- package/dist/chunk-KOPGBIES.js.map +1 -0
- package/dist/{chunk-E4VTVUYU.js → chunk-LC54DGGR.js} +2 -2
- package/dist/chunk-LC54DGGR.js.map +1 -0
- package/dist/{chunk-FOTCUNP5.cjs → chunk-N64ZFATA.cjs} +5 -2
- package/dist/chunk-N64ZFATA.cjs.map +1 -0
- package/dist/{chunk-ACBIHS5H.js → chunk-QXAJ4DUJ.js} +5 -2
- package/dist/chunk-QXAJ4DUJ.js.map +1 -0
- package/dist/{chunk-YH5746OF.js → chunk-QYG4HLIC.js} +3 -3
- package/dist/{chunk-YH5746OF.js.map → chunk-QYG4HLIC.js.map} +1 -1
- package/dist/{chunk-GYDY3KX5.cjs → chunk-U3ULJMNH.cjs} +4 -4
- package/dist/{chunk-GYDY3KX5.cjs.map → chunk-U3ULJMNH.cjs.map} +1 -1
- package/dist/{chunk-7M3EAGCA.js → chunk-YVJGF4HQ.js} +132 -22
- package/dist/chunk-YVJGF4HQ.js.map +1 -0
- package/dist/declarative/index.cjs +4 -4
- package/dist/declarative/index.d.cts +6 -6
- package/dist/declarative/index.d.ts +6 -6
- package/dist/declarative/index.js +3 -3
- package/dist/{index-Dog-CyOK.d.ts → index-C22fqyZQ.d.ts} +5 -5
- package/dist/{index-5eIhfrC1.d.cts → index-b1oTo3Lv.d.cts} +5 -5
- package/dist/index.cjs +37 -37
- package/dist/index.d.cts +11 -6
- package/dist/index.d.ts +11 -6
- package/dist/index.js +7 -7
- package/dist/mcp/index.cjs +4 -4
- package/dist/mcp/index.d.cts +2 -2
- package/dist/mcp/index.d.ts +2 -2
- package/dist/mcp/index.js +2 -2
- package/dist/middleware/index.d.cts +7 -7
- package/dist/middleware/index.d.ts +7 -7
- package/dist/persistence/index.cjs +6 -6
- package/dist/persistence/index.d.cts +3 -3
- package/dist/persistence/index.d.ts +3 -3
- package/dist/persistence/index.js +3 -3
- package/dist/{provider-IJnfNhCX.d.cts → provider-B807EuDV.d.cts} +6 -1
- package/dist/{provider-C_rgZvmX.d.ts → provider-CvU3I-Xo.d.ts} +6 -1
- package/dist/providers/index.cjs +7 -6
- package/dist/providers/index.d.cts +39 -4
- package/dist/providers/index.d.ts +39 -4
- package/dist/providers/index.js +2 -1
- package/dist/{registry-B-hicOxp.d.cts → registry-BCkSIe0E.d.cts} +2 -2
- package/dist/{registry-KMWN0p4Z.d.ts → registry-D-CmT0gk.d.ts} +2 -2
- package/dist/{thread-D3zaGK1Y.d.cts → thread-BzwE1OnJ.d.cts} +2 -2
- package/dist/{thread-COV135Ja.d.ts → thread-COljUAtD.d.ts} +2 -2
- package/dist/{tool-BZg_znMZ.d.cts → tool-D9Uodu9Y.d.cts} +1 -1
- package/dist/{tool-CSCC87OD.d.ts → tool-LPMc4QQd.d.ts} +1 -1
- package/dist/tools/index.d.cts +4 -4
- package/dist/tools/index.d.ts +4 -4
- package/dist/{types-Cn1g9Tg4.d.cts → types-AlvjoTyS.d.cts} +24 -1
- package/dist/{types-Cn1g9Tg4.d.ts → types-AlvjoTyS.d.ts} +24 -1
- package/dist/workflows/index.d.cts +6 -6
- package/dist/workflows/index.d.ts +6 -6
- package/package.json +7 -7
- package/dist/chunk-7M3EAGCA.js.map +0 -1
- package/dist/chunk-ACBIHS5H.js.map +0 -1
- package/dist/chunk-E4VTVUYU.js.map +0 -1
- package/dist/chunk-FOTCUNP5.cjs.map +0 -1
- package/dist/chunk-ILBKDEEL.cjs.map +0 -1
- package/dist/chunk-NURRGYIU.cjs.map +0 -1
- package/dist/chunk-U64OEHG6.cjs.map +0 -1
- package/dist/chunk-WEKU7735.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/mcp/adapter.ts","../src/mcp/connection.ts"],"names":["MCPError","requireCapability"],"mappings":"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","file":"chunk-
|
|
1
|
+
{"version":3,"sources":["../src/mcp/adapter.ts","../src/mcp/connection.ts"],"names":["MCPError","requireCapability"],"mappings":"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","file":"chunk-U3ULJMNH.cjs","sourcesContent":["/**\n * Adapts MCP-provided tools onto the framework's uniform {@link Tool} contract,\n * namespaced by the connection id so collisions are impossible. (FR-014, FR-014a)\n *\n * @packageDocumentation\n */\n\nimport type { Tool } from \"../tools/tool.js\";\nimport { MCPError } from \"../core/errors.js\";\n\ninterface MCPToolDef {\n\tname: string;\n\tdescription?: string;\n\tinputSchema: Record<string, unknown>;\n}\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\n/**\n * Wrap an MCP tool definition as a framework tool. Invocation calls back through\n * the MCP client; failures surface as typed {@link MCPError}/tool errors.\n */\nexport function mcpToolToTool(serverId: string, def: MCPToolDef, client: any): Tool {\n\treturn {\n\t\tname: def.name,\n\t\tdescription: def.description ?? \"\",\n\t\tinputSchema: def.inputSchema,\n\t\tsource: serverId,\n\t\tenabled: true,\n\t\tasync run(args: unknown): Promise<unknown> {\n\t\t\ttry {\n\t\t\t\tconst result = await client.callTool({ name: def.name, arguments: args });\n\t\t\t\treturn result.content ?? result;\n\t\t\t} catch (e) {\n\t\t\t\tthrow new MCPError(`MCP tool \"${def.name}\" failed: ${(e as Error).message}`, serverId);\n\t\t\t}\n\t\t},\n\t};\n}\n","/**\n * MCP (Model Context Protocol) integration. Connects to MCP servers and exposes\n * their tools through the framework's uniform tool interface.\n *\n * Remote transport (HTTP/SSE) works in all runtimes; stdio (spawning a server\n * process) works only where process spawning is permitted (Node). Requesting\n * stdio elsewhere throws a typed {@link RuntimeUnsupportedError}. (FR-013, FR-013a,\n * FR-013b, FR-030a)\n *\n * The `@modelcontextprotocol/sdk` package is an optional peer dependency and is\n * loaded lazily so browser bundles that do not use MCP pay no cost.\n *\n * @packageDocumentation\n */\n\nimport { MCPError } from \"../core/errors.js\";\nimport { requireCapability } from \"../core/runtime.js\";\nimport type { Tool } from \"../tools/tool.js\";\nimport { mcpToolToTool } from \"./adapter.js\";\n\n/** Transport options for an MCP connection. */\nexport type MCPTransport =\n\t| { kind: \"remote\"; url: string }\n\t| { kind: \"stdio\"; command: string; args?: string[] };\n\n/** Configuration for connecting to an MCP server. */\nexport interface MCPConnectionConfig {\n\t/** Connection id; becomes the namespace prefix for discovered tools. (FR-014a) */\n\tid: string;\n\ttransport: MCPTransport;\n\t/** Whether the connection's tools are enabled. Defaults to true. */\n\tenabled?: boolean;\n}\n\n/** A live connection to an MCP server. */\nexport interface MCPConnection {\n\treadonly id: string;\n\tconnect(): Promise<void>;\n\tlistTools(): Promise<Tool[]>;\n\tclose(): Promise<void>;\n}\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\ntype AnyClient = any;\n\nasync function createTransport(config: MCPConnectionConfig): Promise<AnyClient> {\n\tif (config.transport.kind === \"stdio\") {\n\t\t// Gate on runtime capability before attempting to spawn. (FR-013b, FR-030a)\n\t\trequireCapability(\"canSpawnProcess\", \"MCP stdio transport\");\n\t\tconst { StdioClientTransport } = await import(\n\t\t\t\"@modelcontextprotocol/sdk/client/stdio.js\"\n\t\t);\n\t\treturn new StdioClientTransport({\n\t\t\tcommand: config.transport.command,\n\t\t\targs: config.transport.args ?? [],\n\t\t});\n\t}\n\tconst { StreamableHTTPClientTransport } = await import(\n\t\t\"@modelcontextprotocol/sdk/client/streamableHttp.js\"\n\t);\n\treturn new StreamableHTTPClientTransport(new URL(config.transport.url));\n}\n\n/**\n * Connect to an MCP server.\n *\n * @example\n * ```ts\n * const mcp = await connectMCP({ id: \"docs\", transport: { kind: \"remote\", url: \"https://mcp.example.com\" } });\n * const tools = await mcp.listTools(); // namespaced as docs.<tool>\n * ```\n */\nexport async function connectMCP(config: MCPConnectionConfig): Promise<MCPConnection> {\n\tlet client: AnyClient | undefined;\n\n\tasync function connect(): Promise<void> {\n\t\ttry {\n\t\t\tconst { Client } = await import(\"@modelcontextprotocol/sdk/client/index.js\");\n\t\t\tconst transport = await createTransport(config);\n\t\t\tclient = new Client({ name: \"agent-framework-js\", version: \"0.1.0\" }, { capabilities: {} });\n\t\t\tawait client.connect(transport);\n\t\t} catch (e) {\n\t\t\t// Preserve typed runtime errors; wrap everything else as an MCP error.\n\t\t\tif ((e as Error).name === \"RuntimeUnsupportedError\") throw e;\n\t\t\tthrow new MCPError(`Failed to connect to MCP server: ${(e as Error).message}`, config.id);\n\t\t}\n\t}\n\n\tasync function listTools(): Promise<Tool[]> {\n\t\tif (!client) throw new MCPError(\"Not connected\", config.id);\n\t\ttry {\n\t\t\tconst result = await client.listTools();\n\t\t\treturn (result.tools ?? []).map((t: { name: string; description?: string; inputSchema: Record<string, unknown> }) =>\n\t\t\t\tmcpToolToTool(config.id, t, client),\n\t\t\t);\n\t\t} catch (e) {\n\t\t\tthrow new MCPError(`Failed to list tools: ${(e as Error).message}`, config.id);\n\t\t}\n\t}\n\n\tasync function close(): Promise<void> {\n\t\tawait client?.close?.();\n\t\tclient = undefined;\n\t}\n\n\treturn { id: config.id, connect, listTools, close };\n}\n"]}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { detectRuntime } from './chunk-QXAJ4DUJ.js';
|
|
2
|
+
import { ValidationError, ProviderError, RuntimeUnsupportedError } from './chunk-IXV4UIF5.js';
|
|
2
3
|
|
|
3
4
|
// src/providers/provider.ts
|
|
4
5
|
function resolveModels(options) {
|
|
@@ -60,6 +61,10 @@ function providerErrorFromStatus(status, message) {
|
|
|
60
61
|
}
|
|
61
62
|
|
|
62
63
|
// src/providers/openai-compatible.ts
|
|
64
|
+
var UNSAFE_TOOL_NAME_CHARS = /[^a-zA-Z0-9_-]/g;
|
|
65
|
+
function sanitizeToolName(name) {
|
|
66
|
+
return name.replace(UNSAFE_TOOL_NAME_CHARS, "_");
|
|
67
|
+
}
|
|
63
68
|
function toOpenAIContent(parts) {
|
|
64
69
|
if (parts.every((p) => p.type === "text")) {
|
|
65
70
|
return parts.map((p) => p.text).join("");
|
|
@@ -68,54 +73,82 @@ function toOpenAIContent(parts) {
|
|
|
68
73
|
(p) => p.type === "text" ? { type: "text", text: p.text } : { type: "image_url", image_url: { url: p.data } }
|
|
69
74
|
);
|
|
70
75
|
}
|
|
76
|
+
function toWireToolCalls(toolCalls) {
|
|
77
|
+
return toolCalls.map((tc) => ({
|
|
78
|
+
id: tc.id,
|
|
79
|
+
type: "function",
|
|
80
|
+
function: {
|
|
81
|
+
name: sanitizeToolName(tc.name),
|
|
82
|
+
arguments: typeof tc.arguments === "string" ? tc.arguments : JSON.stringify(tc.arguments ?? {})
|
|
83
|
+
}
|
|
84
|
+
}));
|
|
85
|
+
}
|
|
71
86
|
function toOpenAIMessages(messages) {
|
|
72
87
|
return messages.map((m) => {
|
|
73
88
|
const msg = { role: m.role, content: toOpenAIContent(m.parts) };
|
|
89
|
+
if (m.toolCalls && m.toolCalls.length > 0) {
|
|
90
|
+
msg.tool_calls = toWireToolCalls(m.toolCalls);
|
|
91
|
+
const hasText = m.parts.some((p) => p.type === "text" && p.text.length > 0);
|
|
92
|
+
if (!hasText) msg.content = null;
|
|
93
|
+
}
|
|
74
94
|
if (m.toolCallId) msg.tool_call_id = m.toolCallId;
|
|
75
|
-
if (m.name) msg.name = m.name;
|
|
95
|
+
if (m.name) msg.name = sanitizeToolName(m.name);
|
|
96
|
+
if (m.reasoningOpaque) msg.reasoning_opaque = m.reasoningOpaque;
|
|
76
97
|
return msg;
|
|
77
98
|
});
|
|
78
99
|
}
|
|
100
|
+
function buildWireTools(specs) {
|
|
101
|
+
const nameMap = /* @__PURE__ */ new Map();
|
|
102
|
+
if (!specs || specs.length === 0) return { tools: void 0, nameMap };
|
|
103
|
+
const tools = specs.map((t) => {
|
|
104
|
+
const wireName = sanitizeToolName(t.name);
|
|
105
|
+
nameMap.set(wireName, t.name);
|
|
106
|
+
return {
|
|
107
|
+
type: "function",
|
|
108
|
+
function: { name: wireName, description: t.description, parameters: t.inputSchema }
|
|
109
|
+
};
|
|
110
|
+
});
|
|
111
|
+
return { tools, nameMap };
|
|
112
|
+
}
|
|
79
113
|
function createOpenAICompatibleProvider(options) {
|
|
80
114
|
const doFetch = options.fetchImpl ?? globalThis.fetch;
|
|
81
115
|
const url = `${options.baseUrl.replace(/\/$/, "")}/chat/completions`;
|
|
82
116
|
const { models, defaultModel, modelOf } = resolveModels(options);
|
|
83
117
|
async function authHeaders() {
|
|
84
118
|
const cred = await options.getCredential();
|
|
85
|
-
const headers = {
|
|
119
|
+
const headers = {
|
|
120
|
+
"content-type": "application/json",
|
|
121
|
+
...options.headers ?? {}
|
|
122
|
+
};
|
|
86
123
|
if (cred) headers["authorization"] = `Bearer ${cred}`;
|
|
87
124
|
return headers;
|
|
88
125
|
}
|
|
89
|
-
function body(req, stream) {
|
|
126
|
+
function body(req, stream, wire) {
|
|
90
127
|
return JSON.stringify({
|
|
91
128
|
model: modelOf(req.model).model,
|
|
92
129
|
messages: toOpenAIMessages(req.messages),
|
|
93
130
|
stream,
|
|
94
|
-
...
|
|
95
|
-
tools: req.tools.map((t) => ({
|
|
96
|
-
type: "function",
|
|
97
|
-
function: { name: t.name, description: t.description, parameters: t.inputSchema }
|
|
98
|
-
}))
|
|
99
|
-
} : {}
|
|
131
|
+
...wire.tools ? { tools: wire.tools } : {}
|
|
100
132
|
});
|
|
101
133
|
}
|
|
102
|
-
function parseToolCalls(raw) {
|
|
134
|
+
function parseToolCalls(raw, nameMap) {
|
|
103
135
|
const calls = raw?.tool_calls;
|
|
104
136
|
if (!calls || calls.length === 0) return void 0;
|
|
105
137
|
return calls.map((c) => ({
|
|
106
138
|
id: c.id,
|
|
107
|
-
name: c.function.name,
|
|
139
|
+
name: nameMap.get(c.function.name) ?? c.function.name,
|
|
108
140
|
arguments: safeJson(c.function.arguments)
|
|
109
141
|
}));
|
|
110
142
|
}
|
|
111
143
|
async function generate(req) {
|
|
112
144
|
return withRetry(async () => {
|
|
145
|
+
const wire = buildWireTools(req.tools);
|
|
113
146
|
let res;
|
|
114
147
|
try {
|
|
115
148
|
res = await doFetch(url, {
|
|
116
149
|
method: "POST",
|
|
117
150
|
headers: await authHeaders(),
|
|
118
|
-
body: body(req, false),
|
|
151
|
+
body: body(req, false, wire),
|
|
119
152
|
signal: req.signal
|
|
120
153
|
});
|
|
121
154
|
} catch (e) {
|
|
@@ -131,20 +164,47 @@ function createOpenAICompatibleProvider(options) {
|
|
|
131
164
|
const choice = json["choices"]?.[0];
|
|
132
165
|
if (!choice) throw new ProviderError("Provider returned no choices", "malformed");
|
|
133
166
|
const message = choice.message;
|
|
167
|
+
const reasoningModel = modelOf(req.model).supportsReasoning;
|
|
168
|
+
let toolCalls = parseToolCalls(message, wire.nameMap);
|
|
169
|
+
if ((!toolCalls || toolCalls.length === 0) && choice.finish_reason === "tool_calls") {
|
|
170
|
+
const assembled = await assembleViaStream(req);
|
|
171
|
+
toolCalls = assembled.toolCalls;
|
|
172
|
+
if (!toolCalls || toolCalls.length === 0) {
|
|
173
|
+
throw new ProviderError(
|
|
174
|
+
"Provider signaled tool_calls but returned none (even when streamed)",
|
|
175
|
+
"malformed"
|
|
176
|
+
);
|
|
177
|
+
}
|
|
178
|
+
return {
|
|
179
|
+
text: message["content"] ?? assembled.text ?? "",
|
|
180
|
+
reasoning: reasoningModel ? message["reasoning"] ?? assembled.reasoning ?? void 0 : void 0,
|
|
181
|
+
reasoningOpaque: reasoningModel ? message["reasoning_opaque"] ?? assembled.reasoningOpaque ?? void 0 : void 0,
|
|
182
|
+
toolCalls
|
|
183
|
+
};
|
|
184
|
+
}
|
|
134
185
|
return {
|
|
135
186
|
text: message["content"] ?? "",
|
|
136
|
-
reasoning:
|
|
137
|
-
|
|
187
|
+
reasoning: reasoningModel ? message["reasoning"] ?? void 0 : void 0,
|
|
188
|
+
reasoningOpaque: reasoningModel ? message["reasoning_opaque"] ?? void 0 : void 0,
|
|
189
|
+
toolCalls
|
|
138
190
|
};
|
|
139
191
|
}, options.retry);
|
|
140
192
|
}
|
|
193
|
+
async function assembleViaStream(req) {
|
|
194
|
+
let final = { text: "" };
|
|
195
|
+
for await (const chunk of generateStream(req)) {
|
|
196
|
+
if (chunk.type === "done") final = chunk.response;
|
|
197
|
+
}
|
|
198
|
+
return final;
|
|
199
|
+
}
|
|
141
200
|
async function* generateStream(req) {
|
|
201
|
+
const wire = buildWireTools(req.tools);
|
|
142
202
|
let res;
|
|
143
203
|
try {
|
|
144
204
|
res = await doFetch(url, {
|
|
145
205
|
method: "POST",
|
|
146
206
|
headers: await authHeaders(),
|
|
147
|
-
body: body(req, true),
|
|
207
|
+
body: body(req, true, wire),
|
|
148
208
|
signal: req.signal
|
|
149
209
|
});
|
|
150
210
|
} catch (e) {
|
|
@@ -152,11 +212,14 @@ function createOpenAICompatibleProvider(options) {
|
|
|
152
212
|
}
|
|
153
213
|
if (!res.ok) throw providerErrorFromStatus(res.status, `Provider returned ${res.status}`);
|
|
154
214
|
if (!res.body) throw new ProviderError("Provider returned no stream body", "malformed");
|
|
215
|
+
const reasoningModel = modelOf(req.model).supportsReasoning;
|
|
155
216
|
const reader = res.body.getReader();
|
|
156
217
|
const decoder = new TextDecoder();
|
|
157
218
|
let buffer = "";
|
|
158
219
|
let text = "";
|
|
159
220
|
let reasoning = "";
|
|
221
|
+
let reasoningOpaque = "";
|
|
222
|
+
const toolAccum = /* @__PURE__ */ new Map();
|
|
160
223
|
for (; ; ) {
|
|
161
224
|
const { value, done } = await reader.read();
|
|
162
225
|
if (done) break;
|
|
@@ -170,19 +233,46 @@ function createOpenAICompatibleProvider(options) {
|
|
|
170
233
|
if (data === "[DONE]") continue;
|
|
171
234
|
const parsed = safeJson(data);
|
|
172
235
|
const delta = parsed?.choices?.[0]?.delta;
|
|
173
|
-
if (delta
|
|
236
|
+
if (!delta) continue;
|
|
237
|
+
if (delta.content) {
|
|
174
238
|
text += delta.content;
|
|
175
239
|
yield { type: "text", text: delta.content };
|
|
176
240
|
}
|
|
177
|
-
if (delta
|
|
241
|
+
if (delta.reasoning && reasoningModel) {
|
|
178
242
|
reasoning += delta.reasoning;
|
|
179
243
|
yield { type: "reasoning", text: delta.reasoning };
|
|
180
244
|
}
|
|
245
|
+
if (delta.reasoning_opaque && reasoningModel) {
|
|
246
|
+
reasoningOpaque += delta.reasoning_opaque;
|
|
247
|
+
}
|
|
248
|
+
if (delta.tool_calls) {
|
|
249
|
+
for (const frag of delta.tool_calls) {
|
|
250
|
+
const idx = frag.index ?? 0;
|
|
251
|
+
const slot = toolAccum.get(idx) ?? { args: "" };
|
|
252
|
+
if (frag.id) slot.id = frag.id;
|
|
253
|
+
if (frag.function?.name) slot.name = frag.function.name;
|
|
254
|
+
if (frag.function?.arguments) slot.args += frag.function.arguments;
|
|
255
|
+
toolAccum.set(idx, slot);
|
|
256
|
+
}
|
|
257
|
+
}
|
|
181
258
|
}
|
|
182
259
|
}
|
|
260
|
+
const toolCalls = [...toolAccum.entries()].sort((a, b) => a[0] - b[0]).filter(([, s]) => s.name).map(([idx, s]) => ({
|
|
261
|
+
id: s.id ?? `call_${idx}`,
|
|
262
|
+
name: wire.nameMap.get(s.name) ?? s.name,
|
|
263
|
+
arguments: safeJson(s.args) ?? {}
|
|
264
|
+
}));
|
|
265
|
+
for (const toolCall of toolCalls) {
|
|
266
|
+
yield { type: "tool-call", toolCall };
|
|
267
|
+
}
|
|
183
268
|
yield {
|
|
184
269
|
type: "done",
|
|
185
|
-
response: {
|
|
270
|
+
response: {
|
|
271
|
+
text,
|
|
272
|
+
reasoning: reasoning || void 0,
|
|
273
|
+
reasoningOpaque: reasoningOpaque || void 0,
|
|
274
|
+
toolCalls: toolCalls.length > 0 ? toolCalls : void 0
|
|
275
|
+
}
|
|
186
276
|
};
|
|
187
277
|
}
|
|
188
278
|
return {
|
|
@@ -204,13 +294,33 @@ function safeJson(s) {
|
|
|
204
294
|
|
|
205
295
|
// src/providers/copilot.ts
|
|
206
296
|
var DEFAULT_COPILOT_BASE_URL = "https://api.githubcopilot.com";
|
|
297
|
+
var COPILOT_DEFAULT_HEADERS = {
|
|
298
|
+
"Editor-Version": "vscode/1.95.0",
|
|
299
|
+
"Editor-Plugin-Version": "copilot-chat/0.20.0",
|
|
300
|
+
"Copilot-Integration-Id": "vscode-chat",
|
|
301
|
+
"Openai-Intent": "conversation-panel"
|
|
302
|
+
};
|
|
207
303
|
function createCopilotProvider(options) {
|
|
304
|
+
const baseUrl = options.baseUrl ?? DEFAULT_COPILOT_BASE_URL;
|
|
305
|
+
const usingDefaultHost = baseUrl === DEFAULT_COPILOT_BASE_URL;
|
|
306
|
+
if (usingDefaultHost && detectRuntime().isBrowser) {
|
|
307
|
+
throw new RuntimeUnsupportedError(
|
|
308
|
+
"GitHub Copilot directly from a browser (the Copilot API sends no CORS headers)",
|
|
309
|
+
{
|
|
310
|
+
reason: "cors",
|
|
311
|
+
remedy: "Run a lightweight backend/proxy (e.g. a Vite dev-server proxy or a small server route) that forwards to https://api.githubcopilot.com, then set `baseUrl` to your proxy URL. Alternatively, run the Copilot provider server-side (Node or an edge function)."
|
|
312
|
+
}
|
|
313
|
+
);
|
|
314
|
+
}
|
|
208
315
|
const inner = createOpenAICompatibleProvider({
|
|
209
|
-
baseUrl
|
|
316
|
+
baseUrl,
|
|
210
317
|
getCredential: options.getCredential,
|
|
211
318
|
capabilities: options.capabilities,
|
|
212
319
|
models: options.models,
|
|
213
320
|
defaultModel: options.defaultModel,
|
|
321
|
+
// Copilot rejects calls missing its identification headers; defaults are
|
|
322
|
+
// applied here and remain overridable via `options.headers`.
|
|
323
|
+
headers: { ...COPILOT_DEFAULT_HEADERS, ...options.headers ?? {} },
|
|
214
324
|
retry: options.retry,
|
|
215
325
|
fetchImpl: options.fetchImpl
|
|
216
326
|
});
|
|
@@ -225,5 +335,5 @@ function createCopilotProvider(options) {
|
|
|
225
335
|
}
|
|
226
336
|
|
|
227
337
|
export { createCopilotProvider, createOpenAICompatibleProvider, providerErrorFromStatus, resolveModels, withRetry };
|
|
228
|
-
//# sourceMappingURL=chunk-
|
|
229
|
-
//# sourceMappingURL=chunk-
|
|
338
|
+
//# sourceMappingURL=chunk-YVJGF4HQ.js.map
|
|
339
|
+
//# sourceMappingURL=chunk-YVJGF4HQ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/providers/provider.ts","../src/providers/retry.ts","../src/providers/openai-compatible.ts","../src/providers/copilot.ts"],"names":[],"mappings":"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","file":"chunk-YVJGF4HQ.js","sourcesContent":["/**\n * LLM provider abstraction. Agents and workflows depend only on this interface,\n * never on a concrete provider, so new providers can be added without changing\n * agent/workflow code. (FR-007)\n *\n * Credentials are always obtained via a caller-supplied callback and are never\n * bundled, persisted, or logged by the framework. (FR-005a, FR-008)\n *\n * @packageDocumentation\n */\n\nimport type { Message, ModelCapabilities } from \"../core/types.js\";\nimport { ValidationError } from \"../core/errors.js\";\n\n/** A caller-supplied source of credentials. The framework never stores the value. */\nexport interface CredentialSource {\n\t/** Return the current credential (token/api key). May be async. */\n\tgetCredential(): string | Promise<string>;\n}\n\n/**\n * Model configuration for a provider. A provider may expose **one or more** models\n * (e.g. GitHub Copilot offers several; an OpenAI-compatible endpoint is usually one).\n * Supply either a single `capabilities` object or an array via `models`.\n */\nexport interface ModelSelectionOptions {\n\t/** Single-model shorthand. */\n\tcapabilities?: ModelCapabilities;\n\t/** One or more models this provider can use. */\n\tmodels?: ModelCapabilities[];\n\t/** Name of the default model (defaults to the first entry). */\n\tdefaultModel?: string;\n}\n\n/** Resolved model set with a default and a lookup helper. */\nexport interface ResolvedModels {\n\t/** All configured models (at least one). */\n\tmodels: ModelCapabilities[];\n\t/** The default model used when a request does not specify one. */\n\tdefaultModel: ModelCapabilities;\n\t/** Look up a model by name, or return the default when omitted. */\n\tmodelOf(name?: string): ModelCapabilities;\n}\n\n/**\n * Normalize {@link ModelSelectionOptions} into a model list, a default, and a\n * lookup helper. Throws {@link ValidationError} if no model is configured or a\n * named model is missing.\n *\n * @example\n * ```ts\n * const { defaultModel, modelOf } = resolveModels({\n * models: [\n * { model: \"gpt-4o\", maxInputTokens: 128000, maxOutputTokens: 16000 },\n * { model: \"o3-mini\", maxInputTokens: 200000, maxOutputTokens: 100000, supportsReasoning: true },\n * ],\n * defaultModel: \"gpt-4o\",\n * });\n * ```\n */\nexport function resolveModels(options: ModelSelectionOptions): ResolvedModels {\n\tconst models = options.models ?? (options.capabilities ? [options.capabilities] : []);\n\tif (models.length === 0) {\n\t\tthrow new ValidationError(\"Provider requires at least one model (set `capabilities` or `models`)\");\n\t}\n\tconst defaultModel = options.defaultModel\n\t\t? models.find((m) => m.model === options.defaultModel)\n\t\t: models[0];\n\tif (!defaultModel) {\n\t\tthrow new ValidationError(`defaultModel \"${options.defaultModel}\" is not present in models`);\n\t}\n\tconst modelOf = (name?: string): ModelCapabilities => {\n\t\tif (!name) return defaultModel;\n\t\tconst found = models.find((m) => m.model === name);\n\t\tif (!found) {\n\t\t\tthrow new ValidationError(`Model \"${name}\" is not configured for this provider`);\n\t\t}\n\t\treturn found;\n\t};\n\treturn { models, defaultModel, modelOf };\n}\n\n/** A tool description passed to the provider so the model can decide to call it. */\nexport interface ToolSpec {\n\tname: string;\n\tdescription: string;\n\tinputSchema: Record<string, unknown>;\n}\n\n/** A request to generate a model response. */\nexport interface GenerateRequest {\n\tmessages: Message[];\n\ttools?: ToolSpec[];\n\t/** Which configured model to use; defaults to the provider's default model. */\n\tmodel?: string;\n\t/** Abort signal to cancel an in-flight request. */\n\tsignal?: AbortSignal;\n}\n\n/** A tool call requested by the model. */\nexport interface ToolCall {\n\tid: string;\n\tname: string;\n\t/** Raw JSON arguments (validated by the tools module before invocation). */\n\targuments: unknown;\n}\n\n/** A complete (non-streaming) model response. */\nexport interface GenerateResponse {\n\t/** Final answer text. */\n\ttext: string;\n\t/** Reasoning/thinking content — only present for reasoning-capable models. (FR-003a) */\n\treasoning?: string;\n\t/**\n\t * Opaque reasoning blob (e.g. Claude thinking signature) to round-trip on the\n\t * next assistant turn for thinking continuity. Never logged or inspected.\n\t */\n\treasoningOpaque?: string;\n\t/** Tool calls the model wants to make, if any. */\n\ttoolCalls?: ToolCall[];\n\t/** Approximate token usage if reported by the provider. */\n\tusage?: { inputTokens?: number; outputTokens?: number };\n}\n\n/** An incremental streaming chunk. */\nexport type GenerateChunk =\n\t| { type: \"text\"; text: string }\n\t| { type: \"reasoning\"; text: string }\n\t| { type: \"tool-call\"; toolCall: ToolCall }\n\t| { type: \"done\"; response: GenerateResponse };\n\n/**\n * An LLM backend. Implementations adapt a concrete API (Copilot, OpenAI-compatible)\n * onto this uniform surface.\n */\nexport interface Provider {\n\t/** Stable provider identifier, e.g. `\"openai-compatible\"`. */\n\treadonly name: string;\n\t/** The default model's capability configuration. (FR-007a) */\n\treadonly capabilities: ModelCapabilities;\n\t/** All models this provider is configured with (one or more). */\n\treadonly models: ModelCapabilities[];\n\t/** Look up a configured model by name, or the default when omitted. */\n\tmodel(name?: string): ModelCapabilities;\n\t/** Generate a complete response. */\n\tgenerate(req: GenerateRequest): Promise<GenerateResponse>;\n\t/** Generate a streamed response. */\n\tgenerateStream(req: GenerateRequest): AsyncIterable<GenerateChunk>;\n}\n","/**\n * Exponential-backoff retry for transient provider failures. Transient errors\n * (429 with Retry-After, 5xx, network/timeout) are retried; auth/4xx fail fast.\n * (FR-008a)\n *\n * @packageDocumentation\n */\n\nimport { ProviderError } from \"../core/errors.js\";\n\n/** Retry tuning. All fields have safe defaults. */\nexport interface RetryOptions {\n\t/** Maximum retry attempts after the first try. Default 3. */\n\tmaxRetries?: number;\n\t/** Base delay in ms for backoff. Default 250. */\n\tbaseDelayMs?: number;\n\t/** Maximum delay cap in ms. Default 8000. */\n\tmaxDelayMs?: number;\n}\n\nconst DEFAULTS: Required<RetryOptions> = {\n\tmaxRetries: 3,\n\tbaseDelayMs: 250,\n\tmaxDelayMs: 8000,\n};\n\nfunction sleep(ms: number): Promise<void> {\n\treturn new Promise((r) => setTimeout(r, ms));\n}\n\n/**\n * Run `fn`, retrying transient {@link ProviderError}s with exponential backoff\n * and jitter. Non-transient errors are rethrown immediately (fail fast).\n *\n * @param fn - The operation to attempt. It should throw a {@link ProviderError}.\n * @param opts - Retry tuning.\n * @param retryAfterMs - Optional hook returning a server-specified delay (Retry-After).\n */\nexport async function withRetry<T>(\n\tfn: () => Promise<T>,\n\topts?: RetryOptions,\n\tretryAfterMs?: (err: ProviderError) => number | undefined,\n): Promise<T> {\n\tconst cfg = { ...DEFAULTS, ...opts };\n\tlet attempt = 0;\n\n\tfor (; ;) {\n\t\ttry {\n\t\t\treturn await fn();\n\t\t} catch (err) {\n\t\t\tconst isRetryable = err instanceof ProviderError && err.retryable;\n\t\t\tif (!isRetryable || attempt >= cfg.maxRetries) {\n\t\t\t\tthrow err;\n\t\t\t}\n\t\t\tconst serverDelay = retryAfterMs?.(err as ProviderError);\n\t\t\tconst backoff = Math.min(cfg.baseDelayMs * 2 ** attempt, cfg.maxDelayMs);\n\t\t\tconst jitter = Math.random() * cfg.baseDelayMs;\n\t\t\tawait sleep(serverDelay ?? backoff + jitter);\n\t\t\tattempt++;\n\t\t}\n\t}\n}\n\n/** Map an HTTP status to a {@link ProviderError} with the right retry semantics. */\nexport function providerErrorFromStatus(status: number, message: string): ProviderError {\n\tif (status === 429 || status >= 500) {\n\t\treturn new ProviderError(message, \"transient\", { status });\n\t}\n\tif (status === 401 || status === 403) {\n\t\treturn new ProviderError(message, \"auth\", { status });\n\t}\n\treturn new ProviderError(message, \"client\", { status });\n}\n","/**\n * OpenAI-compatible provider. Targets any endpoint speaking the OpenAI\n * `/chat/completions` API, including local servers such as LM Studio via a custom\n * `baseUrl`, and GitHub Copilot (see {@link createCopilotProvider}). (FR-006)\n *\n * Provider compatibility notes (handled here so callers don't have to):\n * - Tool names are sanitized to `^[a-zA-Z0-9_-]+$` on the wire (OpenAI/Copilot\n * reject dotted names like `webiq.browse`) and translated back to the registry\n * key when the model calls them.\n * - Assistant turns that requested tools emit `tool_calls` with `content: null`\n * so strict providers (e.g. Anthropic) can pair each tool result with its call.\n * - Streaming responses accumulate `delta.tool_calls[]` keyed by `index`\n * (fragments may start at a non-zero index when reasoning occupies 0/1).\n * - Some reasoning models report `finish_reason: \"tool_calls\"` from the\n * non-streaming endpoint without a `tool_calls` array; `generate` transparently\n * re-requests in streaming mode and assembles them, failing loud (typed\n * {@link ProviderError}) rather than silently stopping if none materialize.\n *\n * @packageDocumentation\n */\n\nimport type { Message, ContentPart, MessageToolCall } from \"../core/types.js\";\nimport { ProviderError } from \"../core/errors.js\";\nimport type {\n\tProvider,\n\tCredentialSource,\n\tGenerateRequest,\n\tGenerateResponse,\n\tGenerateChunk,\n\tToolCall,\n\tToolSpec,\n} from \"./provider.js\";\nimport { resolveModels, type ModelSelectionOptions } from \"./provider.js\";\nimport { withRetry, providerErrorFromStatus, type RetryOptions } from \"./retry.js\";\n\n/**\n * Options for {@link createOpenAICompatibleProvider}.\n *\n * Supply a single model via `capabilities`, or multiple via `models` (most\n * OpenAI-compatible endpoints expose one model, but multiple are supported).\n */\nexport interface OpenAICompatibleProviderOptions extends CredentialSource, ModelSelectionOptions {\n\t/** Base URL of the OpenAI-compatible API, e.g. `http://localhost:1234/v1`. */\n\tbaseUrl: string;\n\t/**\n\t * Extra request headers merged into every call (e.g. provider-required\n\t * identification headers). The `authorization` header is always set from\n\t * `getCredential()` and cannot be overridden here.\n\t */\n\theaders?: Record<string, string>;\n\t/** Retry tuning for transient failures. */\n\tretry?: RetryOptions;\n\t/** Optional custom fetch (for testing or non-standard runtimes). */\n\tfetchImpl?: typeof fetch;\n}\n\ninterface OpenAIMessage {\n\trole: string;\n\tcontent: unknown;\n\ttool_calls?: Array<{ id: string; type: \"function\"; function: { name: string; arguments: string } }>;\n\ttool_call_id?: string;\n\tname?: string;\n\treasoning_opaque?: string;\n}\n\n/** OpenAI/Copilot require tool names to match `^[a-zA-Z0-9_-]{1,128}$`. */\nconst UNSAFE_TOOL_NAME_CHARS = /[^a-zA-Z0-9_-]/g;\n\n/**\n * Sanitize a (possibly namespaced) tool name for the wire. Dotted MCP names like\n * `webiq.browse` become `webiq_browse`; the original is recovered via the\n * per-request name map when the model calls the tool.\n */\nfunction sanitizeToolName(name: string): string {\n\treturn name.replace(UNSAFE_TOOL_NAME_CHARS, \"_\");\n}\n\nfunction toOpenAIContent(parts: ContentPart[]): unknown {\n\tif (parts.every((p) => p.type === \"text\")) {\n\t\treturn parts.map((p) => (p as { text: string }).text).join(\"\");\n\t}\n\treturn parts.map((p) =>\n\t\tp.type === \"text\"\n\t\t\t? { type: \"text\", text: p.text }\n\t\t\t: { type: \"image_url\", image_url: { url: p.data } },\n\t);\n}\n\nfunction toWireToolCalls(\n\ttoolCalls: MessageToolCall[],\n): Array<{ id: string; type: \"function\"; function: { name: string; arguments: string } }> {\n\treturn toolCalls.map((tc) => ({\n\t\tid: tc.id,\n\t\ttype: \"function\",\n\t\tfunction: {\n\t\t\tname: sanitizeToolName(tc.name),\n\t\t\targuments:\n\t\t\t\ttypeof tc.arguments === \"string\" ? tc.arguments : JSON.stringify(tc.arguments ?? {}),\n\t\t},\n\t}));\n}\n\nfunction toOpenAIMessages(messages: Message[]): OpenAIMessage[] {\n\treturn messages.map((m) => {\n\t\tconst msg: OpenAIMessage = { role: m.role, content: toOpenAIContent(m.parts) };\n\t\tif (m.toolCalls && m.toolCalls.length > 0) {\n\t\t\tmsg.tool_calls = toWireToolCalls(m.toolCalls);\n\t\t\t// Strict providers require `content: null` (not \"\") on an assistant turn\n\t\t\t// that only carries tool calls.\n\t\t\tconst hasText = m.parts.some((p) => p.type === \"text\" && p.text.length > 0);\n\t\t\tif (!hasText) msg.content = null;\n\t\t}\n\t\tif (m.toolCallId) msg.tool_call_id = m.toolCallId;\n\t\tif (m.name) msg.name = sanitizeToolName(m.name);\n\t\tif (m.reasoningOpaque) msg.reasoning_opaque = m.reasoningOpaque;\n\t\treturn msg;\n\t});\n}\n\n/** Wire tool specs plus a map from sanitized name back to the registry key. */\ninterface WireTools {\n\ttools?: Array<{ type: \"function\"; function: { name: string; description: string; parameters: unknown } }>;\n\tnameMap: Map<string, string>;\n}\n\nfunction buildWireTools(specs?: ToolSpec[]): WireTools {\n\tconst nameMap = new Map<string, string>();\n\tif (!specs || specs.length === 0) return { tools: undefined, nameMap };\n\tconst tools = specs.map((t) => {\n\t\tconst wireName = sanitizeToolName(t.name);\n\t\tnameMap.set(wireName, t.name);\n\t\treturn {\n\t\t\ttype: \"function\" as const,\n\t\t\tfunction: { name: wireName, description: t.description, parameters: t.inputSchema },\n\t\t};\n\t});\n\treturn { tools, nameMap };\n}\n\n/**\n * Create an OpenAI-compatible provider (works with LM Studio, vLLM, etc.).\n *\n * @example\n * ```ts\n * const provider = createOpenAICompatibleProvider({\n * baseUrl: \"http://localhost:1234/v1\",\n * getCredential: () => process.env.LMSTUDIO_KEY ?? \"\",\n * capabilities: { model: \"local\", maxInputTokens: 262144, maxOutputTokens: 32000 },\n * });\n * ```\n */\nexport function createOpenAICompatibleProvider(\n\toptions: OpenAICompatibleProviderOptions,\n): Provider {\n\tconst doFetch = options.fetchImpl ?? globalThis.fetch;\n\tconst url = `${options.baseUrl.replace(/\\/$/, \"\")}/chat/completions`;\n\tconst { models, defaultModel, modelOf } = resolveModels(options);\n\n\tasync function authHeaders(): Promise<Record<string, string>> {\n\t\tconst cred = await options.getCredential();\n\t\t// content-type first, then caller headers (may override it), then the\n\t\t// credential-derived authorization which always wins.\n\t\tconst headers: Record<string, string> = {\n\t\t\t\"content-type\": \"application/json\",\n\t\t\t...(options.headers ?? {}),\n\t\t};\n\t\tif (cred) headers[\"authorization\"] = `Bearer ${cred}`;\n\t\treturn headers;\n\t}\n\n\tfunction body(req: GenerateRequest, stream: boolean, wire: WireTools): string {\n\t\treturn JSON.stringify({\n\t\t\tmodel: modelOf(req.model).model,\n\t\t\tmessages: toOpenAIMessages(req.messages),\n\t\t\tstream,\n\t\t\t...(wire.tools ? { tools: wire.tools } : {}),\n\t\t});\n\t}\n\n\tfunction parseToolCalls(raw: unknown, nameMap: Map<string, string>): ToolCall[] | undefined {\n\t\tconst calls = (raw as {\n\t\t\ttool_calls?: Array<{ id: string; function: { name: string; arguments: string } }>;\n\t\t})?.tool_calls;\n\t\tif (!calls || calls.length === 0) return undefined;\n\t\treturn calls.map((c) => ({\n\t\t\tid: c.id,\n\t\t\tname: nameMap.get(c.function.name) ?? c.function.name,\n\t\t\targuments: safeJson(c.function.arguments),\n\t\t}));\n\t}\n\n\tasync function generate(req: GenerateRequest): Promise<GenerateResponse> {\n\t\treturn withRetry(async () => {\n\t\t\tconst wire = buildWireTools(req.tools);\n\t\t\tlet res: Response;\n\t\t\ttry {\n\t\t\t\tres = await doFetch(url, {\n\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\theaders: await authHeaders(),\n\t\t\t\t\tbody: body(req, false, wire),\n\t\t\t\t\tsignal: req.signal,\n\t\t\t\t});\n\t\t\t} catch (e) {\n\t\t\t\tthrow new ProviderError(`Network error: ${(e as Error).message}`, \"transient\");\n\t\t\t}\n\t\t\tif (!res.ok) throw providerErrorFromStatus(res.status, `Provider returned ${res.status}`);\n\n\t\t\tlet json: Record<string, unknown>;\n\t\t\ttry {\n\t\t\t\tjson = (await res.json()) as Record<string, unknown>;\n\t\t\t} catch {\n\t\t\t\tthrow new ProviderError(\"Malformed provider response\", \"malformed\");\n\t\t\t}\n\t\t\tconst choice = (\n\t\t\t\tjson[\"choices\"] as Array<{ message: Record<string, unknown>; finish_reason?: string }>\n\t\t\t)?.[0];\n\t\t\tif (!choice) throw new ProviderError(\"Provider returned no choices\", \"malformed\");\n\t\t\tconst message = choice.message;\n\t\t\tconst reasoningModel = modelOf(req.model).supportsReasoning;\n\t\t\tlet toolCalls = parseToolCalls(message, wire.nameMap);\n\n\t\t\t// Bug 4(b): some reasoning models report `finish_reason: \"tool_calls\"` from\n\t\t\t// the non-streaming endpoint without a `tool_calls` array. Re-request in\n\t\t\t// streaming mode and assemble them so the agent loop can proceed.\n\t\t\tif ((!toolCalls || toolCalls.length === 0) && choice.finish_reason === \"tool_calls\") {\n\t\t\t\tconst assembled = await assembleViaStream(req);\n\t\t\t\ttoolCalls = assembled.toolCalls;\n\t\t\t\tif (!toolCalls || toolCalls.length === 0) {\n\t\t\t\t\tthrow new ProviderError(\n\t\t\t\t\t\t\"Provider signaled tool_calls but returned none (even when streamed)\",\n\t\t\t\t\t\t\"malformed\",\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\treturn {\n\t\t\t\t\ttext: (message[\"content\"] as string) ?? assembled.text ?? \"\",\n\t\t\t\t\treasoning: reasoningModel\n\t\t\t\t\t\t? ((message[\"reasoning\"] as string) ?? assembled.reasoning ?? undefined)\n\t\t\t\t\t\t: undefined,\n\t\t\t\t\treasoningOpaque: reasoningModel\n\t\t\t\t\t\t? ((message[\"reasoning_opaque\"] as string) ?? assembled.reasoningOpaque ?? undefined)\n\t\t\t\t\t\t: undefined,\n\t\t\t\t\ttoolCalls,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\ttext: (message[\"content\"] as string) ?? \"\",\n\t\t\t\treasoning: reasoningModel ? ((message[\"reasoning\"] as string) ?? undefined) : undefined,\n\t\t\t\treasoningOpaque: reasoningModel\n\t\t\t\t\t? ((message[\"reasoning_opaque\"] as string) ?? undefined)\n\t\t\t\t\t: undefined,\n\t\t\t\ttoolCalls,\n\t\t\t};\n\t\t}, options.retry);\n\t}\n\n\t/** Drive a streaming request to completion and return its assembled final response. */\n\tasync function assembleViaStream(req: GenerateRequest): Promise<GenerateResponse> {\n\t\tlet final: GenerateResponse = { text: \"\" };\n\t\tfor await (const chunk of generateStream(req)) {\n\t\t\tif (chunk.type === \"done\") final = chunk.response;\n\t\t}\n\t\treturn final;\n\t}\n\n\tasync function* generateStream(req: GenerateRequest): AsyncIterable<GenerateChunk> {\n\t\tconst wire = buildWireTools(req.tools);\n\t\tlet res: Response;\n\t\ttry {\n\t\t\tres = await doFetch(url, {\n\t\t\t\tmethod: \"POST\",\n\t\t\t\theaders: await authHeaders(),\n\t\t\t\tbody: body(req, true, wire),\n\t\t\t\tsignal: req.signal,\n\t\t\t});\n\t\t} catch (e) {\n\t\t\tthrow new ProviderError(`Network error: ${(e as Error).message}`, \"transient\");\n\t\t}\n\t\tif (!res.ok) throw providerErrorFromStatus(res.status, `Provider returned ${res.status}`);\n\t\tif (!res.body) throw new ProviderError(\"Provider returned no stream body\", \"malformed\");\n\n\t\tconst reasoningModel = modelOf(req.model).supportsReasoning;\n\t\tconst reader = res.body.getReader();\n\t\tconst decoder = new TextDecoder();\n\t\tlet buffer = \"\";\n\t\tlet text = \"\";\n\t\tlet reasoning = \"\";\n\t\tlet reasoningOpaque = \"\";\n\t\t// Accumulate streamed tool-call fragments keyed by their `index` (which may\n\t\t// start at a non-zero value when reasoning deltas occupy the first indices).\n\t\tconst toolAccum = new Map<number, { id?: string; name?: string; args: string }>();\n\n\t\tfor (; ;) {\n\t\t\tconst { value, done } = await reader.read();\n\t\t\tif (done) break;\n\t\t\tbuffer += decoder.decode(value, { stream: true });\n\t\t\tconst lines = buffer.split(\"\\n\");\n\t\t\tbuffer = lines.pop() ?? \"\";\n\t\t\tfor (const line of lines) {\n\t\t\t\tconst trimmed = line.trim();\n\t\t\t\tif (!trimmed.startsWith(\"data:\")) continue;\n\t\t\t\tconst data = trimmed.slice(5).trim();\n\t\t\t\tif (data === \"[DONE]\") continue;\n\t\t\t\tconst parsed = safeJson(data) as\n\t\t\t\t\t| {\n\t\t\t\t\t\tchoices?: Array<{\n\t\t\t\t\t\t\tdelta?: {\n\t\t\t\t\t\t\t\tcontent?: string;\n\t\t\t\t\t\t\t\treasoning?: string;\n\t\t\t\t\t\t\t\treasoning_opaque?: string;\n\t\t\t\t\t\t\t\ttool_calls?: Array<{\n\t\t\t\t\t\t\t\t\tindex?: number;\n\t\t\t\t\t\t\t\t\tid?: string;\n\t\t\t\t\t\t\t\t\tfunction?: { name?: string; arguments?: string };\n\t\t\t\t\t\t\t\t}>;\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t}>;\n\t\t\t\t\t}\n\t\t\t\t\t| undefined;\n\t\t\t\tconst delta = parsed?.choices?.[0]?.delta;\n\t\t\t\tif (!delta) continue;\n\t\t\t\tif (delta.content) {\n\t\t\t\t\ttext += delta.content;\n\t\t\t\t\tyield { type: \"text\", text: delta.content };\n\t\t\t\t}\n\t\t\t\tif (delta.reasoning && reasoningModel) {\n\t\t\t\t\treasoning += delta.reasoning;\n\t\t\t\t\tyield { type: \"reasoning\", text: delta.reasoning };\n\t\t\t\t}\n\t\t\t\tif (delta.reasoning_opaque && reasoningModel) {\n\t\t\t\t\treasoningOpaque += delta.reasoning_opaque;\n\t\t\t\t}\n\t\t\t\tif (delta.tool_calls) {\n\t\t\t\t\tfor (const frag of delta.tool_calls) {\n\t\t\t\t\t\tconst idx = frag.index ?? 0;\n\t\t\t\t\t\tconst slot = toolAccum.get(idx) ?? { args: \"\" };\n\t\t\t\t\t\tif (frag.id) slot.id = frag.id;\n\t\t\t\t\t\tif (frag.function?.name) slot.name = frag.function.name;\n\t\t\t\t\t\tif (frag.function?.arguments) slot.args += frag.function.arguments;\n\t\t\t\t\t\ttoolAccum.set(idx, slot);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Materialize accumulated tool calls (sorted by stream index) and surface\n\t\t// them both as chunks and in the final `done` response.\n\t\tconst toolCalls: ToolCall[] = [...toolAccum.entries()]\n\t\t\t.sort((a, b) => a[0] - b[0])\n\t\t\t.filter(([, s]) => s.name)\n\t\t\t.map(([idx, s]) => ({\n\t\t\t\tid: s.id ?? `call_${idx}`,\n\t\t\t\tname: wire.nameMap.get(s.name as string) ?? (s.name as string),\n\t\t\t\targuments: safeJson(s.args) ?? {},\n\t\t\t}));\n\t\tfor (const toolCall of toolCalls) {\n\t\t\tyield { type: \"tool-call\", toolCall };\n\t\t}\n\t\tyield {\n\t\t\ttype: \"done\",\n\t\t\tresponse: {\n\t\t\t\ttext,\n\t\t\t\treasoning: reasoning || undefined,\n\t\t\t\treasoningOpaque: reasoningOpaque || undefined,\n\t\t\t\ttoolCalls: toolCalls.length > 0 ? toolCalls : undefined,\n\t\t\t},\n\t\t};\n\t}\n\n\treturn {\n\t\tname: \"openai-compatible\",\n\t\tcapabilities: defaultModel,\n\t\tmodels,\n\t\tmodel: modelOf,\n\t\tgenerate,\n\t\tgenerateStream,\n\t};\n}\n\nfunction safeJson(s: string): unknown {\n\ttry {\n\t\treturn JSON.parse(s);\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n","/**\n * GitHub Copilot provider. (FR-005)\n *\n * Copilot's chat API is OpenAI-compatible, so this provider configures the shared\n * OpenAI-compatible transport with Copilot's endpoint and the caller-supplied\n * credential (a Copilot/GitHub token). The token is obtained via callback and is\n * never bundled, persisted, or logged. (FR-005a)\n *\n * In a frontend-only deployment the end user supplies their own token (it stays\n * client-side); in a backend deployment the developer may supply it, or the user\n * sends it per request over SSL/TLS and the backend must not log or persist it.\n *\n * Note: the Copilot API (`api.githubcopilot.com`) sends no CORS headers, so it\n * cannot be called directly from a browser. A browser deployment must route through\n * a backend/proxy (set `baseUrl` to it); constructing this provider in a browser\n * against the default host throws {@link RuntimeUnsupportedError}.\n *\n * @packageDocumentation\n */\n\nimport type { Provider, CredentialSource, ModelSelectionOptions } from \"./provider.js\";\nimport type { RetryOptions } from \"./retry.js\";\nimport { createOpenAICompatibleProvider } from \"./openai-compatible.js\";\nimport { detectRuntime } from \"../core/runtime.js\";\nimport { RuntimeUnsupportedError } from \"../core/errors.js\";\n\n/** Default Copilot-compatible chat completions base URL. */\nconst DEFAULT_COPILOT_BASE_URL = \"https://api.githubcopilot.com\";\n\n/**\n * Headers `api.githubcopilot.com` requires on every request. Omitting any of\n * these causes the API to reject the call with HTTP 400. They are sent by default\n * and can be overridden per option via `headers`.\n */\nconst COPILOT_DEFAULT_HEADERS: Record<string, string> = {\n\t\"Editor-Version\": \"vscode/1.95.0\",\n\t\"Editor-Plugin-Version\": \"copilot-chat/0.20.0\",\n\t\"Copilot-Integration-Id\": \"vscode-chat\",\n\t\"Openai-Intent\": \"conversation-panel\",\n};\n\n/**\n * Options for {@link createCopilotProvider}.\n *\n * GitHub Copilot exposes several models, so configure them via `models` (with an\n * optional `defaultModel`). A single `capabilities` object is also accepted.\n */\nexport interface CopilotProviderOptions extends CredentialSource, ModelSelectionOptions {\n\t/** Override the Copilot base URL if needed. */\n\tbaseUrl?: string;\n\t/**\n\t * Extra/override request headers. Merged over the required Copilot defaults\n\t * (`Editor-Version`, `Editor-Plugin-Version`, `Copilot-Integration-Id`,\n\t * `Openai-Intent`), so you can adjust them without losing the others.\n\t */\n\theaders?: Record<string, string>;\n\t/** Retry tuning for transient failures. */\n\tretry?: RetryOptions;\n\t/** Optional custom fetch (for testing or non-standard runtimes). */\n\tfetchImpl?: typeof fetch;\n}\n\n/**\n * Create a GitHub Copilot provider.\n *\n * @example Single model\n * ```ts\n * const provider = createCopilotProvider({\n * getCredential: () => myCopilotToken, // never logged or persisted\n * capabilities: { model: \"gpt-4o\", maxInputTokens: 128000, maxOutputTokens: 16000 },\n * });\n * ```\n *\n * @example Multiple models\n * ```ts\n * const provider = createCopilotProvider({\n * getCredential: () => myCopilotToken,\n * models: [\n * { model: \"gpt-4o\", maxInputTokens: 128000, maxOutputTokens: 16000, supportsVision: true },\n * { model: \"o3-mini\", maxInputTokens: 200000, maxOutputTokens: 100000, supportsReasoning: true },\n * ],\n * defaultModel: \"gpt-4o\",\n * });\n * // Pick a model per request: provider.generate({ messages, model: \"o3-mini\" })\n * ```\n *\n * @throws {RuntimeUnsupportedError} when constructed in a browser against the\n * default Copilot host. `api.githubcopilot.com` does not send CORS headers, so a\n * browser cannot call it directly — host a small backend/proxy and point `baseUrl`\n * at it (which lifts this guard), or run the provider server-side (Node/edge).\n */\nexport function createCopilotProvider(options: CopilotProviderOptions): Provider {\n\tconst baseUrl = options.baseUrl ?? DEFAULT_COPILOT_BASE_URL;\n\n\t// Frontend-only guard: the Copilot API has no CORS support, so a browser must\n\t// route through a backend/proxy. Setting a custom `baseUrl` (your proxy) is the\n\t// supported opt-in and lifts this guard. Edge/Node (server-side) are unaffected.\n\tconst usingDefaultHost = baseUrl === DEFAULT_COPILOT_BASE_URL;\n\tif (usingDefaultHost && detectRuntime().isBrowser) {\n\t\tthrow new RuntimeUnsupportedError(\n\t\t\t\"GitHub Copilot directly from a browser (the Copilot API sends no CORS headers)\",\n\t\t\t{\n\t\t\t\treason: \"cors\",\n\t\t\t\tremedy:\n\t\t\t\t\t\"Run a lightweight backend/proxy (e.g. a Vite dev-server proxy or a small server route) \" +\n\t\t\t\t\t\"that forwards to https://api.githubcopilot.com, then set `baseUrl` to your proxy URL. \" +\n\t\t\t\t\t\"Alternatively, run the Copilot provider server-side (Node or an edge function).\",\n\t\t\t},\n\t\t);\n\t}\n\n\tconst inner = createOpenAICompatibleProvider({\n\t\tbaseUrl,\n\t\tgetCredential: options.getCredential,\n\t\tcapabilities: options.capabilities,\n\t\tmodels: options.models,\n\t\tdefaultModel: options.defaultModel,\n\t\t// Copilot rejects calls missing its identification headers; defaults are\n\t\t// applied here and remain overridable via `options.headers`.\n\t\theaders: { ...COPILOT_DEFAULT_HEADERS, ...(options.headers ?? {}) },\n\t\tretry: options.retry,\n\t\tfetchImpl: options.fetchImpl,\n\t});\n\t// Preserve the provider contract but report the Copilot name.\n\treturn {\n\t\tname: \"copilot\",\n\t\tcapabilities: inner.capabilities,\n\t\tmodels: inner.models,\n\t\tmodel: inner.model.bind(inner),\n\t\tgenerate: inner.generate.bind(inner),\n\t\tgenerateStream: inner.generateStream.bind(inner),\n\t};\n}\n"]}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
4
|
-
require('../chunk-
|
|
3
|
+
var chunk2WBJEXNY_cjs = require('../chunk-2WBJEXNY.cjs');
|
|
4
|
+
require('../chunk-FDCTSJMB.cjs');
|
|
5
5
|
require('../chunk-WSMYH2IN.cjs');
|
|
6
6
|
require('../chunk-TAMJ5HSR.cjs');
|
|
7
7
|
require('../chunk-FSDMBWQV.cjs');
|
|
8
|
-
require('../chunk-
|
|
8
|
+
require('../chunk-I55OVD23.cjs');
|
|
9
9
|
require('../chunk-MQ2XTH3S.cjs');
|
|
10
10
|
require('../chunk-IJASUMIQ.cjs');
|
|
11
11
|
|
|
@@ -13,7 +13,7 @@ require('../chunk-IJASUMIQ.cjs');
|
|
|
13
13
|
|
|
14
14
|
Object.defineProperty(exports, "loadAgentDefinition", {
|
|
15
15
|
enumerable: true,
|
|
16
|
-
get: function () { return
|
|
16
|
+
get: function () { return chunk2WBJEXNY_cjs.loadAgentDefinition; }
|
|
17
17
|
});
|
|
18
18
|
//# sourceMappingURL=index.cjs.map
|
|
19
19
|
//# sourceMappingURL=index.cjs.map
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { P as Provider } from '../provider-
|
|
3
|
-
import { T as Tool } from '../tool-
|
|
1
|
+
import { b as ModelCapabilities } from '../types-AlvjoTyS.cjs';
|
|
2
|
+
import { P as Provider } from '../provider-B807EuDV.cjs';
|
|
3
|
+
import { T as Tool } from '../tool-D9Uodu9Y.cjs';
|
|
4
4
|
import { S as Skill } from '../skill-DfNChtJN.cjs';
|
|
5
|
-
import { A as Agent } from '../index-
|
|
5
|
+
import { A as Agent } from '../index-b1oTo3Lv.cjs';
|
|
6
6
|
import '../errors-CjVz4W_5.cjs';
|
|
7
|
-
import '../thread-
|
|
8
|
-
import '../registry-
|
|
7
|
+
import '../thread-BzwE1OnJ.cjs';
|
|
8
|
+
import '../registry-BCkSIe0E.cjs';
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* Declarative agent definitions. Agents can be defined in YAML or JSON against a
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { P as Provider } from '../provider-
|
|
3
|
-
import { T as Tool } from '../tool-
|
|
1
|
+
import { b as ModelCapabilities } from '../types-AlvjoTyS.js';
|
|
2
|
+
import { P as Provider } from '../provider-CvU3I-Xo.js';
|
|
3
|
+
import { T as Tool } from '../tool-LPMc4QQd.js';
|
|
4
4
|
import { S as Skill } from '../skill-DfNChtJN.js';
|
|
5
|
-
import { A as Agent } from '../index-
|
|
5
|
+
import { A as Agent } from '../index-C22fqyZQ.js';
|
|
6
6
|
import '../errors-CjVz4W_5.js';
|
|
7
|
-
import '../thread-
|
|
8
|
-
import '../registry-
|
|
7
|
+
import '../thread-COljUAtD.js';
|
|
8
|
+
import '../registry-D-CmT0gk.js';
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* Declarative agent definitions. Agents can be defined in YAML or JSON against a
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
export { loadAgentDefinition } from '../chunk-
|
|
2
|
-
import '../chunk-
|
|
1
|
+
export { loadAgentDefinition } from '../chunk-55NB43FN.js';
|
|
2
|
+
import '../chunk-KOPGBIES.js';
|
|
3
3
|
import '../chunk-YCBDEEAV.js';
|
|
4
4
|
import '../chunk-HGEPXJDG.js';
|
|
5
5
|
import '../chunk-7ZXUIHLH.js';
|
|
6
|
-
import '../chunk-
|
|
6
|
+
import '../chunk-LC54DGGR.js';
|
|
7
7
|
import '../chunk-IXV4UIF5.js';
|
|
8
8
|
import '../chunk-DEABART4.js';
|
|
9
9
|
//# sourceMappingURL=index.js.map
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { M as Message } from './types-
|
|
1
|
+
import { M as Message } from './types-AlvjoTyS.js';
|
|
2
2
|
import { P as ProviderError } from './errors-CjVz4W_5.js';
|
|
3
|
-
import { a as GenerateRequest, b as GenerateResponse, P as Provider } from './provider-
|
|
4
|
-
import { T as Tool } from './tool-
|
|
3
|
+
import { a as GenerateRequest, b as GenerateResponse, P as Provider } from './provider-CvU3I-Xo.js';
|
|
4
|
+
import { T as Tool } from './tool-LPMc4QQd.js';
|
|
5
5
|
import { S as Skill } from './skill-DfNChtJN.js';
|
|
6
|
-
import { T as Thread } from './thread-
|
|
7
|
-
import { T as ToolRegistry } from './registry-
|
|
6
|
+
import { T as Thread } from './thread-COljUAtD.js';
|
|
7
|
+
import { T as ToolRegistry } from './registry-D-CmT0gk.js';
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* Middleware pipeline for intercepting and processing agent provider calls —
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { M as Message } from './types-
|
|
1
|
+
import { M as Message } from './types-AlvjoTyS.cjs';
|
|
2
2
|
import { P as ProviderError } from './errors-CjVz4W_5.cjs';
|
|
3
|
-
import { a as GenerateRequest, b as GenerateResponse, P as Provider } from './provider-
|
|
4
|
-
import { T as Tool } from './tool-
|
|
3
|
+
import { a as GenerateRequest, b as GenerateResponse, P as Provider } from './provider-B807EuDV.cjs';
|
|
4
|
+
import { T as Tool } from './tool-D9Uodu9Y.cjs';
|
|
5
5
|
import { S as Skill } from './skill-DfNChtJN.cjs';
|
|
6
|
-
import { T as Thread } from './thread-
|
|
7
|
-
import { T as ToolRegistry } from './registry-
|
|
6
|
+
import { T as Thread } from './thread-BzwE1OnJ.cjs';
|
|
7
|
+
import { T as ToolRegistry } from './registry-BCkSIe0E.cjs';
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* Middleware pipeline for intercepting and processing agent provider calls —
|