@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.
Files changed (105) hide show
  1. package/README.md +6 -5
  2. package/cards/context.card.md +4 -4
  3. package/decks/anthropic/agent-sdk/PROMPT.md +9 -0
  4. package/decks/openai/codex-sdk/PROMPT.md +9 -0
  5. package/decks/openai/codex-sdk/codex_client.ts +109 -0
  6. package/decks/openai/codex-sdk/codex_sdk_bridge.deck.ts +36 -0
  7. package/esm/cards/context.card.md +9 -0
  8. package/esm/cards/end.card.md +10 -0
  9. package/esm/cards/generate-test-input.card.md +12 -0
  10. package/esm/cards/respond.card.md +10 -0
  11. package/esm/decks/anthropic/agent-sdk/PROMPT.md +9 -0
  12. package/esm/decks/openai/codex-sdk/PROMPT.md +9 -0
  13. package/esm/decks/openai/codex-sdk/codex_client.ts +109 -0
  14. package/esm/decks/openai/codex-sdk/codex_sdk_bridge.deck.ts +36 -0
  15. package/esm/mod.d.ts +1 -1
  16. package/esm/mod.d.ts.map +1 -1
  17. package/esm/schemas/graders/contexts/conversation.ts +40 -0
  18. package/esm/schemas/graders/contexts/conversation.zod.ts +1 -0
  19. package/esm/schemas/graders/contexts/conversation_tools.ts +63 -0
  20. package/esm/schemas/graders/contexts/conversation_tools.zod.ts +1 -0
  21. package/esm/schemas/graders/contexts/tools.ts +5 -0
  22. package/esm/schemas/graders/contexts/tools.zod.ts +1 -0
  23. package/esm/schemas/graders/contexts/turn.ts +17 -0
  24. package/esm/schemas/graders/contexts/turn.zod.ts +1 -0
  25. package/esm/schemas/graders/contexts/turn_tools.ts +63 -0
  26. package/esm/schemas/graders/contexts/turn_tools.zod.ts +1 -0
  27. package/esm/schemas/graders/grader_output.ts +15 -0
  28. package/esm/schemas/graders/grader_output.zod.ts +1 -0
  29. package/esm/schemas/graders/respond.ts +19 -0
  30. package/esm/schemas/graders/respond.zod.ts +1 -0
  31. package/esm/schemas/scenarios/plain_chat_input_optional.ts +6 -0
  32. package/esm/schemas/scenarios/plain_chat_input_optional.zod.ts +1 -0
  33. package/esm/schemas/scenarios/plain_chat_output.ts +5 -0
  34. package/esm/schemas/scenarios/plain_chat_output.zod.ts +1 -0
  35. package/esm/snippets/context.md +8 -0
  36. package/esm/snippets/end.md +10 -0
  37. package/esm/snippets/generate-test-input.md +12 -0
  38. package/esm/snippets/init.md +12 -0
  39. package/esm/snippets/respond.md +10 -0
  40. package/esm/snippets/scenario-participant.md +10 -0
  41. package/esm/src/constants.d.ts +0 -1
  42. package/esm/src/constants.d.ts.map +1 -1
  43. package/esm/src/constants.js +0 -4
  44. package/esm/src/loader.d.ts.map +1 -1
  45. package/esm/src/loader.js +101 -0
  46. package/esm/src/markdown.d.ts.map +1 -1
  47. package/esm/src/markdown.js +109 -9
  48. package/esm/src/runtime.d.ts +16 -1
  49. package/esm/src/runtime.d.ts.map +1 -1
  50. package/esm/src/runtime.js +1607 -311
  51. package/esm/src/types.d.ts +25 -1
  52. package/esm/src/types.d.ts.map +1 -1
  53. package/package.json +1 -1
  54. package/script/cards/context.card.md +9 -0
  55. package/script/cards/end.card.md +10 -0
  56. package/script/cards/generate-test-input.card.md +12 -0
  57. package/script/cards/respond.card.md +10 -0
  58. package/script/decks/anthropic/agent-sdk/PROMPT.md +9 -0
  59. package/script/decks/openai/codex-sdk/PROMPT.md +9 -0
  60. package/script/decks/openai/codex-sdk/codex_client.ts +109 -0
  61. package/script/decks/openai/codex-sdk/codex_sdk_bridge.deck.ts +36 -0
  62. package/script/mod.d.ts +1 -1
  63. package/script/mod.d.ts.map +1 -1
  64. package/script/schemas/graders/contexts/conversation.ts +40 -0
  65. package/script/schemas/graders/contexts/conversation.zod.ts +1 -0
  66. package/script/schemas/graders/contexts/conversation_tools.ts +63 -0
  67. package/script/schemas/graders/contexts/conversation_tools.zod.ts +1 -0
  68. package/script/schemas/graders/contexts/tools.ts +5 -0
  69. package/script/schemas/graders/contexts/tools.zod.ts +1 -0
  70. package/script/schemas/graders/contexts/turn.ts +17 -0
  71. package/script/schemas/graders/contexts/turn.zod.ts +1 -0
  72. package/script/schemas/graders/contexts/turn_tools.ts +63 -0
  73. package/script/schemas/graders/contexts/turn_tools.zod.ts +1 -0
  74. package/script/schemas/graders/grader_output.ts +15 -0
  75. package/script/schemas/graders/grader_output.zod.ts +1 -0
  76. package/script/schemas/graders/respond.ts +19 -0
  77. package/script/schemas/graders/respond.zod.ts +1 -0
  78. package/script/schemas/scenarios/plain_chat_input_optional.ts +6 -0
  79. package/script/schemas/scenarios/plain_chat_input_optional.zod.ts +1 -0
  80. package/script/schemas/scenarios/plain_chat_output.ts +5 -0
  81. package/script/schemas/scenarios/plain_chat_output.zod.ts +1 -0
  82. package/script/snippets/context.md +8 -0
  83. package/script/snippets/end.md +10 -0
  84. package/script/snippets/generate-test-input.md +12 -0
  85. package/script/snippets/init.md +12 -0
  86. package/script/snippets/respond.md +10 -0
  87. package/script/snippets/scenario-participant.md +10 -0
  88. package/script/src/constants.d.ts +0 -1
  89. package/script/src/constants.d.ts.map +1 -1
  90. package/script/src/constants.js +1 -5
  91. package/script/src/loader.d.ts.map +1 -1
  92. package/script/src/loader.js +101 -0
  93. package/script/src/markdown.d.ts.map +1 -1
  94. package/script/src/markdown.js +109 -9
  95. package/script/src/runtime.d.ts +16 -1
  96. package/script/src/runtime.d.ts.map +1 -1
  97. package/script/src/runtime.js +1606 -310
  98. package/script/src/types.d.ts +25 -1
  99. package/script/src/types.d.ts.map +1 -1
  100. package/snippets/context.md +8 -0
  101. package/snippets/end.md +10 -0
  102. package/snippets/generate-test-input.md +12 -0
  103. package/snippets/init.md +12 -0
  104. package/snippets/respond.md +10 -0
  105. package/snippets/scenario-participant.md +10 -0
@@ -0,0 +1 @@
1
+ export { default } from "./grader_output.ts";
@@ -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,6 @@
1
+ import { z } from "zod";
2
+
3
+ const plainChatInputOptionalSchema: z.ZodType<string | undefined> = z.string()
4
+ .optional();
5
+
6
+ export default plainChatInputOptionalSchema;
@@ -0,0 +1 @@
1
+ export { default } from "./plain_chat_input_optional.ts";
@@ -0,0 +1,5 @@
1
+ import { z } from "zod";
2
+
3
+ const plainChatOutputSchema: z.ZodType<string> = z.string();
4
+
5
+ export default plainChatOutputSchema;
@@ -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,oBAAoB,oBAAoB,CAAC;AACtD,eAAO,MAAM,eAAe,eAAe,CAAC;AAC5C,eAAO,MAAM,qBAAqB,EAAE,WAAW,CAAC,MAAM,CAMpD,CAAC;AAGH,eAAO,MAAM,uBAAuB,MAAM,CAAC"}
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"}
@@ -12,14 +12,10 @@ export const GAMBIT_TOOL_CONTEXT = "gambit_context";
12
12
  */
13
13
  export const GAMBIT_TOOL_INIT = "gambit_init";
14
14
  export const GAMBIT_TOOL_RESPOND = "gambit_respond";
15
- export const GAMBIT_TOOL_COMPLETE = "gambit_complete";
16
15
  export const GAMBIT_TOOL_END = "gambit_end";
17
16
  export const BUILTIN_TOOL_NAME_SET = new Set([
18
17
  GAMBIT_TOOL_CONTEXT,
19
18
  GAMBIT_TOOL_INIT,
20
- GAMBIT_TOOL_RESPOND,
21
- GAMBIT_TOOL_COMPLETE,
22
- GAMBIT_TOOL_END,
23
19
  ]);
24
20
  // Default delay for busy/idle handler triggers.
25
21
  export const 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,EAEX,MAAM,YAAY,CAAC;AAiPpB,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,CA4JrB"}
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/esm/src/loader.js CHANGED
@@ -59,6 +59,66 @@ function toFileUrl(p) {
59
59
  const abs = path.resolve(p);
60
60
  return path.toFileUrl(abs).href;
61
61
  }
62
+ function normalizeActionIntermediateOutputPolicy(raw, context) {
63
+ const invalid = () => {
64
+ throw new Error(`[gambit] Invalid intermediateOutput policy for ${context}. Expected { emit: "allow" | "deny" }.`);
65
+ };
66
+ if (raw === undefined || raw === null) {
67
+ return { emit: "deny" };
68
+ }
69
+ if (typeof raw === "boolean") {
70
+ return { emit: raw ? "allow" : "deny" };
71
+ }
72
+ if (typeof raw === "string") {
73
+ const emit = raw.trim().toLowerCase();
74
+ if (emit === "allow" || emit === "deny")
75
+ return { emit };
76
+ invalid();
77
+ }
78
+ if (!raw || typeof raw !== "object" || Array.isArray(raw))
79
+ invalid();
80
+ const emitRaw = raw.emit;
81
+ if (emitRaw === undefined || emitRaw === null) {
82
+ return { emit: "deny" };
83
+ }
84
+ if (typeof emitRaw === "string") {
85
+ const emit = emitRaw.trim().toLowerCase();
86
+ if (emit === "allow" || emit === "deny")
87
+ return { emit };
88
+ }
89
+ invalid();
90
+ return { emit: "deny" };
91
+ }
92
+ function normalizeActionAsyncStartPolicy(raw, context) {
93
+ const invalid = () => {
94
+ throw new Error(`[gambit] Invalid asyncStart policy for ${context}. Expected { mode: "allow" | "deny" }.`);
95
+ };
96
+ if (raw === undefined || raw === null) {
97
+ return { mode: "deny" };
98
+ }
99
+ if (typeof raw === "boolean") {
100
+ return { mode: raw ? "allow" : "deny" };
101
+ }
102
+ if (typeof raw === "string") {
103
+ const mode = raw.trim().toLowerCase();
104
+ if (mode === "allow" || mode === "deny")
105
+ return { mode };
106
+ invalid();
107
+ }
108
+ if (!raw || typeof raw !== "object" || Array.isArray(raw))
109
+ invalid();
110
+ const modeRaw = raw.mode;
111
+ if (modeRaw === undefined || modeRaw === null) {
112
+ return { mode: "deny" };
113
+ }
114
+ if (typeof modeRaw === "string") {
115
+ const mode = modeRaw.trim().toLowerCase();
116
+ if (mode === "allow" || mode === "deny")
117
+ return { mode };
118
+ }
119
+ invalid();
120
+ return { mode: "deny" };
121
+ }
62
122
  function normalizeActionDecks(actions, basePath) {
63
123
  if (!actions)
64
124
  return [];
@@ -67,6 +127,8 @@ function normalizeActionDecks(actions, basePath) {
67
127
  path: a.path.startsWith("gambit://") || !basePath
68
128
  ? a.path
69
129
  : path.resolve(path.dirname(basePath), a.path),
130
+ intermediateOutput: normalizeActionIntermediateOutputPolicy(a.intermediateOutput, `action "${a.name}"`),
131
+ asyncStart: normalizeActionAsyncStartPolicy(a.asyncStart, `action "${a.name}"`),
70
132
  permissions: normalizePermissionDeclaration(a.permissions, basePath ? path.dirname(basePath) : dntShim.Deno.cwd()),
71
133
  }));
72
134
  }
@@ -115,6 +177,43 @@ function normalizeExternalTools(tools, resolvedPath) {
115
177
  };
116
178
  });
117
179
  }
180
+ const CORE_RESPONSE_ITEM_TYPES = new Set([
181
+ "message",
182
+ "function_call",
183
+ "function_call_output",
184
+ "reasoning",
185
+ ]);
186
+ function normalizeResponseItemExtensions(extensions, resolvedPath) {
187
+ if (!extensions)
188
+ return [];
189
+ const seen = new Set();
190
+ return extensions.map((entry) => {
191
+ const type = String(entry.type ?? "").trim();
192
+ if (!type) {
193
+ throw new Error(`Response item extension in ${resolvedPath} must include a type`);
194
+ }
195
+ if (!type.includes(":")) {
196
+ throw new Error(`Response item extension type "${type}" in ${resolvedPath} must be namespaced (expected "<namespace>:<type>")`);
197
+ }
198
+ if (CORE_RESPONSE_ITEM_TYPES.has(type)) {
199
+ throw new Error(`Response item extension type "${type}" in ${resolvedPath} conflicts with core OpenResponses item types`);
200
+ }
201
+ if (seen.has(type)) {
202
+ throw new Error(`Duplicate response item extension type "${type}" in ${resolvedPath}`);
203
+ }
204
+ seen.add(type);
205
+ if (!entry.dataSchema) {
206
+ throw new Error(`Response item extension "${type}" in ${resolvedPath} must include dataSchema`);
207
+ }
208
+ return {
209
+ type: type,
210
+ dataSchema: entry.dataSchema,
211
+ description: typeof entry.description === "string"
212
+ ? entry.description
213
+ : undefined,
214
+ };
215
+ });
216
+ }
118
217
  async function loadCardInternal(cardPath, parentPath, stack = []) {
119
218
  const resolved = parentPath
120
219
  ? path.resolve(path.dirname(parentPath), cardPath)
@@ -200,6 +299,7 @@ export async function loadDeck(deckPath, parentPath) {
200
299
  }
201
300
  const actionDecks = Object.values(mergedActions);
202
301
  const tools = normalizeExternalTools(deck.tools, resolved);
302
+ const responseItemExtensions = normalizeResponseItemExtensions(deck.responseItemExtensions, resolved);
203
303
  const actionNames = new Set(actionDecks.map((action) => action.name));
204
304
  for (const tool of tools) {
205
305
  if (actionNames.has(tool.name)) {
@@ -266,6 +366,7 @@ export async function loadDeck(deckPath, parentPath) {
266
366
  testDecks: normalizeCompanionDecks(deck.testDecks, resolved),
267
367
  graderDecks: normalizeCompanionDecks(deck.graderDecks, resolved),
268
368
  tools,
369
+ responseItemExtensions,
269
370
  contextSchema,
270
371
  responseSchema,
271
372
  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,EAEX,MAAM,YAAY,CAAC;AAuVpB,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,CAqPrB;AAED,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAExD"}
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"}
@@ -88,9 +88,6 @@ function normalizeDeckRefs(refs, basePath, opts) {
88
88
  if (!p) {
89
89
  throw new Error("Deck reference must include a path");
90
90
  }
91
- if (opts?.requirePrompt && !p.endsWith("PROMPT.md")) {
92
- throw new Error(`Deck reference must point to PROMPT.md (${basePath})`);
93
- }
94
91
  const normalized = { ...rec };
95
92
  normalized.path = p.startsWith("gambit://")
96
93
  ? p
@@ -130,6 +127,66 @@ function mergeDeckRefs(...lists) {
130
127
  }
131
128
  return Array.from(merged.values());
132
129
  }
130
+ function normalizeActionIntermediateOutputPolicy(raw, basePath) {
131
+ const invalid = () => {
132
+ throw new Error(`[gambit] Invalid intermediateOutput policy for action deck (${basePath}). Expected { emit: "allow" | "deny" }.`);
133
+ };
134
+ if (raw === undefined || raw === null) {
135
+ return { emit: "deny" };
136
+ }
137
+ if (typeof raw === "boolean") {
138
+ return { emit: raw ? "allow" : "deny" };
139
+ }
140
+ if (typeof raw === "string") {
141
+ const emit = raw.trim().toLowerCase();
142
+ if (emit === "allow" || emit === "deny")
143
+ return { emit };
144
+ invalid();
145
+ }
146
+ if (!raw || typeof raw !== "object" || Array.isArray(raw))
147
+ invalid();
148
+ const emitRaw = raw.emit;
149
+ if (emitRaw === undefined || emitRaw === null) {
150
+ return { emit: "deny" };
151
+ }
152
+ if (typeof emitRaw === "string") {
153
+ const emit = emitRaw.trim().toLowerCase();
154
+ if (emit === "allow" || emit === "deny")
155
+ return { emit };
156
+ }
157
+ invalid();
158
+ return { emit: "deny" };
159
+ }
160
+ function normalizeActionAsyncStartPolicy(raw, basePath) {
161
+ const invalid = () => {
162
+ throw new Error(`[gambit] Invalid asyncStart policy for action deck (${basePath}). Expected { mode: "allow" | "deny" }.`);
163
+ };
164
+ if (raw === undefined || raw === null) {
165
+ return { mode: "deny" };
166
+ }
167
+ if (typeof raw === "boolean") {
168
+ return { mode: raw ? "allow" : "deny" };
169
+ }
170
+ if (typeof raw === "string") {
171
+ const mode = raw.trim().toLowerCase();
172
+ if (mode === "allow" || mode === "deny")
173
+ return { mode };
174
+ invalid();
175
+ }
176
+ if (!raw || typeof raw !== "object" || Array.isArray(raw))
177
+ invalid();
178
+ const modeRaw = raw.mode;
179
+ if (modeRaw === undefined || modeRaw === null) {
180
+ return { mode: "deny" };
181
+ }
182
+ if (typeof modeRaw === "string") {
183
+ const mode = modeRaw.trim().toLowerCase();
184
+ if (mode === "allow" || mode === "deny")
185
+ return { mode };
186
+ }
187
+ invalid();
188
+ return { mode: "deny" };
189
+ }
133
190
  async function normalizeActionDecks(entries, basePath, opts) {
134
191
  if (!Array.isArray(entries))
135
192
  return [];
@@ -157,9 +214,6 @@ async function normalizeActionDecks(entries, basePath, opts) {
157
214
  if (hasPath === hasExecute) {
158
215
  throw new Error(`Action deck must include exactly one of path or execute (${basePath})`);
159
216
  }
160
- if (hasPath && opts?.requirePrompt && !rawPath.endsWith("PROMPT.md")) {
161
- throw new Error(`Deck reference must point to PROMPT.md (${basePath})`);
162
- }
163
217
  const actionContextSchema = await maybeLoadSchema(rec.contextSchema, basePath);
164
218
  const actionResponseSchema = await maybeLoadSchema(rec.responseSchema, basePath);
165
219
  if (hasExecute && (!actionContextSchema || !actionResponseSchema)) {
@@ -178,6 +232,8 @@ async function normalizeActionDecks(entries, basePath, opts) {
178
232
  execute: hasExecute ? normalizedPath : undefined,
179
233
  contextSchema: actionContextSchema,
180
234
  responseSchema: actionResponseSchema,
235
+ intermediateOutput: normalizeActionIntermediateOutputPolicy(rec.intermediateOutput, basePath),
236
+ asyncStart: normalizeActionAsyncStartPolicy(rec.asyncStart, basePath),
181
237
  };
182
238
  if (rec.permissions !== undefined) {
183
239
  const parsed = normalizePermissionDeclaration(rec.permissions, path.dirname(basePath));
@@ -217,6 +273,49 @@ async function normalizeExternalTools(refs, basePath) {
217
273
  }
218
274
  return out;
219
275
  }
276
+ const CORE_RESPONSE_ITEM_TYPES = new Set([
277
+ "message",
278
+ "function_call",
279
+ "function_call_output",
280
+ "reasoning",
281
+ ]);
282
+ async function normalizeResponseItemExtensions(refs, basePath) {
283
+ if (!Array.isArray(refs))
284
+ return [];
285
+ const out = [];
286
+ const seen = new Set();
287
+ for (const entry of refs) {
288
+ if (!entry || typeof entry !== "object" || Array.isArray(entry))
289
+ continue;
290
+ const rec = entry;
291
+ const type = String(rec.type ?? "").trim();
292
+ if (!type) {
293
+ throw new Error(`Response item extension must include a type (${basePath})`);
294
+ }
295
+ if (!type.includes(":")) {
296
+ throw new Error(`Response item extension type "${type}" must be namespaced (<namespace>:<type>) (${basePath})`);
297
+ }
298
+ if (CORE_RESPONSE_ITEM_TYPES.has(type)) {
299
+ throw new Error(`Response item extension type "${type}" conflicts with core OpenResponses item types (${basePath})`);
300
+ }
301
+ if (seen.has(type)) {
302
+ throw new Error(`Duplicate response item extension type "${type}" (${basePath})`);
303
+ }
304
+ seen.add(type);
305
+ const dataSchema = await maybeLoadSchema(rec.dataSchema, basePath);
306
+ if (!dataSchema) {
307
+ throw new Error(`Response item extension "${type}" must include dataSchema (${basePath})`);
308
+ }
309
+ out.push({
310
+ type: type,
311
+ dataSchema,
312
+ description: typeof rec.description === "string"
313
+ ? rec.description
314
+ : undefined,
315
+ });
316
+ }
317
+ return out;
318
+ }
220
319
  async function expandEmbedsInBody(args) {
221
320
  const { body, resolvedPath, stack } = args;
222
321
  const regex = /!\[[^\]]*\]\(([^)]+)\)/g;
@@ -345,7 +444,6 @@ export async function loadMarkdownDeck(filePath, parentPath) {
345
444
  const hasNewActionDecks = deckMeta.actionDecks;
346
445
  const canonicalActions = deckMeta.actions;
347
446
  const actionDecks = await normalizeActionDecks(canonicalActions, resolved, {
348
- requirePrompt: true,
349
447
  requireDescription: true,
350
448
  });
351
449
  const legacyActionDecks = await normalizeActionDecks(hasNewActionDecks, resolved);
@@ -358,8 +456,8 @@ export async function loadMarkdownDeck(filePath, parentPath) {
358
456
  if (deckMeta.graderDecks) {
359
457
  logger.warn(`[gambit] deck at ${resolved} uses deprecated "graderDecks"; use "[[graders]]" instead.`);
360
458
  }
361
- const scenarioDecks = normalizeDeckRefs(deckMeta.scenarios, resolved, { requirePrompt: true });
362
- const graderDecks = normalizeDeckRefs(deckMeta.graders, resolved, { requirePrompt: true });
459
+ const scenarioDecks = normalizeDeckRefs(deckMeta.scenarios, resolved);
460
+ const graderDecks = normalizeDeckRefs(deckMeta.graders, resolved);
363
461
  const allActionDecks = [...actionDecks, ...legacyActionDecks];
364
462
  allActionDecks.forEach((a) => {
365
463
  if (a.name.startsWith(RESERVED_TOOL_PREFIX) &&
@@ -443,6 +541,7 @@ export async function loadMarkdownDeck(filePath, parentPath) {
443
541
  : undefined;
444
542
  const mergedActionDecks = Object.values(mergedActions);
445
543
  const tools = await normalizeExternalTools(deckMeta.tools, resolved);
544
+ const responseItemExtensions = await normalizeResponseItemExtensions(deckMeta.responseItemExtensions, resolved);
446
545
  const actionNameSet = new Set(mergedActionDecks.map((action) => action.name));
447
546
  for (const tool of tools) {
448
547
  if (actionNameSet.has(tool.name)) {
@@ -462,6 +561,7 @@ export async function loadMarkdownDeck(filePath, parentPath) {
462
561
  actionDecks: mergedActionDecks,
463
562
  actions: mergedActionDecks,
464
563
  tools,
564
+ responseItemExtensions,
465
565
  testDecks: mergeDeckRefs(scenarioDecks, rootTestDecks, embeddedTestDecks),
466
566
  graderDecks: mergeDeckRefs(graderDecks, rootGraderDecks, embeddedGraderDecks),
467
567
  cards: allCards,
@@ -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":"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"}
1
+ {"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../src/src/runtime.ts"],"names":[],"mappings":"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"}