@wrenai/genbi 0.0.4 → 0.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +64 -2
- package/dist/assets/{echarts-LTFC-ysd.js → echarts-DYM4hjvk.js} +2 -2
- package/dist/assets/index-A_Wrq7Ey.css +1 -0
- package/dist/assets/{index-Bo--QMUN.js → index-DsH129tV.js} +18 -17
- package/dist/index.html +2 -2
- package/dist-server/harness/bundle/schema.d.ts +38 -0
- package/dist-server/harness/bundle/schema.js +18 -10
- package/dist-server/harness/bundle/version.js +1 -1
- package/dist-server/harness/cli-args.d.ts +10 -2
- package/dist-server/harness/cli-args.js +24 -8
- package/dist-server/harness/cli.js +75 -9
- package/dist-server/harness/compile/cache.js +4 -4
- package/dist-server/harness/compile/compose-profile.d.ts +51 -14
- package/dist-server/harness/compile/compose-profile.js +85 -19
- package/dist-server/harness/compile/context-loader.d.ts +56 -0
- package/dist-server/harness/compile/context-loader.js +237 -0
- package/dist-server/harness/compile/errors.d.ts +19 -0
- package/dist-server/harness/compile/errors.js +35 -0
- package/dist-server/harness/compile/index.d.ts +4 -3
- package/dist-server/harness/compile/index.js +4 -3
- package/dist-server/harness/compile/pipeline.d.ts +15 -7
- package/dist-server/harness/compile/pipeline.js +62 -14
- package/dist-server/harness/compile/resolve-binary.d.ts +2 -2
- package/dist-server/harness/compile/resolve-binary.js +3 -3
- package/dist-server/harness/compile/types.d.ts +29 -0
- package/dist-server/harness/compile/warble-identity.d.ts +11 -0
- package/dist-server/harness/compile/warble-identity.js +13 -0
- package/dist-server/harness/components/ai-step.d.ts +4 -0
- package/dist-server/harness/components/ai-step.js +40 -0
- package/dist-server/harness/components/broker.d.ts +60 -0
- package/dist-server/harness/components/broker.js +117 -0
- package/dist-server/harness/components/capability-card.d.ts +98 -0
- package/dist-server/harness/components/capability-card.js +169 -0
- package/dist-server/harness/components/context.d.ts +2 -0
- package/dist-server/harness/components/context.js +30 -0
- package/dist-server/harness/components/display.d.ts +6 -0
- package/dist-server/harness/components/display.js +29 -0
- package/dist-server/harness/components/egress-judge.d.ts +12 -0
- package/dist-server/harness/components/egress-judge.js +27 -0
- package/dist-server/harness/components/egress.d.ts +142 -0
- package/dist-server/harness/components/egress.js +469 -0
- package/dist-server/harness/components/in-process.d.ts +7 -0
- package/dist-server/harness/components/in-process.js +245 -0
- package/dist-server/harness/components/normalize.d.ts +35 -0
- package/dist-server/harness/components/normalize.js +245 -0
- package/dist-server/harness/components/plan.d.ts +31 -0
- package/dist-server/harness/components/plan.js +184 -0
- package/dist-server/harness/components/report.d.ts +207 -0
- package/dist-server/harness/components/report.js +309 -0
- package/dist-server/harness/components/runner.d.ts +193 -0
- package/dist-server/harness/components/runner.js +492 -0
- package/dist-server/harness/components/semantic-guards.d.ts +20 -0
- package/dist-server/harness/components/semantic-guards.js +42 -0
- package/dist-server/harness/components/terminal-json.d.ts +18 -0
- package/dist-server/harness/components/terminal-json.js +82 -0
- package/dist-server/harness/components/usage.d.ts +14 -0
- package/dist-server/harness/components/usage.js +19 -0
- package/dist-server/harness/components/wren-access.d.ts +29 -0
- package/dist-server/harness/components/wren-access.js +233 -0
- package/dist-server/harness/components/zone-dry-run.d.ts +43 -0
- package/dist-server/harness/components/zone-dry-run.js +107 -0
- package/dist-server/harness/components/zone-gate.d.ts +76 -0
- package/dist-server/harness/components/zone-gate.js +144 -0
- package/dist-server/harness/events/index.d.ts +1 -1
- package/dist-server/harness/events/types.d.ts +52 -0
- package/dist-server/harness/index.d.ts +9 -2
- package/dist-server/harness/index.js +5 -1
- package/dist-server/harness/loop/executor.d.ts +1 -0
- package/dist-server/harness/loop/executor.js +37 -15
- package/dist-server/harness/npm-package-resolve.d.ts +2 -0
- package/dist-server/harness/npm-package-resolve.js +16 -4
- package/dist-server/harness/providers/adapters/openai-compatible.d.ts +13 -0
- package/dist-server/harness/providers/adapters/openai-compatible.js +17 -0
- package/dist-server/harness/providers/adapters/openai.d.ts +7 -0
- package/dist-server/harness/providers/adapters/openai.js +6 -0
- package/dist-server/harness/providers/adapters/pi-ai.d.ts +48 -0
- package/dist-server/harness/providers/adapters/pi-ai.js +518 -0
- package/dist-server/harness/providers/binding.d.ts +45 -4
- package/dist-server/harness/providers/binding.js +44 -8
- package/dist-server/harness/providers/index.d.ts +9 -3
- package/dist-server/harness/providers/index.js +10 -3
- package/dist-server/harness/providers/zone.d.ts +96 -0
- package/dist-server/harness/providers/zone.js +112 -0
- package/dist-server/harness/render/answering-query.d.ts +29 -0
- package/dist-server/harness/render/answering-query.js +62 -0
- package/dist-server/harness/render/envelope.d.ts +6 -0
- package/dist-server/harness/render/envelope.js +10 -3
- package/dist-server/harness/route/adapter-spec.d.ts +8 -9
- package/dist-server/harness/route/adapter-spec.js +13 -14
- package/dist-server/harness/route/codex-ask-events.js +2 -1
- package/dist-server/harness/route/codex-ask.d.ts +4 -0
- package/dist-server/harness/route/codex-ask.js +69 -30
- package/dist-server/harness/route/codex-host-query.d.ts +52 -0
- package/dist-server/harness/route/codex-host-query.js +191 -0
- package/dist-server/harness/route/codex-local-manifest.d.ts +9 -1
- package/dist-server/harness/route/codex-local-manifest.js +96 -15
- package/dist-server/harness/route/codex-wren-proxy.d.ts +33 -0
- package/dist-server/harness/route/codex-wren-proxy.js +227 -0
- package/dist-server/harness/route/describe.js +45 -6
- package/dist-server/harness/route/in-process.d.ts +22 -1
- package/dist-server/harness/route/in-process.js +54 -4
- package/dist-server/harness/route/route.js +5 -2
- package/dist-server/harness/route/types.d.ts +30 -1
- package/dist-server/harness/session/run.js +30 -10
- package/dist-server/harness/setup/runner.d.ts +2 -0
- package/dist-server/harness/setup/runner.js +38 -17
- package/dist-server/harness/setup/yaml-scalar.d.ts +23 -0
- package/dist-server/harness/setup/yaml-scalar.js +62 -0
- package/dist-server/server/adopt.js +1 -17
- package/dist-server/server/app.d.ts +1 -0
- package/dist-server/server/app.js +163 -14
- package/dist-server/server/auth-choice.d.ts +13 -1
- package/dist-server/server/auth-choice.js +66 -1
- package/dist-server/server/bin.js +177 -25
- package/dist-server/server/codex-local-grounding.d.ts +18 -0
- package/dist-server/server/codex-local-grounding.js +92 -0
- package/dist-server/server/codex-native-session.d.ts +25 -0
- package/dist-server/server/codex-native-session.js +1 -0
- package/dist-server/server/codex-runtime-composition.d.ts +34 -0
- package/dist-server/server/codex-runtime-composition.js +250 -0
- package/dist-server/server/codex-structured-ask.d.ts +23 -0
- package/dist-server/server/codex-structured-ask.js +102 -0
- package/dist-server/server/conn-config.js +4 -16
- package/dist-server/server/conversation-socket.d.ts +16 -0
- package/dist-server/server/conversation-socket.js +65 -0
- package/dist-server/server/db.d.ts +46 -0
- package/dist-server/server/db.js +88 -9
- package/dist-server/server/env-detect.d.ts +6 -0
- package/dist-server/server/env-detect.js +7 -0
- package/dist-server/server/fold.d.ts +22 -4
- package/dist-server/server/fold.js +37 -5
- package/dist-server/server/harness.d.ts +2 -2
- package/dist-server/server/harness.js +33 -7
- package/dist-server/server/interactive-terminal.d.ts +10 -6
- package/dist-server/server/interactive-terminal.js +33 -8
- package/dist-server/server/managed-wren-runtime.d.ts +116 -0
- package/dist-server/server/managed-wren-runtime.js +670 -0
- package/dist-server/server/native-artifacts.d.ts +23 -7
- package/dist-server/server/native-artifacts.js +43 -12
- package/dist-server/server/native-component-context.d.ts +19 -0
- package/dist-server/server/native-component-context.js +76 -0
- package/dist-server/server/native-component-preparation.d.ts +20 -0
- package/dist-server/server/native-component-preparation.js +129 -0
- package/dist-server/server/native-component-runtime.d.ts +36 -0
- package/dist-server/server/native-component-runtime.js +92 -0
- package/dist-server/server/native-components.d.ts +84 -0
- package/dist-server/server/native-components.js +160 -0
- package/dist-server/server/native-dispatch-process.d.ts +8 -0
- package/dist-server/server/native-dispatch-process.js +65 -0
- package/dist-server/server/native-runtime-spec.d.ts +89 -0
- package/dist-server/server/native-runtime-spec.js +169 -0
- package/dist-server/server/native-sessions.d.ts +172 -19
- package/dist-server/server/native-sessions.js +839 -244
- package/dist-server/server/native-shutdown.d.ts +6 -0
- package/dist-server/server/native-shutdown.js +28 -0
- package/dist-server/server/native-wren-home.d.ts +18 -0
- package/dist-server/server/native-wren-home.js +262 -0
- package/dist-server/server/node-pty-host.d.ts +2 -1
- package/dist-server/server/node-pty-host.js +3 -2
- package/dist-server/server/profile-registry.d.ts +139 -0
- package/dist-server/server/profile-registry.js +620 -0
- package/dist-server/server/runtime-binding.d.ts +4 -1
- package/dist-server/server/runtime-binding.js +50 -2
- package/dist-server/server/runtime-host/claude-component-step.d.ts +25 -0
- package/dist-server/server/runtime-host/claude-component-step.js +186 -0
- package/dist-server/server/runtime-host/codex-app-server.d.ts +75 -0
- package/dist-server/server/runtime-host/codex-app-server.js +239 -0
- package/dist-server/server/runtime-host/codex-compatibility.d.ts +110 -0
- package/dist-server/server/runtime-host/codex-compatibility.js +162 -0
- package/dist-server/server/runtime-host/codex-component-step.d.ts +19 -0
- package/dist-server/server/runtime-host/codex-component-step.js +308 -0
- package/dist-server/server/runtime-host/codex-conversation.d.ts +109 -0
- package/dist-server/server/runtime-host/codex-conversation.js +295 -0
- package/dist-server/server/runtime-host/codex-direct-tools.d.ts +23 -0
- package/dist-server/server/runtime-host/codex-direct-tools.js +59 -0
- package/dist-server/server/runtime-host/codex-events.d.ts +647 -0
- package/dist-server/server/runtime-host/codex-events.js +66 -0
- package/dist-server/server/runtime-host/codex-policy.d.ts +16 -0
- package/dist-server/server/runtime-host/codex-policy.js +151 -0
- package/dist-server/server/runtime-host/codex-process.d.ts +8 -0
- package/dist-server/server/runtime-host/codex-process.js +96 -0
- package/dist-server/server/runtime-host/codex-rpc.d.ts +47 -0
- package/dist-server/server/runtime-host/codex-rpc.js +182 -0
- package/dist-server/server/runtime-host/codex-session.d.ts +74 -0
- package/dist-server/server/runtime-host/codex-session.js +492 -0
- package/dist-server/server/runtime-host/codex-terminal-protocol.d.ts +35 -0
- package/dist-server/server/runtime-host/codex-terminal-protocol.js +243 -0
- package/dist-server/server/runtime-host/codex-terminal.d.ts +16 -0
- package/dist-server/server/runtime-host/codex-terminal.js +120 -0
- package/dist-server/server/runtime-host/index.d.ts +5 -0
- package/dist-server/server/runtime-host/index.js +3 -0
- package/dist-server/server/runtime-host/local.d.ts +29 -0
- package/dist-server/server/runtime-host/local.js +90 -0
- package/dist-server/server/runtime-host/policy.d.ts +8 -0
- package/dist-server/server/runtime-host/policy.js +78 -0
- package/dist-server/server/runtime-host/types.d.ts +52 -0
- package/dist-server/server/runtime-host/types.js +62 -0
- package/dist-server/server/structured-query-evidence.d.ts +7 -0
- package/dist-server/server/structured-query-evidence.js +47 -0
- package/dist-server/server/structured-runtime.d.ts +52 -0
- package/dist-server/server/structured-runtime.js +130 -0
- package/dist-server/server/structured-scope.d.ts +4 -0
- package/dist-server/server/structured-scope.js +12 -0
- package/dist-server/server/turn.d.ts +6 -1
- package/dist-server/server/turn.js +82 -25
- package/dist-server/server/wire-types.d.ts +67 -3
- package/dist-server/server/wren-profiles.js +1 -1
- package/managed-wren/README.md +60 -0
- package/managed-wren/dependency-wheels.json +282 -0
- package/managed-wren/manifest.json +373 -0
- package/managed-wren/release-inputs.json +45 -0
- package/managed-wren/runtime-tree.cjs +115 -0
- package/managed-wren/source-inputs.json +40 -0
- package/package.json +15 -6
- package/profiles/genbi-default/context/binding.yml +17 -7
- package/profiles/genbi-default/context/context.json +146 -0
- package/profiles/genbi-default/ir.golden.json +39 -43
- package/profiles/genbi-default/profile.yml +31 -0
- package/profiles/genbi-enrich-context/context/binding.yml +14 -3
- package/profiles/genbi-enrich-context/context/context.json +146 -0
- package/profiles/genbi-enrich-context/ir.golden.json +4 -5
- package/profiles/genbi-monitor/context/binding.yml +13 -5
- package/profiles/genbi-monitor/context/context.json +146 -0
- package/profiles/genbi-monitor/ir.golden.json +13 -7
- package/profiles/genbi-report/context/binding.yml +19 -0
- package/profiles/genbi-report/context/context.json +223 -0
- package/profiles/genbi-report/ir.golden.json +328 -0
- package/profiles/genbi-report/profile.yml +38 -0
- package/profiles/genbi-setup/ir.golden.json +3 -1
- package/dist/assets/index-Xs4q7pNo.css +0 -1
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { isDeepStrictEqual } from "node:util";
|
|
3
|
+
import { z } from "zod";
|
|
4
|
+
export const HOST_FEATURES = [
|
|
5
|
+
"immutable_step_authority", "isolated_component_tools", "fresh_child_context",
|
|
6
|
+
"verified_context_preconditions", "component_owned_bindings", "exact_step_tiers",
|
|
7
|
+
"exact_dataflow", "bounded_repair", "shared_admission_ledger",
|
|
8
|
+
"deadline_and_descendant_cancellation", "normalized_child_results",
|
|
9
|
+
"root_only_persistence", "redacted_usage_trace",
|
|
10
|
+
];
|
|
11
|
+
export const VERCEL_HOST_CONTRACT = Object.freeze({
|
|
12
|
+
protocol: "warble-component-host/1", bundle_version: "0.2", features: HOST_FEATURES,
|
|
13
|
+
guardrails: ["read_only_execution", "row_limit", "statement_timeout", "deterministic_gate", "artifact_write", "drill_depth_limit", "additivity_guard"],
|
|
14
|
+
tool_authority: {
|
|
15
|
+
query: { source: "native", capabilities: ["sql_execution:read_only"] },
|
|
16
|
+
semantic_introspect: { source: "native", capabilities: ["semantic_introspection"] },
|
|
17
|
+
},
|
|
18
|
+
});
|
|
19
|
+
const limits = z.object({
|
|
20
|
+
max_depth: z.literal(8), max_attempts: z.literal(32), max_steps: z.literal(40),
|
|
21
|
+
max_steps_per_child: z.literal(12), max_in_flight: z.literal(1),
|
|
22
|
+
max_request_bytes: z.literal(65536), max_result_bytes: z.literal(1048576), timeout_ms: z.literal(120000),
|
|
23
|
+
}).strict();
|
|
24
|
+
const digest = z.string().regex(/^sha256:[a-f0-9]{64}$/);
|
|
25
|
+
const strings = z.array(z.string());
|
|
26
|
+
const record = z.record(z.string(), z.unknown());
|
|
27
|
+
const calls = z.array(z.object({ alias: z.string(), component: z.string() }).strict());
|
|
28
|
+
const when = z.object({ guard: z.literal("on_failure"), target: z.string() }).strict();
|
|
29
|
+
const tool = z.object({ name: z.string(), source: z.string() }).strict();
|
|
30
|
+
const irStep = z.object({
|
|
31
|
+
name: z.string(), tier: z.string(), consumes: strings, produces: z.string(),
|
|
32
|
+
prompt: z.string(), conditional: z.boolean(), when: when.nullable().optional(),
|
|
33
|
+
produces_exclusive: z.boolean().optional(), capabilities: strings.optional(),
|
|
34
|
+
component_calls: calls.optional(),
|
|
35
|
+
}).strict();
|
|
36
|
+
const declaration = z.object({
|
|
37
|
+
id: z.string(), verb: z.string(), type: z.literal("analytical"), realization_kind: z.literal("skill"),
|
|
38
|
+
trigger: z.object({ kind: z.literal("one_shot") }).strict(),
|
|
39
|
+
effect: z.object({ outcome: z.object({ kind: z.literal("none") }).strict(), render_blocks: z.array(record).optional() }).strict(),
|
|
40
|
+
entrypoint: z.boolean().optional(), brief: z.string().optional(), description: z.string().optional(),
|
|
41
|
+
llm_calls: z.array(irStep), required_capabilities: strings,
|
|
42
|
+
guardrails: z.array(record), borrowed_actions: strings, context_binding: record,
|
|
43
|
+
context_requirements: strings, context_precondition: z.array(record).optional(),
|
|
44
|
+
precondition_result: record, params: z.array(record).optional(), binds: record.nullable().optional(),
|
|
45
|
+
prompt_fragment: z.string().optional(), examples: strings.optional(), eval: record.optional(), eval_ref: z.string().optional(),
|
|
46
|
+
}).strict();
|
|
47
|
+
const realization = z.union([
|
|
48
|
+
z.object({ kind: z.literal("independent") }).strict(),
|
|
49
|
+
z.object({ kind: z.literal("repair_fold"), fold_into: z.string(), max_attempts: z.literal(1),
|
|
50
|
+
failure_input: z.string().optional(), on_exhaustion: z.literal("fail").optional() }).strict(),
|
|
51
|
+
]);
|
|
52
|
+
const shared = {
|
|
53
|
+
warble_ir_version: z.literal("0.9"), protocol: z.literal("warble-component-host/1"),
|
|
54
|
+
execution_status: z.literal("not_executed"), profile: z.string(),
|
|
55
|
+
input_ir_sha256: digest, context_binding: record, system_prompt: z.string().nullable().optional(),
|
|
56
|
+
limits, model_turn_hard_limit: z.literal(false), monetary_hard_limit: z.literal(false),
|
|
57
|
+
};
|
|
58
|
+
const vercel = z.object({
|
|
59
|
+
...shared, vercel_bundle_version: z.literal("0.2"), target: z.literal("vercel:headless"),
|
|
60
|
+
entries: strings, required_host: record, bundle_sha256: digest,
|
|
61
|
+
components: z.record(z.string(), z.object({
|
|
62
|
+
declaration,
|
|
63
|
+
steps: z.array(z.object({ name: z.string(), effective_capabilities: strings, tools: z.array(tool), realization }).strict()),
|
|
64
|
+
capabilities: z.unknown(),
|
|
65
|
+
}).strict()),
|
|
66
|
+
}).strict();
|
|
67
|
+
const sessionComponent = z.object({
|
|
68
|
+
session_plan_version: z.literal("2"), producer_version: z.string(), warble_ir_version: z.literal("0.9"),
|
|
69
|
+
input_ir_sha256: digest, host_contract_sha256: digest, context_identity_sha256: digest, plan_sha256: digest,
|
|
70
|
+
profile: z.string(), component: z.string(), declaration,
|
|
71
|
+
instructions: z.object({ brief: z.string().nullable() }).strict(),
|
|
72
|
+
steps: z.array(z.object({ name: z.string(), tier: z.string(), consumes: strings, produces: z.string(),
|
|
73
|
+
produces_exclusive: z.boolean(), instructions: z.string(), capabilities: strings, tools: strings,
|
|
74
|
+
when: when.nullable(), realization, product_availability: z.enum(["after_attempt", "if_executed"]), component_calls: calls }).strict()),
|
|
75
|
+
slot_supply: record, capability_bindings: z.record(z.string(), z.object({ tool: z.string().optional() }).strict()),
|
|
76
|
+
required_host_capabilities: strings, required_capabilities: strings, guardrails: z.array(record), borrowed_actions: strings,
|
|
77
|
+
context_requirements: strings, context_precondition: z.array(record), precondition_result: record, render_blocks: z.array(record),
|
|
78
|
+
required_execution: strings, authority: z.literal("host_owned"), execution_status: z.literal("not_executed"),
|
|
79
|
+
}).strict();
|
|
80
|
+
const session = z.object({
|
|
81
|
+
...shared, session_plan_version: z.literal("2"), producer_version: z.string(), authority: z.literal("host_owned"),
|
|
82
|
+
host_contract_sha256: digest, entry: z.string(), required_execution: strings,
|
|
83
|
+
components: z.record(z.string(), sessionComponent), plan_sha256: digest,
|
|
84
|
+
}).strict();
|
|
85
|
+
/** SHA over recursively sorted JSON, matching the producer's documented digest form. */
|
|
86
|
+
export function canonicalPlanJson(value) {
|
|
87
|
+
const sort = (item) => {
|
|
88
|
+
if (Array.isArray(item))
|
|
89
|
+
return item.map(sort);
|
|
90
|
+
if (item && typeof item === "object")
|
|
91
|
+
return Object.fromEntries(Object.keys(item).sort().map((key) => [key, sort(item[key])]));
|
|
92
|
+
return item;
|
|
93
|
+
};
|
|
94
|
+
return JSON.stringify(sort(value));
|
|
95
|
+
}
|
|
96
|
+
export function planDigest(value) { return `sha256:${createHash("sha256").update(canonicalPlanJson(value)).digest("hex")}`; }
|
|
97
|
+
function checkDigest(value, key, expected) {
|
|
98
|
+
const { [key]: claimed, ...payload } = value;
|
|
99
|
+
if (claimed !== planDigest(payload) || (expected !== undefined && claimed !== expected))
|
|
100
|
+
throw new Error("Component plan identity mismatch");
|
|
101
|
+
}
|
|
102
|
+
function assertEqual(left, right) {
|
|
103
|
+
if (!isDeepStrictEqual(left, right))
|
|
104
|
+
throw new Error("Component plan projection mismatch");
|
|
105
|
+
}
|
|
106
|
+
function commonStep(source, derived) {
|
|
107
|
+
if (source.conditional !== (derived.kind === "repair_fold"))
|
|
108
|
+
throw new Error("Unsupported step realization");
|
|
109
|
+
if (derived.kind === "repair_fold" && (source.when?.target !== derived.fold_into || source.when.guard !== "on_failure"))
|
|
110
|
+
throw new Error("Invalid repair target");
|
|
111
|
+
return { name: source.name, tier: source.tier, prompt: source.prompt, consumes: source.consumes,
|
|
112
|
+
produces: source.produces, tools: [], calls: source.component_calls ?? [],
|
|
113
|
+
...(derived.kind === "repair_fold" ? { repairOf: derived.fold_into } : {}) };
|
|
114
|
+
}
|
|
115
|
+
export function readExecutionPlan(document, receipt) {
|
|
116
|
+
if (Buffer.byteLength(document) > 4 * 1024 * 1024)
|
|
117
|
+
throw new Error("Component plan exceeds byte limit");
|
|
118
|
+
const raw = JSON.parse(document);
|
|
119
|
+
const components = Object.create(null);
|
|
120
|
+
if (raw && typeof raw === "object" && "vercel_bundle_version" in raw) {
|
|
121
|
+
const bundle = vercel.parse(raw);
|
|
122
|
+
checkDigest(raw, "bundle_sha256", receipt.digest);
|
|
123
|
+
assertEqual(bundle.input_ir_sha256, receipt.inputIrDigest);
|
|
124
|
+
assertEqual(bundle.context_binding, receipt.contextBinding);
|
|
125
|
+
assertEqual(bundle.required_host, VERCEL_HOST_CONTRACT);
|
|
126
|
+
for (const [id, node] of Object.entries(bundle.components)) {
|
|
127
|
+
assertEqual(id, node.declaration.id);
|
|
128
|
+
assertEqual(node.declaration, receipt.declarations[id]);
|
|
129
|
+
assertEqual(node.steps.length, node.declaration.llm_calls.length);
|
|
130
|
+
const steps = node.steps.map((step, index) => {
|
|
131
|
+
const source = node.declaration.llm_calls[index];
|
|
132
|
+
assertEqual(step.name, source.name);
|
|
133
|
+
assertEqual(step.effective_capabilities, source.capabilities ?? node.declaration.required_capabilities);
|
|
134
|
+
for (const grant of step.tools) {
|
|
135
|
+
const authority = VERCEL_HOST_CONTRACT.tool_authority[grant.name];
|
|
136
|
+
if (!authority || authority.source !== grant.source || authority.capabilities.some((cap) => !step.effective_capabilities.includes(cap)))
|
|
137
|
+
throw new Error("Unsupported tool authority");
|
|
138
|
+
}
|
|
139
|
+
return { ...commonStep(source, step.realization), tools: step.tools };
|
|
140
|
+
});
|
|
141
|
+
components[id] = { id, declaration: node.declaration, steps, ...(node.declaration.brief !== undefined ? { brief: node.declaration.brief } : {}) };
|
|
142
|
+
}
|
|
143
|
+
return { identity: bundle.bundle_sha256, entries: bundle.entries, components, contextBinding: bundle.context_binding,
|
|
144
|
+
...(bundle.system_prompt ? { systemPrompt: bundle.system_prompt } : {}) };
|
|
145
|
+
}
|
|
146
|
+
const plan = session.parse(raw);
|
|
147
|
+
checkDigest(raw, "plan_sha256", receipt.digest);
|
|
148
|
+
assertEqual(plan.input_ir_sha256, receipt.inputIrDigest);
|
|
149
|
+
assertEqual(plan.context_binding, receipt.contextBinding);
|
|
150
|
+
if (!receipt.directHostDocument)
|
|
151
|
+
throw new Error("Missing direct host receipt");
|
|
152
|
+
assertEqual(plan.host_contract_sha256, `sha256:${createHash("sha256").update(receipt.directHostDocument).digest("hex")}`);
|
|
153
|
+
assertEqual(plan.required_execution, HOST_FEATURES);
|
|
154
|
+
for (const [id, node] of Object.entries(plan.components)) {
|
|
155
|
+
checkDigest(raw.components[id], "plan_sha256");
|
|
156
|
+
assertEqual(id, node.component);
|
|
157
|
+
assertEqual(id, node.declaration.id);
|
|
158
|
+
assertEqual(node.declaration, receipt.declarations[id]);
|
|
159
|
+
assertEqual(node.input_ir_sha256, plan.input_ir_sha256);
|
|
160
|
+
assertEqual(node.profile, plan.profile);
|
|
161
|
+
assertEqual(node.context_identity_sha256, planDigest(receipt.contextBinding));
|
|
162
|
+
assertEqual(node.context_precondition, node.declaration.context_precondition ?? []);
|
|
163
|
+
assertEqual(node.precondition_result, node.declaration.precondition_result);
|
|
164
|
+
assertEqual(node.guardrails, node.declaration.guardrails);
|
|
165
|
+
assertEqual(node.render_blocks, node.declaration.effect.render_blocks ?? []);
|
|
166
|
+
assertEqual(node.required_capabilities, node.declaration.required_capabilities);
|
|
167
|
+
assertEqual(node.steps.length, node.declaration.llm_calls.length);
|
|
168
|
+
const steps = node.steps.map((step, index) => {
|
|
169
|
+
const source = node.declaration.llm_calls[index];
|
|
170
|
+
assertEqual([step.name, step.tier, step.consumes, step.produces, step.instructions, step.component_calls], [source.name, source.tier, source.consumes, source.produces, source.prompt, source.component_calls ?? []]);
|
|
171
|
+
assertEqual(step.capabilities, source.capabilities ?? node.declaration.required_capabilities);
|
|
172
|
+
const tools = step.tools.map((name) => {
|
|
173
|
+
const owners = Object.entries(node.capability_bindings).filter(([, binding]) => binding.tool === name);
|
|
174
|
+
if (owners.length !== 1 || !step.capabilities.includes(owners[0][0]) || !["semantic_introspection", "sql_execution:read_only"].includes(owners[0][0]))
|
|
175
|
+
throw new Error("Unsupported session tool authority");
|
|
176
|
+
return { name, source: `host:${owners[0][0]}` };
|
|
177
|
+
});
|
|
178
|
+
return { ...commonStep(source, step.realization), tools };
|
|
179
|
+
});
|
|
180
|
+
components[id] = { id, declaration: node.declaration, steps, ...(node.instructions.brief !== null ? { brief: node.instructions.brief } : {}) };
|
|
181
|
+
}
|
|
182
|
+
return { identity: plan.plan_sha256, entries: [plan.entry], components, contextBinding: plan.context_binding,
|
|
183
|
+
...(plan.system_prompt ? { systemPrompt: plan.system_prompt } : {}) };
|
|
184
|
+
}
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
import { type ComponentInvocationResult } from "@warble/claude-agent-sdk";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import type { DisclosedAnswer, EgressProvenance } from "./egress.js";
|
|
4
|
+
import type { ComponentEvidence, ComponentPlan } from "./runner.js";
|
|
5
|
+
/**
|
|
6
|
+
* The two-stage report: host-side slot materialisation and synthesis.
|
|
7
|
+
*
|
|
8
|
+
* A report component (the Hub `plan_report`) runs two model steps. The first
|
|
9
|
+
* lays out blocks whose data cells are `{slot_id}` placeholders and asks the
|
|
10
|
+
* callee for every answer in one batched call; the second writes the summary
|
|
11
|
+
* and per-block notes. Neither step is allowed to type a value into the
|
|
12
|
+
* report: this module is where the values come from.
|
|
13
|
+
*
|
|
14
|
+
* - {@link buildSlotTable} turns the disclosed child results (what the caller
|
|
15
|
+
* was allowed to see, after egress) and the provenance the egress step kept
|
|
16
|
+
* aside into one table keyed by slot id.
|
|
17
|
+
* - {@link materialiseReportPlan} fills the layout from that table for the
|
|
18
|
+
* narrator to read: filled cells carry their values, refused or unanswered
|
|
19
|
+
* cells carry `status: unavailable` and a reason category. Provenance
|
|
20
|
+
* (SQL, source tables) is withheld here; the narrator runs on a public tier.
|
|
21
|
+
* - {@link synthesiseReport} builds the final render envelope from the layout,
|
|
22
|
+
* the slot table and only the narrator's text (summary, notes, titles). A
|
|
23
|
+
* value the narrator retyped is never read. Provenance is attached here, by
|
|
24
|
+
* the host, from the child run.
|
|
25
|
+
*
|
|
26
|
+
* Every value in the rendered report therefore traces to a disclosed answer,
|
|
27
|
+
* and every disclosed answer traces to an observed query result in the child.
|
|
28
|
+
*/
|
|
29
|
+
export declare const BLOCK_SHAPES: {
|
|
30
|
+
readonly kpi_card: "scalar";
|
|
31
|
+
readonly chart: "series";
|
|
32
|
+
readonly table: "table";
|
|
33
|
+
readonly narrative: "narrative";
|
|
34
|
+
};
|
|
35
|
+
export type DataBlockType = keyof typeof BLOCK_SHAPES;
|
|
36
|
+
declare const chartTypeSchema: z.ZodEnum<{
|
|
37
|
+
area: "area";
|
|
38
|
+
bar: "bar";
|
|
39
|
+
line: "line";
|
|
40
|
+
pie: "pie";
|
|
41
|
+
scatter: "scatter";
|
|
42
|
+
}>;
|
|
43
|
+
/** Unknown keys are stripped: a number the planner copied into a placeholder is dropped, never read. */
|
|
44
|
+
declare const layoutBlockSchema: z.ZodObject<{
|
|
45
|
+
type: z.ZodEnum<{
|
|
46
|
+
chart: "chart";
|
|
47
|
+
kpi_card: "kpi_card";
|
|
48
|
+
narrative: "narrative";
|
|
49
|
+
table: "table";
|
|
50
|
+
}>;
|
|
51
|
+
label: z.ZodOptional<z.ZodString>;
|
|
52
|
+
title: z.ZodOptional<z.ZodString>;
|
|
53
|
+
chart_type: z.ZodOptional<z.ZodEnum<{
|
|
54
|
+
area: "area";
|
|
55
|
+
bar: "bar";
|
|
56
|
+
line: "line";
|
|
57
|
+
pie: "pie";
|
|
58
|
+
scatter: "scatter";
|
|
59
|
+
}>>;
|
|
60
|
+
slot_id: z.ZodString;
|
|
61
|
+
}, z.core.$strip>;
|
|
62
|
+
export declare const reportPlanSchema: z.ZodObject<{
|
|
63
|
+
title: z.ZodOptional<z.ZodString>;
|
|
64
|
+
preamble: z.ZodDefault<z.ZodObject<{
|
|
65
|
+
period: z.ZodOptional<z.ZodString>;
|
|
66
|
+
currency: z.ZodOptional<z.ZodString>;
|
|
67
|
+
filters: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
68
|
+
}, z.core.$strip>>;
|
|
69
|
+
slots: z.ZodArray<z.ZodObject<{
|
|
70
|
+
slot_id: z.ZodString;
|
|
71
|
+
block_type: z.ZodEnum<{
|
|
72
|
+
chart: "chart";
|
|
73
|
+
kpi_card: "kpi_card";
|
|
74
|
+
narrative: "narrative";
|
|
75
|
+
table: "table";
|
|
76
|
+
}>;
|
|
77
|
+
expected_shape: z.ZodEnum<{
|
|
78
|
+
narrative: "narrative";
|
|
79
|
+
scalar: "scalar";
|
|
80
|
+
series: "series";
|
|
81
|
+
table: "table";
|
|
82
|
+
}>;
|
|
83
|
+
question: z.ZodString;
|
|
84
|
+
unit: z.ZodOptional<z.ZodString>;
|
|
85
|
+
max_rows: z.ZodOptional<z.ZodNumber>;
|
|
86
|
+
}, z.core.$strip>>;
|
|
87
|
+
blocks: z.ZodArray<z.ZodObject<{
|
|
88
|
+
type: z.ZodEnum<{
|
|
89
|
+
chart: "chart";
|
|
90
|
+
kpi_card: "kpi_card";
|
|
91
|
+
narrative: "narrative";
|
|
92
|
+
table: "table";
|
|
93
|
+
}>;
|
|
94
|
+
label: z.ZodOptional<z.ZodString>;
|
|
95
|
+
title: z.ZodOptional<z.ZodString>;
|
|
96
|
+
chart_type: z.ZodOptional<z.ZodEnum<{
|
|
97
|
+
area: "area";
|
|
98
|
+
bar: "bar";
|
|
99
|
+
line: "line";
|
|
100
|
+
pie: "pie";
|
|
101
|
+
scatter: "scatter";
|
|
102
|
+
}>>;
|
|
103
|
+
slot_id: z.ZodString;
|
|
104
|
+
}, z.core.$strip>>;
|
|
105
|
+
summary_brief: z.ZodOptional<z.ZodString>;
|
|
106
|
+
}, z.core.$strip>;
|
|
107
|
+
export type ReportPlan = z.infer<typeof reportPlanSchema>;
|
|
108
|
+
export type LayoutBlock = z.infer<typeof layoutBlockSchema>;
|
|
109
|
+
declare const cell: z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean, z.ZodNull]>;
|
|
110
|
+
type Cell = z.infer<typeof cell>;
|
|
111
|
+
export interface SlotEntry {
|
|
112
|
+
readonly answer: DisclosedAnswer;
|
|
113
|
+
/** Host-only: never handed to a model. */
|
|
114
|
+
readonly provenance?: EgressProvenance;
|
|
115
|
+
}
|
|
116
|
+
export type SlotTable = ReadonlyMap<string, SlotEntry>;
|
|
117
|
+
/**
|
|
118
|
+
* One row per slot from the disclosed child results (first answer per slot id
|
|
119
|
+
* wins; a follow-up call adds new ids). Provenance is joined by slot id.
|
|
120
|
+
*/
|
|
121
|
+
export declare function buildSlotTable(children: readonly ComponentInvocationResult[], provenance?: readonly EgressProvenance[]): SlotTable;
|
|
122
|
+
export type MaterialisedBlock = {
|
|
123
|
+
readonly type: "kpi_card";
|
|
124
|
+
readonly label: string;
|
|
125
|
+
readonly slot_id: string;
|
|
126
|
+
readonly value: number | string;
|
|
127
|
+
readonly unit?: string;
|
|
128
|
+
} | {
|
|
129
|
+
readonly type: "chart";
|
|
130
|
+
readonly title: string;
|
|
131
|
+
readonly chart_type: z.infer<typeof chartTypeSchema>;
|
|
132
|
+
readonly slot_id: string;
|
|
133
|
+
readonly x: string;
|
|
134
|
+
readonly series: readonly string[];
|
|
135
|
+
readonly rows: readonly Cell[][];
|
|
136
|
+
} | {
|
|
137
|
+
readonly type: "table";
|
|
138
|
+
readonly title: string;
|
|
139
|
+
readonly slot_id: string;
|
|
140
|
+
readonly columns: readonly string[];
|
|
141
|
+
readonly rows: readonly Cell[][];
|
|
142
|
+
} | {
|
|
143
|
+
readonly type: "narrative";
|
|
144
|
+
readonly title: string;
|
|
145
|
+
readonly slot_id: string;
|
|
146
|
+
readonly text: string;
|
|
147
|
+
} | {
|
|
148
|
+
readonly type: DataBlockType;
|
|
149
|
+
readonly label: string;
|
|
150
|
+
readonly slot_id: string;
|
|
151
|
+
readonly status: "unavailable";
|
|
152
|
+
readonly reason_category: string;
|
|
153
|
+
};
|
|
154
|
+
export interface MaterialisedPlan {
|
|
155
|
+
readonly title?: string;
|
|
156
|
+
readonly preamble: ReportPlan["preamble"];
|
|
157
|
+
readonly blocks: readonly MaterialisedBlock[];
|
|
158
|
+
readonly summary_brief?: string;
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* The layout with every data cell resolved from the slot table. This is what
|
|
162
|
+
* the narrator consumes as `report_plan`: values it must copy, never compute.
|
|
163
|
+
* No `definition` block is included; provenance stays host-side until
|
|
164
|
+
* {@link synthesiseReport}.
|
|
165
|
+
*/
|
|
166
|
+
export declare function materialiseReportPlan(plan: ReportPlan, table: SlotTable): MaterialisedPlan;
|
|
167
|
+
/** Parses a step product (string or object) as a report plan; undefined when it is not one. */
|
|
168
|
+
export declare function parseReportPlan(product: unknown): ReportPlan | undefined;
|
|
169
|
+
export interface NarratorText {
|
|
170
|
+
readonly summary?: string;
|
|
171
|
+
readonly notes: ReadonlyMap<string, {
|
|
172
|
+
readonly note?: string;
|
|
173
|
+
readonly label?: string;
|
|
174
|
+
}>;
|
|
175
|
+
}
|
|
176
|
+
/** Reads the narrator's text out of its output; the values it may have written are not looked at. */
|
|
177
|
+
export declare function readNarratorText(product: unknown): NarratorText | undefined;
|
|
178
|
+
export interface SynthesisedReport {
|
|
179
|
+
readonly blocks: readonly Record<string, unknown>[];
|
|
180
|
+
readonly summary?: string;
|
|
181
|
+
/** True only when at least one cell is filled and every filled cell came from a verified answer. */
|
|
182
|
+
readonly verified: boolean;
|
|
183
|
+
/** Slot ids whose provenance was attached as `definition` blocks. */
|
|
184
|
+
readonly definitions: readonly string[];
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* The rendered report. Values come from the slot table through the same
|
|
188
|
+
* materialisation the narrator read; the narrator contributes summary, notes
|
|
189
|
+
* and adjusted labels only; the host appends one `definition` block per
|
|
190
|
+
* filled slot whose provenance carries SQL. The narrator cannot add, drop or
|
|
191
|
+
* reorder blocks, and a number it emitted is never read.
|
|
192
|
+
*/
|
|
193
|
+
export declare function synthesiseReport(plan: ReportPlan, table: SlotTable, narrator: NarratorText | undefined): SynthesisedReport;
|
|
194
|
+
/** A component whose render contract declares an `unavailable` cell is a report: the host synthesises its envelope. */
|
|
195
|
+
export declare function isReportComponent(component: ComponentPlan): boolean;
|
|
196
|
+
/** The step that lays the report out (owns the call edge) and the one that narrates it (consumes the layout). */
|
|
197
|
+
export declare function reportSteps(component: ComponentPlan): {
|
|
198
|
+
layout: ComponentPlan["steps"][number];
|
|
199
|
+
narrate?: ComponentPlan["steps"][number];
|
|
200
|
+
} | undefined;
|
|
201
|
+
/**
|
|
202
|
+
* Root normalization for a report component: the host-owned synthesis. The
|
|
203
|
+
* produced envelope is validated against the component's declared render
|
|
204
|
+
* contract exactly as a model-authored one would be.
|
|
205
|
+
*/
|
|
206
|
+
export declare function normalizeReportEvidence(component: ComponentPlan, evidence: ComponentEvidence): ComponentInvocationResult;
|
|
207
|
+
export {};
|