@bolt-foundry/gambit-core 0.8.5-rc.9 → 0.8.5
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/README.md +6 -5
- package/cards/context.card.md +4 -4
- package/decks/anthropic/agent-sdk/PROMPT.md +9 -0
- package/decks/openai/codex-sdk/PROMPT.md +9 -0
- package/decks/openai/codex-sdk/codex_client.ts +109 -0
- package/decks/openai/codex-sdk/codex_sdk_bridge.deck.ts +36 -0
- package/esm/cards/context.card.md +9 -0
- package/esm/cards/end.card.md +10 -0
- package/esm/cards/generate-test-input.card.md +12 -0
- package/esm/cards/respond.card.md +10 -0
- package/esm/decks/anthropic/agent-sdk/PROMPT.md +9 -0
- package/esm/decks/openai/codex-sdk/PROMPT.md +9 -0
- package/esm/decks/openai/codex-sdk/codex_client.ts +109 -0
- package/esm/decks/openai/codex-sdk/codex_sdk_bridge.deck.ts +36 -0
- package/esm/mod.d.ts +1 -1
- package/esm/mod.d.ts.map +1 -1
- package/esm/schemas/graders/contexts/conversation.ts +40 -0
- package/esm/schemas/graders/contexts/conversation.zod.ts +1 -0
- package/esm/schemas/graders/contexts/conversation_tools.ts +63 -0
- package/esm/schemas/graders/contexts/conversation_tools.zod.ts +1 -0
- package/esm/schemas/graders/contexts/tools.ts +5 -0
- package/esm/schemas/graders/contexts/tools.zod.ts +1 -0
- package/esm/schemas/graders/contexts/turn.ts +17 -0
- package/esm/schemas/graders/contexts/turn.zod.ts +1 -0
- package/esm/schemas/graders/contexts/turn_tools.ts +63 -0
- package/esm/schemas/graders/contexts/turn_tools.zod.ts +1 -0
- package/esm/schemas/graders/grader_output.ts +15 -0
- package/esm/schemas/graders/grader_output.zod.ts +1 -0
- package/esm/schemas/graders/respond.ts +19 -0
- package/esm/schemas/graders/respond.zod.ts +1 -0
- package/esm/schemas/scenarios/plain_chat_input_optional.ts +6 -0
- package/esm/schemas/scenarios/plain_chat_input_optional.zod.ts +1 -0
- package/esm/schemas/scenarios/plain_chat_output.ts +5 -0
- package/esm/schemas/scenarios/plain_chat_output.zod.ts +1 -0
- package/esm/snippets/context.md +8 -0
- package/esm/snippets/end.md +10 -0
- package/esm/snippets/generate-test-input.md +12 -0
- package/esm/snippets/init.md +12 -0
- package/esm/snippets/respond.md +10 -0
- package/esm/snippets/scenario-participant.md +10 -0
- package/esm/src/constants.d.ts +0 -1
- package/esm/src/constants.d.ts.map +1 -1
- package/esm/src/constants.js +0 -4
- package/esm/src/loader.d.ts.map +1 -1
- package/esm/src/loader.js +101 -0
- package/esm/src/markdown.d.ts.map +1 -1
- package/esm/src/markdown.js +109 -9
- package/esm/src/runtime.d.ts +16 -1
- package/esm/src/runtime.d.ts.map +1 -1
- package/esm/src/runtime.js +1607 -311
- package/esm/src/types.d.ts +25 -1
- package/esm/src/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/script/cards/context.card.md +9 -0
- package/script/cards/end.card.md +10 -0
- package/script/cards/generate-test-input.card.md +12 -0
- package/script/cards/respond.card.md +10 -0
- package/script/decks/anthropic/agent-sdk/PROMPT.md +9 -0
- package/script/decks/openai/codex-sdk/PROMPT.md +9 -0
- package/script/decks/openai/codex-sdk/codex_client.ts +109 -0
- package/script/decks/openai/codex-sdk/codex_sdk_bridge.deck.ts +36 -0
- package/script/mod.d.ts +1 -1
- package/script/mod.d.ts.map +1 -1
- package/script/schemas/graders/contexts/conversation.ts +40 -0
- package/script/schemas/graders/contexts/conversation.zod.ts +1 -0
- package/script/schemas/graders/contexts/conversation_tools.ts +63 -0
- package/script/schemas/graders/contexts/conversation_tools.zod.ts +1 -0
- package/script/schemas/graders/contexts/tools.ts +5 -0
- package/script/schemas/graders/contexts/tools.zod.ts +1 -0
- package/script/schemas/graders/contexts/turn.ts +17 -0
- package/script/schemas/graders/contexts/turn.zod.ts +1 -0
- package/script/schemas/graders/contexts/turn_tools.ts +63 -0
- package/script/schemas/graders/contexts/turn_tools.zod.ts +1 -0
- package/script/schemas/graders/grader_output.ts +15 -0
- package/script/schemas/graders/grader_output.zod.ts +1 -0
- package/script/schemas/graders/respond.ts +19 -0
- package/script/schemas/graders/respond.zod.ts +1 -0
- package/script/schemas/scenarios/plain_chat_input_optional.ts +6 -0
- package/script/schemas/scenarios/plain_chat_input_optional.zod.ts +1 -0
- package/script/schemas/scenarios/plain_chat_output.ts +5 -0
- package/script/schemas/scenarios/plain_chat_output.zod.ts +1 -0
- package/script/snippets/context.md +8 -0
- package/script/snippets/end.md +10 -0
- package/script/snippets/generate-test-input.md +12 -0
- package/script/snippets/init.md +12 -0
- package/script/snippets/respond.md +10 -0
- package/script/snippets/scenario-participant.md +10 -0
- package/script/src/constants.d.ts +0 -1
- package/script/src/constants.d.ts.map +1 -1
- package/script/src/constants.js +1 -5
- package/script/src/loader.d.ts.map +1 -1
- package/script/src/loader.js +101 -0
- package/script/src/markdown.d.ts.map +1 -1
- package/script/src/markdown.js +109 -9
- package/script/src/runtime.d.ts +16 -1
- package/script/src/runtime.d.ts.map +1 -1
- package/script/src/runtime.js +1606 -310
- package/script/src/types.d.ts +25 -1
- package/script/src/types.d.ts.map +1 -1
- package/snippets/context.md +8 -0
- package/snippets/end.md +10 -0
- package/snippets/generate-test-input.md +12 -0
- package/snippets/init.md +12 -0
- package/snippets/respond.md +10 -0
- package/snippets/scenario-participant.md +10 -0
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
|
|
3
|
+
type RespondEnvelope = {
|
|
4
|
+
payload?: unknown;
|
|
5
|
+
status?: number;
|
|
6
|
+
message?: string;
|
|
7
|
+
code?: string;
|
|
8
|
+
meta?: Record<string, unknown>;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
const respondSchema: z.ZodType<RespondEnvelope> = z.object({
|
|
12
|
+
payload: z.any().optional(),
|
|
13
|
+
status: z.number().int().optional(),
|
|
14
|
+
message: z.string().optional(),
|
|
15
|
+
code: z.string().optional(),
|
|
16
|
+
meta: z.record(z.any()).optional(),
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
export default respondSchema;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from "./respond.ts";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from "./plain_chat_input_optional.ts";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from "./plain_chat_output.ts";
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
+++
|
|
2
|
+
label = "Gambit context primer"
|
|
3
|
+
+++
|
|
4
|
+
|
|
5
|
+
The first turn you see should be a `gambit_context` tool. This payload contains
|
|
6
|
+
run metadata or seeded inputs. Read it before you respond, treat it as important
|
|
7
|
+
context, and keep it on hand throughout the workflow so downstream actions have
|
|
8
|
+
the right data. Do not call `gambit_context` yourself; runtime injects it once.
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
+++
|
|
2
|
+
label = "Explicitly end the run"
|
|
3
|
+
allowEnd = true
|
|
4
|
+
+++
|
|
5
|
+
|
|
6
|
+
If the entire conversation/workflow is complete and you must stop all further
|
|
7
|
+
turns, call the `gambit_end` tool with an optional `message`, `payload`,
|
|
8
|
+
`status`, `code`, or `meta`. Only use this when you want Gambit to halt entirely
|
|
9
|
+
(no more user messages). Otherwise continue with normal responses or
|
|
10
|
+
`gambit_respond`.
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
+++
|
|
2
|
+
label = "Generate test input"
|
|
3
|
+
+++
|
|
4
|
+
|
|
5
|
+
When you receive a user message with:
|
|
6
|
+
|
|
7
|
+
{ "type": "gambit_test_bot_init_fill", "missing": ["path.to.field", "..."],
|
|
8
|
+
"current": { ... }, "schemaHints": [ ... ] }
|
|
9
|
+
|
|
10
|
+
Return ONLY valid JSON that supplies values for the missing fields. Do not
|
|
11
|
+
include any fields that are not listed in "missing". If the only missing path is
|
|
12
|
+
"(root)", return the full init JSON value.
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
+++
|
|
2
|
+
label = "Fill missing init fields"
|
|
3
|
+
+++
|
|
4
|
+
|
|
5
|
+
When you receive a user message with:
|
|
6
|
+
|
|
7
|
+
{ "type": "gambit_test_bot_init_fill", "missing": ["path.to.field", "..."],
|
|
8
|
+
"current": { ... }, "schemaHints": [ ... ] }
|
|
9
|
+
|
|
10
|
+
Return ONLY valid JSON that supplies values for the missing fields. Do not
|
|
11
|
+
include any fields that are not listed in "missing". If the only missing path is
|
|
12
|
+
"(root)", return the full init JSON value.
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
+++
|
|
2
|
+
label = "Call gambit_respond"
|
|
3
|
+
respond = true
|
|
4
|
+
+++
|
|
5
|
+
|
|
6
|
+
When you finish this workflow, do **not** emit a normal assistant reply.
|
|
7
|
+
Instead, call the `gambit_respond` tool exactly once with a JSON envelope that
|
|
8
|
+
includes your validated `payload` plus optional `status`, `message`, `code`, or
|
|
9
|
+
`meta` fields. This keeps outputs structured and lets Gambit capture the result
|
|
10
|
+
even when guardrails stop the run early.
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
+++
|
|
2
|
+
label = "Scenario participant"
|
|
3
|
+
+++
|
|
4
|
+
|
|
5
|
+
You are the synthetic scenario participant in this run.
|
|
6
|
+
|
|
7
|
+
- Stay in the user/participant role for every turn.
|
|
8
|
+
- Do not speak as the assistant.
|
|
9
|
+
- Do not narrate assistant reasoning, tools, or internal state.
|
|
10
|
+
- When the scenario is complete, return exactly one empty message.
|
|
@@ -12,7 +12,6 @@ export declare const GAMBIT_TOOL_CONTEXT = "gambit_context";
|
|
|
12
12
|
*/
|
|
13
13
|
export declare const GAMBIT_TOOL_INIT = "gambit_init";
|
|
14
14
|
export declare const GAMBIT_TOOL_RESPOND = "gambit_respond";
|
|
15
|
-
export declare const GAMBIT_TOOL_COMPLETE = "gambit_complete";
|
|
16
15
|
export declare const GAMBIT_TOOL_END = "gambit_end";
|
|
17
16
|
export declare const BUILTIN_TOOL_NAME_SET: ReadonlySet<string>;
|
|
18
17
|
export declare const DEFAULT_STATUS_DELAY_MS = 800;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/src/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,kBAAkB;;;;CAIrB,CAAC;AAEX,eAAO,MAAM,oBAAoB,YAAY,CAAC;AAC9C,eAAO,MAAM,iBAAiB,QAA6B,CAAC;AAC5D,eAAO,MAAM,oBAAoB,KAAK,CAAC;AACvC,eAAO,MAAM,mBAAmB,mBAAmB,CAAC;AACpD;;GAEG;AACH,eAAO,MAAM,gBAAgB,gBAAgB,CAAC;AAC9C,eAAO,MAAM,mBAAmB,mBAAmB,CAAC;AACpD,eAAO,MAAM,
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/src/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,kBAAkB;;;;CAIrB,CAAC;AAEX,eAAO,MAAM,oBAAoB,YAAY,CAAC;AAC9C,eAAO,MAAM,iBAAiB,QAA6B,CAAC;AAC5D,eAAO,MAAM,oBAAoB,KAAK,CAAC;AACvC,eAAO,MAAM,mBAAmB,mBAAmB,CAAC;AACpD;;GAEG;AACH,eAAO,MAAM,gBAAgB,gBAAgB,CAAC;AAC9C,eAAO,MAAM,mBAAmB,mBAAmB,CAAC;AACpD,eAAO,MAAM,eAAe,eAAe,CAAC;AAC5C,eAAO,MAAM,qBAAqB,EAAE,WAAW,CAAC,MAAM,CAGpD,CAAC;AAGH,eAAO,MAAM,uBAAuB,MAAM,CAAC"}
|
package/script/src/constants.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.DEFAULT_STATUS_DELAY_MS = exports.BUILTIN_TOOL_NAME_SET = exports.GAMBIT_TOOL_END = exports.
|
|
3
|
+
exports.DEFAULT_STATUS_DELAY_MS = exports.BUILTIN_TOOL_NAME_SET = exports.GAMBIT_TOOL_END = exports.GAMBIT_TOOL_RESPOND = exports.GAMBIT_TOOL_INIT = exports.GAMBIT_TOOL_CONTEXT = exports.MAX_TOOL_NAME_LENGTH = exports.TOOL_NAME_PATTERN = exports.RESERVED_TOOL_PREFIX = exports.DEFAULT_GUARDRAILS = void 0;
|
|
4
4
|
exports.DEFAULT_GUARDRAILS = {
|
|
5
5
|
maxDepth: 3,
|
|
6
6
|
maxPasses: 10,
|
|
@@ -15,14 +15,10 @@ exports.GAMBIT_TOOL_CONTEXT = "gambit_context";
|
|
|
15
15
|
*/
|
|
16
16
|
exports.GAMBIT_TOOL_INIT = "gambit_init";
|
|
17
17
|
exports.GAMBIT_TOOL_RESPOND = "gambit_respond";
|
|
18
|
-
exports.GAMBIT_TOOL_COMPLETE = "gambit_complete";
|
|
19
18
|
exports.GAMBIT_TOOL_END = "gambit_end";
|
|
20
19
|
exports.BUILTIN_TOOL_NAME_SET = new Set([
|
|
21
20
|
exports.GAMBIT_TOOL_CONTEXT,
|
|
22
21
|
exports.GAMBIT_TOOL_INIT,
|
|
23
|
-
exports.GAMBIT_TOOL_RESPOND,
|
|
24
|
-
exports.GAMBIT_TOOL_COMPLETE,
|
|
25
|
-
exports.GAMBIT_TOOL_END,
|
|
26
22
|
]);
|
|
27
23
|
// Default delay for busy/idle handler triggers.
|
|
28
24
|
exports.DEFAULT_STATUS_DELAY_MS = 800;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../src/src/loader.ts"],"names":[],"mappings":"AAwBA,OAAO,KAAK,EAMV,UAAU,EACV,UAAU,
|
|
1
|
+
{"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../src/src/loader.ts"],"names":[],"mappings":"AAwBA,OAAO,KAAK,EAMV,UAAU,EACV,UAAU,EAGX,MAAM,YAAY,CAAC;AA8WpB,wBAAsB,QAAQ,CAC5B,QAAQ,EAAE,MAAM,EAChB,UAAU,CAAC,EAAE,MAAM,EACnB,KAAK,GAAE,KAAK,CAAC,MAAM,CAAM,GACxB,OAAO,CAAC,UAAU,CAAC,CAQrB;AAED,wBAAsB,QAAQ,CAC5B,QAAQ,EAAE,MAAM,EAChB,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,UAAU,CAAC,CAiKrB"}
|
package/script/src/loader.js
CHANGED
|
@@ -96,6 +96,66 @@ function toFileUrl(p) {
|
|
|
96
96
|
const abs = path.resolve(p);
|
|
97
97
|
return path.toFileUrl(abs).href;
|
|
98
98
|
}
|
|
99
|
+
function normalizeActionIntermediateOutputPolicy(raw, context) {
|
|
100
|
+
const invalid = () => {
|
|
101
|
+
throw new Error(`[gambit] Invalid intermediateOutput policy for ${context}. Expected { emit: "allow" | "deny" }.`);
|
|
102
|
+
};
|
|
103
|
+
if (raw === undefined || raw === null) {
|
|
104
|
+
return { emit: "deny" };
|
|
105
|
+
}
|
|
106
|
+
if (typeof raw === "boolean") {
|
|
107
|
+
return { emit: raw ? "allow" : "deny" };
|
|
108
|
+
}
|
|
109
|
+
if (typeof raw === "string") {
|
|
110
|
+
const emit = raw.trim().toLowerCase();
|
|
111
|
+
if (emit === "allow" || emit === "deny")
|
|
112
|
+
return { emit };
|
|
113
|
+
invalid();
|
|
114
|
+
}
|
|
115
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw))
|
|
116
|
+
invalid();
|
|
117
|
+
const emitRaw = raw.emit;
|
|
118
|
+
if (emitRaw === undefined || emitRaw === null) {
|
|
119
|
+
return { emit: "deny" };
|
|
120
|
+
}
|
|
121
|
+
if (typeof emitRaw === "string") {
|
|
122
|
+
const emit = emitRaw.trim().toLowerCase();
|
|
123
|
+
if (emit === "allow" || emit === "deny")
|
|
124
|
+
return { emit };
|
|
125
|
+
}
|
|
126
|
+
invalid();
|
|
127
|
+
return { emit: "deny" };
|
|
128
|
+
}
|
|
129
|
+
function normalizeActionAsyncStartPolicy(raw, context) {
|
|
130
|
+
const invalid = () => {
|
|
131
|
+
throw new Error(`[gambit] Invalid asyncStart policy for ${context}. Expected { mode: "allow" | "deny" }.`);
|
|
132
|
+
};
|
|
133
|
+
if (raw === undefined || raw === null) {
|
|
134
|
+
return { mode: "deny" };
|
|
135
|
+
}
|
|
136
|
+
if (typeof raw === "boolean") {
|
|
137
|
+
return { mode: raw ? "allow" : "deny" };
|
|
138
|
+
}
|
|
139
|
+
if (typeof raw === "string") {
|
|
140
|
+
const mode = raw.trim().toLowerCase();
|
|
141
|
+
if (mode === "allow" || mode === "deny")
|
|
142
|
+
return { mode };
|
|
143
|
+
invalid();
|
|
144
|
+
}
|
|
145
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw))
|
|
146
|
+
invalid();
|
|
147
|
+
const modeRaw = raw.mode;
|
|
148
|
+
if (modeRaw === undefined || modeRaw === null) {
|
|
149
|
+
return { mode: "deny" };
|
|
150
|
+
}
|
|
151
|
+
if (typeof modeRaw === "string") {
|
|
152
|
+
const mode = modeRaw.trim().toLowerCase();
|
|
153
|
+
if (mode === "allow" || mode === "deny")
|
|
154
|
+
return { mode };
|
|
155
|
+
}
|
|
156
|
+
invalid();
|
|
157
|
+
return { mode: "deny" };
|
|
158
|
+
}
|
|
99
159
|
function normalizeActionDecks(actions, basePath) {
|
|
100
160
|
if (!actions)
|
|
101
161
|
return [];
|
|
@@ -104,6 +164,8 @@ function normalizeActionDecks(actions, basePath) {
|
|
|
104
164
|
path: a.path.startsWith("gambit://") || !basePath
|
|
105
165
|
? a.path
|
|
106
166
|
: path.resolve(path.dirname(basePath), a.path),
|
|
167
|
+
intermediateOutput: normalizeActionIntermediateOutputPolicy(a.intermediateOutput, `action "${a.name}"`),
|
|
168
|
+
asyncStart: normalizeActionAsyncStartPolicy(a.asyncStart, `action "${a.name}"`),
|
|
107
169
|
permissions: (0, permissions_js_1.normalizePermissionDeclaration)(a.permissions, basePath ? path.dirname(basePath) : dntShim.Deno.cwd()),
|
|
108
170
|
}));
|
|
109
171
|
}
|
|
@@ -152,6 +214,43 @@ function normalizeExternalTools(tools, resolvedPath) {
|
|
|
152
214
|
};
|
|
153
215
|
});
|
|
154
216
|
}
|
|
217
|
+
const CORE_RESPONSE_ITEM_TYPES = new Set([
|
|
218
|
+
"message",
|
|
219
|
+
"function_call",
|
|
220
|
+
"function_call_output",
|
|
221
|
+
"reasoning",
|
|
222
|
+
]);
|
|
223
|
+
function normalizeResponseItemExtensions(extensions, resolvedPath) {
|
|
224
|
+
if (!extensions)
|
|
225
|
+
return [];
|
|
226
|
+
const seen = new Set();
|
|
227
|
+
return extensions.map((entry) => {
|
|
228
|
+
const type = String(entry.type ?? "").trim();
|
|
229
|
+
if (!type) {
|
|
230
|
+
throw new Error(`Response item extension in ${resolvedPath} must include a type`);
|
|
231
|
+
}
|
|
232
|
+
if (!type.includes(":")) {
|
|
233
|
+
throw new Error(`Response item extension type "${type}" in ${resolvedPath} must be namespaced (expected "<namespace>:<type>")`);
|
|
234
|
+
}
|
|
235
|
+
if (CORE_RESPONSE_ITEM_TYPES.has(type)) {
|
|
236
|
+
throw new Error(`Response item extension type "${type}" in ${resolvedPath} conflicts with core OpenResponses item types`);
|
|
237
|
+
}
|
|
238
|
+
if (seen.has(type)) {
|
|
239
|
+
throw new Error(`Duplicate response item extension type "${type}" in ${resolvedPath}`);
|
|
240
|
+
}
|
|
241
|
+
seen.add(type);
|
|
242
|
+
if (!entry.dataSchema) {
|
|
243
|
+
throw new Error(`Response item extension "${type}" in ${resolvedPath} must include dataSchema`);
|
|
244
|
+
}
|
|
245
|
+
return {
|
|
246
|
+
type: type,
|
|
247
|
+
dataSchema: entry.dataSchema,
|
|
248
|
+
description: typeof entry.description === "string"
|
|
249
|
+
? entry.description
|
|
250
|
+
: undefined,
|
|
251
|
+
};
|
|
252
|
+
});
|
|
253
|
+
}
|
|
155
254
|
async function loadCardInternal(cardPath, parentPath, stack = []) {
|
|
156
255
|
const resolved = parentPath
|
|
157
256
|
? path.resolve(path.dirname(parentPath), cardPath)
|
|
@@ -237,6 +336,7 @@ async function loadDeck(deckPath, parentPath) {
|
|
|
237
336
|
}
|
|
238
337
|
const actionDecks = Object.values(mergedActions);
|
|
239
338
|
const tools = normalizeExternalTools(deck.tools, resolved);
|
|
339
|
+
const responseItemExtensions = normalizeResponseItemExtensions(deck.responseItemExtensions, resolved);
|
|
240
340
|
const actionNames = new Set(actionDecks.map((action) => action.name));
|
|
241
341
|
for (const tool of tools) {
|
|
242
342
|
if (actionNames.has(tool.name)) {
|
|
@@ -303,6 +403,7 @@ async function loadDeck(deckPath, parentPath) {
|
|
|
303
403
|
testDecks: normalizeCompanionDecks(deck.testDecks, resolved),
|
|
304
404
|
graderDecks: normalizeCompanionDecks(deck.graderDecks, resolved),
|
|
305
405
|
tools,
|
|
406
|
+
responseItemExtensions,
|
|
306
407
|
contextSchema,
|
|
307
408
|
responseSchema,
|
|
308
409
|
inputSchema,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"markdown.d.ts","sourceRoot":"","sources":["../../src/src/markdown.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EAKV,UAAU,EACV,UAAU,
|
|
1
|
+
{"version":3,"file":"markdown.d.ts","sourceRoot":"","sources":["../../src/src/markdown.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EAKV,UAAU,EACV,UAAU,EAGX,MAAM,YAAY,CAAC;AA8cpB,wBAAsB,gBAAgB,CACpC,QAAQ,EAAE,MAAM,EAChB,UAAU,CAAC,EAAE,MAAM,EACnB,KAAK,GAAE,KAAK,CAAC,MAAM,CAAM,GACxB,OAAO,CAAC,UAAU,CAAC,CAsGrB;AAED,wBAAsB,gBAAgB,CACpC,QAAQ,EAAE,MAAM,EAChB,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,UAAU,CAAC,CAuPrB;AAED,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAExD"}
|
package/script/src/markdown.js
CHANGED
|
@@ -126,9 +126,6 @@ function normalizeDeckRefs(refs, basePath, opts) {
|
|
|
126
126
|
if (!p) {
|
|
127
127
|
throw new Error("Deck reference must include a path");
|
|
128
128
|
}
|
|
129
|
-
if (opts?.requirePrompt && !p.endsWith("PROMPT.md")) {
|
|
130
|
-
throw new Error(`Deck reference must point to PROMPT.md (${basePath})`);
|
|
131
|
-
}
|
|
132
129
|
const normalized = { ...rec };
|
|
133
130
|
normalized.path = p.startsWith("gambit://")
|
|
134
131
|
? p
|
|
@@ -168,6 +165,66 @@ function mergeDeckRefs(...lists) {
|
|
|
168
165
|
}
|
|
169
166
|
return Array.from(merged.values());
|
|
170
167
|
}
|
|
168
|
+
function normalizeActionIntermediateOutputPolicy(raw, basePath) {
|
|
169
|
+
const invalid = () => {
|
|
170
|
+
throw new Error(`[gambit] Invalid intermediateOutput policy for action deck (${basePath}). Expected { emit: "allow" | "deny" }.`);
|
|
171
|
+
};
|
|
172
|
+
if (raw === undefined || raw === null) {
|
|
173
|
+
return { emit: "deny" };
|
|
174
|
+
}
|
|
175
|
+
if (typeof raw === "boolean") {
|
|
176
|
+
return { emit: raw ? "allow" : "deny" };
|
|
177
|
+
}
|
|
178
|
+
if (typeof raw === "string") {
|
|
179
|
+
const emit = raw.trim().toLowerCase();
|
|
180
|
+
if (emit === "allow" || emit === "deny")
|
|
181
|
+
return { emit };
|
|
182
|
+
invalid();
|
|
183
|
+
}
|
|
184
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw))
|
|
185
|
+
invalid();
|
|
186
|
+
const emitRaw = raw.emit;
|
|
187
|
+
if (emitRaw === undefined || emitRaw === null) {
|
|
188
|
+
return { emit: "deny" };
|
|
189
|
+
}
|
|
190
|
+
if (typeof emitRaw === "string") {
|
|
191
|
+
const emit = emitRaw.trim().toLowerCase();
|
|
192
|
+
if (emit === "allow" || emit === "deny")
|
|
193
|
+
return { emit };
|
|
194
|
+
}
|
|
195
|
+
invalid();
|
|
196
|
+
return { emit: "deny" };
|
|
197
|
+
}
|
|
198
|
+
function normalizeActionAsyncStartPolicy(raw, basePath) {
|
|
199
|
+
const invalid = () => {
|
|
200
|
+
throw new Error(`[gambit] Invalid asyncStart policy for action deck (${basePath}). Expected { mode: "allow" | "deny" }.`);
|
|
201
|
+
};
|
|
202
|
+
if (raw === undefined || raw === null) {
|
|
203
|
+
return { mode: "deny" };
|
|
204
|
+
}
|
|
205
|
+
if (typeof raw === "boolean") {
|
|
206
|
+
return { mode: raw ? "allow" : "deny" };
|
|
207
|
+
}
|
|
208
|
+
if (typeof raw === "string") {
|
|
209
|
+
const mode = raw.trim().toLowerCase();
|
|
210
|
+
if (mode === "allow" || mode === "deny")
|
|
211
|
+
return { mode };
|
|
212
|
+
invalid();
|
|
213
|
+
}
|
|
214
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw))
|
|
215
|
+
invalid();
|
|
216
|
+
const modeRaw = raw.mode;
|
|
217
|
+
if (modeRaw === undefined || modeRaw === null) {
|
|
218
|
+
return { mode: "deny" };
|
|
219
|
+
}
|
|
220
|
+
if (typeof modeRaw === "string") {
|
|
221
|
+
const mode = modeRaw.trim().toLowerCase();
|
|
222
|
+
if (mode === "allow" || mode === "deny")
|
|
223
|
+
return { mode };
|
|
224
|
+
}
|
|
225
|
+
invalid();
|
|
226
|
+
return { mode: "deny" };
|
|
227
|
+
}
|
|
171
228
|
async function normalizeActionDecks(entries, basePath, opts) {
|
|
172
229
|
if (!Array.isArray(entries))
|
|
173
230
|
return [];
|
|
@@ -195,9 +252,6 @@ async function normalizeActionDecks(entries, basePath, opts) {
|
|
|
195
252
|
if (hasPath === hasExecute) {
|
|
196
253
|
throw new Error(`Action deck must include exactly one of path or execute (${basePath})`);
|
|
197
254
|
}
|
|
198
|
-
if (hasPath && opts?.requirePrompt && !rawPath.endsWith("PROMPT.md")) {
|
|
199
|
-
throw new Error(`Deck reference must point to PROMPT.md (${basePath})`);
|
|
200
|
-
}
|
|
201
255
|
const actionContextSchema = await maybeLoadSchema(rec.contextSchema, basePath);
|
|
202
256
|
const actionResponseSchema = await maybeLoadSchema(rec.responseSchema, basePath);
|
|
203
257
|
if (hasExecute && (!actionContextSchema || !actionResponseSchema)) {
|
|
@@ -216,6 +270,8 @@ async function normalizeActionDecks(entries, basePath, opts) {
|
|
|
216
270
|
execute: hasExecute ? normalizedPath : undefined,
|
|
217
271
|
contextSchema: actionContextSchema,
|
|
218
272
|
responseSchema: actionResponseSchema,
|
|
273
|
+
intermediateOutput: normalizeActionIntermediateOutputPolicy(rec.intermediateOutput, basePath),
|
|
274
|
+
asyncStart: normalizeActionAsyncStartPolicy(rec.asyncStart, basePath),
|
|
219
275
|
};
|
|
220
276
|
if (rec.permissions !== undefined) {
|
|
221
277
|
const parsed = (0, permissions_js_1.normalizePermissionDeclaration)(rec.permissions, path.dirname(basePath));
|
|
@@ -255,6 +311,49 @@ async function normalizeExternalTools(refs, basePath) {
|
|
|
255
311
|
}
|
|
256
312
|
return out;
|
|
257
313
|
}
|
|
314
|
+
const CORE_RESPONSE_ITEM_TYPES = new Set([
|
|
315
|
+
"message",
|
|
316
|
+
"function_call",
|
|
317
|
+
"function_call_output",
|
|
318
|
+
"reasoning",
|
|
319
|
+
]);
|
|
320
|
+
async function normalizeResponseItemExtensions(refs, basePath) {
|
|
321
|
+
if (!Array.isArray(refs))
|
|
322
|
+
return [];
|
|
323
|
+
const out = [];
|
|
324
|
+
const seen = new Set();
|
|
325
|
+
for (const entry of refs) {
|
|
326
|
+
if (!entry || typeof entry !== "object" || Array.isArray(entry))
|
|
327
|
+
continue;
|
|
328
|
+
const rec = entry;
|
|
329
|
+
const type = String(rec.type ?? "").trim();
|
|
330
|
+
if (!type) {
|
|
331
|
+
throw new Error(`Response item extension must include a type (${basePath})`);
|
|
332
|
+
}
|
|
333
|
+
if (!type.includes(":")) {
|
|
334
|
+
throw new Error(`Response item extension type "${type}" must be namespaced (<namespace>:<type>) (${basePath})`);
|
|
335
|
+
}
|
|
336
|
+
if (CORE_RESPONSE_ITEM_TYPES.has(type)) {
|
|
337
|
+
throw new Error(`Response item extension type "${type}" conflicts with core OpenResponses item types (${basePath})`);
|
|
338
|
+
}
|
|
339
|
+
if (seen.has(type)) {
|
|
340
|
+
throw new Error(`Duplicate response item extension type "${type}" (${basePath})`);
|
|
341
|
+
}
|
|
342
|
+
seen.add(type);
|
|
343
|
+
const dataSchema = await maybeLoadSchema(rec.dataSchema, basePath);
|
|
344
|
+
if (!dataSchema) {
|
|
345
|
+
throw new Error(`Response item extension "${type}" must include dataSchema (${basePath})`);
|
|
346
|
+
}
|
|
347
|
+
out.push({
|
|
348
|
+
type: type,
|
|
349
|
+
dataSchema,
|
|
350
|
+
description: typeof rec.description === "string"
|
|
351
|
+
? rec.description
|
|
352
|
+
: undefined,
|
|
353
|
+
});
|
|
354
|
+
}
|
|
355
|
+
return out;
|
|
356
|
+
}
|
|
258
357
|
async function expandEmbedsInBody(args) {
|
|
259
358
|
const { body, resolvedPath, stack } = args;
|
|
260
359
|
const regex = /!\[[^\]]*\]\(([^)]+)\)/g;
|
|
@@ -383,7 +482,6 @@ async function loadMarkdownDeck(filePath, parentPath) {
|
|
|
383
482
|
const hasNewActionDecks = deckMeta.actionDecks;
|
|
384
483
|
const canonicalActions = deckMeta.actions;
|
|
385
484
|
const actionDecks = await normalizeActionDecks(canonicalActions, resolved, {
|
|
386
|
-
requirePrompt: true,
|
|
387
485
|
requireDescription: true,
|
|
388
486
|
});
|
|
389
487
|
const legacyActionDecks = await normalizeActionDecks(hasNewActionDecks, resolved);
|
|
@@ -396,8 +494,8 @@ async function loadMarkdownDeck(filePath, parentPath) {
|
|
|
396
494
|
if (deckMeta.graderDecks) {
|
|
397
495
|
logger.warn(`[gambit] deck at ${resolved} uses deprecated "graderDecks"; use "[[graders]]" instead.`);
|
|
398
496
|
}
|
|
399
|
-
const scenarioDecks = normalizeDeckRefs(deckMeta.scenarios, resolved
|
|
400
|
-
const graderDecks = normalizeDeckRefs(deckMeta.graders, resolved
|
|
497
|
+
const scenarioDecks = normalizeDeckRefs(deckMeta.scenarios, resolved);
|
|
498
|
+
const graderDecks = normalizeDeckRefs(deckMeta.graders, resolved);
|
|
401
499
|
const allActionDecks = [...actionDecks, ...legacyActionDecks];
|
|
402
500
|
allActionDecks.forEach((a) => {
|
|
403
501
|
if (a.name.startsWith(constants_js_1.RESERVED_TOOL_PREFIX) &&
|
|
@@ -481,6 +579,7 @@ async function loadMarkdownDeck(filePath, parentPath) {
|
|
|
481
579
|
: undefined;
|
|
482
580
|
const mergedActionDecks = Object.values(mergedActions);
|
|
483
581
|
const tools = await normalizeExternalTools(deckMeta.tools, resolved);
|
|
582
|
+
const responseItemExtensions = await normalizeResponseItemExtensions(deckMeta.responseItemExtensions, resolved);
|
|
484
583
|
const actionNameSet = new Set(mergedActionDecks.map((action) => action.name));
|
|
485
584
|
for (const tool of tools) {
|
|
486
585
|
if (actionNameSet.has(tool.name)) {
|
|
@@ -500,6 +599,7 @@ async function loadMarkdownDeck(filePath, parentPath) {
|
|
|
500
599
|
actionDecks: mergedActionDecks,
|
|
501
600
|
actions: mergedActionDecks,
|
|
502
601
|
tools,
|
|
602
|
+
responseItemExtensions,
|
|
503
603
|
testDecks: mergeDeckRefs(scenarioDecks, rootTestDecks, embeddedTestDecks),
|
|
504
604
|
graderDecks: mergeDeckRefs(graderDecks, rootGraderDecks, embeddedGraderDecks),
|
|
505
605
|
cards: allCards,
|
package/script/src/runtime.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Guardrails, ModelProvider } from "./types.js";
|
|
1
|
+
import type { Guardrails, ModelProvider, ResponseItem } from "./types.js";
|
|
2
2
|
import type { SavedState } from "./state.js";
|
|
3
3
|
import type { NormalizedPermissionSet, PermissionDeclarationInput } from "./permissions.js";
|
|
4
4
|
export type GambitEndSignal = {
|
|
@@ -10,6 +10,18 @@ export type GambitEndSignal = {
|
|
|
10
10
|
meta?: Record<string, unknown>;
|
|
11
11
|
};
|
|
12
12
|
export declare function isGambitEndSignal(value: unknown): value is GambitEndSignal;
|
|
13
|
+
export type IntermediateOutputErrorContext = {
|
|
14
|
+
actionName?: string;
|
|
15
|
+
parentDeckPath?: string;
|
|
16
|
+
};
|
|
17
|
+
export type IntermediateOutputEmission = {
|
|
18
|
+
responseId: string;
|
|
19
|
+
actionCallId: string;
|
|
20
|
+
parentActionCallId?: string;
|
|
21
|
+
deckPath: string;
|
|
22
|
+
outputIndex: number;
|
|
23
|
+
item: ResponseItem;
|
|
24
|
+
};
|
|
13
25
|
export type RunOptions = {
|
|
14
26
|
path: string;
|
|
15
27
|
input: unknown;
|
|
@@ -42,6 +54,9 @@ export type RunOptions = {
|
|
|
42
54
|
workerSandbox?: boolean;
|
|
43
55
|
inOrchestrationWorker?: boolean;
|
|
44
56
|
signal?: AbortSignal;
|
|
57
|
+
intermediateOutputAllow?: boolean;
|
|
58
|
+
onIntermediateOutputItem?: (emission: IntermediateOutputEmission) => void;
|
|
59
|
+
intermediateOutputErrorContext?: IntermediateOutputErrorContext;
|
|
45
60
|
onCancel?: () => unknown | Promise<unknown>;
|
|
46
61
|
onTool?: (input: {
|
|
47
62
|
name: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../src/src/runtime.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../src/src/runtime.ts"],"names":[],"mappings":"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"}
|