@trydreamstate/cli 1.3.7 → 1.3.11
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/agent-plugin/.claude-plugin/plugin.json +1 -1
- package/agent-plugin/.codex-plugin/plugin.json +1 -1
- package/agent-plugin/skills/crm/SKILL.md +2 -0
- package/agent-plugin/skills/diagnostics/SKILL.md +7 -1
- package/agent-plugin/skills/facebook-posts/SKILL.md +46 -0
- package/agent-plugin/skills/instagram-posts/SKILL.md +56 -0
- package/agent-plugin/skills/list-building/SKILL.md +3 -0
- package/agent-plugin/skills/list-building/column-authoring.md +6 -0
- package/agent-plugin/skills/list-building/incoming-people.md +32 -0
- package/agent-plugin/skills/list-building/sourcing.md +14 -0
- package/agent-plugin/skills/outreach/SKILL.md +8 -0
- package/agent-plugin/skills/outreach/enrollment.md +5 -1
- package/agent-plugin/skills/plays/SKILL.md +15 -0
- package/agent-plugin/skills/social/SKILL.md +4 -0
- package/agent-plugin/skills/tiktok-posts/SKILL.md +51 -0
- package/agent-plugin/skills/visibility/SKILL.md +4 -0
- package/agent-plugin/skills/workflows/SKILL.md +2 -0
- package/agent-plugin/skills/workflows/lifecycle-and-enrollment.md +2 -0
- package/agent-plugin/skills/youtube-posts/SKILL.md +49 -0
- package/dist/client.d.ts +6 -1
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +35 -11
- package/dist/commandTable.d.ts +2 -2
- package/dist/commandTable.d.ts.map +1 -1
- package/dist/commandTable.js +5 -2
- package/dist/commands/genericPack.d.ts +13 -0
- package/dist/commands/genericPack.d.ts.map +1 -0
- package/dist/commands/genericPack.js +31 -0
- package/dist/commands/knowledge.d.ts +2 -0
- package/dist/commands/knowledge.d.ts.map +1 -0
- package/dist/commands/knowledge.js +6 -0
- package/dist/commands/shared.d.ts +3 -1
- package/dist/commands/shared.d.ts.map +1 -1
- package/dist/commands/shared.js +14 -5
- package/dist/commands/tables.d.ts +2 -0
- package/dist/commands/tables.d.ts.map +1 -0
- package/dist/commands/tables.js +6 -0
- package/dist/commands/unibox.d.ts +2 -0
- package/dist/commands/unibox.d.ts.map +1 -0
- package/dist/commands/unibox.js +6 -0
- package/dist/gatedRun.d.ts.map +1 -1
- package/dist/gatedRun.js +105 -35
- package/dist/generated/packVerbs.generated.json +332 -4
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +47 -6
- package/dist/money.d.ts +2 -1
- package/dist/money.d.ts.map +1 -1
- package/dist/money.js +22 -5
- package/dist/runWait.d.ts +1 -1
- package/dist/runWait.d.ts.map +1 -1
- package/dist/runWait.js +37 -5
- package/dist/turnCache.d.ts +5 -1
- package/dist/turnCache.d.ts.map +1 -1
- package/dist/turnCache.js +5 -3
- package/package.json +1 -1
package/dist/commandTable.d.ts
CHANGED
|
@@ -6,8 +6,8 @@
|
|
|
6
6
|
* what the CLI really parses, with no second hand-kept list:
|
|
7
7
|
*
|
|
8
8
|
* - every `dreamstate ...` usage line the CLI prints (USAGE in index.ts), and
|
|
9
|
-
* - every sequences / workflows
|
|
10
|
-
* capability each one runs.
|
|
9
|
+
* - every sequences / workflows / knowledge / unibox / tables verb (the verb
|
|
10
|
+
* tables in commands/), with the capability each one runs.
|
|
11
11
|
*
|
|
12
12
|
* A capability with no verb is reached through `tools run`, which stays a
|
|
13
13
|
* catalog search (`tools search`); `commands search` reports those separately.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"commandTable.d.ts","sourceRoot":"","sources":["../src/commandTable.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,eAAe;IAC9B,6EAA6E;IAC7E,OAAO,EAAE,MAAM,CAAC;IAChB,6CAA6C;IAC7C,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,4DAA4D;IAC5D,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AA6BD,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,eAAe,EAAE,
|
|
1
|
+
{"version":3,"file":"commandTable.d.ts","sourceRoot":"","sources":["../src/commandTable.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,eAAe;IAC9B,6EAA6E;IAC7E,OAAO,EAAE,MAAM,CAAC;IAChB,6CAA6C;IAC7C,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,4DAA4D;IAC5D,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AA6BD,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,eAAe,EAAE,CAchE;AAMD,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,SAAK,GAAG,eAAe,EAAE,CAc5F"}
|
package/dist/commandTable.js
CHANGED
|
@@ -11,7 +11,7 @@ function usageEntries(usage) {
|
|
|
11
11
|
return usage.split('\n')
|
|
12
12
|
.filter((line) => line.startsWith(' dreamstate '))
|
|
13
13
|
.map((line) => line.trim())
|
|
14
|
-
.filter((line) => !/^dreamstate (sequences|workflows) <verb>/.test(line))
|
|
14
|
+
.filter((line) => !/^dreamstate (sequences|workflows|knowledge|unibox|tables) <verb>/.test(line))
|
|
15
15
|
.map((line) => {
|
|
16
16
|
const words = line.split(/\s+/);
|
|
17
17
|
// `dreamstate tools run <capability_id> ...`: the typed command is the leading words
|
|
@@ -25,13 +25,16 @@ function cliCommandTable(usage) {
|
|
|
25
25
|
// Required lazily: the verb tables import the CLI entry point's helpers.
|
|
26
26
|
const { SEQUENCE_VERBS } = require('./commands/sequences');
|
|
27
27
|
const { WORKFLOW_VERBS } = require('./commands/workflows');
|
|
28
|
+
const { KNOWLEDGE_VERBS } = require('./commands/knowledge');
|
|
29
|
+
const { UNIBOX_VERBS } = require('./commands/unibox');
|
|
30
|
+
const { TABLES_VERBS } = require('./commands/tables');
|
|
28
31
|
const verbs = (pack, specs) => specs.map((spec) => ({
|
|
29
32
|
command: `dreamstate ${pack} ${spec.verb}`,
|
|
30
33
|
usage: verbUsage(pack, spec),
|
|
31
34
|
summary: '',
|
|
32
35
|
capability_id: spec.capabilityId,
|
|
33
36
|
}));
|
|
34
|
-
return [...usageEntries(usage), ...verbs('sequences', SEQUENCE_VERBS), ...verbs('workflows', WORKFLOW_VERBS)];
|
|
37
|
+
return [...usageEntries(usage), ...verbs('sequences', SEQUENCE_VERBS), ...verbs('workflows', WORKFLOW_VERBS), ...verbs('knowledge', KNOWLEDGE_VERBS), ...verbs('unibox', UNIBOX_VERBS), ...verbs('tables', TABLES_VERBS)];
|
|
35
38
|
}
|
|
36
39
|
function terms(value) {
|
|
37
40
|
return value.toLowerCase().split(/[^a-z0-9_]+/).filter((word) => word.length > 1);
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type PackVerbSpec } from './shared';
|
|
2
|
+
import type { CliCommand } from '../index';
|
|
3
|
+
import type { GatedRunContext } from '../gatedRun';
|
|
4
|
+
/** Pack groups that have no shared authoring kind and no local init scaffold. */
|
|
5
|
+
export type SimplePackName = 'knowledge' | 'unibox' | 'tables';
|
|
6
|
+
export interface PackSurface {
|
|
7
|
+
verbs: PackVerbSpec[];
|
|
8
|
+
usage: string;
|
|
9
|
+
parse: (argv: string[]) => CliCommand;
|
|
10
|
+
run: (context: GatedRunContext | undefined, command: CliCommand, stdout: NodeJS.WritableStream) => Promise<void>;
|
|
11
|
+
}
|
|
12
|
+
export declare function packSurface(pack: SimplePackName): PackSurface;
|
|
13
|
+
//# sourceMappingURL=genericPack.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"genericPack.d.ts","sourceRoot":"","sources":["../../src/commands/genericPack.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoD,KAAK,YAAY,EAAE,MAAM,UAAU,CAAC;AAC/F,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAC3C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAInD,iFAAiF;AACjF,MAAM,MAAM,cAAc,GAAG,WAAW,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAE/D,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,YAAY,EAAE,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,UAAU,CAAC;IACtC,GAAG,EAAE,CAAC,OAAO,EAAE,eAAe,GAAG,SAAS,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,CAAC,cAAc,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAClH;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,cAAc,GAAG,WAAW,CAoB7D"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.packSurface = packSurface;
|
|
7
|
+
const shared_1 = require("./shared");
|
|
8
|
+
const errors_1 = require("../errors");
|
|
9
|
+
const packVerbs_generated_json_1 = __importDefault(require("../generated/packVerbs.generated.json"));
|
|
10
|
+
function packSurface(pack) {
|
|
11
|
+
const prefix = pack + ' ';
|
|
12
|
+
const verbs = packVerbs_generated_json_1.default.verbs
|
|
13
|
+
.filter(({ command }) => command.startsWith(prefix))
|
|
14
|
+
.map(({ command, capabilityId, positional, local }) => ({
|
|
15
|
+
verb: command.slice(prefix.length),
|
|
16
|
+
capabilityId,
|
|
17
|
+
...(positional ? { positional } : {}),
|
|
18
|
+
...(local === 'init' ? { local: 'init' } : {}),
|
|
19
|
+
}));
|
|
20
|
+
const usage = (0, shared_1.renderPackUsage)(pack, verbs);
|
|
21
|
+
return {
|
|
22
|
+
verbs,
|
|
23
|
+
usage,
|
|
24
|
+
parse: (0, shared_1.buildPackParser)(pack, undefined, verbs, usage),
|
|
25
|
+
async run(context, command, stdout) {
|
|
26
|
+
if (!context)
|
|
27
|
+
throw new errors_1.CliUsageError(pack + ' commands require an authenticated session.');
|
|
28
|
+
await (0, shared_1.runPackCommand)(context, command, stdout);
|
|
29
|
+
},
|
|
30
|
+
};
|
|
31
|
+
}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export declare const KNOWLEDGE_VERBS: import("./shared").PackVerbSpec[], KNOWLEDGE_USAGE: string, parseKnowledgeCommand: (argv: string[]) => import("..").CliCommand, runKnowledgeCommand: (context: import("../gatedRun").GatedRunContext | undefined, command: import("..").CliCommand, stdout: NodeJS.WritableStream) => Promise<void>;
|
|
2
|
+
//# sourceMappingURL=knowledge.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"knowledge.d.ts","sourceRoot":"","sources":["../../src/commands/knowledge.ts"],"names":[],"mappings":"AAEA,eAAO,MACE,eAAe,qCACf,eAAe,UACf,qBAAqB,+CACvB,mBAAmB,gJACE,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var _a;
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.runKnowledgeCommand = exports.parseKnowledgeCommand = exports.KNOWLEDGE_USAGE = exports.KNOWLEDGE_VERBS = void 0;
|
|
5
|
+
const genericPack_1 = require("./genericPack");
|
|
6
|
+
_a = (0, genericPack_1.packSurface)('knowledge'), exports.KNOWLEDGE_VERBS = _a.verbs, exports.KNOWLEDGE_USAGE = _a.usage, exports.parseKnowledgeCommand = _a.parse, exports.runKnowledgeCommand = _a.run;
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { type CliCommand } from '../index';
|
|
2
2
|
import { type GatedRunContext } from '../gatedRun';
|
|
3
|
+
/** First-class CLI pack groups. sequences and workflows also carry the shared authoring kind. */
|
|
4
|
+
export type PackName = 'sequences' | 'workflows' | 'knowledge' | 'unibox' | 'tables';
|
|
3
5
|
export interface PackVerbSpec {
|
|
4
6
|
verb: string;
|
|
5
7
|
capabilityId: string;
|
|
@@ -18,7 +20,7 @@ export interface PackVerbSpec {
|
|
|
18
20
|
/** Local-only route; `init` accepts --name and --file without an API schema. */
|
|
19
21
|
local?: 'init';
|
|
20
22
|
}
|
|
21
|
-
export declare function buildPackParser(pack:
|
|
23
|
+
export declare function buildPackParser(pack: PackName, kind: 'sequence' | 'workflow' | undefined, specs: PackVerbSpec[], usage: string): (argv: string[]) => CliCommand;
|
|
22
24
|
/**
|
|
23
25
|
* A starter document written to disk, so authoring can begin from a file the way the
|
|
24
26
|
* rest of this pack now accepts one. It writes nothing to the workspace and calls no
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../src/commands/shared.ts"],"names":[],"mappings":"AAKA,OAAO,EAAc,KAAK,UAAU,EAAiC,MAAM,UAAU,CAAC;AAEtF,OAAO,EAA4B,KAAK,eAAe,EAAE,MAAM,aAAa,CAAC;AAS7E,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IACnC;;;;;;OAMG;IACH,UAAU,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAE,EAAE,CAAC;IAClE,gFAAgF;IAChF,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AA4CD,wBAAgB,eAAe,CAC7B,IAAI,EAAE,
|
|
1
|
+
{"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../src/commands/shared.ts"],"names":[],"mappings":"AAKA,OAAO,EAAc,KAAK,UAAU,EAAiC,MAAM,UAAU,CAAC;AAEtF,OAAO,EAA4B,KAAK,eAAe,EAAE,MAAM,aAAa,CAAC;AAS7E,iGAAiG;AACjG,MAAM,MAAM,QAAQ,GAAG,WAAW,GAAG,WAAW,GAAG,WAAW,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAErF,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IACnC;;;;;;OAMG;IACH,UAAU,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAE,EAAE,CAAC;IAClE,gFAAgF;IAChF,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AA4CD,wBAAgB,eAAe,CAC7B,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,UAAU,GAAC,UAAU,GAAC,SAAS,EAAE,KAAK,EAAE,YAAY,EAAE,EAAE,KAAK,EAAE,MAAM,GAC1F,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,UAAU,CAsFhC;AAGD;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,UAAU,GAAG,UAAU,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAKjG;AAED,wBAAgB,WAAW,CACzB,IAAI,EAAE,UAAU,GAAG,UAAU,EAC7B,OAAO,EAAE,UAAU,EACnB,MAAM,EAAE,MAAM,CAAC,cAAc,GAC5B,IAAI,CAuBN;AAYD,wBAAsB,cAAc,CAClC,OAAO,EAAE,eAAe,EACxB,OAAO,EAAE,UAAU,EACnB,MAAM,EAAE,MAAM,CAAC,cAAc,GAC5B,OAAO,CAAC,IAAI,CAAC,CA6Df;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,EAAE,GAAG,MAAM,CAK3E"}
|
package/dist/commands/shared.js
CHANGED
|
@@ -132,7 +132,7 @@ function buildPackParser(pack, kind, specs, usage) {
|
|
|
132
132
|
// family-specific capabilities have strict schemas that do not declare it,
|
|
133
133
|
// so injecting it everywhere made every one of those verbs fail validation
|
|
134
134
|
// with an unrecognized key before it reached the server's real work.
|
|
135
|
-
if (spec.capabilityId.startsWith('workflow.automations.'))
|
|
135
|
+
if (kind !== undefined && spec.capabilityId.startsWith('workflow.automations.'))
|
|
136
136
|
input.kind = kind;
|
|
137
137
|
// No default mode. A mutating verb run with no mode used to be rewritten to dry_run
|
|
138
138
|
// silently, where `tools run` sends none and lets the server answer mode_required
|
|
@@ -238,10 +238,7 @@ async function runPackCommand(context, command, stdout) {
|
|
|
238
238
|
const outcome = await (0, gatedRun_1.runGated)(context, {
|
|
239
239
|
capabilityId: command.capabilityId,
|
|
240
240
|
body: {
|
|
241
|
-
params:
|
|
242
|
-
...command.input,
|
|
243
|
-
...(command.maxLiveSends === undefined ? {} : { max_live_sends: command.maxLiveSends }),
|
|
244
|
-
},
|
|
241
|
+
params: command.input,
|
|
245
242
|
...(command.mode ? { mode: command.mode } : {}),
|
|
246
243
|
...(maxCredits === undefined ? {} : { max_credits: maxCredits }),
|
|
247
244
|
...(command.approved ? { approved: true } : {}),
|
|
@@ -254,6 +251,18 @@ async function runPackCommand(context, command, stdout) {
|
|
|
254
251
|
waitTimeout: command.waitTimeout,
|
|
255
252
|
...(command.noWait ? { noWait: true } : {}),
|
|
256
253
|
coerceParams: true,
|
|
254
|
+
// max_live_sends is a capability param, not a door control. It belongs in
|
|
255
|
+
// params only where the live schema declares it; sequence lifecycle and
|
|
256
|
+
// enrollment capabilities (for example sequence.sequences.activate_audience)
|
|
257
|
+
// have a strict, cap-free schema, so injecting it there was refused before
|
|
258
|
+
// the request left the CLI.
|
|
259
|
+
...(command.maxLiveSends === undefined ? {} : { adjustParams: (params, capability) => {
|
|
260
|
+
const schema = capability?.input_json_schema;
|
|
261
|
+
const properties = schema && typeof schema === 'object' ? schema.properties : null;
|
|
262
|
+
return properties && typeof properties === 'object' && Object.prototype.hasOwnProperty.call(properties, 'max_live_sends')
|
|
263
|
+
? { ...params, max_live_sends: command.maxLiveSends }
|
|
264
|
+
: params;
|
|
265
|
+
} }),
|
|
257
266
|
});
|
|
258
267
|
const result = outcome.value;
|
|
259
268
|
if (outcome.timedOut)
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export declare const TABLES_VERBS: import("./shared").PackVerbSpec[], TABLES_USAGE: string, parseTablesCommand: (argv: string[]) => import("..").CliCommand, runTablesCommand: (context: import("../gatedRun").GatedRunContext | undefined, command: import("..").CliCommand, stdout: NodeJS.WritableStream) => Promise<void>;
|
|
2
|
+
//# sourceMappingURL=tables.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tables.d.ts","sourceRoot":"","sources":["../../src/commands/tables.ts"],"names":[],"mappings":"AAEA,eAAO,MACE,YAAY,qCACZ,YAAY,UACZ,kBAAkB,+CACpB,gBAAgB,gJACE,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var _a;
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.runTablesCommand = exports.parseTablesCommand = exports.TABLES_USAGE = exports.TABLES_VERBS = void 0;
|
|
5
|
+
const genericPack_1 = require("./genericPack");
|
|
6
|
+
_a = (0, genericPack_1.packSurface)('tables'), exports.TABLES_VERBS = _a.verbs, exports.TABLES_USAGE = _a.usage, exports.parseTablesCommand = _a.parse, exports.runTablesCommand = _a.run;
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export declare const UNIBOX_VERBS: import("./shared").PackVerbSpec[], UNIBOX_USAGE: string, parseUniboxCommand: (argv: string[]) => import("..").CliCommand, runUniboxCommand: (context: import("../gatedRun").GatedRunContext | undefined, command: import("..").CliCommand, stdout: NodeJS.WritableStream) => Promise<void>;
|
|
2
|
+
//# sourceMappingURL=unibox.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"unibox.d.ts","sourceRoot":"","sources":["../../src/commands/unibox.ts"],"names":[],"mappings":"AAEA,eAAO,MACE,YAAY,qCACZ,YAAY,UACZ,kBAAkB,+CACpB,gBAAgB,gJACE,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var _a;
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.runUniboxCommand = exports.parseUniboxCommand = exports.UNIBOX_USAGE = exports.UNIBOX_VERBS = void 0;
|
|
5
|
+
const genericPack_1 = require("./genericPack");
|
|
6
|
+
_a = (0, genericPack_1.packSurface)('unibox'), exports.UNIBOX_VERBS = _a.verbs, exports.UNIBOX_USAGE = _a.usage, exports.parseUniboxCommand = _a.parse, exports.runUniboxCommand = _a.run;
|
package/dist/gatedRun.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gatedRun.d.ts","sourceRoot":"","sources":["../src/gatedRun.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAA0B,KAAK,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAEnF,OAAO,EAA4F,KAAK,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAoBnJ,wBAAgB,IAAI,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAIvD;AAUD,4FAA4F;AAC5F,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAKjF;AAgBD;;;;;;;;;GASG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,GAAG,SAAS,EAAE,QAAQ,EAAE,mBAAmB,GAAG,MAAM,GAAG,IAAI,CAKrI;AAED,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,GAAG,SAAS,CAKzF;AAED;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,YAAY,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,QAAQ,GAAG,IAAI,CAazF;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAMrE;
|
|
1
|
+
{"version":3,"file":"gatedRun.d.ts","sourceRoot":"","sources":["../src/gatedRun.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAA0B,KAAK,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAEnF,OAAO,EAA4F,KAAK,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAoBnJ,wBAAgB,IAAI,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAIvD;AAUD,4FAA4F;AAC5F,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAKjF;AAgBD;;;;;;;;;GASG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,GAAG,SAAS,EAAE,QAAQ,EAAE,mBAAmB,GAAG,MAAM,GAAG,IAAI,CAKrI;AAED,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,GAAG,SAAS,CAKzF;AAED;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,YAAY,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,QAAQ,GAAG,IAAI,CAazF;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAMrE;AAqLD,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,gBAAgB,CAAC;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,mGAAmG;IACnG,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,iEAAiE;IACjE,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC,cAAc,CAAC;IAC9B,KAAK,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAChD;AAED,MAAM,WAAW,aAAa;IAC5B,YAAY,EAAE,MAAM,CAAC;IACrB,sFAAsF;IACtF,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,qEAAqE;IACrE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,qFAAqF;IACrF,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;;;OAGG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB;;;;;OAKG;IACH,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,KAAK,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACzH;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,OAAO,CAAC;IACf,QAAQ,EAAE,OAAO,CAAC;IAClB,4EAA4E;IAC5E,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,qGAAqG;IACrG,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AASD,wBAAsB,QAAQ,CAAC,OAAO,EAAE,eAAe,EAAE,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,eAAe,CAAC,CAoOvG;AAED,uFAAuF;AACvF,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,GAAG,QAAQ,GAAG,IAAI,CAEpE;AAED,mGAAmG;AACnG,wBAAsB,cAAc,CAClC,OAAO,EAAE,eAAe,EACxB,YAAY,EAAE,MAAM,EACpB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,OAAO,CAAC,CAGlB"}
|
package/dist/gatedRun.js
CHANGED
|
@@ -121,7 +121,19 @@ function planFingerprint(body) {
|
|
|
121
121
|
delete params[key];
|
|
122
122
|
return (0, node_crypto_1.createHash)('sha256').update((0, idempotency_1.stableJson)({ params, max_credits: body.max_credits ?? null })).digest('hex');
|
|
123
123
|
}
|
|
124
|
-
|
|
124
|
+
function creditsPhrase(estimate) {
|
|
125
|
+
if (!estimate)
|
|
126
|
+
return null;
|
|
127
|
+
const { minimum_credits: minimum, maximum_credits: maximum, expected_credits: expected } = estimate;
|
|
128
|
+
if (typeof minimum === 'number' && typeof maximum === 'number' && minimum !== maximum)
|
|
129
|
+
return `${minimum}..${maximum} credits`;
|
|
130
|
+
if (typeof minimum !== 'number' && typeof maximum === 'number')
|
|
131
|
+
return `up to ${maximum} credits`;
|
|
132
|
+
if (typeof expected === 'number')
|
|
133
|
+
return `${expected} credits`;
|
|
134
|
+
return typeof maximum === 'number' ? `${maximum} credits` : null;
|
|
135
|
+
}
|
|
136
|
+
/** The quote a supported rehearsal returned, wherever the envelope nests its outputs. */
|
|
125
137
|
function quoteFromResult(value, depth = 0) {
|
|
126
138
|
if (!value || typeof value !== 'object' || depth > 6)
|
|
127
139
|
return null;
|
|
@@ -135,10 +147,14 @@ function quoteFromResult(value, depth = 0) {
|
|
|
135
147
|
}
|
|
136
148
|
const entry = value;
|
|
137
149
|
if (typeof entry.quote_hash === 'string' && runContract_1.QUOTE_HASH_PATTERN.test(entry.quote_hash)) {
|
|
138
|
-
const estimate = entry.
|
|
150
|
+
const estimate = record(entry.credit_estimate) ?? record(entry.estimate);
|
|
151
|
+
const affected = record(entry.affected_count);
|
|
152
|
+
const rows = affected?.rows ?? affected?.row_or_recipient_count;
|
|
139
153
|
return {
|
|
140
154
|
quote_hash: entry.quote_hash,
|
|
141
155
|
maximum_credits: typeof estimate?.maximum_credits === 'number' ? estimate.maximum_credits : null,
|
|
156
|
+
rows: typeof rows === 'number' ? rows : null,
|
|
157
|
+
credits: creditsPhrase(estimate),
|
|
142
158
|
};
|
|
143
159
|
}
|
|
144
160
|
for (const key of ['data', 'run', 'outputs', 'steps']) {
|
|
@@ -148,11 +164,20 @@ function quoteFromResult(value, depth = 0) {
|
|
|
148
164
|
}
|
|
149
165
|
return null;
|
|
150
166
|
}
|
|
151
|
-
function quotePriced(capabilityId, body,
|
|
167
|
+
function quotePriced(capabilityId, body, price, rehearsal = 'dry_run') {
|
|
152
168
|
const params = body.params && typeof body.params === 'object' ? body.params : {};
|
|
153
|
-
const
|
|
154
|
-
const
|
|
155
|
-
|
|
169
|
+
const rowCount = price.rows ?? (typeof params.max_rows === 'number' ? params.max_rows : null);
|
|
170
|
+
const rows = rowCount === null ? 'rows not stated' : `${rowCount} rows`;
|
|
171
|
+
const credits = price.credits ?? 'credits not stated';
|
|
172
|
+
const name = rehearsal === 'smoke_test' ? 'Smoke test' : rehearsal === 'dry_run' ? 'Dry run' : 'Rehearsal';
|
|
173
|
+
return `${name} of ${capabilityId} priced: ${rows}, ${credits}.`;
|
|
174
|
+
}
|
|
175
|
+
function rehearsalMode(fetched) {
|
|
176
|
+
const contract = record(capabilityRecord(fetched)?.execution_mode_contract);
|
|
177
|
+
const supported = Array.isArray(contract?.supported_modes) ? contract.supported_modes : [];
|
|
178
|
+
if (supported.includes('dry_run'))
|
|
179
|
+
return 'dry_run';
|
|
180
|
+
return supported.includes('smoke_test') ? 'smoke_test' : null;
|
|
156
181
|
}
|
|
157
182
|
const CREDENTIALS_REQUIRED_SENTENCE = 'A connected credential is required before this run can continue.';
|
|
158
183
|
function readinessRecord(value) {
|
|
@@ -315,10 +340,10 @@ async function runGated(context, input) {
|
|
|
315
340
|
if (params)
|
|
316
341
|
body.params = params;
|
|
317
342
|
}
|
|
318
|
-
// A
|
|
319
|
-
// and
|
|
320
|
-
// only while a quote is pending, together with
|
|
321
|
-
//
|
|
343
|
+
// A quote-bound live run needs the quote_hash of a supported rehearsal of
|
|
344
|
+
// the same input, and the quote is bound to the turn that asked for it. So a
|
|
345
|
+
// turn is reused only while a quote is pending, together with that quote,
|
|
346
|
+
// and forgotten once the live run is admitted.
|
|
322
347
|
const explicitKey = parameterIdempotencyKey(body) ?? input.idempotencyKey;
|
|
323
348
|
const fingerprint = planFingerprint(body);
|
|
324
349
|
const cached = input.turnToken
|
|
@@ -332,7 +357,7 @@ async function runGated(context, input) {
|
|
|
332
357
|
const inlineFromCache = !input.turnToken && !pending && !explicitKey && cachedPosture?.inlineRead === true;
|
|
333
358
|
if (!input.turnToken && !pending && !inlineFromCache)
|
|
334
359
|
await contract();
|
|
335
|
-
|
|
360
|
+
let posture = fetched ? (0, capabilityPosture_1.postureFromContract)(fetched) : cachedPosture;
|
|
336
361
|
if (fetched && posture)
|
|
337
362
|
(0, registryManifest_1.rememberPosture)(capabilityId, posture);
|
|
338
363
|
const refusal = fetched ? cliSurfaceRefusal(capabilityId, fetched) : null;
|
|
@@ -346,9 +371,12 @@ async function runGated(context, input) {
|
|
|
346
371
|
let quoteHash = explicitQuote
|
|
347
372
|
? body.quote_hash
|
|
348
373
|
: live ? cached?.quote_hash ?? undefined : undefined;
|
|
349
|
-
//
|
|
350
|
-
|
|
351
|
-
let
|
|
374
|
+
// The price of the quote in hand. A cached quote prices this input only when it
|
|
375
|
+
// is the quote named (explicit --quote-hash) or the quote this input was dry run for.
|
|
376
|
+
let quotedPrice = cached?.quote_hash && (!explicitQuote || cached.quote_hash === body.quote_hash)
|
|
377
|
+
? { quote_hash: cached.quote_hash, maximum_credits: cached.maximum_credits, rows: cached.rows ?? null, credits: cached.credits ?? null }
|
|
378
|
+
: null;
|
|
379
|
+
let ranRehearsal = false;
|
|
352
380
|
let sentKey = null;
|
|
353
381
|
const requestBody = () => ({
|
|
354
382
|
...body,
|
|
@@ -379,20 +407,48 @@ async function runGated(context, input) {
|
|
|
379
407
|
sentKey = await keyFor(sent);
|
|
380
408
|
return client.runCapability(capabilityId, sent, sentKey);
|
|
381
409
|
};
|
|
410
|
+
let retriedCapabilityDigestStale = false;
|
|
411
|
+
const refreshCapabilityAfterDigestStale = async () => {
|
|
412
|
+
retriedCapabilityDigestStale = true;
|
|
413
|
+
// A stale refusal is terminal for the original logical attempt. A new
|
|
414
|
+
// contract starts a fresh generated key, while a caller-supplied key keeps
|
|
415
|
+
// its explicit replay semantics.
|
|
416
|
+
if (attemptIdentity) {
|
|
417
|
+
await (0, idempotency_1.finishIdempotencyAttempt)(idempotencyPath, attemptIdentity);
|
|
418
|
+
attemptIdentity = null;
|
|
419
|
+
}
|
|
420
|
+
if (!input.turnToken) {
|
|
421
|
+
await (0, turnCache_1.forgetTurnToken)(context.turnsPath, context.baseUrl, context.turnKey, capabilityId, warnTurnCache);
|
|
422
|
+
}
|
|
423
|
+
fetched = await client.getTool(capabilityId);
|
|
424
|
+
posture = (0, capabilityPosture_1.postureFromContract)(fetched);
|
|
425
|
+
(0, registryManifest_1.rememberPosture)(capabilityId, posture);
|
|
426
|
+
const refreshedTurnToken = optionalToolTurnToken(fetched);
|
|
427
|
+
turnToken = refreshedTurnToken;
|
|
428
|
+
// A cached quote is bound to the stale turn. An explicitly supplied quote
|
|
429
|
+
// remains caller intent and the server decides whether it is still valid.
|
|
430
|
+
if (!explicitQuote) {
|
|
431
|
+
quoteHash = undefined;
|
|
432
|
+
quotedPrice = null;
|
|
433
|
+
}
|
|
434
|
+
};
|
|
382
435
|
let result;
|
|
383
436
|
try {
|
|
384
437
|
try {
|
|
385
438
|
if (live && quoteHash) {
|
|
386
|
-
const maximum = explicitQuote ? null : quotedMaximum ?? null;
|
|
387
439
|
// The shared gateway owns per-call paid, external-effect and recurring
|
|
388
440
|
// consent. A positive quote alone does not require human approval.
|
|
389
441
|
// Forward only caller-supplied approval; preserve every server refusal.
|
|
390
|
-
stderr.write(`${quotePriced(capabilityId, body, {
|
|
442
|
+
stderr.write(`${quotePriced(capabilityId, body, quotedPrice ?? { rows: null, credits: null }, rehearsalMode(fetched))}\nRunning live on that quote.\n`);
|
|
391
443
|
}
|
|
392
444
|
result = await run();
|
|
393
445
|
}
|
|
394
446
|
catch (error) {
|
|
395
|
-
if (
|
|
447
|
+
if (code(error) === 'capability_digest_stale') {
|
|
448
|
+
await refreshCapabilityAfterDigestStale();
|
|
449
|
+
result = await run();
|
|
450
|
+
}
|
|
451
|
+
else if (!input.turnToken && code(error) === 'capability_not_fetched') {
|
|
396
452
|
// Capability posture can change between tools get and run. Refresh it
|
|
397
453
|
// once rather than maintaining a client-side list of token-free reads.
|
|
398
454
|
fetched = await client.getTool(capabilityId);
|
|
@@ -403,17 +459,18 @@ async function runGated(context, input) {
|
|
|
403
459
|
result = await run();
|
|
404
460
|
}
|
|
405
461
|
else if (live && code(error) === 'quote_required' && !quoteHash && turnToken) {
|
|
406
|
-
// A live
|
|
407
|
-
//
|
|
408
|
-
//
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
462
|
+
// A live quote is minted by the capability's advertised rehearsal.
|
|
463
|
+
// Most capabilities use dry_run; activation intentionally has only
|
|
464
|
+
// smoke_test and live, so never invent an unsupported dry_run mode.
|
|
465
|
+
const rehearsal = rehearsalMode(fetched);
|
|
466
|
+
if (!rehearsal)
|
|
467
|
+
throw error;
|
|
468
|
+
const rehearsalResult = await client.runCapability(capabilityId, {
|
|
412
469
|
...body,
|
|
413
|
-
mode:
|
|
470
|
+
mode: rehearsal,
|
|
414
471
|
tool_turn_token: turnToken,
|
|
415
472
|
}, null);
|
|
416
|
-
const quote = quoteFromResult(
|
|
473
|
+
const quote = quoteFromResult(rehearsalResult);
|
|
417
474
|
if (!quote)
|
|
418
475
|
throw error;
|
|
419
476
|
// The no-quote call was definitively refused before execution. Its
|
|
@@ -422,11 +479,11 @@ async function runGated(context, input) {
|
|
|
422
479
|
await (0, idempotency_1.finishIdempotencyAttempt)(idempotencyPath, attemptIdentity);
|
|
423
480
|
attemptIdentity = null;
|
|
424
481
|
}
|
|
425
|
-
|
|
482
|
+
ranRehearsal = true;
|
|
426
483
|
quoteHash = quote.quote_hash;
|
|
427
|
-
|
|
428
|
-
stderr.write(`${quotePriced(capabilityId, body, quote)}\n`);
|
|
429
|
-
await (0, turnCache_1.rememberTurnToken)(context.turnsPath, context.baseUrl, context.turnKey, capabilityId, turnToken, Date.now(), warnTurnCache, { quote_hash: quote.quote_hash, fingerprint, maximum_credits: quote.maximum_credits });
|
|
484
|
+
quotedPrice = quote;
|
|
485
|
+
stderr.write(`${quotePriced(capabilityId, body, quote, rehearsal)}\n`);
|
|
486
|
+
await (0, turnCache_1.rememberTurnToken)(context.turnsPath, context.baseUrl, context.turnKey, capabilityId, turnToken, Date.now(), warnTurnCache, { quote_hash: quote.quote_hash, fingerprint, maximum_credits: quote.maximum_credits, rows: quote.rows, credits: quote.credits });
|
|
430
487
|
stderr.write('Running live on that quote.\n');
|
|
431
488
|
result = await run();
|
|
432
489
|
}
|
|
@@ -442,19 +499,22 @@ async function runGated(context, input) {
|
|
|
442
499
|
if (code(error) === 'approval_required') {
|
|
443
500
|
stderr.write('This run needs a person\'s approval. Show them the rows and cost above; when they agree, rerun the same command with --approved.\n');
|
|
444
501
|
}
|
|
445
|
-
await (0, turnCache_1.rememberTurnToken)(context.turnsPath, context.baseUrl, context.turnKey, capabilityId, turnToken, Date.now(), warnTurnCache, quoteHash ? { quote_hash: quoteHash, fingerprint,
|
|
502
|
+
await (0, turnCache_1.rememberTurnToken)(context.turnsPath, context.baseUrl, context.turnKey, capabilityId, turnToken, Date.now(), warnTurnCache, quoteHash ? { quote_hash: quoteHash, fingerprint, maximum_credits: quotedPrice?.maximum_credits ?? null, rows: quotedPrice?.rows ?? null, credits: quotedPrice?.credits ?? null } : undefined);
|
|
446
503
|
}
|
|
447
504
|
// Only an unknown or transient result may resume an attempt. A server
|
|
448
505
|
// refusal with retryable:false is terminal and must receive a new key.
|
|
449
|
-
|
|
506
|
+
// A response body that cannot be parsed is an unknown-effect outcome: the
|
|
507
|
+
// server may have admitted the write before its reply was damaged. Keep the
|
|
508
|
+
// generated key so the unchanged retry can replay that exact attempt.
|
|
509
|
+
const transient = error instanceof client_1.CliError && (error.code === 'request_timeout' || error.code === 'network_error' || error.code === 'invalid_response' || error.retryable === true || error.status >= 500);
|
|
450
510
|
if (attemptIdentity && !transient)
|
|
451
511
|
await (0, idempotency_1.finishIdempotencyAttempt)(idempotencyPath, attemptIdentity);
|
|
452
512
|
throw error;
|
|
453
513
|
}
|
|
454
514
|
if (!input.turnToken) {
|
|
455
|
-
if (body.mode === 'dry_run' && turnToken) {
|
|
515
|
+
if ((body.mode === 'dry_run' || body.mode === 'smoke_test') && turnToken) {
|
|
456
516
|
const quote = quoteFromResult(result);
|
|
457
|
-
await (0, turnCache_1.rememberTurnToken)(context.turnsPath, context.baseUrl, context.turnKey, capabilityId, turnToken, Date.now(), warnTurnCache, quote ? { quote_hash: quote.quote_hash, fingerprint, maximum_credits: quote.maximum_credits } : undefined);
|
|
517
|
+
await (0, turnCache_1.rememberTurnToken)(context.turnsPath, context.baseUrl, context.turnKey, capabilityId, turnToken, Date.now(), warnTurnCache, quote ? { quote_hash: quote.quote_hash, fingerprint, maximum_credits: quote.maximum_credits, rows: quote.rows, credits: quote.credits } : undefined);
|
|
458
518
|
}
|
|
459
519
|
}
|
|
460
520
|
let timedOut = false;
|
|
@@ -463,16 +523,26 @@ async function runGated(context, input) {
|
|
|
463
523
|
result = waited.value;
|
|
464
524
|
timedOut = waited.timedOut;
|
|
465
525
|
}
|
|
526
|
+
let outcomeRefusal = refusalFromRunResult(result);
|
|
527
|
+
if (!retriedCapabilityDigestStale && code(outcomeRefusal) === 'capability_digest_stale') {
|
|
528
|
+
await refreshCapabilityAfterDigestStale();
|
|
529
|
+
result = await run();
|
|
530
|
+
if (!input.noWait && !posture?.returnsRunId) {
|
|
531
|
+
const waited = await (0, runWait_1.waitForRun)(client, result, input.waitTimeout, context.sleep);
|
|
532
|
+
result = waited.value;
|
|
533
|
+
timedOut = waited.timedOut;
|
|
534
|
+
}
|
|
535
|
+
outcomeRefusal = refusalFromRunResult(result);
|
|
536
|
+
}
|
|
466
537
|
// A timeout still owns the quote and the idempotency key. Forgetting the
|
|
467
538
|
// turn here made the rerun hash a body with no quote_hash and start a second run.
|
|
468
|
-
if (!input.turnToken && body.mode !== 'dry_run' && (pending ||
|
|
539
|
+
if (!input.turnToken && body.mode !== 'dry_run' && body.mode !== 'smoke_test' && (pending || ranRehearsal) && !timedOut) {
|
|
469
540
|
await (0, turnCache_1.forgetTurnToken)(context.turnsPath, context.baseUrl, context.turnKey, capabilityId, warnTurnCache);
|
|
470
541
|
}
|
|
471
542
|
// A run still active after waiting has unknown outcome; retain its key for
|
|
472
543
|
// the read-back/retry rule. A terminal response completes this attempt.
|
|
473
544
|
if (attemptIdentity && !timedOut)
|
|
474
545
|
await (0, idempotency_1.finishIdempotencyAttempt)(idempotencyPath, attemptIdentity);
|
|
475
|
-
const outcomeRefusal = refusalFromRunResult(result);
|
|
476
546
|
if (outcomeRefusal)
|
|
477
547
|
throw outcomeRefusal;
|
|
478
548
|
return { value: withIdempotencyMeta(result, explicitKey ? null : sentKey), timedOut, idempotencyKey: sentKey, turnToken: turnToken ?? null };
|