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