@bolt-foundry/gambit 0.5.5 → 0.6.2
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 +26 -2
- package/README.md +4 -4
- package/bin/gambit.cjs +214 -0
- package/esm/mod.d.ts +22 -22
- package/esm/mod.d.ts.map +1 -1
- package/esm/mod.js +7 -7
- package/esm/src/server.d.ts +1 -1
- package/esm/src/server.d.ts.map +1 -1
- package/esm/src/server.js +2 -2
- package/esm/src/trace.d.ts +1 -1
- package/esm/src/trace.d.ts.map +1 -1
- package/package.json +5 -4
- package/script/mod.d.ts +22 -22
- package/script/mod.d.ts.map +1 -1
- package/script/mod.js +14 -14
- package/script/src/server.d.ts +1 -1
- package/script/src/server.d.ts.map +1 -1
- package/script/src/server.js +12 -12
- package/script/src/trace.d.ts +1 -1
- package/script/src/trace.d.ts.map +1 -1
- package/esm/packages/gambit-core/mod.d.ts +0 -50
- package/esm/packages/gambit-core/mod.d.ts.map +0 -1
- package/esm/packages/gambit-core/mod.js +0 -19
- package/esm/packages/gambit-core/src/definitions.d.ts +0 -11
- package/esm/packages/gambit-core/src/definitions.d.ts.map +0 -1
- package/esm/packages/gambit-core/src/definitions.js +0 -14
- package/esm/packages/gambit-core/src/openai_compat.d.ts +0 -63
- package/esm/packages/gambit-core/src/openai_compat.d.ts.map +0 -1
- package/esm/packages/gambit-core/src/openai_compat.js +0 -272
- package/esm/packages/gambit-core/src/providers/openrouter.d.ts +0 -8
- package/esm/packages/gambit-core/src/providers/openrouter.d.ts.map +0 -1
- package/esm/packages/gambit-core/src/providers/openrouter.js +0 -168
- package/esm/packages/gambit-core/src/render.d.ts +0 -51
- package/esm/packages/gambit-core/src/render.d.ts.map +0 -1
- package/esm/packages/gambit-core/src/render.js +0 -188
- package/esm/packages/gambit-core/src/schema.d.ts +0 -8
- package/esm/packages/gambit-core/src/schema.d.ts.map +0 -1
- package/esm/packages/gambit-core/src/schema.js +0 -45
- package/script/packages/gambit-core/mod.d.ts +0 -50
- package/script/packages/gambit-core/mod.d.ts.map +0 -1
- package/script/packages/gambit-core/mod.js +0 -29
- package/script/packages/gambit-core/src/definitions.d.ts +0 -11
- package/script/packages/gambit-core/src/definitions.d.ts.map +0 -1
- package/script/packages/gambit-core/src/definitions.js +0 -20
- package/script/packages/gambit-core/src/openai_compat.d.ts +0 -63
- package/script/packages/gambit-core/src/openai_compat.d.ts.map +0 -1
- package/script/packages/gambit-core/src/openai_compat.js +0 -276
- package/script/packages/gambit-core/src/providers/openrouter.d.ts +0 -8
- package/script/packages/gambit-core/src/providers/openrouter.d.ts.map +0 -1
- package/script/packages/gambit-core/src/providers/openrouter.js +0 -207
- package/script/packages/gambit-core/src/render.d.ts +0 -51
- package/script/packages/gambit-core/src/render.d.ts.map +0 -1
- package/script/packages/gambit-core/src/render.js +0 -192
- package/script/packages/gambit-core/src/schema.d.ts +0 -8
- package/script/packages/gambit-core/src/schema.d.ts.map +0 -1
- package/script/packages/gambit-core/src/schema.js +0 -51
|
@@ -1,276 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.logger = void 0;
|
|
4
|
-
exports.chatCompletionsWithDeck = chatCompletionsWithDeck;
|
|
5
|
-
const constants_1 = require("@bolt-foundry/gambit-core/internal/constants");
|
|
6
|
-
const loader_1 = require("@bolt-foundry/gambit-core/internal/loader");
|
|
7
|
-
const schema_js_1 = require("./schema.js");
|
|
8
|
-
const runtime_1 = require("@bolt-foundry/gambit-core/internal/runtime");
|
|
9
|
-
exports.logger = console;
|
|
10
|
-
function randomId(prefix) {
|
|
11
|
-
const suffix = crypto.randomUUID().replace(/-/g, "").slice(0, 24);
|
|
12
|
-
return `${prefix}-${suffix}`;
|
|
13
|
-
}
|
|
14
|
-
function normalizeContent(content) {
|
|
15
|
-
if (content === null)
|
|
16
|
-
return null;
|
|
17
|
-
if (typeof content === "string")
|
|
18
|
-
return content;
|
|
19
|
-
if (!Array.isArray(content))
|
|
20
|
-
return String(content);
|
|
21
|
-
return content
|
|
22
|
-
.map((c) => (typeof c === "string" ? c : (c.text ?? "")))
|
|
23
|
-
.join("");
|
|
24
|
-
}
|
|
25
|
-
function normalizeMessages(input) {
|
|
26
|
-
return input.map((m) => ({
|
|
27
|
-
role: m.role,
|
|
28
|
-
content: normalizeContent(m.content),
|
|
29
|
-
name: m.name,
|
|
30
|
-
tool_call_id: m.tool_call_id,
|
|
31
|
-
tool_calls: m.tool_calls && m.tool_calls.length > 0
|
|
32
|
-
? m.tool_calls
|
|
33
|
-
: undefined,
|
|
34
|
-
}));
|
|
35
|
-
}
|
|
36
|
-
function providerParamsFromRequest(req) {
|
|
37
|
-
const out = {};
|
|
38
|
-
if (req.temperature !== undefined)
|
|
39
|
-
out.temperature = req.temperature;
|
|
40
|
-
if (req.top_p !== undefined)
|
|
41
|
-
out.top_p = req.top_p;
|
|
42
|
-
if (req.frequency_penalty !== undefined) {
|
|
43
|
-
out.frequency_penalty = req.frequency_penalty;
|
|
44
|
-
}
|
|
45
|
-
if (req.presence_penalty !== undefined) {
|
|
46
|
-
out.presence_penalty = req.presence_penalty;
|
|
47
|
-
}
|
|
48
|
-
if (req.max_tokens !== undefined)
|
|
49
|
-
out.max_tokens = req.max_tokens;
|
|
50
|
-
return Object.keys(out).length ? out : undefined;
|
|
51
|
-
}
|
|
52
|
-
function mergeToolDefs(gambitTools, externalTools) {
|
|
53
|
-
if (!externalTools?.length)
|
|
54
|
-
return gambitTools;
|
|
55
|
-
return [...gambitTools, ...externalTools];
|
|
56
|
-
}
|
|
57
|
-
function toolName(tool) {
|
|
58
|
-
return tool.function?.name ?? "";
|
|
59
|
-
}
|
|
60
|
-
function assertNoToolNameCollisions(args) {
|
|
61
|
-
if (!args.externalTools?.length)
|
|
62
|
-
return;
|
|
63
|
-
const gambit = new Set(args.gambitTools.map(toolName));
|
|
64
|
-
for (const t of args.externalTools) {
|
|
65
|
-
const name = toolName(t);
|
|
66
|
-
if (!name)
|
|
67
|
-
continue;
|
|
68
|
-
if (name.startsWith(constants_1.RESERVED_TOOL_PREFIX)) {
|
|
69
|
-
throw new Error(`External tool name ${name} is reserved (prefix ${constants_1.RESERVED_TOOL_PREFIX})`);
|
|
70
|
-
}
|
|
71
|
-
if (gambit.has(name)) {
|
|
72
|
-
throw new Error(`Tool name collision for ${name} between Gambit deck actions and external tools`);
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
async function buildGambitActionTools(deck) {
|
|
77
|
-
const tools = [];
|
|
78
|
-
const toolNameSet = new Set();
|
|
79
|
-
const actionPathByName = new Map();
|
|
80
|
-
for (const action of deck.actionDecks) {
|
|
81
|
-
const child = await (0, loader_1.loadDeck)(action.path, deck.path);
|
|
82
|
-
if (!child.inputSchema || !child.outputSchema) {
|
|
83
|
-
throw new Error(`Deck ${child.path} must declare inputSchema and outputSchema (non-root)`);
|
|
84
|
-
}
|
|
85
|
-
(0, schema_js_1.assertZodSchema)(child.inputSchema, "inputSchema");
|
|
86
|
-
(0, schema_js_1.assertZodSchema)(child.outputSchema, "outputSchema");
|
|
87
|
-
const params = (0, schema_js_1.toJsonSchema)(child.inputSchema);
|
|
88
|
-
tools.push({
|
|
89
|
-
type: "function",
|
|
90
|
-
function: {
|
|
91
|
-
name: action.name,
|
|
92
|
-
description: action.description,
|
|
93
|
-
parameters: params,
|
|
94
|
-
},
|
|
95
|
-
});
|
|
96
|
-
toolNameSet.add(action.name);
|
|
97
|
-
actionPathByName.set(action.name, action.path);
|
|
98
|
-
}
|
|
99
|
-
return { tools, toolNameSet, actionPathByName };
|
|
100
|
-
}
|
|
101
|
-
function deckSystemPrompt(deck) {
|
|
102
|
-
const parts = [];
|
|
103
|
-
const prompt = deck.body ?? deck.prompt;
|
|
104
|
-
if (prompt)
|
|
105
|
-
parts.push(prompt.trim());
|
|
106
|
-
for (const card of deck.cards) {
|
|
107
|
-
if (card.body)
|
|
108
|
-
parts.push(card.body.trim());
|
|
109
|
-
}
|
|
110
|
-
return parts.join("\n\n").trim();
|
|
111
|
-
}
|
|
112
|
-
function shouldPrependDeckSystem(messages, systemPrompt) {
|
|
113
|
-
if (!systemPrompt)
|
|
114
|
-
return false;
|
|
115
|
-
if (!messages.length)
|
|
116
|
-
return true;
|
|
117
|
-
const hasExact = messages.some((m) => m.role === "system" && m.content === systemPrompt);
|
|
118
|
-
return !hasExact;
|
|
119
|
-
}
|
|
120
|
-
function warnIfSystemMismatch(args) {
|
|
121
|
-
if (!args.systemPrompt)
|
|
122
|
-
return;
|
|
123
|
-
const existing = args.provided.find((m) => m.role === "system");
|
|
124
|
-
if (!existing)
|
|
125
|
-
return;
|
|
126
|
-
if (existing.content === args.systemPrompt)
|
|
127
|
-
return;
|
|
128
|
-
exports.logger.warn(`[gambit] chatCompletionsWithDeck: request includes a system message that does not match the deck prompt (${args.deckPath})`);
|
|
129
|
-
}
|
|
130
|
-
function toolResultContent(result) {
|
|
131
|
-
if (typeof result === "string")
|
|
132
|
-
return result;
|
|
133
|
-
try {
|
|
134
|
-
return JSON.stringify(result);
|
|
135
|
-
}
|
|
136
|
-
catch {
|
|
137
|
-
return String(result);
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
function normalizeError(err) {
|
|
141
|
-
return { message: err instanceof Error ? err.message : String(err) };
|
|
142
|
-
}
|
|
143
|
-
async function chatCompletionsWithDeck(args) {
|
|
144
|
-
const executeDeckTools = args.executeDeckTools ?? true;
|
|
145
|
-
const guardrails = { ...constants_1.DEFAULT_GUARDRAILS, ...args.guardrails };
|
|
146
|
-
const runId = randomId("run");
|
|
147
|
-
const deck = await (0, loader_1.loadDeck)(args.deckPath);
|
|
148
|
-
const systemPrompt = deckSystemPrompt(deck);
|
|
149
|
-
const providedMessages = normalizeMessages(args.request.messages);
|
|
150
|
-
const messages = [];
|
|
151
|
-
warnIfSystemMismatch({
|
|
152
|
-
provided: providedMessages,
|
|
153
|
-
systemPrompt,
|
|
154
|
-
deckPath: deck.path,
|
|
155
|
-
});
|
|
156
|
-
if (shouldPrependDeckSystem(providedMessages, systemPrompt)) {
|
|
157
|
-
messages.push({ role: "system", content: systemPrompt });
|
|
158
|
-
}
|
|
159
|
-
messages.push(...providedMessages);
|
|
160
|
-
const gambit = await buildGambitActionTools(deck);
|
|
161
|
-
assertNoToolNameCollisions({
|
|
162
|
-
gambitTools: gambit.tools,
|
|
163
|
-
externalTools: args.request.tools,
|
|
164
|
-
});
|
|
165
|
-
const tools = mergeToolDefs(gambit.tools, args.request.tools);
|
|
166
|
-
const start = performance.now();
|
|
167
|
-
let passes = 0;
|
|
168
|
-
while (passes < guardrails.maxPasses) {
|
|
169
|
-
passes++;
|
|
170
|
-
if (performance.now() - start > guardrails.timeoutMs) {
|
|
171
|
-
throw new Error("Timeout exceeded");
|
|
172
|
-
}
|
|
173
|
-
const model = args.request.model ?? args.defaultModel ??
|
|
174
|
-
(() => {
|
|
175
|
-
throw new Error("No model provided");
|
|
176
|
-
})();
|
|
177
|
-
const result = await args.modelProvider.chat({
|
|
178
|
-
model,
|
|
179
|
-
messages,
|
|
180
|
-
tools: tools.length ? tools : undefined,
|
|
181
|
-
stream: Boolean(args.request.stream),
|
|
182
|
-
onStreamText: args.onStreamText,
|
|
183
|
-
params: providerParamsFromRequest(args.request),
|
|
184
|
-
});
|
|
185
|
-
messages.push(result.message);
|
|
186
|
-
if (result.toolCalls && result.toolCalls.length > 0) {
|
|
187
|
-
const gambitCalls = result.toolCalls.filter((c) => gambit.toolNameSet.has(c.name));
|
|
188
|
-
const externalCalls = result.toolCalls.filter((c) => !gambit.toolNameSet.has(c.name));
|
|
189
|
-
if (!executeDeckTools || externalCalls.length > 0) {
|
|
190
|
-
return {
|
|
191
|
-
id: randomId("chatcmpl"),
|
|
192
|
-
object: "chat.completion",
|
|
193
|
-
created: Math.floor(Date.now() / 1000),
|
|
194
|
-
model,
|
|
195
|
-
choices: [{
|
|
196
|
-
index: 0,
|
|
197
|
-
message: result.message,
|
|
198
|
-
finish_reason: "tool_calls",
|
|
199
|
-
logprobs: null,
|
|
200
|
-
}],
|
|
201
|
-
usage: result.usage
|
|
202
|
-
? {
|
|
203
|
-
prompt_tokens: result.usage.promptTokens,
|
|
204
|
-
completion_tokens: result.usage.completionTokens,
|
|
205
|
-
total_tokens: result.usage.totalTokens,
|
|
206
|
-
}
|
|
207
|
-
: undefined,
|
|
208
|
-
gambit: { deckPath: deck.path, messages, runId },
|
|
209
|
-
};
|
|
210
|
-
}
|
|
211
|
-
// Execute only deck-defined tool calls.
|
|
212
|
-
for (const call of gambitCalls) {
|
|
213
|
-
const actionPath = gambit.actionPathByName.get(call.name);
|
|
214
|
-
if (!actionPath)
|
|
215
|
-
continue;
|
|
216
|
-
try {
|
|
217
|
-
const childResult = await (0, runtime_1.runDeck)({
|
|
218
|
-
path: actionPath,
|
|
219
|
-
input: call.args,
|
|
220
|
-
modelProvider: args.modelProvider,
|
|
221
|
-
isRoot: false,
|
|
222
|
-
guardrails,
|
|
223
|
-
depth: 1,
|
|
224
|
-
parentActionCallId: call.id,
|
|
225
|
-
runId,
|
|
226
|
-
defaultModel: model,
|
|
227
|
-
modelOverride: undefined,
|
|
228
|
-
trace: undefined,
|
|
229
|
-
stream: Boolean(args.request.stream),
|
|
230
|
-
onStreamText: args.onStreamText,
|
|
231
|
-
inputProvided: true,
|
|
232
|
-
});
|
|
233
|
-
messages.push({
|
|
234
|
-
role: "tool",
|
|
235
|
-
name: call.name,
|
|
236
|
-
tool_call_id: call.id,
|
|
237
|
-
content: toolResultContent(childResult),
|
|
238
|
-
});
|
|
239
|
-
}
|
|
240
|
-
catch (err) {
|
|
241
|
-
messages.push({
|
|
242
|
-
role: "tool",
|
|
243
|
-
name: call.name,
|
|
244
|
-
tool_call_id: call.id,
|
|
245
|
-
content: JSON.stringify({ error: normalizeError(err) }),
|
|
246
|
-
});
|
|
247
|
-
}
|
|
248
|
-
}
|
|
249
|
-
continue;
|
|
250
|
-
}
|
|
251
|
-
if (result.finishReason === "tool_calls") {
|
|
252
|
-
throw new Error("Model requested tool_calls but provided none");
|
|
253
|
-
}
|
|
254
|
-
return {
|
|
255
|
-
id: randomId("chatcmpl"),
|
|
256
|
-
object: "chat.completion",
|
|
257
|
-
created: Math.floor(Date.now() / 1000),
|
|
258
|
-
model,
|
|
259
|
-
choices: [{
|
|
260
|
-
index: 0,
|
|
261
|
-
message: result.message,
|
|
262
|
-
finish_reason: result.finishReason,
|
|
263
|
-
logprobs: null,
|
|
264
|
-
}],
|
|
265
|
-
usage: result.usage
|
|
266
|
-
? {
|
|
267
|
-
prompt_tokens: result.usage.promptTokens,
|
|
268
|
-
completion_tokens: result.usage.completionTokens,
|
|
269
|
-
total_tokens: result.usage.totalTokens,
|
|
270
|
-
}
|
|
271
|
-
: undefined,
|
|
272
|
-
gambit: { deckPath: deck.path, messages, runId },
|
|
273
|
-
};
|
|
274
|
-
}
|
|
275
|
-
throw new Error("Max passes exceeded without completing");
|
|
276
|
-
}
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import type { ModelProvider } from "@bolt-foundry/gambit-core/internal/types";
|
|
2
|
-
export declare function createOpenRouterProvider(opts: {
|
|
3
|
-
apiKey: string;
|
|
4
|
-
baseURL?: string;
|
|
5
|
-
referer?: string;
|
|
6
|
-
title?: string;
|
|
7
|
-
}): ModelProvider;
|
|
8
|
-
//# sourceMappingURL=openrouter.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"openrouter.d.ts","sourceRoot":"","sources":["../../../../../src/packages/gambit-core/src/providers/openrouter.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAGV,aAAa,EAEd,MAAM,0CAA0C,CAAC;AAwBlD,wBAAgB,wBAAwB,CAAC,IAAI,EAAE;IAC7C,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,GAAG,aAAa,CAqLhB"}
|
|
@@ -1,207 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
-
var ownKeys = function(o) {
|
|
20
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
-
var ar = [];
|
|
22
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
-
return ar;
|
|
24
|
-
};
|
|
25
|
-
return ownKeys(o);
|
|
26
|
-
};
|
|
27
|
-
return function (mod) {
|
|
28
|
-
if (mod && mod.__esModule) return mod;
|
|
29
|
-
var result = {};
|
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
-
__setModuleDefault(result, mod);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
|
-
})();
|
|
35
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
-
};
|
|
38
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
-
exports.createOpenRouterProvider = createOpenRouterProvider;
|
|
40
|
-
const dntShim = __importStar(require("../../../../_dnt.shims.js"));
|
|
41
|
-
const openai_1 = __importDefault(require("openai"));
|
|
42
|
-
const logger = console;
|
|
43
|
-
function normalizeMessage(content) {
|
|
44
|
-
const toolCalls = content.tool_calls ??
|
|
45
|
-
undefined;
|
|
46
|
-
return {
|
|
47
|
-
role: content.role,
|
|
48
|
-
content: typeof content.content === "string"
|
|
49
|
-
? content.content
|
|
50
|
-
: Array.isArray(content.content)
|
|
51
|
-
? content.content
|
|
52
|
-
.map((c) => (typeof c === "string" ? c : ""))
|
|
53
|
-
.join("")
|
|
54
|
-
: "",
|
|
55
|
-
name: content.name,
|
|
56
|
-
tool_call_id: content.tool_call_id,
|
|
57
|
-
tool_calls: toolCalls && toolCalls.length > 0 ? toolCalls : undefined,
|
|
58
|
-
};
|
|
59
|
-
}
|
|
60
|
-
function createOpenRouterProvider(opts) {
|
|
61
|
-
const debugStream = dntShim.Deno.env.get("GAMBIT_DEBUG_STREAM") === "1";
|
|
62
|
-
const client = new openai_1.default({
|
|
63
|
-
apiKey: opts.apiKey,
|
|
64
|
-
baseURL: opts.baseURL ?? "https://openrouter.ai/api/v1",
|
|
65
|
-
defaultHeaders: {
|
|
66
|
-
"HTTP-Referer": opts.referer ?? "https://gambit.local",
|
|
67
|
-
"X-Title": opts.title ?? "Gambit CLI",
|
|
68
|
-
},
|
|
69
|
-
});
|
|
70
|
-
return {
|
|
71
|
-
async chat(input) {
|
|
72
|
-
const params = input.params ?? {};
|
|
73
|
-
if (input.stream) {
|
|
74
|
-
if (debugStream) {
|
|
75
|
-
logger.log(`[stream-debug] requesting stream model=${input.model} messages=${input.messages.length} tools=${input.tools?.length ?? 0}`);
|
|
76
|
-
}
|
|
77
|
-
const stream = await client.chat.completions.create({
|
|
78
|
-
model: input.model,
|
|
79
|
-
messages: input
|
|
80
|
-
.messages,
|
|
81
|
-
tools: input
|
|
82
|
-
.tools,
|
|
83
|
-
tool_choice: "auto",
|
|
84
|
-
stream: true,
|
|
85
|
-
...params,
|
|
86
|
-
});
|
|
87
|
-
let finishReason = null;
|
|
88
|
-
const contentParts = [];
|
|
89
|
-
const toolCallMap = new Map();
|
|
90
|
-
let chunkCount = 0;
|
|
91
|
-
let streamedChars = 0;
|
|
92
|
-
for await (const chunk of stream) {
|
|
93
|
-
chunkCount++;
|
|
94
|
-
const choice = chunk.choices[0];
|
|
95
|
-
const fr = choice.finish_reason;
|
|
96
|
-
if (fr === "stop" || fr === "tool_calls" || fr === "length" ||
|
|
97
|
-
fr === null) {
|
|
98
|
-
finishReason = fr ?? finishReason;
|
|
99
|
-
}
|
|
100
|
-
const delta = choice.delta;
|
|
101
|
-
if (typeof delta.content === "string") {
|
|
102
|
-
contentParts.push(delta.content);
|
|
103
|
-
input.onStreamText?.(delta.content);
|
|
104
|
-
streamedChars += delta.content.length;
|
|
105
|
-
}
|
|
106
|
-
else if (Array.isArray(delta.content)) {
|
|
107
|
-
const chunkStr = delta.content
|
|
108
|
-
.map((c) => (typeof c === "string" ? c : ""))
|
|
109
|
-
.join("");
|
|
110
|
-
if (chunkStr) {
|
|
111
|
-
contentParts.push(chunkStr);
|
|
112
|
-
input.onStreamText?.(chunkStr);
|
|
113
|
-
streamedChars += chunkStr.length;
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
for (const tc of delta.tool_calls ?? []) {
|
|
117
|
-
const idx = tc.index ?? 0;
|
|
118
|
-
const existing = toolCallMap.get(idx) ??
|
|
119
|
-
{
|
|
120
|
-
id: tc.id,
|
|
121
|
-
function: { name: tc.function?.name, arguments: "" },
|
|
122
|
-
};
|
|
123
|
-
if (tc.id)
|
|
124
|
-
existing.id = tc.id;
|
|
125
|
-
if (tc.function?.name)
|
|
126
|
-
existing.function.name = tc.function.name;
|
|
127
|
-
if (tc.function?.arguments) {
|
|
128
|
-
existing.function.arguments += tc.function.arguments;
|
|
129
|
-
}
|
|
130
|
-
toolCallMap.set(idx, existing);
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
if (debugStream) {
|
|
134
|
-
logger.log(`[stream-debug] completed stream chunks=${chunkCount} streamedChars=${streamedChars} finishReason=${finishReason}`);
|
|
135
|
-
}
|
|
136
|
-
const tool_calls = Array.from(toolCallMap.values()).map((tc) => ({
|
|
137
|
-
id: tc.id ?? crypto.randomUUID().replace(/-/g, "").slice(0, 24),
|
|
138
|
-
type: "function",
|
|
139
|
-
function: {
|
|
140
|
-
name: tc.function.name ?? "",
|
|
141
|
-
arguments: tc.function.arguments,
|
|
142
|
-
},
|
|
143
|
-
}));
|
|
144
|
-
const message = normalizeMessage({
|
|
145
|
-
role: "assistant",
|
|
146
|
-
content: contentParts.length ? contentParts.join("") : null,
|
|
147
|
-
tool_calls,
|
|
148
|
-
});
|
|
149
|
-
const toolCalls = tool_calls.length > 0
|
|
150
|
-
? tool_calls.map((tc) => ({
|
|
151
|
-
id: tc.id,
|
|
152
|
-
name: tc.function.name,
|
|
153
|
-
args: safeJson(tc.function.arguments),
|
|
154
|
-
}))
|
|
155
|
-
: undefined;
|
|
156
|
-
return {
|
|
157
|
-
message,
|
|
158
|
-
finishReason: finishReason ?? "stop",
|
|
159
|
-
toolCalls,
|
|
160
|
-
};
|
|
161
|
-
}
|
|
162
|
-
const response = await client.chat.completions.create({
|
|
163
|
-
model: input.model,
|
|
164
|
-
messages: input
|
|
165
|
-
.messages,
|
|
166
|
-
tools: input
|
|
167
|
-
.tools,
|
|
168
|
-
tool_choice: "auto",
|
|
169
|
-
stream: false,
|
|
170
|
-
...params,
|
|
171
|
-
});
|
|
172
|
-
const choice = response.choices[0];
|
|
173
|
-
const message = choice.message;
|
|
174
|
-
const normalizedMessage = normalizeMessage(message);
|
|
175
|
-
const toolCalls = message.tool_calls?.map((tc) => ({
|
|
176
|
-
id: tc.id,
|
|
177
|
-
name: tc.function.name,
|
|
178
|
-
args: safeJson(tc.function.arguments),
|
|
179
|
-
}));
|
|
180
|
-
return {
|
|
181
|
-
message: normalizedMessage,
|
|
182
|
-
finishReason: choice.finish_reason ??
|
|
183
|
-
"stop",
|
|
184
|
-
toolCalls,
|
|
185
|
-
usage: response.usage
|
|
186
|
-
? {
|
|
187
|
-
promptTokens: response.usage.prompt_tokens ?? 0,
|
|
188
|
-
completionTokens: response.usage.completion_tokens ?? 0,
|
|
189
|
-
totalTokens: response.usage.total_tokens ?? 0,
|
|
190
|
-
}
|
|
191
|
-
: undefined,
|
|
192
|
-
};
|
|
193
|
-
},
|
|
194
|
-
};
|
|
195
|
-
}
|
|
196
|
-
function safeJson(str) {
|
|
197
|
-
try {
|
|
198
|
-
const parsed = JSON.parse(str);
|
|
199
|
-
if (parsed && typeof parsed === "object") {
|
|
200
|
-
return parsed;
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
catch {
|
|
204
|
-
// ignore bad tool args
|
|
205
|
-
}
|
|
206
|
-
return {};
|
|
207
|
-
}
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
import type { ModelMessage, ToolDefinition } from "@bolt-foundry/gambit-core/internal/types";
|
|
2
|
-
export declare const logger: Console;
|
|
3
|
-
export type RenderChatCompletionsRequest = {
|
|
4
|
-
model?: string;
|
|
5
|
-
messages: Array<{
|
|
6
|
-
role: "system" | "user" | "assistant" | "tool";
|
|
7
|
-
content: string | null | Array<string | {
|
|
8
|
-
text?: string;
|
|
9
|
-
type?: string;
|
|
10
|
-
}>;
|
|
11
|
-
name?: string;
|
|
12
|
-
tool_call_id?: string;
|
|
13
|
-
tool_calls?: ModelMessage["tool_calls"];
|
|
14
|
-
}>;
|
|
15
|
-
tools?: Array<ToolDefinition>;
|
|
16
|
-
stream?: boolean;
|
|
17
|
-
temperature?: number;
|
|
18
|
-
top_p?: number;
|
|
19
|
-
frequency_penalty?: number;
|
|
20
|
-
presence_penalty?: number;
|
|
21
|
-
max_tokens?: number;
|
|
22
|
-
[key: string]: unknown;
|
|
23
|
-
};
|
|
24
|
-
export type RenderDeckOptions = {
|
|
25
|
-
deckPath: string;
|
|
26
|
-
request: RenderChatCompletionsRequest;
|
|
27
|
-
includeDeckSystem?: boolean;
|
|
28
|
-
includeDeckTools?: boolean;
|
|
29
|
-
warnOnSystemMismatch?: boolean;
|
|
30
|
-
};
|
|
31
|
-
export type RenderDeckResult = {
|
|
32
|
-
request: {
|
|
33
|
-
model: string;
|
|
34
|
-
messages: Array<ModelMessage>;
|
|
35
|
-
tools?: Array<ToolDefinition>;
|
|
36
|
-
stream?: boolean;
|
|
37
|
-
temperature?: number;
|
|
38
|
-
top_p?: number;
|
|
39
|
-
frequency_penalty?: number;
|
|
40
|
-
presence_penalty?: number;
|
|
41
|
-
max_tokens?: number;
|
|
42
|
-
[key: string]: unknown;
|
|
43
|
-
};
|
|
44
|
-
gambit: {
|
|
45
|
-
deckPath: string;
|
|
46
|
-
systemPrompt: string;
|
|
47
|
-
actionPathsByName: Record<string, string>;
|
|
48
|
-
};
|
|
49
|
-
};
|
|
50
|
-
export declare function renderDeck(opts: RenderDeckOptions): Promise<RenderDeckResult>;
|
|
51
|
-
//# sourceMappingURL=render.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../../../../src/packages/gambit-core/src/render.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAe,cAAc,EAAE,MAAM,0CAA0C,CAAC;AAE1G,eAAO,MAAM,MAAM,SAAU,CAAC;AAE9B,MAAM,MAAM,4BAA4B,GAAG;IACzC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,KAAK,CAAC;QACd,IAAI,EAAE,QAAQ,GAAG,MAAM,GAAG,WAAW,GAAG,MAAM,CAAC;QAC/C,OAAO,EACH,MAAM,GACN,IAAI,GACJ,KAAK,CAAC,MAAM,GAAG;YAAE,IAAI,CAAC,EAAE,MAAM,CAAC;YAAC,IAAI,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;QACrD,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,UAAU,CAAC,EAAE,YAAY,CAAC,YAAY,CAAC,CAAC;KACzC,CAAC,CAAC;IACH,KAAK,CAAC,EAAE,KAAK,CAAC,cAAc,CAAC,CAAC;IAC9B,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,4BAA4B,CAAC;IACtC,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,oBAAoB,CAAC,EAAE,OAAO,CAAC;CAChC,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,OAAO,EAAE;QACP,KAAK,EAAE,MAAM,CAAC;QACd,QAAQ,EAAE,KAAK,CAAC,YAAY,CAAC,CAAC;QAC9B,KAAK,CAAC,EAAE,KAAK,CAAC,cAAc,CAAC,CAAC;QAC9B,MAAM,CAAC,EAAE,OAAO,CAAC;QACjB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,iBAAiB,CAAC,EAAE,MAAM,CAAC;QAC3B,gBAAgB,CAAC,EAAE,MAAM,CAAC;QAC1B,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;KACxB,CAAC;IACF,MAAM,EAAE;QACN,QAAQ,EAAE,MAAM,CAAC;QACjB,YAAY,EAAE,MAAM,CAAC;QACrB,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;KAC3C,CAAC;CACH,CAAC;AA6JF,wBAAsB,UAAU,CAC9B,IAAI,EAAE,iBAAiB,GACtB,OAAO,CAAC,gBAAgB,CAAC,CA0E3B"}
|