@vendoai/apps 0.4.0
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/LICENSE +202 -0
- package/README.md +8 -0
- package/dist/adapter-conformance.d.ts +48 -0
- package/dist/adapter-conformance.d.ts.map +1 -0
- package/dist/adapter-conformance.js +196 -0
- package/dist/adapter-conformance.js.map +1 -0
- package/dist/agent-tools.d.ts +10 -0
- package/dist/agent-tools.d.ts.map +1 -0
- package/dist/agent-tools.js +252 -0
- package/dist/agent-tools.js.map +1 -0
- package/dist/app-data.d.ts +23 -0
- package/dist/app-data.d.ts.map +1 -0
- package/dist/app-data.js +129 -0
- package/dist/app-data.js.map +1 -0
- package/dist/app-token.d.ts +24 -0
- package/dist/app-token.d.ts.map +1 -0
- package/dist/app-token.js +61 -0
- package/dist/app-token.js.map +1 -0
- package/dist/audit.d.ts +11 -0
- package/dist/audit.d.ts.map +1 -0
- package/dist/audit.js +19 -0
- package/dist/audit.js.map +1 -0
- package/dist/automation-plan.d.ts +43 -0
- package/dist/automation-plan.d.ts.map +1 -0
- package/dist/automation-plan.js +212 -0
- package/dist/automation-plan.js.map +1 -0
- package/dist/bench/client.d.ts +43 -0
- package/dist/bench/client.d.ts.map +1 -0
- package/dist/bench/client.js +129 -0
- package/dist/bench/client.js.map +1 -0
- package/dist/bench/fixtures.d.ts +42 -0
- package/dist/bench/fixtures.d.ts.map +1 -0
- package/dist/bench/fixtures.js +146 -0
- package/dist/bench/fixtures.js.map +1 -0
- package/dist/bench/judge.d.ts +9 -0
- package/dist/bench/judge.d.ts.map +1 -0
- package/dist/bench/judge.js +71 -0
- package/dist/bench/judge.js.map +1 -0
- package/dist/bench/metrics.d.ts +32 -0
- package/dist/bench/metrics.d.ts.map +1 -0
- package/dist/bench/metrics.js +172 -0
- package/dist/bench/metrics.js.map +1 -0
- package/dist/bench/prompts.d.ts +17 -0
- package/dist/bench/prompts.d.ts.map +1 -0
- package/dist/bench/prompts.js +100 -0
- package/dist/bench/prompts.js.map +1 -0
- package/dist/bench/report.d.ts +43 -0
- package/dist/bench/report.d.ts.map +1 -0
- package/dist/bench/report.js +74 -0
- package/dist/bench/report.js.map +1 -0
- package/dist/bench/runner.d.ts +15 -0
- package/dist/bench/runner.d.ts.map +1 -0
- package/dist/bench/runner.js +26 -0
- package/dist/bench/runner.js.map +1 -0
- package/dist/bench/toolfork.d.ts +18 -0
- package/dist/bench/toolfork.d.ts.map +1 -0
- package/dist/bench/toolfork.js +125 -0
- package/dist/bench/toolfork.js.map +1 -0
- package/dist/box-agent.d.ts +78 -0
- package/dist/box-agent.d.ts.map +1 -0
- package/dist/box-agent.js +137 -0
- package/dist/box-agent.js.map +1 -0
- package/dist/box-env.d.ts +26 -0
- package/dist/box-env.d.ts.map +1 -0
- package/dist/box-env.js +52 -0
- package/dist/box-env.js.map +1 -0
- package/dist/call.d.ts +23 -0
- package/dist/call.d.ts.map +1 -0
- package/dist/call.js +45 -0
- package/dist/call.js.map +1 -0
- package/dist/cloud.d.ts +4917 -0
- package/dist/cloud.d.ts.map +1 -0
- package/dist/cloud.js +16 -0
- package/dist/cloud.js.map +1 -0
- package/dist/e2b/index.d.ts +30 -0
- package/dist/e2b/index.d.ts.map +1 -0
- package/dist/e2b/index.js +273 -0
- package/dist/e2b/index.js.map +1 -0
- package/dist/egress-approval.d.ts +73 -0
- package/dist/egress-approval.d.ts.map +1 -0
- package/dist/egress-approval.js +74 -0
- package/dist/egress-approval.js.map +1 -0
- package/dist/engine.d.ts +188 -0
- package/dist/engine.d.ts.map +1 -0
- package/dist/engine.js +1507 -0
- package/dist/engine.js.map +1 -0
- package/dist/fn.d.ts +22 -0
- package/dist/fn.d.ts.map +1 -0
- package/dist/fn.js +108 -0
- package/dist/fn.js.map +1 -0
- package/dist/history.d.ts +21 -0
- package/dist/history.d.ts.map +1 -0
- package/dist/history.js +158 -0
- package/dist/history.js.map +1 -0
- package/dist/inclient.d.ts +48 -0
- package/dist/inclient.d.ts.map +1 -0
- package/dist/inclient.js +68 -0
- package/dist/inclient.js.map +1 -0
- package/dist/index.d.ts +24 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +25 -0
- package/dist/index.js.map +1 -0
- package/dist/interchange.d.ts +17 -0
- package/dist/interchange.d.ts.map +1 -0
- package/dist/interchange.js +133 -0
- package/dist/interchange.js.map +1 -0
- package/dist/machine-lifecycle.d.ts +102 -0
- package/dist/machine-lifecycle.d.ts.map +1 -0
- package/dist/machine-lifecycle.js +360 -0
- package/dist/machine-lifecycle.js.map +1 -0
- package/dist/manifest.d.ts +42 -0
- package/dist/manifest.d.ts.map +1 -0
- package/dist/manifest.js +53 -0
- package/dist/manifest.js.map +1 -0
- package/dist/open.d.ts +45 -0
- package/dist/open.d.ts.map +1 -0
- package/dist/open.js +245 -0
- package/dist/open.js.map +1 -0
- package/dist/parked-action.d.ts +51 -0
- package/dist/parked-action.d.ts.map +1 -0
- package/dist/parked-action.js +29 -0
- package/dist/parked-action.js.map +1 -0
- package/dist/persistence.d.ts +41 -0
- package/dist/persistence.d.ts.map +1 -0
- package/dist/persistence.js +86 -0
- package/dist/persistence.js.map +1 -0
- package/dist/pins.d.ts +231 -0
- package/dist/pins.d.ts.map +1 -0
- package/dist/pins.js +213 -0
- package/dist/pins.js.map +1 -0
- package/dist/pipeline.d.ts +142 -0
- package/dist/pipeline.d.ts.map +1 -0
- package/dist/pipeline.js +1014 -0
- package/dist/pipeline.js.map +1 -0
- package/dist/prewired-schema.d.ts +16 -0
- package/dist/prewired-schema.d.ts.map +1 -0
- package/dist/prewired-schema.js +48 -0
- package/dist/prewired-schema.js.map +1 -0
- package/dist/redaction.d.ts +13 -0
- package/dist/redaction.d.ts.map +1 -0
- package/dist/redaction.js +67 -0
- package/dist/redaction.js.map +1 -0
- package/dist/runtime.d.ts +463 -0
- package/dist/runtime.d.ts.map +1 -0
- package/dist/runtime.js +1715 -0
- package/dist/runtime.js.map +1 -0
- package/dist/sandbox.d.ts +90 -0
- package/dist/sandbox.d.ts.map +1 -0
- package/dist/sandbox.js +2 -0
- package/dist/sandbox.js.map +1 -0
- package/dist/schedules.d.ts +89 -0
- package/dist/schedules.d.ts.map +1 -0
- package/dist/schedules.js +334 -0
- package/dist/schedules.js.map +1 -0
- package/dist/secret-exposure.d.ts +55 -0
- package/dist/secret-exposure.d.ts.map +1 -0
- package/dist/secret-exposure.js +53 -0
- package/dist/secret-exposure.js.map +1 -0
- package/dist/ship-diff.d.ts +47 -0
- package/dist/ship-diff.d.ts.map +1 -0
- package/dist/ship-diff.js +39 -0
- package/dist/ship-diff.js.map +1 -0
- package/dist/testing/fake-box.d.ts +67 -0
- package/dist/testing/fake-box.d.ts.map +1 -0
- package/dist/testing/fake-box.js +166 -0
- package/dist/testing/fake-box.js.map +1 -0
- package/dist/testing/fake-sandbox-v2.d.ts +59 -0
- package/dist/testing/fake-sandbox-v2.d.ts.map +1 -0
- package/dist/testing/fake-sandbox-v2.js +121 -0
- package/dist/testing/fake-sandbox-v2.js.map +1 -0
- package/dist/testing/fake-sandbox.d.ts +94 -0
- package/dist/testing/fake-sandbox.d.ts.map +1 -0
- package/dist/testing/fake-sandbox.js +239 -0
- package/dist/testing/fake-sandbox.js.map +1 -0
- package/dist/testing/guard-fixture.d.ts +19 -0
- package/dist/testing/guard-fixture.d.ts.map +1 -0
- package/dist/testing/guard-fixture.js +134 -0
- package/dist/testing/guard-fixture.js.map +1 -0
- package/dist/testing/index.d.ts +8 -0
- package/dist/testing/index.d.ts.map +1 -0
- package/dist/testing/index.js +8 -0
- package/dist/testing/index.js.map +1 -0
- package/dist/testing/memory-store.d.ts +5 -0
- package/dist/testing/memory-store.d.ts.map +1 -0
- package/dist/testing/memory-store.js +4 -0
- package/dist/testing/memory-store.js.map +1 -0
- package/dist/testing/scripted-model.d.ts +32 -0
- package/dist/testing/scripted-model.d.ts.map +1 -0
- package/dist/testing/scripted-model.js +112 -0
- package/dist/testing/scripted-model.js.map +1 -0
- package/dist/testing/seed-app-row.d.ts +4 -0
- package/dist/testing/seed-app-row.d.ts.map +1 -0
- package/dist/testing/seed-app-row.js +7 -0
- package/dist/testing/seed-app-row.js.map +1 -0
- package/dist/unified-diff.d.ts +13 -0
- package/dist/unified-diff.d.ts.map +1 -0
- package/dist/unified-diff.js +127 -0
- package/dist/unified-diff.js.map +1 -0
- package/dist/version-hash.d.ts +9 -0
- package/dist/version-hash.d.ts.map +1 -0
- package/dist/version-hash.js +12 -0
- package/dist/version-hash.js.map +1 -0
- package/package.json +84 -0
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* W1-bench Experiment 2 — the builder-calls fork. The app is emitted as a
|
|
3
|
+
* stream of strict tool calls in ONE assistant turn: `set_query`,
|
|
4
|
+
* `begin_region`/`end_region` for nesting (order-based; the compiler still
|
|
5
|
+
* mints ids), a `place_<Component>` tool per prewired/catalog component
|
|
6
|
+
* (constrained component + prop names), and `define_island`. Bindings and
|
|
7
|
+
* actions are structured tool inputs (`bind_data` field paths). The call
|
|
8
|
+
* stream is reconstructed into ordinary wire so it goes through the exact same
|
|
9
|
+
* compileWireV2 + metrics path as the JSX arm.
|
|
10
|
+
*/
|
|
11
|
+
import { type ToolSet } from "ai";
|
|
12
|
+
export declare const buildForkTools: () => ToolSet;
|
|
13
|
+
/** Reconstruct wire markup from the ordered tool-call stream. */
|
|
14
|
+
export declare const reconstructWire: (calls: {
|
|
15
|
+
toolName: string;
|
|
16
|
+
input: Record<string, unknown>;
|
|
17
|
+
}[]) => string;
|
|
18
|
+
//# sourceMappingURL=toolfork.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"toolfork.d.ts","sourceRoot":"","sources":["../../src/bench/toolfork.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EAAoB,KAAK,OAAO,EAAE,MAAM,IAAI,CAAC;AAiCpD,eAAO,MAAM,cAAc,QAAO,OAkCjC,CAAC;AAsBF,iEAAiE;AACjE,eAAO,MAAM,eAAe,GAAI,OAAO;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,EAAE,KAAG,MA6B/F,CAAC"}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* W1-bench Experiment 2 — the builder-calls fork. The app is emitted as a
|
|
3
|
+
* stream of strict tool calls in ONE assistant turn: `set_query`,
|
|
4
|
+
* `begin_region`/`end_region` for nesting (order-based; the compiler still
|
|
5
|
+
* mints ids), a `place_<Component>` tool per prewired/catalog component
|
|
6
|
+
* (constrained component + prop names), and `define_island`. Bindings and
|
|
7
|
+
* actions are structured tool inputs (`bind_data` field paths). The call
|
|
8
|
+
* stream is reconstructed into ordinary wire so it goes through the exact same
|
|
9
|
+
* compileWireV2 + metrics path as the JSX arm.
|
|
10
|
+
*/
|
|
11
|
+
import { jsonSchema, tool } from "ai";
|
|
12
|
+
import { PREWIRED_SCHEMAS } from "../prewired-schema.js";
|
|
13
|
+
import { MAPLE_CATALOG } from "./fixtures.js";
|
|
14
|
+
const LAYOUT = new Set(["Stack", "Row", "Grid", "Card", "Surface"]);
|
|
15
|
+
const componentNames = [
|
|
16
|
+
...Object.keys(PREWIRED_SCHEMAS),
|
|
17
|
+
...MAPLE_CATALOG.map((c) => c.name),
|
|
18
|
+
];
|
|
19
|
+
const leafNames = componentNames.filter((n) => !LAYOUT.has(n));
|
|
20
|
+
const sig = (name) => {
|
|
21
|
+
const pre = PREWIRED_SCHEMAS[name];
|
|
22
|
+
if (pre)
|
|
23
|
+
return pre.signature;
|
|
24
|
+
return MAPLE_CATALOG.find((c) => c.name === name)?.signature ?? name;
|
|
25
|
+
};
|
|
26
|
+
const objSchema = (props, required = []) => jsonSchema({ type: "object", properties: props, required, additionalProperties: false });
|
|
27
|
+
const placeInput = objSchema({
|
|
28
|
+
props: { type: "object", description: "Literal prop values (strings/numbers/booleans/arrays), e.g. {label:\"Total\", format:\"money\"} or columns for a table.", additionalProperties: true },
|
|
29
|
+
bindings: { type: "object", description: "prop -> data reference string like \"invoicesList.data\" or \"invoicesList.totalCents\" (optionally with a | format(...) pipe). The referenced query must be declared via set_query.", additionalProperties: { type: "string" } },
|
|
30
|
+
actions: { type: "object", description: "prop -> host tool name for on* actions, e.g. {onClick:\"invoices.sendReminders\"}.", additionalProperties: { type: "string" } },
|
|
31
|
+
actionPayloads: { type: "object", description: "prop -> data reference string for the action payload, e.g. {onClick:\"invoicesList.data.0.id\"}.", additionalProperties: { type: "string" } },
|
|
32
|
+
});
|
|
33
|
+
/** Build the strict tool set. */
|
|
34
|
+
// No-op result so the tool-use loop advances (the builder doesn't need real
|
|
35
|
+
// results — it is composing a tree, not reading data).
|
|
36
|
+
const ack = async () => ({ ok: true });
|
|
37
|
+
export const buildForkTools = () => {
|
|
38
|
+
const tools = {};
|
|
39
|
+
tools.set_query = tool({
|
|
40
|
+
description: "Declare a data query. Its result is addressable by <name> in bindings.",
|
|
41
|
+
inputSchema: objSchema({ name: { type: "string" }, tool: { type: "string" }, input: { type: "object", additionalProperties: true } }, ["name", "tool"]),
|
|
42
|
+
execute: ack,
|
|
43
|
+
});
|
|
44
|
+
tools.begin_region = tool({
|
|
45
|
+
description: `Open a layout container and make it the current parent. component is one of: ${[...LAYOUT].join(", ")}.`,
|
|
46
|
+
inputSchema: objSchema({ component: { type: "string", enum: [...LAYOUT] }, props: { type: "object", additionalProperties: true } }, ["component"]),
|
|
47
|
+
execute: ack,
|
|
48
|
+
});
|
|
49
|
+
tools.end_region = tool({ description: "Close the current layout container.", inputSchema: objSchema({}), execute: ack });
|
|
50
|
+
tools.finish = tool({ description: "Call this once the app is fully composed.", inputSchema: objSchema({}), execute: ack });
|
|
51
|
+
tools.define_island = tool({
|
|
52
|
+
description: "Define a custom React island component by name with full TSX source (last resort).",
|
|
53
|
+
inputSchema: objSchema({ name: { type: "string" }, source: { type: "string" } }, ["name", "source"]),
|
|
54
|
+
execute: ack,
|
|
55
|
+
});
|
|
56
|
+
// One place tool per leaf component (constrained component + its prop signature).
|
|
57
|
+
for (const name of leafNames) {
|
|
58
|
+
tools[`place_${name}`] = tool({
|
|
59
|
+
description: `Add a ${name} to the current parent. ${sig(name)}`,
|
|
60
|
+
inputSchema: placeInput,
|
|
61
|
+
execute: ack,
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
return tools;
|
|
65
|
+
};
|
|
66
|
+
const bindingExpr = (ref) => `{${ref}}`;
|
|
67
|
+
const attrsFor = (input) => {
|
|
68
|
+
const parts = [];
|
|
69
|
+
const props = (input.props ?? {});
|
|
70
|
+
for (const [k, v] of Object.entries(props)) {
|
|
71
|
+
if (typeof v === "string")
|
|
72
|
+
parts.push(`${k}="${v.replace(/"/g, """)}"`);
|
|
73
|
+
else
|
|
74
|
+
parts.push(`${k}={${JSON.stringify(v)}}`);
|
|
75
|
+
}
|
|
76
|
+
const bindings = (input.bindings ?? {});
|
|
77
|
+
for (const [k, ref] of Object.entries(bindings))
|
|
78
|
+
parts.push(`${k}=${bindingExpr(ref)}`);
|
|
79
|
+
const actions = (input.actions ?? {});
|
|
80
|
+
const payloads = (input.actionPayloads ?? {});
|
|
81
|
+
for (const [k, t] of Object.entries(actions)) {
|
|
82
|
+
if (payloads[k])
|
|
83
|
+
parts.push(`${k}={{action:"${t}",payload:{value:${payloads[k]}}}}`);
|
|
84
|
+
else
|
|
85
|
+
parts.push(`${k}="${t}"`);
|
|
86
|
+
}
|
|
87
|
+
return parts.length ? " " + parts.join(" ") : "";
|
|
88
|
+
};
|
|
89
|
+
/** Reconstruct wire markup from the ordered tool-call stream. */
|
|
90
|
+
export const reconstructWire = (calls) => {
|
|
91
|
+
const queries = [];
|
|
92
|
+
const islands = [];
|
|
93
|
+
const body = [];
|
|
94
|
+
const regionStack = [];
|
|
95
|
+
for (const call of calls) {
|
|
96
|
+
const inp = call.input ?? {};
|
|
97
|
+
if (call.toolName === "set_query") {
|
|
98
|
+
const name = String(inp.name ?? "q");
|
|
99
|
+
const t = String(inp.tool ?? "");
|
|
100
|
+
const input = inp.input && Object.keys(inp.input).length ? ` input={${JSON.stringify(inp.input)}}` : "";
|
|
101
|
+
queries.push(`<Query id="${name}" tool="${t}"${input}/>`);
|
|
102
|
+
}
|
|
103
|
+
else if (call.toolName === "begin_region") {
|
|
104
|
+
const comp = String(inp.component ?? "Stack");
|
|
105
|
+
regionStack.push(comp);
|
|
106
|
+
body.push(`<${comp}${attrsFor({ props: inp.props })}>`);
|
|
107
|
+
}
|
|
108
|
+
else if (call.toolName === "end_region") {
|
|
109
|
+
const comp = regionStack.pop() ?? "Stack";
|
|
110
|
+
body.push(`</${comp}>`);
|
|
111
|
+
}
|
|
112
|
+
else if (call.toolName === "define_island") {
|
|
113
|
+
const name = String(inp.name ?? "Island");
|
|
114
|
+
islands.push(`<Island name="${name}">${String(inp.source ?? "")}</Island>`);
|
|
115
|
+
}
|
|
116
|
+
else if (call.toolName.startsWith("place_")) {
|
|
117
|
+
const comp = call.toolName.slice("place_".length);
|
|
118
|
+
body.push(`<${comp}${attrsFor(inp)}/>`);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
while (regionStack.length)
|
|
122
|
+
body.push(`</${regionStack.pop()}>`);
|
|
123
|
+
return `<App name="Generated">${queries.join("")}${body.join("")}${islands.join("")}</App>`;
|
|
124
|
+
};
|
|
125
|
+
//# sourceMappingURL=toolfork.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"toolfork.js","sourceRoot":"","sources":["../../src/bench/toolfork.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import type { SandboxMachine } from "./sandbox.js";
|
|
2
|
+
/**
|
|
3
|
+
* execution-v2 Wave 3 — the host-side client of the in-box agent's control
|
|
4
|
+
* port. The agent + supervisor live inside the base box template
|
|
5
|
+
* (packages/apps/box/harness.mjs); this module is the host's transport to it,
|
|
6
|
+
* spoken over the ONE data path into the box, SandboxMachine.request({port}).
|
|
7
|
+
* The app owns $PORT; the harness owns the CONTROL PORT below.
|
|
8
|
+
*
|
|
9
|
+
* Prompt-injection floor: everything the box returns is DATA. A BoxEditResult
|
|
10
|
+
* never carries host authority — it cannot approve egress, grant a secret, or
|
|
11
|
+
* mutate a host document. Graduation reads the summary and fn list; approvals
|
|
12
|
+
* still gate every host mutation (Lane E), and durable writes still ride the
|
|
13
|
+
* app-token /box callbacks through the guard.
|
|
14
|
+
*/
|
|
15
|
+
/** The harness's control port (VENDO_CONTROL_PORT in the box); distinct from
|
|
16
|
+
* the app's $PORT so the app and the agent door never collide. */
|
|
17
|
+
export declare const BOX_CONTROL_PORT = 8811;
|
|
18
|
+
/** The structured result the in-box agent reports (box → host, pure data). */
|
|
19
|
+
export interface BoxEditResult {
|
|
20
|
+
ok: boolean;
|
|
21
|
+
summary: string;
|
|
22
|
+
filesChanged: string[];
|
|
23
|
+
testsRun: number;
|
|
24
|
+
/** The POST /fn/<name> functions the box now serves (agent-declared). */
|
|
25
|
+
fns?: string[];
|
|
26
|
+
/**
|
|
27
|
+
* Wave 4 (layer 3) — the agent's declaration that the box now serves a real
|
|
28
|
+
* web app on non-/fn paths of $PORT. DATA like every other field: the host
|
|
29
|
+
* verifies the served root itself and the experimental flag gates any
|
|
30
|
+
* surface flip; this bit alone changes nothing.
|
|
31
|
+
*/
|
|
32
|
+
servesUi?: boolean;
|
|
33
|
+
}
|
|
34
|
+
/** A minimal sleep seam so tests drive the poll loop without real time. */
|
|
35
|
+
export interface BoxAgentClock {
|
|
36
|
+
sleep(ms: number): Promise<void>;
|
|
37
|
+
now(): number;
|
|
38
|
+
}
|
|
39
|
+
export interface BoxEditOptions {
|
|
40
|
+
prompt: string;
|
|
41
|
+
context?: string;
|
|
42
|
+
pollIntervalMs?: number;
|
|
43
|
+
timeoutMs?: number;
|
|
44
|
+
clock?: BoxAgentClock;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Proxy an APP-port request, retrying the provider's 502/503 "port not open"
|
|
48
|
+
* for a short window. A memory-snapshot resume boots the box's start command
|
|
49
|
+
* fresh, so the supervised app needs a second or two to rebind $PORT; an fn
|
|
50
|
+
* call or manifest read that races that startup would otherwise fail. Control-
|
|
51
|
+
* port requests never use this — the harness is up the moment the box is.
|
|
52
|
+
*/
|
|
53
|
+
export interface BootRetryOptions {
|
|
54
|
+
attempts?: number;
|
|
55
|
+
delayMs?: number;
|
|
56
|
+
sleep?: (ms: number) => Promise<void>;
|
|
57
|
+
}
|
|
58
|
+
export declare const requestAppWithBootRetry: (machine: SandboxMachine, req: Parameters<SandboxMachine["request"]>[0], options?: BootRetryOptions) => Promise<Awaited<ReturnType<SandboxMachine["request"]>>>;
|
|
59
|
+
/**
|
|
60
|
+
* Re-inject the boundary env into a live box and restart its app. This is the
|
|
61
|
+
* in-box restart loop Lane E's env-baked-at-provision gap needs: a secret
|
|
62
|
+
* grant flipped while the machine slept lands here at the next edit/wake.
|
|
63
|
+
*/
|
|
64
|
+
export declare const pushBoxEnv: (machine: SandboxMachine, env: Record<string, string>) => Promise<void>;
|
|
65
|
+
/** Read the box's `vendo.json` manifest verbatim (empty when the box has none).
|
|
66
|
+
* Uses the post-resume boot retry: a manifest read right after an edit can
|
|
67
|
+
* race the harness restarting the app, and a dropped read would silently lose
|
|
68
|
+
* a freshly declared egress domain (and its approval card). */
|
|
69
|
+
export declare const readBoxManifest: (machine: SandboxMachine, bootRetry?: BootRetryOptions) => Promise<string | undefined>;
|
|
70
|
+
/**
|
|
71
|
+
* Send one edit prompt to the in-box agent and long-poll to completion. The
|
|
72
|
+
* agent writes code, installs deps, runs its own server, curls its endpoints,
|
|
73
|
+
* and reports a structured result — self-verification against reality. A
|
|
74
|
+
* timeout is a failed edit (the caller rolls back), never a throw into the
|
|
75
|
+
* tree.
|
|
76
|
+
*/
|
|
77
|
+
export declare const runBoxEdit: (machine: SandboxMachine, options: BoxEditOptions) => Promise<BoxEditResult>;
|
|
78
|
+
//# sourceMappingURL=box-agent.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"box-agent.d.ts","sourceRoot":"","sources":["../src/box-agent.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAEnD;;;;;;;;;;;;GAYG;AAEH;mEACmE;AACnE,eAAO,MAAM,gBAAgB,OAAO,CAAC;AAQrC,8EAA8E;AAC9E,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,OAAO,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,yEAAyE;IACzE,GAAG,CAAC,EAAE,MAAM,EAAE,CAAC;IACf;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,2EAA2E;AAC3E,MAAM,WAAW,aAAa;IAC5B,KAAK,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACjC,GAAG,IAAI,MAAM,CAAC;CACf;AAOD,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,aAAa,CAAC;CACvB;AA4CD;;;;;;GAMG;AACH,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACvC;AAED,eAAO,MAAM,uBAAuB,GAClC,SAAS,cAAc,EACvB,KAAK,UAAU,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,EAC7C,UAAS,gBAAqB,KAC7B,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC,CAAC,CAUxD,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,UAAU,GAAU,SAAS,cAAc,EAAE,KAAK,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAAG,OAAO,CAAC,IAAI,CAKnG,CAAC;AAEF;;;gEAGgE;AAChE,eAAO,MAAM,eAAe,GAC1B,SAAS,cAAc,EACvB,YAAW,gBAAqB,KAC/B,OAAO,CAAC,MAAM,GAAG,SAAS,CAO5B,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,UAAU,GACrB,SAAS,cAAc,EACvB,SAAS,cAAc,KACtB,OAAO,CAAC,aAAa,CAiCvB,CAAC"}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import { VendoError } from "@vendoai/core";
|
|
2
|
+
/**
|
|
3
|
+
* execution-v2 Wave 3 — the host-side client of the in-box agent's control
|
|
4
|
+
* port. The agent + supervisor live inside the base box template
|
|
5
|
+
* (packages/apps/box/harness.mjs); this module is the host's transport to it,
|
|
6
|
+
* spoken over the ONE data path into the box, SandboxMachine.request({port}).
|
|
7
|
+
* The app owns $PORT; the harness owns the CONTROL PORT below.
|
|
8
|
+
*
|
|
9
|
+
* Prompt-injection floor: everything the box returns is DATA. A BoxEditResult
|
|
10
|
+
* never carries host authority — it cannot approve egress, grant a secret, or
|
|
11
|
+
* mutate a host document. Graduation reads the summary and fn list; approvals
|
|
12
|
+
* still gate every host mutation (Lane E), and durable writes still ride the
|
|
13
|
+
* app-token /box callbacks through the guard.
|
|
14
|
+
*/
|
|
15
|
+
/** The harness's control port (VENDO_CONTROL_PORT in the box); distinct from
|
|
16
|
+
* the app's $PORT so the app and the agent door never collide. */
|
|
17
|
+
export const BOX_CONTROL_PORT = 8811;
|
|
18
|
+
const DEFAULT_POLL_INTERVAL_MS = 2_000;
|
|
19
|
+
const DEFAULT_TASK_TIMEOUT_MS = 8 * 60_000;
|
|
20
|
+
const encoder = new TextEncoder();
|
|
21
|
+
const decoder = new TextDecoder();
|
|
22
|
+
const realClock = {
|
|
23
|
+
sleep: (ms) => new Promise((resolve) => setTimeout(resolve, ms)),
|
|
24
|
+
now: () => Date.now(),
|
|
25
|
+
};
|
|
26
|
+
const controlRequest = async (machine, method, path, body) => {
|
|
27
|
+
const answer = await machine.request({
|
|
28
|
+
method,
|
|
29
|
+
path,
|
|
30
|
+
port: BOX_CONTROL_PORT,
|
|
31
|
+
...(body === undefined ? {} : {
|
|
32
|
+
headers: { "content-type": "application/json" },
|
|
33
|
+
body: encoder.encode(JSON.stringify(body)),
|
|
34
|
+
}),
|
|
35
|
+
});
|
|
36
|
+
let json;
|
|
37
|
+
try {
|
|
38
|
+
json = JSON.parse(decoder.decode(answer.body));
|
|
39
|
+
}
|
|
40
|
+
catch {
|
|
41
|
+
json = undefined;
|
|
42
|
+
}
|
|
43
|
+
return { status: answer.status, json };
|
|
44
|
+
};
|
|
45
|
+
const asResult = (value) => {
|
|
46
|
+
const record = (typeof value === "object" && value !== null ? value : {});
|
|
47
|
+
return {
|
|
48
|
+
ok: record.ok === true,
|
|
49
|
+
summary: typeof record.summary === "string" ? record.summary : "(box returned no summary)",
|
|
50
|
+
filesChanged: Array.isArray(record.filesChanged)
|
|
51
|
+
? record.filesChanged.filter((entry) => typeof entry === "string")
|
|
52
|
+
: [],
|
|
53
|
+
testsRun: typeof record.testsRun === "number" && Number.isInteger(record.testsRun) && record.testsRun >= 0
|
|
54
|
+
? record.testsRun
|
|
55
|
+
: 0,
|
|
56
|
+
...(Array.isArray(record.fns)
|
|
57
|
+
? { fns: record.fns.filter((entry) => typeof entry === "string") }
|
|
58
|
+
: {}),
|
|
59
|
+
...(record.servesUi === true ? { servesUi: true } : {}),
|
|
60
|
+
};
|
|
61
|
+
};
|
|
62
|
+
export const requestAppWithBootRetry = async (machine, req, options = {}) => {
|
|
63
|
+
const attempts = options.attempts ?? 5;
|
|
64
|
+
const delayMs = options.delayMs ?? 1_500;
|
|
65
|
+
const sleep = options.sleep ?? ((ms) => new Promise((resolve) => setTimeout(resolve, ms)));
|
|
66
|
+
let answer = await machine.request(req);
|
|
67
|
+
for (let attempt = 1; attempt < attempts && (answer.status === 502 || answer.status === 503); attempt += 1) {
|
|
68
|
+
await sleep(delayMs);
|
|
69
|
+
answer = await machine.request(req);
|
|
70
|
+
}
|
|
71
|
+
return answer;
|
|
72
|
+
};
|
|
73
|
+
/**
|
|
74
|
+
* Re-inject the boundary env into a live box and restart its app. This is the
|
|
75
|
+
* in-box restart loop Lane E's env-baked-at-provision gap needs: a secret
|
|
76
|
+
* grant flipped while the machine slept lands here at the next edit/wake.
|
|
77
|
+
*/
|
|
78
|
+
export const pushBoxEnv = async (machine, env) => {
|
|
79
|
+
const { status } = await controlRequest(machine, "POST", "/agent/env", { env });
|
|
80
|
+
if (status < 200 || status >= 300) {
|
|
81
|
+
throw new VendoError("sandbox-unavailable", `box env injection failed (${status})`);
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
/** Read the box's `vendo.json` manifest verbatim (empty when the box has none).
|
|
85
|
+
* Uses the post-resume boot retry: a manifest read right after an edit can
|
|
86
|
+
* race the harness restarting the app, and a dropped read would silently lose
|
|
87
|
+
* a freshly declared egress domain (and its approval card). */
|
|
88
|
+
export const readBoxManifest = async (machine, bootRetry = {}) => {
|
|
89
|
+
const answer = await requestAppWithBootRetry(machine, { method: "GET", path: "/vendo.json" }, bootRetry);
|
|
90
|
+
if (answer.status === 404)
|
|
91
|
+
return undefined;
|
|
92
|
+
if (answer.status < 200 || answer.status >= 300) {
|
|
93
|
+
throw new VendoError("validation", `vendo.json read failed (${answer.status})`);
|
|
94
|
+
}
|
|
95
|
+
return decoder.decode(answer.body);
|
|
96
|
+
};
|
|
97
|
+
/**
|
|
98
|
+
* Send one edit prompt to the in-box agent and long-poll to completion. The
|
|
99
|
+
* agent writes code, installs deps, runs its own server, curls its endpoints,
|
|
100
|
+
* and reports a structured result — self-verification against reality. A
|
|
101
|
+
* timeout is a failed edit (the caller rolls back), never a throw into the
|
|
102
|
+
* tree.
|
|
103
|
+
*/
|
|
104
|
+
export const runBoxEdit = async (machine, options) => {
|
|
105
|
+
const clock = options.clock ?? realClock;
|
|
106
|
+
const pollIntervalMs = options.pollIntervalMs ?? DEFAULT_POLL_INTERVAL_MS;
|
|
107
|
+
const timeoutMs = options.timeoutMs ?? DEFAULT_TASK_TIMEOUT_MS;
|
|
108
|
+
const started = await controlRequest(machine, "POST", "/agent/task", {
|
|
109
|
+
prompt: options.prompt,
|
|
110
|
+
...(options.context === undefined ? {} : { context: options.context }),
|
|
111
|
+
});
|
|
112
|
+
if (started.status !== 202 || typeof started.json?.taskId !== "string") {
|
|
113
|
+
return {
|
|
114
|
+
ok: false,
|
|
115
|
+
summary: `box refused the edit task (${started.status})`,
|
|
116
|
+
filesChanged: [],
|
|
117
|
+
testsRun: 0,
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
const taskId = started.json.taskId;
|
|
121
|
+
const deadline = clock.now() + timeoutMs;
|
|
122
|
+
while (clock.now() < deadline) {
|
|
123
|
+
await clock.sleep(pollIntervalMs);
|
|
124
|
+
const polled = await controlRequest(machine, "GET", `/agent/task/${taskId}`);
|
|
125
|
+
const payload = polled.json;
|
|
126
|
+
if (polled.status === 200 && payload?.status === "done") {
|
|
127
|
+
return asResult(payload.result);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
return {
|
|
131
|
+
ok: false,
|
|
132
|
+
summary: `box edit timed out after ${Math.round(timeoutMs / 1000)}s`,
|
|
133
|
+
filesChanged: [],
|
|
134
|
+
testsRun: 0,
|
|
135
|
+
};
|
|
136
|
+
};
|
|
137
|
+
//# sourceMappingURL=box-agent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"box-agent.js","sourceRoot":"","sources":["../src/box-agent.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { type AppDocument, type SecretsProvider } from "@vendoai/core";
|
|
2
|
+
/** Resolves the box inference endpoint; undefined = no inference in this box. */
|
|
3
|
+
export type InferenceResolver = () => Promise<{
|
|
4
|
+
url: string;
|
|
5
|
+
key: string;
|
|
6
|
+
} | undefined>;
|
|
7
|
+
export interface BuildEnvContext {
|
|
8
|
+
/** Secret names the owner granted to THIS app; only declared ∩ granted inject. */
|
|
9
|
+
granted: ReadonlySet<string>;
|
|
10
|
+
secrets?: SecretsProvider;
|
|
11
|
+
/** Base URL for the durable-rows callback surface (the wire's /box mount). */
|
|
12
|
+
storeUrl: string;
|
|
13
|
+
/** Base URL for the host-tools callback surface (same mount in OSS). */
|
|
14
|
+
hostUrl: string;
|
|
15
|
+
/** The per-app bearer minted at provision (createAppTokens). */
|
|
16
|
+
appToken: string;
|
|
17
|
+
inference?: InferenceResolver;
|
|
18
|
+
port?: number;
|
|
19
|
+
}
|
|
20
|
+
export interface BuiltBoxEnv {
|
|
21
|
+
env: Record<string, string>;
|
|
22
|
+
/** Names whose REAL values entered the box — the provisioner audits these. */
|
|
23
|
+
injectedSecrets: string[];
|
|
24
|
+
}
|
|
25
|
+
export declare function buildEnv(app: AppDocument, ctx: BuildEnvContext): Promise<BuiltBoxEnv>;
|
|
26
|
+
//# sourceMappingURL=box-env.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"box-env.d.ts","sourceRoot":"","sources":["../src/box-env.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,KAAK,WAAW,EAAE,KAAK,eAAe,EAAE,MAAM,eAAe,CAAC;AA0BnF,iFAAiF;AACjF,MAAM,MAAM,iBAAiB,GAAG,MAAM,OAAO,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAAC,CAAC;AAExF,MAAM,WAAW,eAAe;IAC9B,kFAAkF;IAClF,OAAO,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAC7B,OAAO,CAAC,EAAE,eAAe,CAAC;IAC1B,8EAA8E;IAC9E,QAAQ,EAAE,MAAM,CAAC;IACjB,wEAAwE;IACxE,OAAO,EAAE,MAAM,CAAC;IAChB,gEAAgE;IAChE,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,iBAAiB,CAAC;IAC9B,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5B,8EAA8E;IAC9E,eAAe,EAAE,MAAM,EAAE,CAAC;CAC3B;AAED,wBAAsB,QAAQ,CAAC,GAAG,EAAE,WAAW,EAAE,GAAG,EAAE,eAAe,GAAG,OAAO,CAAC,WAAW,CAAC,CA0B3F"}
|
package/dist/box-env.js
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { VendoError } from "@vendoai/core";
|
|
2
|
+
/** execution-v2 skin contract, env half — the ONE seam that assembles what
|
|
3
|
+
* Vendo puts into the box at provision/wake. Lane B's lifecycle calls this
|
|
4
|
+
* when it creates a machine; nothing else composes box env vars. Inside the
|
|
5
|
+
* box is free country — these vars are the whole "in" side of the contract:
|
|
6
|
+
* - PORT: where the app must listen;
|
|
7
|
+
* - each GRANTED declared secret, by its own name, real value (the v2 box
|
|
8
|
+
* does its own allowlisted egress — no handles, no egress proxy);
|
|
9
|
+
* - VENDO_STORE_URL + VENDO_APP_TOKEN: durable rows over plain HTTP;
|
|
10
|
+
* - VENDO_HOST_URL + the same token: host tool calls through the guard;
|
|
11
|
+
* - VENDO_INFERENCE_URL/KEY: the in-box agent's model door (resolver seam;
|
|
12
|
+
* Cloud-gateway vs BYO value wiring rides model provisioning, Wave 3+). */
|
|
13
|
+
const DEFAULT_PORT = 8080;
|
|
14
|
+
/** The boundary vars the contract owns; a secret must never shadow one. */
|
|
15
|
+
const RESERVED_ENV = new Set([
|
|
16
|
+
"PORT",
|
|
17
|
+
"VENDO_STORE_URL",
|
|
18
|
+
"VENDO_APP_TOKEN",
|
|
19
|
+
"VENDO_HOST_URL",
|
|
20
|
+
"VENDO_INFERENCE_URL",
|
|
21
|
+
"VENDO_INFERENCE_KEY",
|
|
22
|
+
]);
|
|
23
|
+
export async function buildEnv(app, ctx) {
|
|
24
|
+
if (ctx.port !== undefined && (!Number.isInteger(ctx.port) || ctx.port < 1 || ctx.port > 65_535)) {
|
|
25
|
+
throw new VendoError("validation", "port must be an integer between 1 and 65535");
|
|
26
|
+
}
|
|
27
|
+
const env = {};
|
|
28
|
+
const injectedSecrets = [];
|
|
29
|
+
for (const name of new Set(app.secrets ?? [])) {
|
|
30
|
+
if (RESERVED_ENV.has(name)) {
|
|
31
|
+
throw new VendoError("validation", `secret name ${name} collides with a reserved box env var`);
|
|
32
|
+
}
|
|
33
|
+
if (!ctx.granted.has(name) || ctx.secrets === undefined)
|
|
34
|
+
continue;
|
|
35
|
+
const value = await ctx.secrets.get(name);
|
|
36
|
+
if (value === undefined || value.length === 0)
|
|
37
|
+
continue;
|
|
38
|
+
env[name] = value;
|
|
39
|
+
injectedSecrets.push(name);
|
|
40
|
+
}
|
|
41
|
+
env["PORT"] = String(ctx.port ?? DEFAULT_PORT);
|
|
42
|
+
env["VENDO_STORE_URL"] = ctx.storeUrl;
|
|
43
|
+
env["VENDO_APP_TOKEN"] = ctx.appToken;
|
|
44
|
+
env["VENDO_HOST_URL"] = ctx.hostUrl;
|
|
45
|
+
const inference = await ctx.inference?.();
|
|
46
|
+
if (inference !== undefined) {
|
|
47
|
+
env["VENDO_INFERENCE_URL"] = inference.url;
|
|
48
|
+
env["VENDO_INFERENCE_KEY"] = inference.key;
|
|
49
|
+
}
|
|
50
|
+
return { env, injectedSecrets };
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=box-env.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"box-env.js","sourceRoot":"","sources":["../src/box-env.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAA0C,MAAM,eAAe,CAAC;AAEnF;;;;;;;;;;+EAU+E;AAE/E,MAAM,YAAY,GAAG,IAAI,CAAC;AAE1B,2EAA2E;AAC3E,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC;IAC3B,MAAM;IACN,iBAAiB;IACjB,iBAAiB;IACjB,gBAAgB;IAChB,qBAAqB;IACrB,qBAAqB;CACtB,CAAC,CAAC;AAyBH,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,GAAgB,EAAE,GAAoB;IACnE,IAAI,GAAG,CAAC,IAAI,KAAK,SAAS,IAAI,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,IAAI,GAAG,CAAC,IAAI,GAAG,CAAC,IAAI,GAAG,MAAM,CAAC,EAAE,CAAC;QACjG,MAAM,IAAI,UAAU,CAAC,YAAY,EAAE,6CAA6C,CAAC,CAAC;IACpF,CAAC;IACD,MAAM,GAAG,GAA2B,EAAE,CAAC;IACvC,MAAM,eAAe,GAAa,EAAE,CAAC;IACrC,KAAK,MAAM,IAAI,IAAI,IAAI,GAAG,CAAC,GAAG,CAAC,OAAO,IAAI,EAAE,CAAC,EAAE,CAAC;QAC9C,IAAI,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YAC3B,MAAM,IAAI,UAAU,CAAC,YAAY,EAAE,eAAe,IAAI,uCAAuC,CAAC,CAAC;QACjG,CAAC;QACD,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,OAAO,KAAK,SAAS;YAAE,SAAS;QAClE,MAAM,KAAK,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC1C,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,SAAS;QACxD,GAAG,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC;QAClB,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC7B,CAAC;IACD,GAAG,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,IAAI,IAAI,YAAY,CAAC,CAAC;IAC/C,GAAG,CAAC,iBAAiB,CAAC,GAAG,GAAG,CAAC,QAAQ,CAAC;IACtC,GAAG,CAAC,iBAAiB,CAAC,GAAG,GAAG,CAAC,QAAQ,CAAC;IACtC,GAAG,CAAC,gBAAgB,CAAC,GAAG,GAAG,CAAC,OAAO,CAAC;IACpC,MAAM,SAAS,GAAG,MAAM,GAAG,CAAC,SAAS,EAAE,EAAE,CAAC;IAC1C,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;QAC5B,GAAG,CAAC,qBAAqB,CAAC,GAAG,SAAS,CAAC,GAAG,CAAC;QAC3C,GAAG,CAAC,qBAAqB,CAAC,GAAG,SAAS,CAAC,GAAG,CAAC;IAC7C,CAAC;IACD,OAAO,EAAE,GAAG,EAAE,eAAe,EAAE,CAAC;AAClC,CAAC"}
|
package/dist/call.d.ts
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { type AppDocument, type ApprovalId, type Json, type RunContext, type ToolCall, type ToolOutcome, type ToolRegistry } from "@vendoai/core";
|
|
2
|
+
/** The name half of core's 01 §8 `fn:<name>` grammar. */
|
|
3
|
+
export declare const FN_NAME_PATTERN: RegExp;
|
|
4
|
+
/** 06-apps §4.1 — internal execution surface shared by open() and call(). */
|
|
5
|
+
export interface AppCaller {
|
|
6
|
+
call(app: AppDocument, ref: string, args: Json, ctx: RunContext): Promise<ToolOutcome>;
|
|
7
|
+
callFn(app: AppDocument, name: string, args: Json, ctx: RunContext): Promise<ToolOutcome>;
|
|
8
|
+
callQuery(app: AppDocument, ref: string, args: Json, ctx: RunContext): Promise<ToolOutcome>;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* W0 — hooks the runtime attaches to capture the exact parked call. When a
|
|
12
|
+
* mutating in-app ACTION (call(), not a read query) parks on an approval, the
|
|
13
|
+
* runtime records the byte-exact call + context so it can re-dispatch it when
|
|
14
|
+
* the owner approves (see parked-action.ts). Only actions resume; a parked
|
|
15
|
+
* read query surfaces as a render error, not a stalled effect.
|
|
16
|
+
*/
|
|
17
|
+
export interface AppCallerHooks {
|
|
18
|
+
onParkedAction(app: AppDocument, call: ToolCall, ctx: RunContext, approvalId: ApprovalId): Promise<void>;
|
|
19
|
+
}
|
|
20
|
+
export declare const fnOutcome: (name: string) => ToolOutcome;
|
|
21
|
+
/** 06-apps §4.1 — resolve fn: references and guard-bound host tools. */
|
|
22
|
+
export declare const createAppCaller: (tools: ToolRegistry, hooks?: AppCallerHooks) => AppCaller;
|
|
23
|
+
//# sourceMappingURL=call.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"call.d.ts","sourceRoot":"","sources":["../src/call.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,WAAW,EAChB,KAAK,UAAU,EACf,KAAK,IAAI,EACT,KAAK,UAAU,EACf,KAAK,QAAQ,EACb,KAAK,WAAW,EAChB,KAAK,YAAY,EAClB,MAAM,eAAe,CAAC;AAEvB,yDAAyD;AACzD,eAAO,MAAM,eAAe,QAA8B,CAAC;AAE3D,6EAA6E;AAC7E,MAAM,WAAW,SAAS;IACxB,IAAI,CAAC,GAAG,EAAE,WAAW,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;IACvF,MAAM,CAAC,GAAG,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;IAC1F,SAAS,CAAC,GAAG,EAAE,WAAW,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;CAC7F;AAED;;;;;;GAMG;AACH,MAAM,WAAW,cAAc;IAC7B,cAAc,CACZ,GAAG,EAAE,WAAW,EAChB,IAAI,EAAE,QAAQ,EACd,GAAG,EAAE,UAAU,EACf,UAAU,EAAE,UAAU,GACrB,OAAO,CAAC,IAAI,CAAC,CAAC;CAClB;AAOD,eAAO,MAAM,SAAS,GAAI,MAAM,MAAM,KAAG,WAKvC,CAAC;AAEH,wEAAwE;AACxE,eAAO,MAAM,eAAe,GAAI,OAAO,YAAY,EAAE,QAAQ,cAAc,KAAG,SAiC7E,CAAC"}
|
package/dist/call.js
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/** The name half of core's 01 §8 `fn:<name>` grammar. */
|
|
2
|
+
export const FN_NAME_PATTERN = /^[A-Za-z_][A-Za-z0-9_-]*$/;
|
|
3
|
+
// execution-v2 — the v1 MachineSessions fn: path is deleted. fn: refs on a
|
|
4
|
+
// machine-bearing app resolve over the v2 box door (fn.ts decorates this
|
|
5
|
+
// caller in createApps); what remains HERE is the fallthrough for an app with
|
|
6
|
+
// no machine, which settles as a CONTAINED error outcome — a stale binding
|
|
7
|
+
// must not take down open() or an automation run.
|
|
8
|
+
export const fnOutcome = (name) => ({
|
|
9
|
+
status: "error",
|
|
10
|
+
error: FN_NAME_PATTERN.test(name)
|
|
11
|
+
? { code: "validation", message: `fn:${name} requires a machine; the app has not graduated` }
|
|
12
|
+
: { code: "validation", message: `invalid fn reference: fn:${name}` },
|
|
13
|
+
});
|
|
14
|
+
/** 06-apps §4.1 — resolve fn: references and guard-bound host tools. */
|
|
15
|
+
export const createAppCaller = (tools, hooks) => {
|
|
16
|
+
// Returns the outcome AND the exact call/ctx it ran under, so the action path
|
|
17
|
+
// can hand a byte-exact parked call to the approve→resume seam.
|
|
18
|
+
const hostTool = async (app, ref, args, ctx) => {
|
|
19
|
+
const call = { id: `call_${globalThis.crypto.randomUUID()}`, tool: ref, args };
|
|
20
|
+
const appCtx = { ...ctx, venue: "app", appId: app.id };
|
|
21
|
+
return { call, appCtx, outcome: await tools.execute(call, appCtx) };
|
|
22
|
+
};
|
|
23
|
+
return {
|
|
24
|
+
async call(app, ref, args, ctx) {
|
|
25
|
+
if (ref.startsWith("fn:"))
|
|
26
|
+
return fnOutcome(ref.slice(3));
|
|
27
|
+
const { call, appCtx, outcome } = await hostTool(app, ref, args, ctx);
|
|
28
|
+
// An action the guard sent to approval is remembered so its effect can
|
|
29
|
+
// land the moment the owner approves — the bug was that nobody did this.
|
|
30
|
+
if (outcome.status === "pending-approval" && hooks !== undefined) {
|
|
31
|
+
await hooks.onParkedAction(app, call, appCtx, outcome.approvalId);
|
|
32
|
+
}
|
|
33
|
+
return outcome;
|
|
34
|
+
},
|
|
35
|
+
async callFn(app, name) {
|
|
36
|
+
return fnOutcome(name);
|
|
37
|
+
},
|
|
38
|
+
async callQuery(app, ref, args, ctx) {
|
|
39
|
+
if (ref.startsWith("fn:"))
|
|
40
|
+
return fnOutcome(ref.slice(3));
|
|
41
|
+
return (await hostTool(app, ref, args, ctx)).outcome;
|
|
42
|
+
},
|
|
43
|
+
};
|
|
44
|
+
};
|
|
45
|
+
//# sourceMappingURL=call.js.map
|
package/dist/call.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"call.js","sourceRoot":"","sources":["../src/call.ts"],"names":[],"mappings":"AAUA,yDAAyD;AACzD,MAAM,CAAC,MAAM,eAAe,GAAG,2BAA2B,CAAC;AAyB3D,2EAA2E;AAC3E,yEAAyE;AACzE,8EAA8E;AAC9E,2EAA2E;AAC3E,kDAAkD;AAClD,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,IAAY,EAAe,EAAE,CAAC,CAAC;IACvD,MAAM,EAAE,OAAO;IACf,KAAK,EAAE,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC;QAC/B,CAAC,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,IAAI,gDAAgD,EAAE;QAC7F,CAAC,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,OAAO,EAAE,4BAA4B,IAAI,EAAE,EAAE;CACxE,CAAC,CAAC;AAEH,wEAAwE;AACxE,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,KAAmB,EAAE,KAAsB,EAAa,EAAE;IACxF,8EAA8E;IAC9E,gEAAgE;IAChE,MAAM,QAAQ,GAAG,KAAK,EACpB,GAAgB,EAChB,GAAW,EACX,IAAU,EACV,GAAe,EACwD,EAAE;QACzE,MAAM,IAAI,GAAa,EAAE,EAAE,EAAE,QAAQ,UAAU,CAAC,MAAM,CAAC,UAAU,EAAE,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC;QACzF,MAAM,MAAM,GAAe,EAAE,GAAG,GAAG,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,CAAC,EAAE,EAAE,CAAC;QACnE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE,CAAC;IACtE,CAAC,CAAC;IAEF,OAAO;QACL,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG;YAC5B,IAAI,GAAG,CAAC,UAAU,CAAC,KAAK,CAAC;gBAAE,OAAO,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;YAC1D,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,CAAC,CAAC;YACtE,uEAAuE;YACvE,yEAAyE;YACzE,IAAI,OAAO,CAAC,MAAM,KAAK,kBAAkB,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;gBACjE,MAAM,KAAK,CAAC,cAAc,CAAC,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,UAAU,CAAC,CAAC;YACpE,CAAC;YACD,OAAO,OAAO,CAAC;QACjB,CAAC;QACD,KAAK,CAAC,MAAM,CAAC,GAAG,EAAE,IAAI;YACpB,OAAO,SAAS,CAAC,IAAI,CAAC,CAAC;QACzB,CAAC;QACD,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG;YACjC,IAAI,GAAG,CAAC,UAAU,CAAC,KAAK,CAAC;gBAAE,OAAO,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;YAC1D,OAAO,CAAC,MAAM,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC;QACvD,CAAC;KACF,CAAC;AACJ,CAAC,CAAC"}
|