@wrenai/genbi 0.0.1
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 +201 -0
- package/README.md +141 -0
- package/bin/genbi.mjs +31 -0
- package/dist/assets/echarts-LTFC-ysd.js +40 -0
- package/dist/assets/index-Bo--QMUN.js +441 -0
- package/dist/assets/index-Xs4q7pNo.css +1 -0
- package/dist/index.html +14 -0
- package/dist/wrenai_logo.png +0 -0
- package/dist/wrenai_logo_white.png +0 -0
- package/dist-server/harness/auth/detect.d.ts +18 -0
- package/dist-server/harness/auth/detect.js +37 -0
- package/dist-server/harness/auth/index.d.ts +4 -0
- package/dist-server/harness/auth/index.js +2 -0
- package/dist-server/harness/auth/probe.d.ts +18 -0
- package/dist-server/harness/auth/probe.js +52 -0
- package/dist-server/harness/auth/types.d.ts +42 -0
- package/dist-server/harness/auth/types.js +9 -0
- package/dist-server/harness/bundle/loader.d.ts +32 -0
- package/dist-server/harness/bundle/loader.js +43 -0
- package/dist-server/harness/bundle/schema.d.ts +199 -0
- package/dist-server/harness/bundle/schema.js +127 -0
- package/dist-server/harness/bundle/version.d.ts +10 -0
- package/dist-server/harness/bundle/version.js +43 -0
- package/dist-server/harness/capability/gate.d.ts +6 -0
- package/dist-server/harness/capability/gate.js +29 -0
- package/dist-server/harness/capability/registry.d.ts +6 -0
- package/dist-server/harness/capability/registry.js +17 -0
- package/dist-server/harness/cli-args.d.ts +123 -0
- package/dist-server/harness/cli-args.js +247 -0
- package/dist-server/harness/cli.d.ts +2 -0
- package/dist-server/harness/cli.js +151 -0
- package/dist-server/harness/compile/cache.d.ts +23 -0
- package/dist-server/harness/compile/cache.js +109 -0
- package/dist-server/harness/compile/compose-profile.d.ts +34 -0
- package/dist-server/harness/compile/compose-profile.js +95 -0
- package/dist-server/harness/compile/errors.d.ts +22 -0
- package/dist-server/harness/compile/errors.js +41 -0
- package/dist-server/harness/compile/fingerprint.d.ts +22 -0
- package/dist-server/harness/compile/fingerprint.js +84 -0
- package/dist-server/harness/compile/index.d.ts +8 -0
- package/dist-server/harness/compile/index.js +7 -0
- package/dist-server/harness/compile/pipeline.d.ts +66 -0
- package/dist-server/harness/compile/pipeline.js +176 -0
- package/dist-server/harness/compile/resolve-binary.d.ts +55 -0
- package/dist-server/harness/compile/resolve-binary.js +133 -0
- package/dist-server/harness/compile/types.d.ts +107 -0
- package/dist-server/harness/compile/types.js +1 -0
- package/dist-server/harness/compile/warble-identity.d.ts +12 -0
- package/dist-server/harness/compile/warble-identity.js +33 -0
- package/dist-server/harness/compliance/gate.d.ts +35 -0
- package/dist-server/harness/compliance/gate.js +48 -0
- package/dist-server/harness/compliance/index.d.ts +2 -0
- package/dist-server/harness/compliance/index.js +1 -0
- package/dist-server/harness/compliance/types.d.ts +16 -0
- package/dist-server/harness/compliance/types.js +1 -0
- package/dist-server/harness/events/emitter.d.ts +34 -0
- package/dist-server/harness/events/emitter.js +25 -0
- package/dist-server/harness/events/index.d.ts +4 -0
- package/dist-server/harness/events/index.js +2 -0
- package/dist-server/harness/events/sse.d.ts +20 -0
- package/dist-server/harness/events/sse.js +48 -0
- package/dist-server/harness/events/types.d.ts +131 -0
- package/dist-server/harness/events/types.js +1 -0
- package/dist-server/harness/exec/errors.d.ts +16 -0
- package/dist-server/harness/exec/errors.js +29 -0
- package/dist-server/harness/exec/index.d.ts +5 -0
- package/dist-server/harness/exec/index.js +2 -0
- package/dist-server/harness/exec/local.d.ts +32 -0
- package/dist-server/harness/exec/local.js +134 -0
- package/dist-server/harness/exec/policy.d.ts +12 -0
- package/dist-server/harness/exec/policy.js +1 -0
- package/dist-server/harness/exec/types.d.ts +63 -0
- package/dist-server/harness/exec/types.js +1 -0
- package/dist-server/harness/guardrails/index.d.ts +2 -0
- package/dist-server/harness/guardrails/index.js +1 -0
- package/dist-server/harness/guardrails/policy.d.ts +45 -0
- package/dist-server/harness/guardrails/policy.js +57 -0
- package/dist-server/harness/index.d.ts +37 -0
- package/dist-server/harness/index.js +19 -0
- package/dist-server/harness/loop/errors.d.ts +53 -0
- package/dist-server/harness/loop/errors.js +72 -0
- package/dist-server/harness/loop/executor.d.ts +123 -0
- package/dist-server/harness/loop/executor.js +380 -0
- package/dist-server/harness/loop/guard.d.ts +16 -0
- package/dist-server/harness/loop/guard.js +1 -0
- package/dist-server/harness/loop/index.d.ts +5 -0
- package/dist-server/harness/loop/index.js +3 -0
- package/dist-server/harness/native-producer/index.d.ts +109 -0
- package/dist-server/harness/native-producer/index.js +302 -0
- package/dist-server/harness/npm-package-resolve.d.ts +28 -0
- package/dist-server/harness/npm-package-resolve.js +47 -0
- package/dist-server/harness/providers/adapters/anthropic.d.ts +7 -0
- package/dist-server/harness/providers/adapters/anthropic.js +6 -0
- package/dist-server/harness/providers/adapters/mock.d.ts +4 -0
- package/dist-server/harness/providers/adapters/mock.js +5 -0
- package/dist-server/harness/providers/adapters/openai-compatible.d.ts +10 -0
- package/dist-server/harness/providers/adapters/openai-compatible.js +10 -0
- package/dist-server/harness/providers/binding.d.ts +23 -0
- package/dist-server/harness/providers/binding.js +13 -0
- package/dist-server/harness/providers/errors.d.ts +6 -0
- package/dist-server/harness/providers/errors.js +12 -0
- package/dist-server/harness/providers/index.d.ts +18 -0
- package/dist-server/harness/providers/index.js +22 -0
- package/dist-server/harness/providers/registry.d.ts +16 -0
- package/dist-server/harness/providers/registry.js +24 -0
- package/dist-server/harness/render/envelope.d.ts +145 -0
- package/dist-server/harness/render/envelope.js +428 -0
- package/dist-server/harness/render/errors.d.ts +33 -0
- package/dist-server/harness/render/errors.js +46 -0
- package/dist-server/harness/render/index.d.ts +5 -0
- package/dist-server/harness/render/index.js +3 -0
- package/dist-server/harness/render/validate.d.ts +13 -0
- package/dist-server/harness/render/validate.js +88 -0
- package/dist-server/harness/route/adapter-spec.d.ts +40 -0
- package/dist-server/harness/route/adapter-spec.js +61 -0
- package/dist-server/harness/route/agent-sdk-cli.d.ts +30 -0
- package/dist-server/harness/route/agent-sdk-cli.js +86 -0
- package/dist-server/harness/route/agent-sdk-manifest.d.ts +31 -0
- package/dist-server/harness/route/agent-sdk-manifest.js +56 -0
- package/dist-server/harness/route/artifact-content.d.ts +53 -0
- package/dist-server/harness/route/artifact-content.js +83 -0
- package/dist-server/harness/route/chat-event-mapper.d.ts +95 -0
- package/dist-server/harness/route/chat-event-mapper.js +164 -0
- package/dist-server/harness/route/codex-ask-events.d.ts +25 -0
- package/dist-server/harness/route/codex-ask-events.js +395 -0
- package/dist-server/harness/route/codex-ask.d.ts +15 -0
- package/dist-server/harness/route/codex-ask.js +242 -0
- package/dist-server/harness/route/codex-local-cli.d.ts +20 -0
- package/dist-server/harness/route/codex-local-cli.js +78 -0
- package/dist-server/harness/route/codex-local-manifest.d.ts +22 -0
- package/dist-server/harness/route/codex-local-manifest.js +180 -0
- package/dist-server/harness/route/describe.d.ts +54 -0
- package/dist-server/harness/route/describe.js +84 -0
- package/dist-server/harness/route/dispatched.d.ts +138 -0
- package/dist-server/harness/route/dispatched.js +339 -0
- package/dist-server/harness/route/in-process.d.ts +43 -0
- package/dist-server/harness/route/in-process.js +106 -0
- package/dist-server/harness/route/index.d.ts +19 -0
- package/dist-server/harness/route/index.js +12 -0
- package/dist-server/harness/route/profile-source.d.ts +37 -0
- package/dist-server/harness/route/profile-source.js +76 -0
- package/dist-server/harness/route/route.d.ts +33 -0
- package/dist-server/harness/route/route.js +114 -0
- package/dist-server/harness/route/tier-binding.d.ts +36 -0
- package/dist-server/harness/route/tier-binding.js +63 -0
- package/dist-server/harness/route/types.d.ts +286 -0
- package/dist-server/harness/route/types.js +1 -0
- package/dist-server/harness/session/errors.d.ts +4 -0
- package/dist-server/harness/session/errors.js +7 -0
- package/dist-server/harness/session/gate.d.ts +11 -0
- package/dist-server/harness/session/gate.js +13 -0
- package/dist-server/harness/session/index.d.ts +5 -0
- package/dist-server/harness/session/index.js +3 -0
- package/dist-server/harness/session/run.d.ts +60 -0
- package/dist-server/harness/session/run.js +333 -0
- package/dist-server/harness/session/types.d.ts +29 -0
- package/dist-server/harness/session/types.js +1 -0
- package/dist-server/harness/setup/codex-events.d.ts +12 -0
- package/dist-server/harness/setup/codex-events.js +108 -0
- package/dist-server/harness/setup/runner.d.ts +497 -0
- package/dist-server/harness/setup/runner.js +1314 -0
- package/dist-server/harness/tools/errors.d.ts +107 -0
- package/dist-server/harness/tools/errors.js +141 -0
- package/dist-server/harness/tools/index.d.ts +13 -0
- package/dist-server/harness/tools/index.js +8 -0
- package/dist-server/harness/tools/mcp.d.ts +26 -0
- package/dist-server/harness/tools/mcp.js +15 -0
- package/dist-server/harness/tools/native.d.ts +179 -0
- package/dist-server/harness/tools/native.js +322 -0
- package/dist-server/harness/tools/parse.d.ts +14 -0
- package/dist-server/harness/tools/parse.js +18 -0
- package/dist-server/harness/tools/resolve-wren-binary.d.ts +12 -0
- package/dist-server/harness/tools/resolve-wren-binary.js +21 -0
- package/dist-server/harness/tools/resolve.d.ts +51 -0
- package/dist-server/harness/tools/resolve.js +79 -0
- package/dist-server/harness/tools/setup-native.d.ts +84 -0
- package/dist-server/harness/tools/setup-native.js +353 -0
- package/dist-server/harness/tools/wiring.d.ts +10 -0
- package/dist-server/harness/tools/wiring.js +16 -0
- package/dist-server/providers/setup.provider.yaml +31 -0
- package/dist-server/providers/wren.provider.yaml +33 -0
- package/dist-server/server/adopt.d.ts +87 -0
- package/dist-server/server/adopt.js +263 -0
- package/dist-server/server/app.d.ts +6 -0
- package/dist-server/server/app.js +2521 -0
- package/dist-server/server/auth-choice.d.ts +16 -0
- package/dist-server/server/auth-choice.js +36 -0
- package/dist-server/server/bin.d.ts +2 -0
- package/dist-server/server/bin.js +601 -0
- package/dist-server/server/bootstrap-project-binding.d.ts +31 -0
- package/dist-server/server/bootstrap-project-binding.js +71 -0
- package/dist-server/server/clarify.d.ts +10 -0
- package/dist-server/server/clarify.js +17 -0
- package/dist-server/server/codex-setup-mcp.d.ts +2 -0
- package/dist-server/server/codex-setup-mcp.js +147 -0
- package/dist-server/server/compose.d.ts +89 -0
- package/dist-server/server/compose.js +271 -0
- package/dist-server/server/conn-config.d.ts +30 -0
- package/dist-server/server/conn-config.js +253 -0
- package/dist-server/server/context-files.d.ts +12 -0
- package/dist-server/server/context-files.js +117 -0
- package/dist-server/server/context-map.d.ts +30 -0
- package/dist-server/server/context-map.js +95 -0
- package/dist-server/server/context-source.d.ts +68 -0
- package/dist-server/server/context-source.js +85 -0
- package/dist-server/server/db.d.ts +862 -0
- package/dist-server/server/db.js +1839 -0
- package/dist-server/server/enrichment-runner.d.ts +184 -0
- package/dist-server/server/enrichment-runner.js +213 -0
- package/dist-server/server/enrichment-verify.d.ts +73 -0
- package/dist-server/server/enrichment-verify.js +290 -0
- package/dist-server/server/enrichment.d.ts +232 -0
- package/dist-server/server/enrichment.js +199 -0
- package/dist-server/server/env-detect.d.ts +8 -0
- package/dist-server/server/env-detect.js +17 -0
- package/dist-server/server/env-field-hints.d.ts +46 -0
- package/dist-server/server/env-field-hints.js +48 -0
- package/dist-server/server/fold.d.ts +133 -0
- package/dist-server/server/fold.js +407 -0
- package/dist-server/server/harness-profile-sources.d.ts +3 -0
- package/dist-server/server/harness-profile-sources.js +24 -0
- package/dist-server/server/harness.d.ts +19 -0
- package/dist-server/server/harness.js +439 -0
- package/dist-server/server/impact.d.ts +18 -0
- package/dist-server/server/impact.js +85 -0
- package/dist-server/server/interactive-terminal.d.ts +175 -0
- package/dist-server/server/interactive-terminal.js +336 -0
- package/dist-server/server/native-artifacts.d.ts +1004 -0
- package/dist-server/server/native-artifacts.js +564 -0
- package/dist-server/server/native-dispatch-registry.d.ts +42 -0
- package/dist-server/server/native-dispatch-registry.js +45 -0
- package/dist-server/server/native-producer-fence.d.ts +14 -0
- package/dist-server/server/native-producer-fence.js +48 -0
- package/dist-server/server/native-session-resume.d.ts +6 -0
- package/dist-server/server/native-session-resume.js +103 -0
- package/dist-server/server/native-session-workspace.d.ts +40 -0
- package/dist-server/server/native-session-workspace.js +175 -0
- package/dist-server/server/native-sessions.d.ts +374 -0
- package/dist-server/server/native-sessions.js +1517 -0
- package/dist-server/server/native-wren-runtime.d.ts +20 -0
- package/dist-server/server/native-wren-runtime.js +259 -0
- package/dist-server/server/node-pty-host.d.ts +31 -0
- package/dist-server/server/node-pty-host.js +100 -0
- package/dist-server/server/route-intent.d.ts +40 -0
- package/dist-server/server/route-intent.js +23 -0
- package/dist-server/server/runtime-binding.d.ts +52 -0
- package/dist-server/server/runtime-binding.js +258 -0
- package/dist-server/server/source-catalog.d.ts +84 -0
- package/dist-server/server/source-catalog.js +221 -0
- package/dist-server/server/source-driver.d.ts +35 -0
- package/dist-server/server/source-driver.js +124 -0
- package/dist-server/server/spa.d.ts +2 -0
- package/dist-server/server/spa.js +51 -0
- package/dist-server/server/subscription-model-catalog.d.ts +27 -0
- package/dist-server/server/subscription-model-catalog.js +203 -0
- package/dist-server/server/turn.d.ts +249 -0
- package/dist-server/server/turn.js +1074 -0
- package/dist-server/server/wire-types.d.ts +799 -0
- package/dist-server/server/wire-types.js +1 -0
- package/dist-server/server/wren-home.d.ts +19 -0
- package/dist-server/server/wren-home.js +33 -0
- package/dist-server/server/wren-profiles.d.ts +43 -0
- package/dist-server/server/wren-profiles.js +123 -0
- package/package.json +93 -0
- package/profiles/genbi-default/context/binding.yml +9 -0
- package/profiles/genbi-default/ir.golden.json +506 -0
- package/profiles/genbi-default/profile.yml +16 -0
- package/profiles/genbi-enrich-context/components/apply_enrichment/component.yml +42 -0
- package/profiles/genbi-enrich-context/components/draft_enrichment/component.yml +30 -0
- package/profiles/genbi-enrich-context/components/draft_enrichment/steps/draft.md +34 -0
- package/profiles/genbi-enrich-context/components/inspect_context/component.yml +32 -0
- package/profiles/genbi-enrich-context/components/inspect_context/steps/inspect.md +13 -0
- package/profiles/genbi-enrich-context/context/binding.yml +4 -0
- package/profiles/genbi-enrich-context/ir.golden.json +302 -0
- package/profiles/genbi-enrich-context/profile.yml +15 -0
- package/profiles/genbi-monitor/context/binding.yml +7 -0
- package/profiles/genbi-monitor/ir.golden.json +188 -0
- package/profiles/genbi-monitor/profile.yml +27 -0
- package/profiles/genbi-setup/components/build_context/component.yml +44 -0
- package/profiles/genbi-setup/components/build_context/steps/build.md +14 -0
- package/profiles/genbi-setup/components/connect_source/component.yml +51 -0
- package/profiles/genbi-setup/components/connect_source/steps/connect.md +23 -0
- package/profiles/genbi-setup/context/binding.yml +8 -0
- package/profiles/genbi-setup/ir.golden.json +140 -0
- package/profiles/genbi-setup/profile.yml +18 -0
- package/profiles/genbi-setup/raw/schema.json +5 -0
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Host-owned contract for optional post-bind enrichment.
|
|
3
|
+
*
|
|
4
|
+
* This is intentionally a GenBI contract, not an import of any runtime's
|
|
5
|
+
* implementation. A runtime may inspect and draft, but only this host keeps
|
|
6
|
+
* the revision lock, risk classification, approvals and completion ledger.
|
|
7
|
+
*/
|
|
8
|
+
import { createHash } from "node:crypto";
|
|
9
|
+
import { existsSync, readFileSync, realpathSync, statSync } from "node:fs";
|
|
10
|
+
import path from "node:path";
|
|
11
|
+
export class EnrichmentContractError extends Error {
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Identifies a project directory without requiring it to be built. This is
|
|
15
|
+
* the only resolution `bindProject` may use: binding must succeed for a
|
|
16
|
+
* freshly connected, not-yet-compiled project, so it can never read or
|
|
17
|
+
* require `target/mdl.json`.
|
|
18
|
+
*/
|
|
19
|
+
export function resolveProjectIdentity(projectPath) {
|
|
20
|
+
const canonicalPath = realpathSync(projectPath);
|
|
21
|
+
const stats = statSync(canonicalPath);
|
|
22
|
+
return {
|
|
23
|
+
path: canonicalPath,
|
|
24
|
+
// `dev` and `ino` are the portable subset Node exposes on POSIX and are
|
|
25
|
+
// stringified so SQLite/JSON never loses precision on a large inode.
|
|
26
|
+
identity: `dev:${String(stats.dev)}:ino:${String(stats.ino)}`,
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Identifies a project directory *and* proves it is built. Only enrichment
|
|
31
|
+
* call sites may use this: they need a concrete revision to lock a run
|
|
32
|
+
* against or to fence an in-flight operation, and it is legitimate for them
|
|
33
|
+
* to refuse (via `EnrichmentContractError`) when the project isn't built.
|
|
34
|
+
*/
|
|
35
|
+
export function resolveEnrichmentBinding(projectPath) {
|
|
36
|
+
const identity = resolveProjectIdentity(projectPath);
|
|
37
|
+
return { ...identity, revision: computeBoundProjectRevision(identity.path) };
|
|
38
|
+
}
|
|
39
|
+
export function sameEnrichmentBinding(left, right) {
|
|
40
|
+
return left.path === right.path
|
|
41
|
+
&& left.identity === right.identity
|
|
42
|
+
&& left.generation === right.generation
|
|
43
|
+
&& left.revision === right.revision;
|
|
44
|
+
}
|
|
45
|
+
export function computeBoundProjectRevision(projectPath) {
|
|
46
|
+
const required = ["wren_project.yml", path.join("target", "mdl.json")];
|
|
47
|
+
const hash = createHash("sha256");
|
|
48
|
+
for (const relative of required) {
|
|
49
|
+
const file = path.join(projectPath, relative);
|
|
50
|
+
if (!existsSync(file))
|
|
51
|
+
throw new EnrichmentContractError("bound project is not built; compile and bind before enriching context");
|
|
52
|
+
hash.update(relative);
|
|
53
|
+
hash.update(readFileSync(file));
|
|
54
|
+
}
|
|
55
|
+
return `sha256:${hash.digest("hex")}`;
|
|
56
|
+
}
|
|
57
|
+
// Sink paths are project-relative to the bound Wren project root. These must match the real
|
|
58
|
+
// project file layout this codebase already uses everywhere else (see server/context-files.ts:
|
|
59
|
+
// `models/<name>/metadata.yml`, `views/<name>/metadata.yml`, `cubes/<name>/metadata.yml`, a single
|
|
60
|
+
// top-level `relationships.yml`) and, for knowledge, the layout `wren context init` actually
|
|
61
|
+
// creates on disk (core/wren's `_KNOWLEDGE_SUBDIRS` skeleton: `knowledge/knowledge.yml` plus a
|
|
62
|
+
// `knowledge/{rules,glossary,metrics,caveats,sql}/` subdirectory per category — never a flat
|
|
63
|
+
// `knowledge/<file>.md`). A previous edit here fixed a `mdl/`-prefixed shape that could never
|
|
64
|
+
// match a real sink, and introduced this flat `knowledge/*.md` shape in the same breath — which
|
|
65
|
+
// is exactly as unreal: it accepts a path the real layout never produces (`knowledge/general.md`)
|
|
66
|
+
// and rejects the one every project ships with (`knowledge/rules/general.md`). See
|
|
67
|
+
// `test/enrichment-sink-real-layout.test.ts`, which checks these patterns against a project a
|
|
68
|
+
// real `wren context init` produced, not a hand-written string, so this cannot drift again
|
|
69
|
+
// unnoticed.
|
|
70
|
+
const KNOWLEDGE_CATEGORIES = ["rules", "glossary", "metrics", "caveats", "sql"];
|
|
71
|
+
const SINKS = { knowledge_append: new RegExp(`^knowledge/(?:${KNOWLEDGE_CATEGORIES.join("|")})/[a-z0-9_-]+\\.md$`, "i"), new_cube: /^cubes\/[a-z0-9_-]+\/metadata\.yml$/, new_view: /^views\/[a-z0-9_-]+\/metadata\.yml$/, new_relationship: /^relationships\.yml$/, mdl_metric: /^models\/[a-z0-9_-]+\/metadata\.yml$/, calculated_column: /^models\/[a-z0-9_-]+\/metadata\.yml$/, conflict: /^(?:models|views|cubes|knowledge)\/|^relationships\.yml$/, ambiguous: /^(?:models|views|cubes|knowledge)\/|^relationships\.yml$/ };
|
|
72
|
+
function riskFor(kind) { if (kind === "conflict")
|
|
73
|
+
return "conflict"; if (kind === "ambiguous")
|
|
74
|
+
return "ambiguous"; return kind === "knowledge_append" ? "low" : "high"; }
|
|
75
|
+
const MAX_OPERATIONS = 20;
|
|
76
|
+
const MAX_SUMMARY_LENGTH = 512;
|
|
77
|
+
const MAX_DRAFT_LENGTH = 4096;
|
|
78
|
+
const DISPLAY_SECRET = /\b(?:api[_ -]?key|access[_ -]?key|password|secret|token|authorization|bearer)\b\s*[:=]\s*[^\s,;]+|\b(?:sk|sess)_[A-Za-z0-9_-]+/gi;
|
|
79
|
+
const DISPLAY_INTERNAL = /(?:\/Users\/|\/home\/|[A-Za-z]:\\\\)[^\s,;]+|\b(?:resume[_ -]?session(?:[_ -]?id)?|sdk[_ -]?session(?:[_ -]?id)?|session[_ -]?id|provider|model|prompt)\b\s*[:=]\s*[^\s,;]+|\b(?:openai|anthropic|gemini|claude|codex)\b/gi;
|
|
80
|
+
function record(value) {
|
|
81
|
+
return typeof value === "object" && value !== null && !Array.isArray(value) ? value : undefined;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Names which check failed so a future occurrence is diagnosable without
|
|
85
|
+
* reading this source \u2014 but never echoes `value` itself: a value failing
|
|
86
|
+
* exactly because it's a raw path or credential is the one case the
|
|
87
|
+
* `DISPLAY_INTERNAL`/`DISPLAY_SECRET` redaction below exists to strip, so
|
|
88
|
+
* putting it back into the message would defeat that redaction.
|
|
89
|
+
*/
|
|
90
|
+
function display(value, maxLength, field) {
|
|
91
|
+
if (typeof value !== "string")
|
|
92
|
+
throw new EnrichmentContractError(`enrichment operation's ${field} must be a string`);
|
|
93
|
+
if (value.length === 0)
|
|
94
|
+
throw new EnrichmentContractError(`enrichment operation's ${field} is empty`);
|
|
95
|
+
if (value.length > maxLength)
|
|
96
|
+
throw new EnrichmentContractError(`enrichment operation's ${field} exceeds the ${maxLength}-character limit`);
|
|
97
|
+
if (/[\u0000-\u0008\u000b\u000c\u000e-\u001f]/.test(value))
|
|
98
|
+
throw new EnrichmentContractError(`enrichment operation's ${field} contains control characters`);
|
|
99
|
+
const redacted = value.replace(DISPLAY_SECRET, "[REDACTED]").replace(DISPLAY_INTERNAL, "[REDACTED]").trim();
|
|
100
|
+
if (redacted.length === 0)
|
|
101
|
+
throw new EnrichmentContractError(`enrichment operation's ${field} was empty after redaction`);
|
|
102
|
+
return redacted;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Converts untrusted model confidence into bounded UI text without making it
|
|
106
|
+
* an operation-validity gate. Unsafe, missing, or structured values become a
|
|
107
|
+
* neutral label instead of costing an otherwise valid proposal.
|
|
108
|
+
*/
|
|
109
|
+
export function normalizeEnrichmentConfidence(value) {
|
|
110
|
+
if (typeof value === "number")
|
|
111
|
+
return Number.isFinite(value) ? String(value) : "Not provided";
|
|
112
|
+
if (typeof value !== "string")
|
|
113
|
+
return "Not provided";
|
|
114
|
+
try {
|
|
115
|
+
const label = display(value, 64, "confidence");
|
|
116
|
+
return label.includes("[REDACTED]") ? "Not provided" : label;
|
|
117
|
+
}
|
|
118
|
+
catch {
|
|
119
|
+
return "Not provided";
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
export function hashEnrichmentOperation(operation) {
|
|
123
|
+
// Confidence is model-authored display text, so it must not change the
|
|
124
|
+
// approval-bound identity of an otherwise identical operation.
|
|
125
|
+
return `sha256:${createHash("sha256").update(JSON.stringify([operation.id, operation.sink, operation.risk, operation.changeKind, operation.summary, operation.draft])).digest("hex")}`;
|
|
126
|
+
}
|
|
127
|
+
export function canonicalizeProposal(draft, revision) {
|
|
128
|
+
const input = record(draft);
|
|
129
|
+
if (!input || !Array.isArray(input.operations))
|
|
130
|
+
throw new EnrichmentContractError("enrichment proposal must be an object with an operations array");
|
|
131
|
+
if (input.operations.length === 0)
|
|
132
|
+
throw new EnrichmentContractError("enrichment proposal has no operations");
|
|
133
|
+
if (input.operations.length > MAX_OPERATIONS)
|
|
134
|
+
throw new EnrichmentContractError(`enrichment proposal exceeds the ${MAX_OPERATIONS}-operation limit`);
|
|
135
|
+
const ids = new Set();
|
|
136
|
+
const operations = input.operations.map((rawOperation) => {
|
|
137
|
+
const operation = record(rawOperation);
|
|
138
|
+
if (!operation)
|
|
139
|
+
throw new EnrichmentContractError("enrichment operation must be an object");
|
|
140
|
+
if (typeof operation.changeKind !== "string" || !Object.prototype.hasOwnProperty.call(SINKS, operation.changeKind)) {
|
|
141
|
+
throw new EnrichmentContractError("enrichment operation has an unknown changeKind");
|
|
142
|
+
}
|
|
143
|
+
if (typeof operation.sink !== "string" || operation.sink.length === 0 || operation.sink.length > 160) {
|
|
144
|
+
throw new EnrichmentContractError("enrichment operation's sink is missing, empty, or exceeds the 160-character limit");
|
|
145
|
+
}
|
|
146
|
+
if (!SINKS[operation.changeKind].test(operation.sink)) {
|
|
147
|
+
throw new EnrichmentContractError(`enrichment operation's sink does not match the required layout for changeKind "${operation.changeKind}"`);
|
|
148
|
+
}
|
|
149
|
+
const summary = display(operation.summary, MAX_SUMMARY_LENGTH, "summary");
|
|
150
|
+
const operationDraft = display(operation.draft, MAX_DRAFT_LENGTH, "draft");
|
|
151
|
+
const changeKind = operation.changeKind;
|
|
152
|
+
const confidence = normalizeEnrichmentConfidence(operation.confidence);
|
|
153
|
+
const id = `op-${createHash("sha256").update(JSON.stringify([operation.sink, changeKind, summary, operationDraft])).digest("hex").slice(0, 24)}`;
|
|
154
|
+
if (ids.has(id))
|
|
155
|
+
throw new EnrichmentContractError("runtime returned duplicate enrichment operations");
|
|
156
|
+
ids.add(id);
|
|
157
|
+
return { id, sink: operation.sink, changeKind, risk: riskFor(changeKind), summary, draft: operationDraft, confidence };
|
|
158
|
+
});
|
|
159
|
+
const authoritativeOperations = operations.map(({ id, sink, risk, summary, draft: operationDraft, changeKind }) => ({ id, sink, risk, summary, draft: operationDraft, changeKind }));
|
|
160
|
+
const hash = `sha256:${createHash("sha256").update(JSON.stringify({ revision, operations: authoritativeOperations })).digest("hex")}`;
|
|
161
|
+
return { id: `proposal-${hash.slice(7, 31)}`, hash, projectRevision: revision, operations };
|
|
162
|
+
}
|
|
163
|
+
export function requiresApproval(mode, risk) {
|
|
164
|
+
return risk !== "low" || mode === "grill";
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* The host-mediated MCP tool a native `context_enrichment` session uses to
|
|
168
|
+
* hand a drafted proposal to the host. The agent never writes into the bound
|
|
169
|
+
* project directly: this tool only carries the proposal *document* through
|
|
170
|
+
* to the same canonicalize -> shadow-verify -> finalize pipeline `POST
|
|
171
|
+
* /api/context/enrichment/start` already uses (see `server/app.ts`'s
|
|
172
|
+
* `settleEnrichmentDraft`). The schema below is deliberately permissive --
|
|
173
|
+
* `canonicalizeProposal` above is the single source of truth for shape and
|
|
174
|
+
* content validation, so this schema must not duplicate or drift from it.
|
|
175
|
+
*/
|
|
176
|
+
export const NATIVE_ENRICHMENT_SUBMIT_MCP_TOOL_NAME = "submit_context_proposal";
|
|
177
|
+
export const NATIVE_ENRICHMENT_SUBMIT_INPUT_SCHEMA = {
|
|
178
|
+
type: "object",
|
|
179
|
+
additionalProperties: false,
|
|
180
|
+
required: ["operations"],
|
|
181
|
+
properties: {
|
|
182
|
+
operations: {
|
|
183
|
+
type: "array",
|
|
184
|
+
minItems: 1,
|
|
185
|
+
items: {
|
|
186
|
+
type: "object",
|
|
187
|
+
additionalProperties: false,
|
|
188
|
+
required: ["sink", "changeKind", "summary", "draft"],
|
|
189
|
+
properties: {
|
|
190
|
+
sink: { type: "string" },
|
|
191
|
+
changeKind: { enum: ["knowledge_append", "new_cube", "new_view", "new_relationship", "mdl_metric", "calculated_column", "conflict", "ambiguous"] },
|
|
192
|
+
summary: { type: "string" },
|
|
193
|
+
draft: { type: "string" },
|
|
194
|
+
confidence: {},
|
|
195
|
+
},
|
|
196
|
+
},
|
|
197
|
+
},
|
|
198
|
+
},
|
|
199
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { AdapterEnvStatus } from "./wire-types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Reports which api-key adapters have their required credential env var present on the BFF
|
|
4
|
+
* process — booleans only. The key values themselves (or any prefix/suffix/length derived
|
|
5
|
+
* from them) must never be exposed to the frontend; this is the only shape `GET
|
|
6
|
+
* /api/config/env-detect` (`server/app.ts`) is allowed to return.
|
|
7
|
+
*/
|
|
8
|
+
export declare function detectAdapterEnv(): AdapterEnvStatus;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/** True iff the named env var is set to a non-empty (non-whitespace-only) value. */
|
|
2
|
+
function isNonEmptyEnv(name) {
|
|
3
|
+
const value = process.env[name];
|
|
4
|
+
return value !== undefined && value.trim().length > 0;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Reports which api-key adapters have their required credential env var present on the BFF
|
|
8
|
+
* process — booleans only. The key values themselves (or any prefix/suffix/length derived
|
|
9
|
+
* from them) must never be exposed to the frontend; this is the only shape `GET
|
|
10
|
+
* /api/config/env-detect` (`server/app.ts`) is allowed to return.
|
|
11
|
+
*/
|
|
12
|
+
export function detectAdapterEnv() {
|
|
13
|
+
return {
|
|
14
|
+
anthropic: isNonEmptyEnv("ANTHROPIC_API_KEY"),
|
|
15
|
+
openaiCompatible: isNonEmptyEnv("OPENAI_API_KEY"),
|
|
16
|
+
};
|
|
17
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Gives each key in a scaffolded `.env` template the description wren already
|
|
3
|
+
* publishes for it.
|
|
4
|
+
*
|
|
5
|
+
* The credential form is field-key-driven: it renders one input per `KEY=` line
|
|
6
|
+
* the connect turn wrote, and until now that was all it knew — a name in caps
|
|
7
|
+
* and whether it looked secret. So `BIGQUERY_TYPE` arrived as an empty box with
|
|
8
|
+
* no way to know it is a fixed discriminator, and `BIGQUERY_CREDENTIALS` gave
|
|
9
|
+
* no hint that it wants base64 of a service-account file.
|
|
10
|
+
*
|
|
11
|
+
* None of that had to be invented: `wren docs connection-info` already carries a
|
|
12
|
+
* title, prose, a worked example, required-ness and, for discriminators, the
|
|
13
|
+
* `const` value. This joins the two.
|
|
14
|
+
*/
|
|
15
|
+
import type { CatalogSource } from "./source-catalog.js";
|
|
16
|
+
export interface EnvFieldHint {
|
|
17
|
+
readonly key: string;
|
|
18
|
+
readonly secret: boolean;
|
|
19
|
+
/** wren's human title, e.g. "Dataset Id". Absent when the key matched no field. */
|
|
20
|
+
readonly label?: string;
|
|
21
|
+
readonly description?: string;
|
|
22
|
+
readonly example?: string;
|
|
23
|
+
readonly required?: boolean;
|
|
24
|
+
/**
|
|
25
|
+
* Set when wren fixes this field's value. The form shows it rather than
|
|
26
|
+
* asking, since a discriminator's value is decided by the variant, not by
|
|
27
|
+
* the user.
|
|
28
|
+
*/
|
|
29
|
+
readonly fixedValue?: string;
|
|
30
|
+
readonly defaultValue?: string;
|
|
31
|
+
/**
|
|
32
|
+
* True when the field wants base64 of a file's contents — wren says so in its
|
|
33
|
+
* own description. The form offers a file picker for these instead of
|
|
34
|
+
* expecting a hand-encoded blob.
|
|
35
|
+
*/
|
|
36
|
+
readonly fileEncoded?: boolean;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Annotates env keys with their source's field metadata. Keys that match
|
|
40
|
+
* nothing are returned unchanged rather than dropped: the template is the
|
|
41
|
+
* agent's output, and a key we cannot explain still has to be fillable.
|
|
42
|
+
*/
|
|
43
|
+
export declare function annotateEnvFields(fields: readonly {
|
|
44
|
+
readonly key: string;
|
|
45
|
+
readonly secret: boolean;
|
|
46
|
+
}[], source: CatalogSource | undefined): readonly EnvFieldHint[];
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/** wren describes these as "Base64 encode `<file>`"; nothing else marks them. */
|
|
2
|
+
function wantsFileUpload(field) {
|
|
3
|
+
return /base64\s+encode/i.test(field.description ?? "");
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* The connect turn writes `.env` keys from the field names, upper-cased and
|
|
7
|
+
* usually prefixed with the source. Both shapes occur — `BIGQUERY_PROJECT_ID`
|
|
8
|
+
* for `project_id`, and `BIGQUERY_TYPE` for `bigquery_type`, where the prefix
|
|
9
|
+
* would otherwise be doubled — so match the unprefixed name first and fall back
|
|
10
|
+
* to the prefixed one.
|
|
11
|
+
*/
|
|
12
|
+
function matchField(key, sourceKey, fields) {
|
|
13
|
+
const upper = key.toUpperCase();
|
|
14
|
+
const prefix = `${sourceKey.toUpperCase()}_`;
|
|
15
|
+
const unprefixed = upper.startsWith(prefix) ? upper.slice(prefix.length) : upper;
|
|
16
|
+
return (fields.find((field) => field.name.toUpperCase() === upper) ??
|
|
17
|
+
fields.find((field) => field.name.toUpperCase() === unprefixed));
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Annotates env keys with their source's field metadata. Keys that match
|
|
21
|
+
* nothing are returned unchanged rather than dropped: the template is the
|
|
22
|
+
* agent's output, and a key we cannot explain still has to be fillable.
|
|
23
|
+
*/
|
|
24
|
+
export function annotateEnvFields(fields, source) {
|
|
25
|
+
if (source === undefined)
|
|
26
|
+
return fields;
|
|
27
|
+
// Variants are alternative authentication shapes for the same source; the
|
|
28
|
+
// template only ever reflects one, so search them all and take the first hit.
|
|
29
|
+
const all = source.variants.flatMap((variant) => variant.fields);
|
|
30
|
+
return fields.map((field) => {
|
|
31
|
+
const matched = matchField(field.key, source.key, all);
|
|
32
|
+
if (matched === undefined)
|
|
33
|
+
return field;
|
|
34
|
+
return {
|
|
35
|
+
key: field.key,
|
|
36
|
+
// wren's `format: password` is the authority on whether a value is a
|
|
37
|
+
// credential; the route's name heuristic is only a fallback.
|
|
38
|
+
secret: field.secret || matched.secret,
|
|
39
|
+
label: matched.label,
|
|
40
|
+
required: matched.required,
|
|
41
|
+
...(matched.description !== undefined ? { description: matched.description } : {}),
|
|
42
|
+
...(matched.example !== undefined ? { example: matched.example } : {}),
|
|
43
|
+
...(matched.fixedValue !== undefined ? { fixedValue: matched.fixedValue } : {}),
|
|
44
|
+
...(matched.defaultValue !== undefined ? { defaultValue: matched.defaultValue } : {}),
|
|
45
|
+
...(wantsFileUpload(matched) ? { fileEncoded: true } : {}),
|
|
46
|
+
};
|
|
47
|
+
});
|
|
48
|
+
}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Folds the harness's `AgentEvent`/`StepTrace` runtime types down
|
|
3
|
+
* into the UI's `ToolStep[]` work-log shape and its terminal `SessionEvent`.
|
|
4
|
+
*
|
|
5
|
+
* Two paths:
|
|
6
|
+
* - Floor (always available): `RunAgentResult.trace` is populated
|
|
7
|
+
* unconditionally by `runAgent` regardless of whether `onEvent` is wired,
|
|
8
|
+
* so `foldTrace` alone is enough to produce one work-log snapshot even
|
|
9
|
+
* with no live event stream.
|
|
10
|
+
* - Live (best-effort): if the caller wires `onEvent`, `LiveWorkLog`
|
|
11
|
+
* accumulates an incrementally-growing `ToolStep[]` as `step.*`/`tool.*`
|
|
12
|
+
* events arrive, for a richer in-flight work log. In-process never populates
|
|
13
|
+
* `parent`/`depth` today, so this never invents fake nesting — it only
|
|
14
|
+
* forwards whatever the runtime actually reports.
|
|
15
|
+
*/
|
|
16
|
+
import type { AgentEvent, RouteResult, StepTrace } from "../harness/index.js";
|
|
17
|
+
import type { AnswerEvent, ArtifactEvent, ArtifactKind, RefusalEvent, ToolStep } from "./wire-types.js";
|
|
18
|
+
/**
|
|
19
|
+
* Canned remediation text for a refusal. `RefusalAgentEvent`/`RefusalResult`
|
|
20
|
+
* carry no remediation hint from the agent runtime — the UI's `fix` field is
|
|
21
|
+
* synthesized here as a fixed, hand-written string.
|
|
22
|
+
*/
|
|
23
|
+
export declare const REFUSAL_FIX_HINT = "Ask a workspace admin to grant access, or rephrase the question to use an aggregate that does not expose restricted values.";
|
|
24
|
+
/** Floor path: one work-log snapshot from a resolved run's final `StepTrace`. */
|
|
25
|
+
export declare function foldTrace(trace: StepTrace): ToolStep[];
|
|
26
|
+
/** Extracts the floor `StepTrace` from a route() result, if the backend produced one (in-process only). */
|
|
27
|
+
export declare function extractTrace(result: RouteResult): StepTrace | undefined;
|
|
28
|
+
/**
|
|
29
|
+
* Maps a resolved route() result to the UI's terminal answer/refusal event
|
|
30
|
+
* (id assigned by the caller).
|
|
31
|
+
*
|
|
32
|
+
* Dispatched (`backend: "agent-sdk"`) has no structured `RenderEnvelope` of its
|
|
33
|
+
* own — `runDispatchedDefault` only returns the dispatcher's final stdout text
|
|
34
|
+
* (`finalText`) — but the dispatched agent still emits its final structured
|
|
35
|
+
* answer as a (possibly fenced) JSON envelope inside that text (this was the
|
|
36
|
+
* root cause of the bug this handles: that envelope was previously dropped
|
|
37
|
+
* on the floor and the raw text always went out as `form: "text"`,
|
|
38
|
+
* `verified: false`). `extractEnvelopeFromText` recovers it — including
|
|
39
|
+
* `answer_query`'s flat `{columns, rows}` tool-contract shape, normalized
|
|
40
|
+
* into a `table` block — and `verified` is whatever the recovered envelope
|
|
41
|
+
* actually carries, never hardcoded. Only when no envelope can be recovered
|
|
42
|
+
* at all does the raw text fall back to `form: "text"`.
|
|
43
|
+
*
|
|
44
|
+
* That `form: "text"` fallback is the one case where "verified: false" is
|
|
45
|
+
* ambiguous between two very different situations: a pure conversational
|
|
46
|
+
* reply (no data claim at all — the UI should hide the badge) and a data
|
|
47
|
+
* task that ran but whose result the model chose not to render as an
|
|
48
|
+
* envelope (the UI should still show "Unverified" — that's meaningful).
|
|
49
|
+
* `worklog` (the turn's already-folded `ToolStep[]`, live or floor) is
|
|
50
|
+
* inspected for a data-access tool call to disambiguate the two; schema
|
|
51
|
+
* introspection and artifact-saving tool calls don't count as a data claim.
|
|
52
|
+
*/
|
|
53
|
+
export declare function toAnswerOrRefusalEvent(id: string, result: RouteResult, worklog?: readonly ToolStep[]): AnswerEvent | RefusalEvent;
|
|
54
|
+
/** Maps a `RunFinishEvent`'s companion `ArtifactAgentEvent` straight through — no BFF-side transformation needed. */
|
|
55
|
+
export declare function toArtifactEvent(id: string, name: string, artifactKind: ArtifactKind, location: string, artifactId: string): ArtifactEvent;
|
|
56
|
+
export declare const DECISION_ROUTE_ID = "decision-route";
|
|
57
|
+
export declare const DECISION_CLARIFY_ID = "decision-clarify";
|
|
58
|
+
export declare const DECISION_GATE_ID = "decision-gate";
|
|
59
|
+
/** The intent-routing decision — always prepended to a turn's work log. */
|
|
60
|
+
export declare function routeDecisionStep(agentId: string, reason: string): ToolStep;
|
|
61
|
+
/** The clarify decision — only present when the turn short-circuits to a clarify prompt. */
|
|
62
|
+
export declare function clarifyDecisionStep(detail: string): ToolStep;
|
|
63
|
+
/**
|
|
64
|
+
* The trailing verify-gate verdict, derived from the resolved `route()` result:
|
|
65
|
+
* - a verified ANSWER (`envelope.verified === true`) -> a "done" verdict;
|
|
66
|
+
* - a REFUSAL -> an "error" verdict carrying the refusal reason;
|
|
67
|
+
* - a non-verified answer (or dispatched, which has no envelope/verify signal)
|
|
68
|
+
* -> `undefined`, so no gate entry is appended.
|
|
69
|
+
*/
|
|
70
|
+
export declare function gateDecisionStep(result: RouteResult): ToolStep | undefined;
|
|
71
|
+
/**
|
|
72
|
+
* A failure verdict for a turn whose execution THREW (the error path) — appended
|
|
73
|
+
* to the partial work log so a failed turn's persisted trace ends with why it
|
|
74
|
+
* failed. Detail is the bounded error message.
|
|
75
|
+
*/
|
|
76
|
+
export declare function gateFailureStep(errorMessage: string): ToolStep;
|
|
77
|
+
/**
|
|
78
|
+
* A BFF-owned setup-contract rejection. This deliberately reuses the
|
|
79
|
+
* established `ToolStep.kind: "decision"` wire shape, so the frontend can
|
|
80
|
+
* render recovery evidence without an SSE schema addition.
|
|
81
|
+
*/
|
|
82
|
+
export declare function hostContractRecoveryStep(detail: string): ToolStep;
|
|
83
|
+
/** Redacts URLs, credentials, and arbitrary local absolute paths from setup text. */
|
|
84
|
+
export declare function redactSetupText(text: string): string;
|
|
85
|
+
/** Strict public setup diagnostic redaction shared by SSE, SQLite, and recovery. */
|
|
86
|
+
export declare function redactPublicSetupText(text: string, internalValues?: readonly string[]): string;
|
|
87
|
+
/**
|
|
88
|
+
* Explicit, strict public worklog allowlist shared by all Setup boundaries.
|
|
89
|
+
* Raw agent `input` and `detail` never cross this boundary: the BFF derives a
|
|
90
|
+
* bounded inspection projection instead, so reload/recovery cannot revive a
|
|
91
|
+
* broader historical trace.
|
|
92
|
+
*/
|
|
93
|
+
export declare function sanitizePublicSetupWorklog(value: unknown, internalValues?: readonly string[]): ToolStep[];
|
|
94
|
+
/**
|
|
95
|
+
* Live-frame variant of `sanitizePublicSetupWorklog`, for a subscription-mode
|
|
96
|
+
* setup turn's in-flight progress stream (see `server/turn.ts`'s
|
|
97
|
+
* `executeSetupTurn`). The end-of-turn snapshot can redact by KNOWN VALUE —
|
|
98
|
+
* `sanitizePublicSetupWorklog(..., knownInternalValues)` — once an attempt has
|
|
99
|
+
* actually returned its session anchor. A live frame can't: the anchor a
|
|
100
|
+
* rotating subscription attempt will settle on isn't known until it resolves
|
|
101
|
+
* or throws, so falling back to by-SHAPE redaction (this module's
|
|
102
|
+
* `SETUP_INTERNAL_DIAGNOSTIC`/`SETUP_PROVIDER_NAME`
|
|
103
|
+
* patterns) is the only option that can run before then.
|
|
104
|
+
*
|
|
105
|
+
* That fallback is a genuine, accepted weakening: a pattern only catches an
|
|
106
|
+
* anchor that looks the way these patterns anticipate, not any anchor shape a
|
|
107
|
+
* future provider might introduce. To bound that risk, this also drops raw
|
|
108
|
+
* `input`/`detail` and the derived `inspection` outright rather than merely
|
|
109
|
+
* redacting them — a step's raw tool input or diagnostic text is exactly where
|
|
110
|
+
* an unanticipated anchor shape would hide, and a field never sent cannot
|
|
111
|
+
* leak. `WorkLog.tsx` only needs `label`/`state`/`kind`/`parent`/`depth` to
|
|
112
|
+
* render progress; a step becomes expandable with its safe inspection
|
|
113
|
+
* projection once the end-of-turn snapshot replaces this live one.
|
|
114
|
+
*/
|
|
115
|
+
export declare function sanitizeLiveSetupWorklog(worklog: readonly ToolStep[]): ToolStep[];
|
|
116
|
+
/** Short text used for `turns.answer_summary` — feeds `server/compose.ts`'s D3 context composition. Never the full envelope. */
|
|
117
|
+
export declare function summarizeResult(result: RouteResult): string;
|
|
118
|
+
/**
|
|
119
|
+
* Live path accumulator: call `ingest` for each `AgentEvent` as it arrives
|
|
120
|
+
* from `onEvent`; each call returns a fresh immutable snapshot of the
|
|
121
|
+
* work log so far, or `undefined` for event kinds that don't affect it
|
|
122
|
+
* (`run.start`, `token`, `answer`, `refusal`, `artifact`, `run.finish`,
|
|
123
|
+
* `error` — those are terminal/non-worklog events handled elsewhere).
|
|
124
|
+
*/
|
|
125
|
+
export declare class LiveWorkLog {
|
|
126
|
+
private readonly order;
|
|
127
|
+
private readonly steps;
|
|
128
|
+
ingest(event: AgentEvent): ToolStep[] | undefined;
|
|
129
|
+
snapshot(): ToolStep[];
|
|
130
|
+
private upsert;
|
|
131
|
+
private setState;
|
|
132
|
+
private setInput;
|
|
133
|
+
}
|