@sapiom/harness 0.1.5 → 0.2.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/CHANGELOG.md +151 -0
- package/dist/cli/args.d.ts +16 -0
- package/dist/cli/args.d.ts.map +1 -0
- package/dist/cli/args.js +80 -0
- package/dist/cli/args.js.map +1 -0
- package/dist/cli/bin.js +30 -66
- package/dist/cli/bin.js.map +1 -1
- package/dist/cli/consent.js +1 -1
- package/dist/cli/settings.d.ts.map +1 -1
- package/dist/cli/settings.js +33 -1
- package/dist/cli/settings.js.map +1 -1
- package/dist/core/adapters/adapter.d.ts +2 -2
- package/dist/core/adapters/claude-code.d.ts +60 -2
- package/dist/core/adapters/claude-code.d.ts.map +1 -1
- package/dist/core/adapters/claude-code.js +119 -32
- package/dist/core/adapters/claude-code.js.map +1 -1
- package/dist/core/adapters/codex.d.ts +21 -2
- package/dist/core/adapters/codex.d.ts.map +1 -1
- package/dist/core/adapters/codex.js +53 -2
- package/dist/core/adapters/codex.js.map +1 -1
- package/dist/core/adapters/detect.d.ts +9 -0
- package/dist/core/adapters/detect.d.ts.map +1 -1
- package/dist/core/adapters/detect.js +9 -0
- package/dist/core/adapters/detect.js.map +1 -1
- package/dist/core/api-key-provider.d.ts +79 -0
- package/dist/core/api-key-provider.d.ts.map +1 -0
- package/dist/core/api-key-provider.js +91 -0
- package/dist/core/api-key-provider.js.map +1 -0
- package/dist/core/canvas-body.d.ts +28 -28
- package/dist/core/canvas-body.d.ts.map +1 -1
- package/dist/core/canvas-body.js +117 -55
- package/dist/core/canvas-body.js.map +1 -1
- package/dist/core/canvas-derive.d.ts +43 -0
- package/dist/core/canvas-derive.d.ts.map +1 -0
- package/dist/core/canvas-derive.js +95 -0
- package/dist/core/canvas-derive.js.map +1 -0
- package/dist/core/canvas-enrichment.d.ts +52 -127
- package/dist/core/canvas-enrichment.d.ts.map +1 -1
- package/dist/core/canvas-enrichment.js +17 -178
- package/dist/core/canvas-enrichment.js.map +1 -1
- package/dist/core/canvas-graph.d.ts +40 -1
- package/dist/core/canvas-graph.d.ts.map +1 -1
- package/dist/core/canvas-graph.js +71 -9
- package/dist/core/canvas-graph.js.map +1 -1
- package/dist/core/canvas-interconnections.d.ts +26 -8
- package/dist/core/canvas-interconnections.d.ts.map +1 -1
- package/dist/core/canvas-interconnections.js +132 -24
- package/dist/core/canvas-interconnections.js.map +1 -1
- package/dist/core/canvas-manifest-check.d.ts.map +1 -1
- package/dist/core/canvas-manifest-check.js +15 -2
- package/dist/core/canvas-manifest-check.js.map +1 -1
- package/dist/core/canvas-render.d.ts +8 -15
- package/dist/core/canvas-render.d.ts.map +1 -1
- package/dist/core/canvas-render.js +29 -41
- package/dist/core/canvas-render.js.map +1 -1
- package/dist/core/canvas-run-state.d.ts +50 -5
- package/dist/core/canvas-run-state.d.ts.map +1 -1
- package/dist/core/canvas-run-state.js +176 -11
- package/dist/core/canvas-run-state.js.map +1 -1
- package/dist/core/canvas-svg.d.ts +9 -4
- package/dist/core/canvas-svg.d.ts.map +1 -1
- package/dist/core/canvas-svg.js +84 -13
- package/dist/core/canvas-svg.js.map +1 -1
- package/dist/core/canvas-template.d.ts +9 -10
- package/dist/core/canvas-template.d.ts.map +1 -1
- package/dist/core/canvas-template.js +57 -20
- package/dist/core/canvas-template.js.map +1 -1
- package/dist/core/canvas-watcher.d.ts +22 -1
- package/dist/core/canvas-watcher.d.ts.map +1 -1
- package/dist/core/canvas-watcher.js +111 -30
- package/dist/core/canvas-watcher.js.map +1 -1
- package/dist/core/collector/normalizer.d.ts +8 -0
- package/dist/core/collector/normalizer.d.ts.map +1 -1
- package/dist/core/collector/normalizer.js +8 -0
- package/dist/core/collector/normalizer.js.map +1 -1
- package/dist/core/collector/store.d.ts +75 -1
- package/dist/core/collector/store.d.ts.map +1 -1
- package/dist/core/collector/store.js +334 -2
- package/dist/core/collector/store.js.map +1 -1
- package/dist/core/definition-slug-resolver.d.ts +13 -0
- package/dist/core/definition-slug-resolver.d.ts.map +1 -1
- package/dist/core/definition-slug-resolver.js +29 -0
- package/dist/core/definition-slug-resolver.js.map +1 -1
- package/dist/core/errors.d.ts +10 -4
- package/dist/core/errors.d.ts.map +1 -1
- package/dist/core/errors.js +11 -5
- package/dist/core/errors.js.map +1 -1
- package/dist/core/example-seed.d.ts +8 -0
- package/dist/core/example-seed.d.ts.map +1 -1
- package/dist/core/example-seed.js +47 -10
- package/dist/core/example-seed.js.map +1 -1
- package/dist/core/inject/system-prompt.d.ts +8 -0
- package/dist/core/inject/system-prompt.d.ts.map +1 -1
- package/dist/core/inject/system-prompt.js +3 -1
- package/dist/core/inject/system-prompt.js.map +1 -1
- package/dist/core/macros.d.ts.map +1 -1
- package/dist/core/macros.js +5 -6
- package/dist/core/macros.js.map +1 -1
- package/dist/core/paths.d.ts +1 -0
- package/dist/core/paths.d.ts.map +1 -1
- package/dist/core/paths.js +1 -0
- package/dist/core/paths.js.map +1 -1
- package/dist/core/record-archive.d.ts +187 -0
- package/dist/core/record-archive.d.ts.map +1 -0
- package/dist/core/record-archive.js +465 -0
- package/dist/core/record-archive.js.map +1 -0
- package/dist/core/rehydration.d.ts +72 -0
- package/dist/core/rehydration.d.ts.map +1 -0
- package/dist/core/rehydration.js +72 -0
- package/dist/core/rehydration.js.map +1 -0
- package/dist/core/render-local-run.d.ts +82 -0
- package/dist/core/render-local-run.d.ts.map +1 -0
- package/dist/core/render-local-run.js +105 -0
- package/dist/core/render-local-run.js.map +1 -0
- package/dist/core/render-log-slice.d.ts +30 -0
- package/dist/core/render-log-slice.d.ts.map +1 -0
- package/dist/core/render-log-slice.js +49 -0
- package/dist/core/render-log-slice.js.map +1 -0
- package/dist/core/render-run-state.d.ts.map +1 -1
- package/dist/core/render-run-state.js +30 -49
- package/dist/core/render-run-state.js.map +1 -1
- package/dist/core/resume-brief.d.ts +130 -0
- package/dist/core/resume-brief.d.ts.map +1 -0
- package/dist/core/resume-brief.js +404 -0
- package/dist/core/resume-brief.js.map +1 -0
- package/dist/core/rolling-summary.d.ts +130 -0
- package/dist/core/rolling-summary.d.ts.map +1 -0
- package/dist/core/rolling-summary.js +227 -0
- package/dist/core/rolling-summary.js.map +1 -0
- package/dist/core/run-local-bootstrap.d.ts +93 -0
- package/dist/core/run-local-bootstrap.d.ts.map +1 -0
- package/dist/core/run-local-bootstrap.js +155 -0
- package/dist/core/run-local-bootstrap.js.map +1 -0
- package/dist/core/run-state.d.ts +16 -1
- package/dist/core/run-state.d.ts.map +1 -1
- package/dist/core/run-state.js +75 -25
- package/dist/core/run-state.js.map +1 -1
- package/dist/core/session-manager.d.ts +11 -3
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +56 -7
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/session-record.d.ts +165 -0
- package/dist/core/session-record.d.ts.map +1 -0
- package/dist/core/session-record.js +470 -0
- package/dist/core/session-record.js.map +1 -0
- package/dist/core/spawn-target.d.ts +12 -0
- package/dist/core/spawn-target.d.ts.map +1 -0
- package/dist/core/spawn-target.js +187 -0
- package/dist/core/spawn-target.js.map +1 -0
- package/dist/core/stub-feedback.d.ts +52 -0
- package/dist/core/stub-feedback.d.ts.map +1 -0
- package/dist/core/stub-feedback.js +33 -0
- package/dist/core/stub-feedback.js.map +1 -0
- package/dist/core/task-manager.d.ts.map +1 -1
- package/dist/core/task-manager.js +9 -1
- package/dist/core/task-manager.js.map +1 -1
- package/dist/core/template-catalog.d.ts +48 -0
- package/dist/core/template-catalog.d.ts.map +1 -0
- package/dist/core/template-catalog.js +338 -0
- package/dist/core/template-catalog.js.map +1 -0
- package/dist/core/workflow-registry.d.ts.map +1 -1
- package/dist/core/workflow-registry.js +2 -2
- package/dist/core/workflow-registry.js.map +1 -1
- package/dist/core/workspace-watcher.d.ts.map +1 -1
- package/dist/core/workspace-watcher.js +4 -3
- package/dist/core/workspace-watcher.js.map +1 -1
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +21 -0
- package/dist/index.js.map +1 -1
- package/dist/profiles/default.d.ts.map +1 -1
- package/dist/profiles/default.js +9 -14
- package/dist/profiles/default.js.map +1 -1
- package/dist/server/actions.d.ts +139 -0
- package/dist/server/actions.d.ts.map +1 -0
- package/dist/server/actions.js +430 -0
- package/dist/server/actions.js.map +1 -0
- package/dist/server/auth-routes.d.ts +92 -0
- package/dist/server/auth-routes.d.ts.map +1 -0
- package/dist/server/auth-routes.js +151 -0
- package/dist/server/auth-routes.js.map +1 -0
- package/dist/server/canvas.d.ts.map +1 -1
- package/dist/server/canvas.js +7 -7
- package/dist/server/canvas.js.map +1 -1
- package/dist/server/fs.d.ts.map +1 -1
- package/dist/server/fs.js +17 -1
- package/dist/server/fs.js.map +1 -1
- package/dist/server/index.d.ts +12 -3
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +0 -0
- package/dist/server/index.js.map +1 -1
- package/dist/server/ingest.d.ts +11 -0
- package/dist/server/ingest.d.ts.map +1 -1
- package/dist/server/ingest.js +1 -0
- package/dist/server/ingest.js.map +1 -1
- package/dist/server/macros.d.ts +4 -6
- package/dist/server/macros.d.ts.map +1 -1
- package/dist/server/macros.js.map +1 -1
- package/dist/server/rest.d.ts +18 -6
- package/dist/server/rest.d.ts.map +1 -1
- package/dist/server/rest.js +185 -50
- package/dist/server/rest.js.map +1 -1
- package/dist/server/runs.d.ts +16 -15
- package/dist/server/runs.d.ts.map +1 -1
- package/dist/server/runs.js +15 -80
- package/dist/server/runs.js.map +1 -1
- package/dist/server/static.d.ts +15 -1
- package/dist/server/static.d.ts.map +1 -1
- package/dist/server/static.js +54 -4
- package/dist/server/static.js.map +1 -1
- package/dist/server/templates.d.ts +24 -0
- package/dist/server/templates.d.ts.map +1 -0
- package/dist/server/templates.js +54 -0
- package/dist/server/templates.js.map +1 -0
- package/dist/shared/types.d.ts +558 -66
- package/dist/shared/types.d.ts.map +1 -1
- package/dist/shared/types.js +19 -11
- package/dist/shared/types.js.map +1 -1
- package/dist/web/assets/index-DC65cskq.js +446 -0
- package/dist/web/assets/index-xtD-3FFa.css +32 -0
- package/dist/web/canvas/sess-boot/index.html +305 -0
- package/dist/web/index.html +4 -9
- package/package.json +8 -4
- package/dist/core/canvas-enrich.d.ts +0 -115
- package/dist/core/canvas-enrich.d.ts.map +0 -1
- package/dist/core/canvas-enrich.js +0 -186
- package/dist/core/canvas-enrich.js.map +0 -1
- package/dist/core/run-spend.d.ts +0 -55
- package/dist/core/run-spend.d.ts.map +0 -1
- package/dist/core/run-spend.js +0 -109
- package/dist/core/run-spend.js.map +0 -1
- package/dist/core/run-transactions.d.ts +0 -60
- package/dist/core/run-transactions.d.ts.map +0 -1
- package/dist/core/run-transactions.js +0 -129
- package/dist/core/run-transactions.js.map +0 -1
- package/dist/profiles/canvas-guidelines.d.ts +0 -20
- package/dist/profiles/canvas-guidelines.d.ts.map +0 -1
- package/dist/profiles/canvas-guidelines.js +0 -48
- package/dist/profiles/canvas-guidelines.js.map +0 -1
- package/dist/server/skills.d.ts +0 -51
- package/dist/server/skills.d.ts.map +0 -1
- package/dist/server/skills.js +0 -312
- package/dist/server/skills.js.map +0 -1
- package/dist/web/assets/index-DM84J83Y.js +0 -234
- package/dist/web/assets/index-DemtWW4L.css +0 -32
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sapiom/harness",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Sapiom Harness — a CLI-launched local web app that runs your coding agent (Claude Code, Codex) in a Sapiom-configured environment: MCP pre-wired, workflows tracked, one-click deploy/run, and a live canvas for previews.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"sapiom",
|
|
@@ -47,13 +47,15 @@
|
|
|
47
47
|
"open": "^10.1.0",
|
|
48
48
|
"ws": "^8.18.0",
|
|
49
49
|
"zod": "^3.25.0",
|
|
50
|
-
"@sapiom/agent": "^0.
|
|
51
|
-
"@sapiom/agent-core": "^0.9.
|
|
50
|
+
"@sapiom/agent": "^0.7.0",
|
|
51
|
+
"@sapiom/agent-core": "^0.9.10",
|
|
52
52
|
"@sapiom/analytics-core": "^0.2.1",
|
|
53
53
|
"@sapiom/mcp": "^0.11.3"
|
|
54
54
|
},
|
|
55
55
|
"devDependencies": {
|
|
56
56
|
"@playwright/test": "^1.61.0",
|
|
57
|
+
"@stryker-mutator/core": "^9.6.1",
|
|
58
|
+
"@stryker-mutator/vitest-runner": "^9.6.1",
|
|
57
59
|
"@types/express": "^4.17.21",
|
|
58
60
|
"@types/node": "^20.11.30",
|
|
59
61
|
"@types/react": "^19.0.0",
|
|
@@ -85,8 +87,10 @@
|
|
|
85
87
|
"dev": "tsx src/cli/bin.ts --dev",
|
|
86
88
|
"dev:web": "vite --config web/vite.config.ts",
|
|
87
89
|
"start": "node dist/cli/bin.js",
|
|
88
|
-
"test": "vitest run",
|
|
90
|
+
"test": "vitest run && vitest run --config vitest.perf.config.ts",
|
|
91
|
+
"test:perf": "vitest run --config vitest.perf.config.ts",
|
|
89
92
|
"test:watch": "vitest",
|
|
93
|
+
"test:mutation": "stryker run",
|
|
90
94
|
"test:ui": "playwright test --config web/e2e/playwright.config.ts",
|
|
91
95
|
"test:canvas": "playwright test --config e2e/playwright.config.ts",
|
|
92
96
|
"typecheck": "tsc --noEmit && tsc --noEmit -p web/tsconfig.json",
|
|
@@ -1,115 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The AI enrichment runner: spawns ONE bounded, headless agent task per
|
|
3
|
-
* workflow (via TaskManager) that reads the workflow's step bodies and
|
|
4
|
-
* returns the JSON `CanvasEnrichment` contract — never HTML, never a file
|
|
5
|
-
* write. On success the validated enrichment is persisted to the workflow's
|
|
6
|
-
* cache file and the render file is rebuilt with it merged in; on any
|
|
7
|
-
* parse/validation failure the enrichment is discarded whole and the base
|
|
8
|
-
* render stands (core/canvas-enrichment.ts's contract). Task-process
|
|
9
|
-
* failures surface through the task record itself (the pane's error state +
|
|
10
|
-
* Retry), never as HTML on disk.
|
|
11
|
-
*
|
|
12
|
-
* Triggering (see server/index.ts):
|
|
13
|
-
* - bind / session create → `ensureFresh`: spawn only when no cache entry
|
|
14
|
-
* matches the current source fingerprint; every skip reason is silent.
|
|
15
|
-
* - the visualize macro → `forceRefresh`: drop the extraction + enrichment
|
|
16
|
-
* caches, re-render the base immediately, re-enrich; refusals propagate
|
|
17
|
-
* (an already-running enrichment for this workflow → 409 via the macros
|
|
18
|
-
* router, exactly like any other double-fired background macro).
|
|
19
|
-
*
|
|
20
|
-
* Dedupe is per WORKFLOW, not per session: TaskManager refuses a second
|
|
21
|
-
* running task with the same macroId + workflowPath regardless of which
|
|
22
|
-
* session asked (see TaskAlreadyRunningError) — two panes bound to the same
|
|
23
|
-
* workflow can never race its cache/render files.
|
|
24
|
-
*/
|
|
25
|
-
import type { BackgroundTask, HarnessKind } from "../shared/types.js";
|
|
26
|
-
import { type CachedExtraction } from "./canvas-cache.js";
|
|
27
|
-
import type { CanvasGraph } from "./canvas-graph.js";
|
|
28
|
-
import { type RenderableWorkflow } from "./canvas-render.js";
|
|
29
|
-
import type { RunTaskRequest } from "./task-manager.js";
|
|
30
|
-
/** The macro identity enrichment tasks run under — the pane's Retry re-fires
|
|
31
|
-
* this macro, which routes back through forceRefresh. */
|
|
32
|
-
export declare const ENRICHMENT_MACRO_ID = "visualize";
|
|
33
|
-
/** Model the enrichment task runs on — overridable per install. */
|
|
34
|
-
export declare function enrichmentModel(env?: NodeJS.ProcessEnv): string;
|
|
35
|
-
/**
|
|
36
|
-
* Builds the one-shot enrichment prompt: the extracted graph inline (the AI
|
|
37
|
-
* annotates THIS structure — it never invents nodes), pointed at the step
|
|
38
|
-
* sources for semantics, with the JSON contract and its hard limits stated
|
|
39
|
-
* verbatim so a well-behaved run needs no retry.
|
|
40
|
-
*/
|
|
41
|
-
export declare function buildEnrichmentPrompt(graph: CanvasGraph, workflowDir: string): string;
|
|
42
|
-
/**
|
|
43
|
-
* Pulls the JSON object out of a task's final result text — either fenced
|
|
44
|
-
* (\`\`\`json ... \`\`\`) or raw, tolerating prose around it by falling back to
|
|
45
|
-
* the outermost {...} span. Null when nothing parses.
|
|
46
|
-
*/
|
|
47
|
-
export declare function extractEnrichmentJson(text: string): unknown | null;
|
|
48
|
-
/** The slice of TaskManager the runner uses — injectable for tests. */
|
|
49
|
-
export interface EnrichmentTaskRunner {
|
|
50
|
-
run(req: RunTaskRequest): Promise<BackgroundTask>;
|
|
51
|
-
onStatusChange(listener: (task: BackgroundTask) => void): () => void;
|
|
52
|
-
/** Returns true when an enrichment task for this workflow is currently
|
|
53
|
-
* running — checked before cache destruction in forceRefresh so a
|
|
54
|
-
* double-click Visualize is a true no-op, not a half-destroyed cache. */
|
|
55
|
-
isRunning(macroId: string, workflowPath: string): boolean;
|
|
56
|
-
}
|
|
57
|
-
/** The session shape the coordinator needs — satisfied by HarnessSession. */
|
|
58
|
-
export interface EnrichmentSession {
|
|
59
|
-
id: string;
|
|
60
|
-
cwd: string;
|
|
61
|
-
harness: HarnessKind;
|
|
62
|
-
boundWorkflowPath: string | null;
|
|
63
|
-
}
|
|
64
|
-
export interface EnrichmentCoordinatorOptions {
|
|
65
|
-
tasks: EnrichmentTaskRunner;
|
|
66
|
-
/** Rebuilds the workflow's render file (with the just-persisted enrichment
|
|
67
|
-
* merged) after a successful run — the write alone hot-reloads any open
|
|
68
|
-
* pane via the canvas watcher. */
|
|
69
|
-
rerender?: (cwd: string, workflow: RenderableWorkflow) => Promise<void>;
|
|
70
|
-
/** Injectable for tests — defaults to the real cached extraction. */
|
|
71
|
-
extractCached?: (dir: string) => Promise<CachedExtraction>;
|
|
72
|
-
env?: NodeJS.ProcessEnv;
|
|
73
|
-
now?: () => string;
|
|
74
|
-
onError?: (message: string) => void;
|
|
75
|
-
}
|
|
76
|
-
export declare class CanvasEnrichmentCoordinator {
|
|
77
|
-
private readonly tasks;
|
|
78
|
-
private readonly rerender;
|
|
79
|
-
private readonly extractCached;
|
|
80
|
-
private readonly env;
|
|
81
|
-
private readonly now;
|
|
82
|
-
private readonly onError;
|
|
83
|
-
constructor(options: EnrichmentCoordinatorOptions);
|
|
84
|
-
/**
|
|
85
|
-
* The bind/create trigger: spawn an enrichment task unless a cached
|
|
86
|
-
* enrichment already matches the workflow's current sources. Silent on
|
|
87
|
-
* every expected refusal — unbound session, failed extraction, fresh
|
|
88
|
-
* cache, an enrichment already in flight for this workflow, a harness
|
|
89
|
-
* with no headless mode, even a spawn failure (logged) — because nothing
|
|
90
|
-
* here was user-initiated and a bind must never fail on enrichment's
|
|
91
|
-
* account.
|
|
92
|
-
*/
|
|
93
|
-
ensureFresh(session: EnrichmentSession, workflows: readonly RenderableWorkflow[]): Promise<void>;
|
|
94
|
-
/**
|
|
95
|
-
* The visualize macro: invalidate both caches, re-render the base diagram
|
|
96
|
-
* immediately (instant feedback, honest content — no leftover enrichment
|
|
97
|
-
* from sources that may have changed), then re-enrich. Refusals propagate
|
|
98
|
-
* to the macros router (TaskAlreadyRunningError → 409,
|
|
99
|
-
* TaskNotSupportedError → 400). Unbound session: just a no-op, matching
|
|
100
|
-
* the deterministic render's own unbound contract.
|
|
101
|
-
*
|
|
102
|
-
* The already-running check happens BEFORE any cache destruction so that a
|
|
103
|
-
* double-click Visualize is a true no-op: the second call rejects with
|
|
104
|
-
* TaskAlreadyRunningError and the caches and render are left exactly as
|
|
105
|
-
* the still-running enrichment will need them.
|
|
106
|
-
*/
|
|
107
|
-
forceRefresh(session: EnrichmentSession, workflows: readonly RenderableWorkflow[]): Promise<void>;
|
|
108
|
-
private resolveBound;
|
|
109
|
-
private spawn;
|
|
110
|
-
/** Completed task → parse → validate → cache file → re-render. Any parse
|
|
111
|
-
* or validation failure discards the enrichment whole; the base render
|
|
112
|
-
* already on disk stands untouched. */
|
|
113
|
-
private persist;
|
|
114
|
-
}
|
|
115
|
-
//# sourceMappingURL=canvas-enrich.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"canvas-enrich.d.ts","sourceRoot":"","sources":["../../src/core/canvas-enrich.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACtE,OAAO,EAAyD,KAAK,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACjH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AASrD,OAAO,EAGL,KAAK,kBAAkB,EACxB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAGxD;0DAC0D;AAC1D,eAAO,MAAM,mBAAmB,cAAc,CAAC;AAO/C,mEAAmE;AACnE,wBAAgB,eAAe,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,MAAM,CAE5E;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CAuBrF;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,GAAG,IAAI,CAgBlE;AAED,uEAAuE;AACvE,MAAM,WAAW,oBAAoB;IACnC,GAAG,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;IAClD,cAAc,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,cAAc,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC;IACrE;;8EAE0E;IAC1E,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC;CAC3D;AAED,6EAA6E;AAC7E,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,WAAW,CAAC;IACrB,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;CAClC;AAED,MAAM,WAAW,4BAA4B;IAC3C,KAAK,EAAE,oBAAoB,CAAC;IAC5B;;uCAEmC;IACnC,QAAQ,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,kBAAkB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACxE,qEAAqE;IACrE,aAAa,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,gBAAgB,CAAC,CAAC;IAC3D,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACrC;AAED,qBAAa,2BAA2B;IACtC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAuB;IAC7C,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA+D;IACxF,OAAO,CAAC,QAAQ,CAAC,aAAa,CAA6C;IAC3E,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAoB;IACxC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAe;IACnC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA4B;gBAExC,OAAO,EAAE,4BAA4B;IASjD;;;;;;;;OAQG;IACG,WAAW,CAAC,OAAO,EAAE,iBAAiB,EAAE,SAAS,EAAE,SAAS,kBAAkB,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAetG;;;;;;;;;;;;OAYG;IACG,YAAY,CAAC,OAAO,EAAE,iBAAiB,EAAE,SAAS,EAAE,SAAS,kBAAkB,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAcvG,OAAO,CAAC,YAAY;YAON,KAAK;IA+BnB;;4CAEwC;YAC1B,OAAO;CAqBtB"}
|
|
@@ -1,186 +0,0 @@
|
|
|
1
|
-
import { extractWorkflowGraphCached, invalidateExtractionCache } from "./canvas-cache.js";
|
|
2
|
-
import { ENRICHMENT_LIMITS, normalizeCanvasEnrichmentCandidate, parseCanvasEnrichment, readEnrichmentCacheFile, removeEnrichmentCacheFile, writeEnrichmentCacheFile, } from "./canvas-enrichment.js";
|
|
3
|
-
import { enrichmentCacheFileFor, renderWorkflowRenderFile, } from "./canvas-render.js";
|
|
4
|
-
import { TaskAlreadyRunningError, TaskNotSupportedError } from "./task-manager.js";
|
|
5
|
-
/** The macro identity enrichment tasks run under — the pane's Retry re-fires
|
|
6
|
-
* this macro, which routes back through forceRefresh. */
|
|
7
|
-
export const ENRICHMENT_MACRO_ID = "visualize";
|
|
8
|
-
const ENRICHMENT_TASK_LABEL = "Visualize";
|
|
9
|
-
/** Hard turn cap: read a few step files, answer. A run that needs more than
|
|
10
|
-
* this is off the rails, not thorough. */
|
|
11
|
-
const ENRICHMENT_MAX_TURNS = 8;
|
|
12
|
-
const DEFAULT_ENRICHMENT_MODEL = "sonnet";
|
|
13
|
-
/** Model the enrichment task runs on — overridable per install. */
|
|
14
|
-
export function enrichmentModel(env = process.env) {
|
|
15
|
-
return env.SAPIOM_HARNESS_VISUALIZE_MODEL || DEFAULT_ENRICHMENT_MODEL;
|
|
16
|
-
}
|
|
17
|
-
/**
|
|
18
|
-
* Builds the one-shot enrichment prompt: the extracted graph inline (the AI
|
|
19
|
-
* annotates THIS structure — it never invents nodes), pointed at the step
|
|
20
|
-
* sources for semantics, with the JSON contract and its hard limits stated
|
|
21
|
-
* verbatim so a well-behaved run needs no retry.
|
|
22
|
-
*/
|
|
23
|
-
export function buildEnrichmentPrompt(graph, workflowDir) {
|
|
24
|
-
const L = ENRICHMENT_LIMITS;
|
|
25
|
-
return `You are annotating an already-rendered workflow diagram. The diagram's structure below is fixed — you only supply short text annotations, as one JSON object.
|
|
26
|
-
|
|
27
|
-
Extracted workflow graph:
|
|
28
|
-
${JSON.stringify(graph, null, 2)}
|
|
29
|
-
|
|
30
|
-
Read the step run() bodies in ${workflowDir} to understand what each step actually does (what it calls, what it decides, why it branches), then RETURN ONLY a JSON object matching this schema — no prose before or after, no markdown required, and DO NOT write or modify any files:
|
|
31
|
-
|
|
32
|
-
{
|
|
33
|
-
"summary": "what this workflow does, one line (max ${L.summary} chars)",
|
|
34
|
-
"nodeDetails": { "<nodeId>": { "sublabel": "short annotation shown in the node (max ${L.sublabel} chars)", "description": "one sentence, shown on hover (max ${L.description} chars)" } },
|
|
35
|
-
"edgeLabels": { "<fromNodeId>-><toNodeId>": "intent/condition name (max ${L.edgeLabel} chars)" },
|
|
36
|
-
"notes": ["up to ${L.noteCount} facts worth knowing, each max ${L.note} chars"],
|
|
37
|
-
"layoutHints": { "groups": [{ "label": "group name (max ${L.groupLabel} chars)", "nodeIds": ["..."] }], "laneOrder": { "<layerIndex>": ["nodeId", "..."] } },
|
|
38
|
-
"crossWorkflow": "how this workflow ties into the project's other workflows, if it does (max ${L.crossWorkflow} chars)"
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
Rules:
|
|
42
|
-
- Every field is optional — omit what you have nothing useful for (omit, don't write null). Empty strings are worse than omissions.
|
|
43
|
-
- Use ONLY node ids that appear in the graph above.
|
|
44
|
-
- Length limits are hard caps and oversize strings get truncated mid-sentence — aim comfortably under each limit.
|
|
45
|
-
- Your final message must be exactly the JSON object.`;
|
|
46
|
-
}
|
|
47
|
-
/**
|
|
48
|
-
* Pulls the JSON object out of a task's final result text — either fenced
|
|
49
|
-
* (\`\`\`json ... \`\`\`) or raw, tolerating prose around it by falling back to
|
|
50
|
-
* the outermost {...} span. Null when nothing parses.
|
|
51
|
-
*/
|
|
52
|
-
export function extractEnrichmentJson(text) {
|
|
53
|
-
const fenced = /```(?:json)?\s*([\s\S]*?)```/.exec(text);
|
|
54
|
-
const candidates = [fenced?.[1], text];
|
|
55
|
-
const first = text.indexOf("{");
|
|
56
|
-
const last = text.lastIndexOf("}");
|
|
57
|
-
if (first !== -1 && last > first)
|
|
58
|
-
candidates.push(text.slice(first, last + 1));
|
|
59
|
-
for (const candidate of candidates) {
|
|
60
|
-
if (!candidate)
|
|
61
|
-
continue;
|
|
62
|
-
try {
|
|
63
|
-
const parsed = JSON.parse(candidate.trim());
|
|
64
|
-
if (typeof parsed === "object" && parsed !== null)
|
|
65
|
-
return parsed;
|
|
66
|
-
}
|
|
67
|
-
catch {
|
|
68
|
-
// Try the next candidate shape.
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
return null;
|
|
72
|
-
}
|
|
73
|
-
export class CanvasEnrichmentCoordinator {
|
|
74
|
-
constructor(options) {
|
|
75
|
-
this.tasks = options.tasks;
|
|
76
|
-
this.rerender = options.rerender ?? (async (cwd, workflow) => void (await renderWorkflowRenderFile(cwd, workflow)));
|
|
77
|
-
this.extractCached = options.extractCached ?? extractWorkflowGraphCached;
|
|
78
|
-
this.env = options.env ?? process.env;
|
|
79
|
-
this.now = options.now ?? (() => new Date().toISOString());
|
|
80
|
-
this.onError = options.onError ?? ((message) => console.error(`[harness] ${message}`));
|
|
81
|
-
}
|
|
82
|
-
/**
|
|
83
|
-
* The bind/create trigger: spawn an enrichment task unless a cached
|
|
84
|
-
* enrichment already matches the workflow's current sources. Silent on
|
|
85
|
-
* every expected refusal — unbound session, failed extraction, fresh
|
|
86
|
-
* cache, an enrichment already in flight for this workflow, a harness
|
|
87
|
-
* with no headless mode, even a spawn failure (logged) — because nothing
|
|
88
|
-
* here was user-initiated and a bind must never fail on enrichment's
|
|
89
|
-
* account.
|
|
90
|
-
*/
|
|
91
|
-
async ensureFresh(session, workflows) {
|
|
92
|
-
const bound = this.resolveBound(session, workflows);
|
|
93
|
-
if (!bound)
|
|
94
|
-
return;
|
|
95
|
-
try {
|
|
96
|
-
const { result, fingerprint } = await this.extractCached(bound.path);
|
|
97
|
-
if (!result.ok)
|
|
98
|
-
return;
|
|
99
|
-
const entry = await readEnrichmentCacheFile(enrichmentCacheFileFor(session.cwd, bound.path));
|
|
100
|
-
if (entry && entry.sourceFingerprint === fingerprint)
|
|
101
|
-
return;
|
|
102
|
-
await this.spawn(session, bound, result.graph, fingerprint);
|
|
103
|
-
}
|
|
104
|
-
catch (err) {
|
|
105
|
-
if (err instanceof TaskAlreadyRunningError || err instanceof TaskNotSupportedError)
|
|
106
|
-
return;
|
|
107
|
-
this.onError(`canvas enrichment (auto) failed to start: ${err.message}`);
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
/**
|
|
111
|
-
* The visualize macro: invalidate both caches, re-render the base diagram
|
|
112
|
-
* immediately (instant feedback, honest content — no leftover enrichment
|
|
113
|
-
* from sources that may have changed), then re-enrich. Refusals propagate
|
|
114
|
-
* to the macros router (TaskAlreadyRunningError → 409,
|
|
115
|
-
* TaskNotSupportedError → 400). Unbound session: just a no-op, matching
|
|
116
|
-
* the deterministic render's own unbound contract.
|
|
117
|
-
*
|
|
118
|
-
* The already-running check happens BEFORE any cache destruction so that a
|
|
119
|
-
* double-click Visualize is a true no-op: the second call rejects with
|
|
120
|
-
* TaskAlreadyRunningError and the caches and render are left exactly as
|
|
121
|
-
* the still-running enrichment will need them.
|
|
122
|
-
*/
|
|
123
|
-
async forceRefresh(session, workflows) {
|
|
124
|
-
const bound = this.resolveBound(session, workflows);
|
|
125
|
-
if (!bound)
|
|
126
|
-
return;
|
|
127
|
-
if (this.tasks.isRunning(ENRICHMENT_MACRO_ID, bound.path)) {
|
|
128
|
-
throw new TaskAlreadyRunningError(ENRICHMENT_TASK_LABEL);
|
|
129
|
-
}
|
|
130
|
-
invalidateExtractionCache(bound.path);
|
|
131
|
-
await removeEnrichmentCacheFile(enrichmentCacheFileFor(session.cwd, bound.path));
|
|
132
|
-
await this.rerender(session.cwd, bound);
|
|
133
|
-
const { result, fingerprint } = await this.extractCached(bound.path);
|
|
134
|
-
if (!result.ok)
|
|
135
|
-
return;
|
|
136
|
-
await this.spawn(session, bound, result.graph, fingerprint);
|
|
137
|
-
}
|
|
138
|
-
resolveBound(session, workflows) {
|
|
139
|
-
return session.boundWorkflowPath ? workflows.find((w) => w.path === session.boundWorkflowPath) : undefined;
|
|
140
|
-
}
|
|
141
|
-
async spawn(session, workflow, graph, fingerprint) {
|
|
142
|
-
const task = await this.tasks.run({
|
|
143
|
-
macroId: ENRICHMENT_MACRO_ID,
|
|
144
|
-
label: ENRICHMENT_TASK_LABEL,
|
|
145
|
-
harnessSessionId: session.id,
|
|
146
|
-
harness: session.harness,
|
|
147
|
-
cwd: session.cwd,
|
|
148
|
-
prompt: buildEnrichmentPrompt(graph, workflow.path),
|
|
149
|
-
workflowPath: workflow.path,
|
|
150
|
-
model: enrichmentModel(this.env),
|
|
151
|
-
maxTurns: ENRICHMENT_MAX_TURNS,
|
|
152
|
-
});
|
|
153
|
-
// Subscribed synchronously right after run() resolves — the process's
|
|
154
|
-
// exit can only arrive via a later event-loop turn, so the terminal
|
|
155
|
-
// status can't be missed.
|
|
156
|
-
const unsubscribe = this.tasks.onStatusChange((update) => {
|
|
157
|
-
if (update.id !== task.id || update.status === "running")
|
|
158
|
-
return;
|
|
159
|
-
unsubscribe();
|
|
160
|
-
if (update.status !== "completed")
|
|
161
|
-
return; // pane shows the failure; nothing to persist
|
|
162
|
-
void this.persist(session.cwd, workflow, graph, fingerprint, update.resultText).catch((err) => {
|
|
163
|
-
this.onError(`canvas enrichment persist failed: ${err.message}`);
|
|
164
|
-
});
|
|
165
|
-
});
|
|
166
|
-
}
|
|
167
|
-
/** Completed task → parse → validate → cache file → re-render. Any parse
|
|
168
|
-
* or validation failure discards the enrichment whole; the base render
|
|
169
|
-
* already on disk stands untouched. */
|
|
170
|
-
async persist(cwd, workflow, graph, fingerprint, resultText) {
|
|
171
|
-
const candidate = resultText ? extractEnrichmentJson(resultText) : null;
|
|
172
|
-
const enrichment = candidate ? parseCanvasEnrichment(normalizeCanvasEnrichmentCandidate(candidate)) : null;
|
|
173
|
-
if (!enrichment) {
|
|
174
|
-
this.onError(`canvas enrichment for ${workflow.path} returned invalid output — discarded, base render stands`);
|
|
175
|
-
return;
|
|
176
|
-
}
|
|
177
|
-
await writeEnrichmentCacheFile(enrichmentCacheFileFor(cwd, workflow.path), {
|
|
178
|
-
graph,
|
|
179
|
-
enrichment,
|
|
180
|
-
sourceFingerprint: fingerprint,
|
|
181
|
-
enrichedAt: this.now(),
|
|
182
|
-
});
|
|
183
|
-
await this.rerender(cwd, workflow);
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
//# sourceMappingURL=canvas-enrich.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"canvas-enrich.js","sourceRoot":"","sources":["../../src/core/canvas-enrich.ts"],"names":[],"mappings":"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"}
|
package/dist/core/run-spend.d.ts
DELETED
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* run-spend — fetches the cost/spend summary for a prod execution from the
|
|
3
|
-
* core surface and maps it to a {@link RunSpend} the canvas can poll.
|
|
4
|
-
*
|
|
5
|
-
* WHY the core surface: the spend endpoint lives at
|
|
6
|
-
* `GET /v1/workflows/executions/:id/spend` on api.sapiom.ai (the CORE
|
|
7
|
-
* capability surface), which is distinct from the agents surface
|
|
8
|
-
* (tools.sapiom.ai) that run-state.ts uses. The same caveat applies:
|
|
9
|
-
* env-consistency with the run's environment matters — both surfaces must be
|
|
10
|
-
* overridden together when pointing at non-prod.
|
|
11
|
-
*
|
|
12
|
-
* WHY the key stays server-side: same rationale as run-state.ts — the Sapiom
|
|
13
|
-
* API key is a harness credential that must never reach the browser. The
|
|
14
|
-
* harness server fetches on behalf of the canvas, so the SPA polls a local
|
|
15
|
-
* `/api/runs/:id/spend` endpoint (no key in the request) rather than calling
|
|
16
|
-
* the upstream surface directly.
|
|
17
|
-
*/
|
|
18
|
-
import type { RunSpend } from "../shared/types.js";
|
|
19
|
-
/**
|
|
20
|
-
* Resolve the CORE surface base URL for the spend endpoint.
|
|
21
|
-
*
|
|
22
|
-
* The spend endpoint lives on the CORE host (`api.<env>`), distinct from the
|
|
23
|
-
* agents host run-state.ts uses (`tools.<env>`). Crucially, a run lives in the
|
|
24
|
-
* agents env, and its spend must be read from the MATCHING core env — otherwise
|
|
25
|
-
* a prod run's spend queried against dev 401s. So we DERIVE the core host from
|
|
26
|
-
* the agents host (`tools.<env>` → `api.<env>`) rather than reading
|
|
27
|
-
* `SAPIOM_API_URL`, which in some setups points at a different env than the
|
|
28
|
-
* agents surface. An explicit `SAPIOM_CORE_URL` still wins for full control.
|
|
29
|
-
*/
|
|
30
|
-
export declare function resolveCoreBaseUrl(): string;
|
|
31
|
-
export type RunSpendResult = {
|
|
32
|
-
ok: true;
|
|
33
|
-
spend: RunSpend;
|
|
34
|
-
} | {
|
|
35
|
-
ok: false;
|
|
36
|
-
status: number;
|
|
37
|
-
error: string;
|
|
38
|
-
};
|
|
39
|
-
export interface RunSpendFetcherOpts {
|
|
40
|
-
apiKey: string | null;
|
|
41
|
-
baseUrl?: string;
|
|
42
|
-
/** Injectable fetch implementation — defaults to global fetch. Test seam. */
|
|
43
|
-
fetchImpl?: typeof fetch;
|
|
44
|
-
}
|
|
45
|
-
export interface RunSpendFetcher {
|
|
46
|
-
fetch(executionId: string): Promise<RunSpendResult>;
|
|
47
|
-
}
|
|
48
|
-
/**
|
|
49
|
-
* Create a fetcher that resolves an execution's spend/cost from the core
|
|
50
|
-
* surface. The fetcher is intentionally non-throwing: all error paths return
|
|
51
|
-
* a typed {@link RunSpendResult} with `ok: false` so the router can forward
|
|
52
|
-
* the appropriate HTTP status without a try/catch at the call site.
|
|
53
|
-
*/
|
|
54
|
-
export declare function createRunSpendFetcher(opts: RunSpendFetcherOpts): RunSpendFetcher;
|
|
55
|
-
//# sourceMappingURL=run-spend.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"run-spend.d.ts","sourceRoot":"","sources":["../../src/core/run-spend.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAGnD;;;;;;;;;;GAUG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,CAc3C;AAED,MAAM,MAAM,cAAc,GACtB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,QAAQ,CAAA;CAAE,GAC7B;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAEjD,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,6EAA6E;IAC7E,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;CAC1B;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;CACrD;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,mBAAmB,GACxB,eAAe,CAsEjB"}
|
package/dist/core/run-spend.js
DELETED
|
@@ -1,109 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* run-spend — fetches the cost/spend summary for a prod execution from the
|
|
3
|
-
* core surface and maps it to a {@link RunSpend} the canvas can poll.
|
|
4
|
-
*
|
|
5
|
-
* WHY the core surface: the spend endpoint lives at
|
|
6
|
-
* `GET /v1/workflows/executions/:id/spend` on api.sapiom.ai (the CORE
|
|
7
|
-
* capability surface), which is distinct from the agents surface
|
|
8
|
-
* (tools.sapiom.ai) that run-state.ts uses. The same caveat applies:
|
|
9
|
-
* env-consistency with the run's environment matters — both surfaces must be
|
|
10
|
-
* overridden together when pointing at non-prod.
|
|
11
|
-
*
|
|
12
|
-
* WHY the key stays server-side: same rationale as run-state.ts — the Sapiom
|
|
13
|
-
* API key is a harness credential that must never reach the browser. The
|
|
14
|
-
* harness server fetches on behalf of the canvas, so the SPA polls a local
|
|
15
|
-
* `/api/runs/:id/spend` endpoint (no key in the request) rather than calling
|
|
16
|
-
* the upstream surface directly.
|
|
17
|
-
*/
|
|
18
|
-
import { resolveAgentsBaseUrl } from "./run-state.js";
|
|
19
|
-
/**
|
|
20
|
-
* Resolve the CORE surface base URL for the spend endpoint.
|
|
21
|
-
*
|
|
22
|
-
* The spend endpoint lives on the CORE host (`api.<env>`), distinct from the
|
|
23
|
-
* agents host run-state.ts uses (`tools.<env>`). Crucially, a run lives in the
|
|
24
|
-
* agents env, and its spend must be read from the MATCHING core env — otherwise
|
|
25
|
-
* a prod run's spend queried against dev 401s. So we DERIVE the core host from
|
|
26
|
-
* the agents host (`tools.<env>` → `api.<env>`) rather than reading
|
|
27
|
-
* `SAPIOM_API_URL`, which in some setups points at a different env than the
|
|
28
|
-
* agents surface. An explicit `SAPIOM_CORE_URL` still wins for full control.
|
|
29
|
-
*/
|
|
30
|
-
export function resolveCoreBaseUrl() {
|
|
31
|
-
const override = process.env.SAPIOM_CORE_URL;
|
|
32
|
-
if (override)
|
|
33
|
-
return override;
|
|
34
|
-
const agents = resolveAgentsBaseUrl();
|
|
35
|
-
try {
|
|
36
|
-
const url = new URL(agents);
|
|
37
|
-
if (url.hostname.startsWith("tools.")) {
|
|
38
|
-
url.hostname = `api.${url.hostname.slice("tools.".length)}`;
|
|
39
|
-
return url.origin;
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
catch {
|
|
43
|
-
// Unparseable agents URL — fall through to the prod default.
|
|
44
|
-
}
|
|
45
|
-
return "https://api.sapiom.ai";
|
|
46
|
-
}
|
|
47
|
-
/**
|
|
48
|
-
* Create a fetcher that resolves an execution's spend/cost from the core
|
|
49
|
-
* surface. The fetcher is intentionally non-throwing: all error paths return
|
|
50
|
-
* a typed {@link RunSpendResult} with `ok: false` so the router can forward
|
|
51
|
-
* the appropriate HTTP status without a try/catch at the call site.
|
|
52
|
-
*/
|
|
53
|
-
export function createRunSpendFetcher(opts) {
|
|
54
|
-
const { apiKey, baseUrl = resolveCoreBaseUrl(), fetchImpl = fetch } = opts;
|
|
55
|
-
return {
|
|
56
|
-
async fetch(executionId) {
|
|
57
|
-
// No API key — do not touch the network; the harness is not signed in.
|
|
58
|
-
if (!apiKey) {
|
|
59
|
-
return {
|
|
60
|
-
ok: false,
|
|
61
|
-
status: 503,
|
|
62
|
-
error: "harness is not signed in to Sapiom",
|
|
63
|
-
};
|
|
64
|
-
}
|
|
65
|
-
let res;
|
|
66
|
-
try {
|
|
67
|
-
res = await fetchImpl(`${baseUrl}/v1/workflows/executions/${encodeURIComponent(executionId)}/spend`, { headers: { "x-api-key": apiKey } });
|
|
68
|
-
}
|
|
69
|
-
catch {
|
|
70
|
-
return { ok: false, status: 502, error: "gateway unreachable" };
|
|
71
|
-
}
|
|
72
|
-
if (res.status === 404) {
|
|
73
|
-
return { ok: false, status: 404, error: "spend not found" };
|
|
74
|
-
}
|
|
75
|
-
if (!res.ok) {
|
|
76
|
-
return {
|
|
77
|
-
ok: false,
|
|
78
|
-
status: 502,
|
|
79
|
-
error: `gateway responded ${res.status}`,
|
|
80
|
-
};
|
|
81
|
-
}
|
|
82
|
-
try {
|
|
83
|
-
const raw = (await res.json());
|
|
84
|
-
// The response is ExecutionSpendDto — we map the capability sub-object
|
|
85
|
-
// fields to RunSpend, falling back to top-level totalUsd when needed.
|
|
86
|
-
const capability = raw.capability;
|
|
87
|
-
const totalUsd = capability?.totalUsd ??
|
|
88
|
-
raw.totalUsd ??
|
|
89
|
-
"0";
|
|
90
|
-
const settleState = capability?.settleState ?? "pending";
|
|
91
|
-
const rawByStep = capability?.byStep ?? [];
|
|
92
|
-
const byStep = rawByStep.map((s) => {
|
|
93
|
-
const step = s;
|
|
94
|
-
return {
|
|
95
|
-
name: step.stepName,
|
|
96
|
-
totalUsd: step.totalUsd,
|
|
97
|
-
entryCount: step.entryCount,
|
|
98
|
-
};
|
|
99
|
-
});
|
|
100
|
-
const spend = { executionId, totalUsd, settleState, byStep };
|
|
101
|
-
return { ok: true, spend };
|
|
102
|
-
}
|
|
103
|
-
catch {
|
|
104
|
-
return { ok: false, status: 502, error: "could not decode spend" };
|
|
105
|
-
}
|
|
106
|
-
},
|
|
107
|
-
};
|
|
108
|
-
}
|
|
109
|
-
//# sourceMappingURL=run-spend.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"run-spend.js","sourceRoot":"","sources":["../../src/core/run-spend.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* run-transactions — fetches the per-call cost drill-down for an execution
|
|
3
|
-
* from the core surface and maps it to a {@link RunCall}[] the canvas shows
|
|
4
|
-
* when a user clicks a step and asks "why is this costly".
|
|
5
|
-
*
|
|
6
|
-
* WHY this exists alongside run-spend: `/spend` gives per-STEP aggregates
|
|
7
|
-
* (totalUsd + entryCount). This endpoint itemises the individual billable
|
|
8
|
-
* capability calls that make up that total (e.g. "renderPdfs $7.95 = 1 sandbox
|
|
9
|
-
* call"), which is what makes the debug macros actionable.
|
|
10
|
-
*
|
|
11
|
-
* WHY provider-agnostic: the raw upstream service name (the provider) is mapped
|
|
12
|
-
* to a generic capability label here, server-side, so the browser never
|
|
13
|
-
* receives — and this open-source file never hard-codes — a provider or model
|
|
14
|
-
* name. See the capability-label heuristic below (keyed on generic op/resource
|
|
15
|
-
* tokens, never a brand).
|
|
16
|
-
*
|
|
17
|
-
* WHY the key stays server-side: identical rationale to run-state / run-spend —
|
|
18
|
-
* the Sapiom API key is a harness credential that must never reach the browser.
|
|
19
|
-
*/
|
|
20
|
-
import type { RunCall } from "../shared/types.js";
|
|
21
|
-
export type RunCallsResult = {
|
|
22
|
-
ok: true;
|
|
23
|
-
calls: RunCall[];
|
|
24
|
-
} | {
|
|
25
|
-
ok: false;
|
|
26
|
-
status: number;
|
|
27
|
-
error: string;
|
|
28
|
-
};
|
|
29
|
-
export interface RunTransactionsFetcherOpts {
|
|
30
|
-
apiKey: string | null;
|
|
31
|
-
/** Override the core base URL (resolved from env by default). Test seam. */
|
|
32
|
-
baseUrl?: string;
|
|
33
|
-
/** Injectable fetch implementation — defaults to global fetch. Test seam. */
|
|
34
|
-
fetchImpl?: typeof fetch;
|
|
35
|
-
}
|
|
36
|
-
export interface RunTransactionsFetcher {
|
|
37
|
-
fetch(executionId: string): Promise<RunCallsResult>;
|
|
38
|
-
}
|
|
39
|
-
/**
|
|
40
|
-
* Map a raw upstream operation/resource to a provider-agnostic capability
|
|
41
|
-
* label. Keyed ONLY on generic tokens (message / sandbox / search) and the
|
|
42
|
-
* operation verb — deliberately never on a provider/brand name, so this file
|
|
43
|
-
* stays clean of internal service names and the label is stable if the
|
|
44
|
-
* underlying provider is swapped. Unknown shapes fall back to the operation
|
|
45
|
-
* verb, which is itself generic ("create", "execute", …).
|
|
46
|
-
*/
|
|
47
|
-
export declare function capabilityLabel(op: string, resource: string): string;
|
|
48
|
-
/**
|
|
49
|
-
* Create a fetcher that resolves an execution's per-call cost breakdown from
|
|
50
|
-
* the core transactions endpoint. Like the spend fetcher, it is intentionally
|
|
51
|
-
* non-throwing: every error path returns a typed {@link RunCallsResult} with
|
|
52
|
-
* `ok: false` so the router forwards the status without a try/catch.
|
|
53
|
-
*
|
|
54
|
-
* Only BILLABLE calls are returned (active captured USD > 0) — the free
|
|
55
|
-
* `workflows` orchestration rows are dropped as noise. Each call is attributed
|
|
56
|
-
* to `metadata.workflowStepName ?? actionName` so the canvas can match it to a
|
|
57
|
-
* step node.
|
|
58
|
-
*/
|
|
59
|
-
export declare function createRunTransactionsFetcher(opts: RunTransactionsFetcherOpts): RunTransactionsFetcher;
|
|
60
|
-
//# sourceMappingURL=run-transactions.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"run-transactions.d.ts","sourceRoot":"","sources":["../../src/core/run-transactions.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAGlD,MAAM,MAAM,cAAc,GACtB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,OAAO,EAAE,CAAA;CAAE,GAC9B;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAEjD,MAAM,WAAW,0BAA0B;IACzC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,4EAA4E;IAC5E,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,6EAA6E;IAC7E,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;CAC1B;AAED,MAAM,WAAW,sBAAsB;IACrC,KAAK,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;CACrD;AAED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAQpE;AAeD;;;;;;;;;;GAUG;AACH,wBAAgB,4BAA4B,CAC1C,IAAI,EAAE,0BAA0B,GAC/B,sBAAsB,CAyExB"}
|