@bolt-foundry/gambit 0.8.0 → 0.8.3
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 +82 -2
- package/README.md +31 -9
- package/esm/gambit/simulator-ui/dist/bundle.js +4744 -4360
- package/esm/gambit/simulator-ui/dist/bundle.js.map +4 -4
- package/esm/gambit/simulator-ui/dist/favicon.ico +0 -0
- package/esm/mod.d.ts +7 -3
- package/esm/mod.d.ts.map +1 -1
- package/esm/mod.js +5 -1
- package/esm/src/cli_utils.d.ts +3 -2
- package/esm/src/cli_utils.d.ts.map +1 -1
- package/esm/src/cli_utils.js +43 -27
- package/esm/src/openai_compat.d.ts +63 -0
- package/esm/src/openai_compat.d.ts.map +1 -0
- package/esm/src/openai_compat.js +277 -0
- package/esm/src/providers/google.d.ts +16 -0
- package/esm/src/providers/google.d.ts.map +1 -0
- package/esm/src/providers/google.js +352 -0
- package/esm/src/providers/ollama.d.ts +17 -0
- package/esm/src/providers/ollama.d.ts.map +1 -0
- package/esm/src/providers/ollama.js +509 -0
- package/esm/src/providers/openrouter.d.ts +14 -1
- package/esm/src/providers/openrouter.d.ts.map +1 -1
- package/esm/src/providers/openrouter.js +460 -463
- package/esm/src/server.d.ts +4 -0
- package/esm/src/server.d.ts.map +1 -1
- package/esm/src/server.js +623 -164
- package/esm/src/trace.d.ts.map +1 -1
- package/esm/src/trace.js +3 -6
- package/package.json +2 -2
- package/script/gambit/simulator-ui/dist/bundle.js +4744 -4360
- package/script/gambit/simulator-ui/dist/bundle.js.map +4 -4
- package/script/gambit/simulator-ui/dist/favicon.ico +0 -0
- package/script/mod.d.ts +7 -3
- package/script/mod.d.ts.map +1 -1
- package/script/mod.js +9 -3
- package/script/src/cli_utils.d.ts +3 -2
- package/script/src/cli_utils.d.ts.map +1 -1
- package/script/src/cli_utils.js +42 -26
- package/script/src/openai_compat.d.ts +63 -0
- package/script/src/openai_compat.d.ts.map +1 -0
- package/script/src/openai_compat.js +281 -0
- package/script/src/providers/google.d.ts +16 -0
- package/script/src/providers/google.d.ts.map +1 -0
- package/script/src/providers/google.js +359 -0
- package/script/src/providers/ollama.d.ts +17 -0
- package/script/src/providers/ollama.d.ts.map +1 -0
- package/script/src/providers/ollama.js +551 -0
- package/script/src/providers/openrouter.d.ts +14 -1
- package/script/src/providers/openrouter.d.ts.map +1 -1
- package/script/src/providers/openrouter.js +461 -463
- package/script/src/server.d.ts +4 -0
- package/script/src/server.d.ts.map +1 -1
- package/script/src/server.js +623 -164
- package/script/src/trace.d.ts.map +1 -1
- package/script/src/trace.js +3 -6
- package/esm/src/compat/openai.d.ts +0 -2
- package/esm/src/compat/openai.d.ts.map +0 -1
- package/esm/src/compat/openai.js +0 -1
- package/script/src/compat/openai.d.ts +0 -2
- package/script/src/compat/openai.d.ts.map +0 -1
- package/script/src/compat/openai.js +0 -5
|
Binary file
|
package/script/mod.d.ts
CHANGED
|
@@ -35,11 +35,11 @@ export { runDeck } from "@bolt-foundry/gambit-core";
|
|
|
35
35
|
/** Signal for explicitly ending a Gambit run. */
|
|
36
36
|
export type { GambitEndSignal } from "@bolt-foundry/gambit-core";
|
|
37
37
|
/** OpenAI Chat Completions compatibility helper for a deck. */
|
|
38
|
-
export { chatCompletionsWithDeck } from "./src/
|
|
38
|
+
export { chatCompletionsWithDeck } from "./src/openai_compat.js";
|
|
39
39
|
/** OpenAI-compatible request payload. */
|
|
40
|
-
export type { ChatCompletionsRequest } from "./src/
|
|
40
|
+
export type { ChatCompletionsRequest } from "./src/openai_compat.js";
|
|
41
41
|
/** OpenAI-compatible response payload. */
|
|
42
|
-
export type { ChatCompletionsResponse } from "./src/
|
|
42
|
+
export type { ChatCompletionsResponse } from "./src/openai_compat.js";
|
|
43
43
|
/** Render a deck to a human-readable outline or debug view. */
|
|
44
44
|
export { renderDeck } from "@bolt-foundry/gambit-core";
|
|
45
45
|
/** Options for deck rendering. */
|
|
@@ -48,6 +48,10 @@ export type { RenderDeckOptions } from "@bolt-foundry/gambit-core";
|
|
|
48
48
|
export type { RenderDeckResult } from "@bolt-foundry/gambit-core";
|
|
49
49
|
/** Provider factory for OpenRouter-backed model calls. */
|
|
50
50
|
export { createOpenRouterProvider } from "./src/providers/openrouter.js";
|
|
51
|
+
/** Provider factory for Ollama-backed model calls. */
|
|
52
|
+
export { createOllamaProvider } from "./src/providers/ollama.js";
|
|
53
|
+
/** Provider factory for Google Gemini-backed model calls. */
|
|
54
|
+
export { createGoogleProvider } from "./src/providers/google.js";
|
|
51
55
|
/** Start the WebSocket simulator server for the Gambit UI. */
|
|
52
56
|
export { startWebSocketSimulator } from "./src/server.js";
|
|
53
57
|
//# sourceMappingURL=mod.d.ts.map
|
package/script/mod.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mod.d.ts","sourceRoot":"","sources":["../src/mod.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,yEAAyE;AACzE,OAAO,qBAAqB,CAAC;AAE7B,OAAO,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AACvD,oDAAoD;AACpD,OAAO,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AACvD,oCAAoC;AACpC,YAAY,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACtE,6BAA6B;AAC7B,YAAY,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAChE,6BAA6B;AAC7B,YAAY,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAChE,iCAAiC;AACjC,YAAY,EAAE,uBAAuB,EAAE,MAAM,2BAA2B,CAAC;AACzE,yCAAyC;AACzC,YAAY,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAClE,oCAAoC;AACpC,YAAY,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACtE,uCAAuC;AACvC,YAAY,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAC5D,2DAA2D;AAC3D,YAAY,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAC3D,iDAAiD;AACjD,YAAY,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC/D,kCAAkC;AAClC,YAAY,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AACpE,yDAAyD;AACzD,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9D,kDAAkD;AAClD,OAAO,EAAE,OAAO,EAAE,MAAM,2BAA2B,CAAC;AACpD,iDAAiD;AACjD,YAAY,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AACjE,+DAA+D;AAC/D,OAAO,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AACjE,yCAAyC;AACzC,YAAY,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AACrE,0CAA0C;AAC1C,YAAY,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AACtE,+DAA+D;AAC/D,OAAO,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AACvD,kCAAkC;AAClC,YAAY,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AACnE,yCAAyC;AACzC,YAAY,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAClE,0DAA0D;AAC1D,OAAO,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;AACzE,8DAA8D;AAC9D,OAAO,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC"}
|
|
1
|
+
{"version":3,"file":"mod.d.ts","sourceRoot":"","sources":["../src/mod.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,yEAAyE;AACzE,OAAO,qBAAqB,CAAC;AAE7B,OAAO,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AACvD,oDAAoD;AACpD,OAAO,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AACvD,oCAAoC;AACpC,YAAY,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACtE,6BAA6B;AAC7B,YAAY,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAChE,6BAA6B;AAC7B,YAAY,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAChE,iCAAiC;AACjC,YAAY,EAAE,uBAAuB,EAAE,MAAM,2BAA2B,CAAC;AACzE,yCAAyC;AACzC,YAAY,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAClE,oCAAoC;AACpC,YAAY,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACtE,uCAAuC;AACvC,YAAY,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAC5D,2DAA2D;AAC3D,YAAY,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAC3D,iDAAiD;AACjD,YAAY,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC/D,kCAAkC;AAClC,YAAY,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AACpE,yDAAyD;AACzD,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9D,kDAAkD;AAClD,OAAO,EAAE,OAAO,EAAE,MAAM,2BAA2B,CAAC;AACpD,iDAAiD;AACjD,YAAY,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AACjE,+DAA+D;AAC/D,OAAO,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AACjE,yCAAyC;AACzC,YAAY,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AACrE,0CAA0C;AAC1C,YAAY,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AACtE,+DAA+D;AAC/D,OAAO,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AACvD,kCAAkC;AAClC,YAAY,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AACnE,yCAAyC;AACzC,YAAY,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAClE,0DAA0D;AAC1D,OAAO,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;AACzE,sDAAsD;AACtD,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACjE,6DAA6D;AAC7D,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACjE,8DAA8D;AAC9D,OAAO,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC"}
|
package/script/mod.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.startWebSocketSimulator = exports.createOpenRouterProvider = exports.renderDeck = exports.chatCompletionsWithDeck = exports.runDeck = exports.isGambitEndSignal = exports.defineDeck = exports.defineCard = void 0;
|
|
3
|
+
exports.startWebSocketSimulator = exports.createGoogleProvider = exports.createOllamaProvider = exports.createOpenRouterProvider = exports.renderDeck = exports.chatCompletionsWithDeck = exports.runDeck = exports.isGambitEndSignal = exports.defineDeck = exports.defineCard = void 0;
|
|
4
4
|
/**
|
|
5
5
|
* Gambit exports for authoring and running decks/cards with runtime helpers.
|
|
6
6
|
*
|
|
@@ -20,14 +20,20 @@ Object.defineProperty(exports, "isGambitEndSignal", { enumerable: true, get: fun
|
|
|
20
20
|
var gambit_core_4 = require("@bolt-foundry/gambit-core");
|
|
21
21
|
Object.defineProperty(exports, "runDeck", { enumerable: true, get: function () { return gambit_core_4.runDeck; } });
|
|
22
22
|
/** OpenAI Chat Completions compatibility helper for a deck. */
|
|
23
|
-
var
|
|
24
|
-
Object.defineProperty(exports, "chatCompletionsWithDeck", { enumerable: true, get: function () { return
|
|
23
|
+
var openai_compat_js_1 = require("./src/openai_compat.js");
|
|
24
|
+
Object.defineProperty(exports, "chatCompletionsWithDeck", { enumerable: true, get: function () { return openai_compat_js_1.chatCompletionsWithDeck; } });
|
|
25
25
|
/** Render a deck to a human-readable outline or debug view. */
|
|
26
26
|
var gambit_core_5 = require("@bolt-foundry/gambit-core");
|
|
27
27
|
Object.defineProperty(exports, "renderDeck", { enumerable: true, get: function () { return gambit_core_5.renderDeck; } });
|
|
28
28
|
/** Provider factory for OpenRouter-backed model calls. */
|
|
29
29
|
var openrouter_js_1 = require("./src/providers/openrouter.js");
|
|
30
30
|
Object.defineProperty(exports, "createOpenRouterProvider", { enumerable: true, get: function () { return openrouter_js_1.createOpenRouterProvider; } });
|
|
31
|
+
/** Provider factory for Ollama-backed model calls. */
|
|
32
|
+
var ollama_js_1 = require("./src/providers/ollama.js");
|
|
33
|
+
Object.defineProperty(exports, "createOllamaProvider", { enumerable: true, get: function () { return ollama_js_1.createOllamaProvider; } });
|
|
34
|
+
/** Provider factory for Google Gemini-backed model calls. */
|
|
35
|
+
var google_js_1 = require("./src/providers/google.js");
|
|
36
|
+
Object.defineProperty(exports, "createGoogleProvider", { enumerable: true, get: function () { return google_js_1.createGoogleProvider; } });
|
|
31
37
|
/** Start the WebSocket simulator server for the Gambit UI. */
|
|
32
38
|
var server_js_1 = require("./src/server.js");
|
|
33
39
|
Object.defineProperty(exports, "startWebSocketSimulator", { enumerable: true, get: function () { return server_js_1.startWebSocketSimulator; } });
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { ModelMessage } from "@bolt-foundry/gambit-core";
|
|
2
|
+
import type { SavedState } from "@bolt-foundry/gambit-core";
|
|
2
3
|
export declare function parsePortValue(value: unknown, label?: string): number | undefined;
|
|
3
4
|
export declare function normalizeFlagList(value: string | Array<string> | undefined): Array<string>;
|
|
4
5
|
export declare function slugifyDeckPath(deckPath: string): string;
|
|
@@ -8,6 +9,6 @@ export declare function enrichStateMeta(state: SavedState, deckPath: string): Sa
|
|
|
8
9
|
export declare function parseContext(raw?: string): unknown;
|
|
9
10
|
export declare function parseMessage(raw?: string): unknown;
|
|
10
11
|
export declare function parseBotInput(raw?: string): unknown;
|
|
11
|
-
export declare function findLastAssistantMessage(messages: Array<
|
|
12
|
+
export declare function findLastAssistantMessage(messages: Array<ModelMessage>): string | undefined;
|
|
12
13
|
export declare function extractContextInput(state?: SavedState): unknown;
|
|
13
14
|
//# sourceMappingURL=cli_utils.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli_utils.d.ts","sourceRoot":"","sources":["../../src/src/cli_utils.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"cli_utils.d.ts","sourceRoot":"","sources":["../../src/src/cli_utils.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAE5D,wBAAgB,cAAc,CAC5B,KAAK,EAAE,OAAO,EACd,KAAK,SAAS,GACb,MAAM,GAAG,SAAS,CAOpB;AAED,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,GAAG,SAAS,GACxC,KAAK,CAAC,MAAM,CAAC,CAGf;AAED,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAQxD;AAuBD,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAM3D;AAED,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAQhE;AAED,wBAAgB,eAAe,CAC7B,KAAK,EAAE,UAAU,EACjB,QAAQ,EAAE,MAAM,GACf,UAAU,CAOZ;AAED,wBAAgB,YAAY,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAOlD;AAED,wBAAgB,YAAY,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAOlD;AAED,wBAAgB,aAAa,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAOnD;AAED,wBAAgB,wBAAwB,CACtC,QAAQ,EAAE,KAAK,CAAC,YAAY,CAAC,GAC5B,MAAM,GAAG,SAAS,CAUpB;AAED,wBAAgB,mBAAmB,CAAC,KAAK,CAAC,EAAE,UAAU,GAAG,OAAO,CAuB/D"}
|
package/script/src/cli_utils.js
CHANGED
|
@@ -140,43 +140,32 @@ function parseBotInput(raw) {
|
|
|
140
140
|
return raw;
|
|
141
141
|
}
|
|
142
142
|
}
|
|
143
|
-
function contentText(parts) {
|
|
144
|
-
return parts.map((part) => {
|
|
145
|
-
switch (part.type) {
|
|
146
|
-
case "input_text":
|
|
147
|
-
case "output_text":
|
|
148
|
-
case "text":
|
|
149
|
-
case "summary_text":
|
|
150
|
-
case "reasoning_text":
|
|
151
|
-
return part.text;
|
|
152
|
-
case "refusal":
|
|
153
|
-
return part.refusal;
|
|
154
|
-
default:
|
|
155
|
-
return "";
|
|
156
|
-
}
|
|
157
|
-
}).join("");
|
|
158
|
-
}
|
|
159
143
|
function findLastAssistantMessage(messages) {
|
|
160
144
|
for (let i = messages.length - 1; i >= 0; i--) {
|
|
161
145
|
const msg = messages[i];
|
|
162
|
-
if (msg?.
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
return contentText(msg.content);
|
|
167
|
-
}
|
|
168
|
-
return JSON.stringify(msg.content ?? "");
|
|
146
|
+
if (msg?.role === "assistant") {
|
|
147
|
+
return typeof msg.content === "string"
|
|
148
|
+
? msg.content
|
|
149
|
+
: JSON.stringify(msg.content ?? "");
|
|
169
150
|
}
|
|
170
151
|
}
|
|
171
152
|
return undefined;
|
|
172
153
|
}
|
|
173
154
|
function extractContextInput(state) {
|
|
174
|
-
if (!state
|
|
155
|
+
if (!state)
|
|
175
156
|
return undefined;
|
|
157
|
+
if (state.format === "responses" && Array.isArray(state.items)) {
|
|
158
|
+
return extractContextInputFromItems(state.items);
|
|
159
|
+
}
|
|
160
|
+
if (!state.messages)
|
|
161
|
+
return undefined;
|
|
162
|
+
const contextToolNames = new Set([
|
|
163
|
+
gambit_core_1.GAMBIT_TOOL_CONTEXT,
|
|
164
|
+
gambit_core_1.GAMBIT_TOOL_INIT,
|
|
165
|
+
]);
|
|
176
166
|
for (let i = state.messages.length - 1; i >= 0; i--) {
|
|
177
167
|
const msg = state.messages[i];
|
|
178
|
-
if (msg.
|
|
179
|
-
msg.name === gambit_core_1.GAMBIT_TOOL_INIT) {
|
|
168
|
+
if (msg.role === "tool" && contextToolNames.has(msg.name ?? "")) {
|
|
180
169
|
const content = msg.content;
|
|
181
170
|
if (typeof content !== "string")
|
|
182
171
|
return undefined;
|
|
@@ -190,3 +179,30 @@ function extractContextInput(state) {
|
|
|
190
179
|
}
|
|
191
180
|
return undefined;
|
|
192
181
|
}
|
|
182
|
+
function extractContextInputFromItems(items) {
|
|
183
|
+
const contextToolNames = new Set([
|
|
184
|
+
gambit_core_1.GAMBIT_TOOL_CONTEXT,
|
|
185
|
+
gambit_core_1.GAMBIT_TOOL_INIT,
|
|
186
|
+
]);
|
|
187
|
+
const callNameById = new Map();
|
|
188
|
+
for (const item of items) {
|
|
189
|
+
if (item.type === "function_call") {
|
|
190
|
+
callNameById.set(item.call_id, item.name);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
for (let i = items.length - 1; i >= 0; i--) {
|
|
194
|
+
const item = items[i];
|
|
195
|
+
if (item.type !== "function_call_output")
|
|
196
|
+
continue;
|
|
197
|
+
const name = callNameById.get(item.call_id);
|
|
198
|
+
if (!name || !contextToolNames.has(name))
|
|
199
|
+
continue;
|
|
200
|
+
try {
|
|
201
|
+
return JSON.parse(item.output);
|
|
202
|
+
}
|
|
203
|
+
catch {
|
|
204
|
+
return item.output;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
return undefined;
|
|
208
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import type { Guardrails, ModelMessage, ModelProvider, ToolDefinition } from "@bolt-foundry/gambit-core";
|
|
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
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openai_compat.d.ts","sourceRoot":"","sources":["../../src/src/openai_compat.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EACV,UAAU,EAEV,YAAY,EACZ,aAAa,EACb,cAAc,EACf,MAAM,2BAA2B,CAAC;AAEnC,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;AA8KF,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"}
|
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.logger = void 0;
|
|
4
|
+
exports.chatCompletionsWithDeck = chatCompletionsWithDeck;
|
|
5
|
+
const gambit_core_1 = require("@bolt-foundry/gambit-core");
|
|
6
|
+
exports.logger = console;
|
|
7
|
+
function randomId(prefix) {
|
|
8
|
+
const suffix = crypto.randomUUID().replace(/-/g, "").slice(0, 24);
|
|
9
|
+
return `${prefix}-${suffix}`;
|
|
10
|
+
}
|
|
11
|
+
function normalizeContent(content) {
|
|
12
|
+
if (content === null)
|
|
13
|
+
return null;
|
|
14
|
+
if (typeof content === "string")
|
|
15
|
+
return content;
|
|
16
|
+
if (!Array.isArray(content))
|
|
17
|
+
return String(content);
|
|
18
|
+
return content
|
|
19
|
+
.map((c) => (typeof c === "string" ? c : (c.text ?? "")))
|
|
20
|
+
.join("");
|
|
21
|
+
}
|
|
22
|
+
function normalizeMessages(input) {
|
|
23
|
+
return input.map((m) => ({
|
|
24
|
+
role: m.role,
|
|
25
|
+
content: normalizeContent(m.content),
|
|
26
|
+
name: m.name,
|
|
27
|
+
tool_call_id: m.tool_call_id,
|
|
28
|
+
tool_calls: m.tool_calls && m.tool_calls.length > 0
|
|
29
|
+
? m.tool_calls
|
|
30
|
+
: undefined,
|
|
31
|
+
}));
|
|
32
|
+
}
|
|
33
|
+
function providerParamsFromRequest(req) {
|
|
34
|
+
const out = {};
|
|
35
|
+
if (req.temperature !== undefined)
|
|
36
|
+
out.temperature = req.temperature;
|
|
37
|
+
if (req.top_p !== undefined)
|
|
38
|
+
out.top_p = req.top_p;
|
|
39
|
+
if (req.frequency_penalty !== undefined) {
|
|
40
|
+
out.frequency_penalty = req.frequency_penalty;
|
|
41
|
+
}
|
|
42
|
+
if (req.presence_penalty !== undefined) {
|
|
43
|
+
out.presence_penalty = req.presence_penalty;
|
|
44
|
+
}
|
|
45
|
+
if (req.max_tokens !== undefined)
|
|
46
|
+
out.max_tokens = req.max_tokens;
|
|
47
|
+
return Object.keys(out).length ? out : undefined;
|
|
48
|
+
}
|
|
49
|
+
function mergeToolDefs(gambitTools, externalTools) {
|
|
50
|
+
if (!externalTools?.length)
|
|
51
|
+
return gambitTools;
|
|
52
|
+
return [...gambitTools, ...externalTools];
|
|
53
|
+
}
|
|
54
|
+
function toolName(tool) {
|
|
55
|
+
return tool.function?.name ?? "";
|
|
56
|
+
}
|
|
57
|
+
function resolveContextSchema(deck) {
|
|
58
|
+
return deck.contextSchema ?? deck.inputSchema;
|
|
59
|
+
}
|
|
60
|
+
function resolveResponseSchema(deck) {
|
|
61
|
+
return deck.responseSchema ?? deck.outputSchema;
|
|
62
|
+
}
|
|
63
|
+
function assertNoToolNameCollisions(args) {
|
|
64
|
+
if (!args.externalTools?.length)
|
|
65
|
+
return;
|
|
66
|
+
const gambit = new Set(args.gambitTools.map(toolName));
|
|
67
|
+
for (const t of args.externalTools) {
|
|
68
|
+
const name = toolName(t);
|
|
69
|
+
if (!name)
|
|
70
|
+
continue;
|
|
71
|
+
if (name.startsWith(gambit_core_1.RESERVED_TOOL_PREFIX)) {
|
|
72
|
+
throw new Error(`External tool name ${name} is reserved (prefix ${gambit_core_1.RESERVED_TOOL_PREFIX})`);
|
|
73
|
+
}
|
|
74
|
+
if (gambit.has(name)) {
|
|
75
|
+
throw new Error(`Tool name collision for ${name} between Gambit deck actions and external tools`);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
async function buildGambitActionTools(deck) {
|
|
80
|
+
const tools = [];
|
|
81
|
+
const toolNameSet = new Set();
|
|
82
|
+
const actionPathByName = new Map();
|
|
83
|
+
for (const action of deck.actionDecks) {
|
|
84
|
+
const child = await (0, gambit_core_1.loadDeck)(action.path, deck.path);
|
|
85
|
+
const contextSchema = resolveContextSchema(child);
|
|
86
|
+
const responseSchema = resolveResponseSchema(child);
|
|
87
|
+
if (!contextSchema || !responseSchema) {
|
|
88
|
+
throw new Error(`Deck ${child.path} must declare contextSchema and responseSchema (non-root)`);
|
|
89
|
+
}
|
|
90
|
+
(0, gambit_core_1.assertZodSchema)(contextSchema, "contextSchema");
|
|
91
|
+
(0, gambit_core_1.assertZodSchema)(responseSchema, "responseSchema");
|
|
92
|
+
const params = (0, gambit_core_1.toJsonSchema)(contextSchema);
|
|
93
|
+
tools.push({
|
|
94
|
+
type: "function",
|
|
95
|
+
function: {
|
|
96
|
+
name: action.name,
|
|
97
|
+
description: action.description,
|
|
98
|
+
parameters: params,
|
|
99
|
+
},
|
|
100
|
+
});
|
|
101
|
+
toolNameSet.add(action.name);
|
|
102
|
+
actionPathByName.set(action.name, action.path);
|
|
103
|
+
}
|
|
104
|
+
return { tools, toolNameSet, actionPathByName };
|
|
105
|
+
}
|
|
106
|
+
function deckSystemPrompt(deck) {
|
|
107
|
+
const parts = [];
|
|
108
|
+
const prompt = deck.body ?? deck.prompt;
|
|
109
|
+
if (prompt)
|
|
110
|
+
parts.push(prompt.trim());
|
|
111
|
+
for (const card of deck.cards) {
|
|
112
|
+
if (card.body)
|
|
113
|
+
parts.push(card.body.trim());
|
|
114
|
+
}
|
|
115
|
+
return parts.join("\n\n").trim();
|
|
116
|
+
}
|
|
117
|
+
function shouldPrependDeckSystem(messages, systemPrompt) {
|
|
118
|
+
if (!systemPrompt)
|
|
119
|
+
return false;
|
|
120
|
+
if (!messages.length)
|
|
121
|
+
return true;
|
|
122
|
+
const hasExact = messages.some((m) => m.role === "system" && m.content === systemPrompt);
|
|
123
|
+
return !hasExact;
|
|
124
|
+
}
|
|
125
|
+
function warnIfSystemMismatch(args) {
|
|
126
|
+
if (!args.systemPrompt)
|
|
127
|
+
return;
|
|
128
|
+
const existing = args.provided.find((m) => m.role === "system");
|
|
129
|
+
if (!existing)
|
|
130
|
+
return;
|
|
131
|
+
if (existing.content === args.systemPrompt)
|
|
132
|
+
return;
|
|
133
|
+
exports.logger.warn(`[gambit] chatCompletionsWithDeck: request includes a system message that does not match the deck prompt (${args.deckPath})`);
|
|
134
|
+
}
|
|
135
|
+
function toolResultContent(result) {
|
|
136
|
+
if (typeof result === "string")
|
|
137
|
+
return result;
|
|
138
|
+
try {
|
|
139
|
+
return JSON.stringify(result);
|
|
140
|
+
}
|
|
141
|
+
catch {
|
|
142
|
+
return String(result);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
function normalizeError(err) {
|
|
146
|
+
return { message: err instanceof Error ? err.message : String(err) };
|
|
147
|
+
}
|
|
148
|
+
async function chatCompletionsWithDeck(args) {
|
|
149
|
+
const executeDeckTools = args.executeDeckTools ?? true;
|
|
150
|
+
const guardrails = { ...gambit_core_1.DEFAULT_GUARDRAILS, ...args.guardrails };
|
|
151
|
+
const runId = randomId("run");
|
|
152
|
+
const deck = await (0, gambit_core_1.loadDeck)(args.deckPath);
|
|
153
|
+
const systemPrompt = deckSystemPrompt(deck);
|
|
154
|
+
const providedMessages = normalizeMessages(args.request.messages);
|
|
155
|
+
const messages = [];
|
|
156
|
+
warnIfSystemMismatch({
|
|
157
|
+
provided: providedMessages,
|
|
158
|
+
systemPrompt,
|
|
159
|
+
deckPath: deck.path,
|
|
160
|
+
});
|
|
161
|
+
if (shouldPrependDeckSystem(providedMessages, systemPrompt)) {
|
|
162
|
+
messages.push({ role: "system", content: systemPrompt });
|
|
163
|
+
}
|
|
164
|
+
messages.push(...providedMessages);
|
|
165
|
+
const gambit = await buildGambitActionTools(deck);
|
|
166
|
+
assertNoToolNameCollisions({
|
|
167
|
+
gambitTools: gambit.tools,
|
|
168
|
+
externalTools: args.request.tools,
|
|
169
|
+
});
|
|
170
|
+
const tools = mergeToolDefs(gambit.tools, args.request.tools);
|
|
171
|
+
const start = performance.now();
|
|
172
|
+
let passes = 0;
|
|
173
|
+
while (passes < guardrails.maxPasses) {
|
|
174
|
+
passes++;
|
|
175
|
+
if (performance.now() - start > guardrails.timeoutMs) {
|
|
176
|
+
throw new Error("Timeout exceeded");
|
|
177
|
+
}
|
|
178
|
+
const model = args.request.model ?? args.defaultModel ??
|
|
179
|
+
(() => {
|
|
180
|
+
throw new Error("No model provided");
|
|
181
|
+
})();
|
|
182
|
+
const result = await args.modelProvider.chat({
|
|
183
|
+
model,
|
|
184
|
+
messages,
|
|
185
|
+
tools: tools.length ? tools : undefined,
|
|
186
|
+
stream: Boolean(args.request.stream),
|
|
187
|
+
onStreamText: args.onStreamText,
|
|
188
|
+
params: providerParamsFromRequest(args.request),
|
|
189
|
+
});
|
|
190
|
+
messages.push(result.message);
|
|
191
|
+
if (result.toolCalls && result.toolCalls.length > 0) {
|
|
192
|
+
const gambitCalls = result.toolCalls.filter((c) => gambit.toolNameSet.has(c.name));
|
|
193
|
+
const externalCalls = result.toolCalls.filter((c) => !gambit.toolNameSet.has(c.name));
|
|
194
|
+
if (!executeDeckTools || externalCalls.length > 0) {
|
|
195
|
+
return {
|
|
196
|
+
id: randomId("chatcmpl"),
|
|
197
|
+
object: "chat.completion",
|
|
198
|
+
created: Math.floor(Date.now() / 1000),
|
|
199
|
+
model,
|
|
200
|
+
choices: [{
|
|
201
|
+
index: 0,
|
|
202
|
+
message: result.message,
|
|
203
|
+
finish_reason: "tool_calls",
|
|
204
|
+
logprobs: null,
|
|
205
|
+
}],
|
|
206
|
+
usage: result.usage
|
|
207
|
+
? {
|
|
208
|
+
prompt_tokens: result.usage.promptTokens,
|
|
209
|
+
completion_tokens: result.usage.completionTokens,
|
|
210
|
+
total_tokens: result.usage.totalTokens,
|
|
211
|
+
}
|
|
212
|
+
: undefined,
|
|
213
|
+
gambit: { deckPath: deck.path, messages, runId },
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
// Execute only deck-defined tool calls.
|
|
217
|
+
for (const call of gambitCalls) {
|
|
218
|
+
const actionPath = gambit.actionPathByName.get(call.name);
|
|
219
|
+
if (!actionPath)
|
|
220
|
+
continue;
|
|
221
|
+
try {
|
|
222
|
+
const childResult = await (0, gambit_core_1.runDeck)({
|
|
223
|
+
path: actionPath,
|
|
224
|
+
input: call.args,
|
|
225
|
+
modelProvider: args.modelProvider,
|
|
226
|
+
isRoot: false,
|
|
227
|
+
guardrails,
|
|
228
|
+
depth: 1,
|
|
229
|
+
parentActionCallId: call.id,
|
|
230
|
+
runId,
|
|
231
|
+
defaultModel: model,
|
|
232
|
+
modelOverride: undefined,
|
|
233
|
+
trace: undefined,
|
|
234
|
+
stream: Boolean(args.request.stream),
|
|
235
|
+
onStreamText: args.onStreamText,
|
|
236
|
+
inputProvided: true,
|
|
237
|
+
});
|
|
238
|
+
messages.push({
|
|
239
|
+
role: "tool",
|
|
240
|
+
name: call.name,
|
|
241
|
+
tool_call_id: call.id,
|
|
242
|
+
content: toolResultContent(childResult),
|
|
243
|
+
});
|
|
244
|
+
}
|
|
245
|
+
catch (err) {
|
|
246
|
+
messages.push({
|
|
247
|
+
role: "tool",
|
|
248
|
+
name: call.name,
|
|
249
|
+
tool_call_id: call.id,
|
|
250
|
+
content: JSON.stringify({ error: normalizeError(err) }),
|
|
251
|
+
});
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
continue;
|
|
255
|
+
}
|
|
256
|
+
if (result.finishReason === "tool_calls") {
|
|
257
|
+
throw new Error("Model requested tool_calls but provided none");
|
|
258
|
+
}
|
|
259
|
+
return {
|
|
260
|
+
id: randomId("chatcmpl"),
|
|
261
|
+
object: "chat.completion",
|
|
262
|
+
created: Math.floor(Date.now() / 1000),
|
|
263
|
+
model,
|
|
264
|
+
choices: [{
|
|
265
|
+
index: 0,
|
|
266
|
+
message: result.message,
|
|
267
|
+
finish_reason: result.finishReason,
|
|
268
|
+
logprobs: null,
|
|
269
|
+
}],
|
|
270
|
+
usage: result.usage
|
|
271
|
+
? {
|
|
272
|
+
prompt_tokens: result.usage.promptTokens,
|
|
273
|
+
completion_tokens: result.usage.completionTokens,
|
|
274
|
+
total_tokens: result.usage.totalTokens,
|
|
275
|
+
}
|
|
276
|
+
: undefined,
|
|
277
|
+
gambit: { deckPath: deck.path, messages, runId },
|
|
278
|
+
};
|
|
279
|
+
}
|
|
280
|
+
throw new Error("Max passes exceeded without completing");
|
|
281
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { ModelProvider } from "@bolt-foundry/gambit-core";
|
|
2
|
+
export declare const GOOGLE_PREFIX = "google/";
|
|
3
|
+
type OpenAIClient = {
|
|
4
|
+
chat: {
|
|
5
|
+
completions: {
|
|
6
|
+
create: (params: unknown) => Promise<unknown>;
|
|
7
|
+
};
|
|
8
|
+
};
|
|
9
|
+
};
|
|
10
|
+
export declare function createGoogleProvider(opts: {
|
|
11
|
+
apiKey: string;
|
|
12
|
+
baseURL?: string;
|
|
13
|
+
client?: OpenAIClient;
|
|
14
|
+
}): ModelProvider;
|
|
15
|
+
export {};
|
|
16
|
+
//# sourceMappingURL=google.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"google.d.ts","sourceRoot":"","sources":["../../../src/src/providers/google.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAIV,aAAa,EAId,MAAM,2BAA2B,CAAC;AAEnC,eAAO,MAAM,aAAa,YAAY,CAAC;AAIvC,KAAK,YAAY,GAAG;IAClB,IAAI,EAAE;QACJ,WAAW,EAAE;YACX,MAAM,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;SAC/C,CAAC;KACH,CAAC;CACH,CAAC;AAwIF,wBAAgB,oBAAoB,CAAC,IAAI,EAAE;IACzC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,YAAY,CAAC;CACvB,GAAG,aAAa,CA6RhB"}
|