@pellux/goodvibes-sdk 0.37.1 → 0.38.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/dist/contracts/artifacts/operator-contract.json +1 -1
- package/dist/events/communication.d.ts +21 -1
- package/dist/events/communication.d.ts.map +1 -1
- package/dist/platform/agents/message-bus-core.d.ts +7 -0
- package/dist/platform/agents/message-bus-core.d.ts.map +1 -1
- package/dist/platform/agents/message-bus-core.js +2 -1
- package/dist/platform/agents/orchestrator-runner.d.ts +37 -1
- package/dist/platform/agents/orchestrator-runner.d.ts.map +1 -1
- package/dist/platform/agents/orchestrator-runner.js +158 -7
- package/dist/platform/agents/orchestrator.d.ts +40 -0
- package/dist/platform/agents/orchestrator.d.ts.map +1 -1
- package/dist/platform/agents/orchestrator.js +29 -0
- package/dist/platform/agents/turn-knowledge-injection.d.ts +107 -0
- package/dist/platform/agents/turn-knowledge-injection.d.ts.map +1 -0
- package/dist/platform/agents/turn-knowledge-injection.js +152 -0
- package/dist/platform/agents/wrfc-controller.d.ts +23 -0
- package/dist/platform/agents/wrfc-controller.d.ts.map +1 -1
- package/dist/platform/agents/wrfc-controller.js +55 -0
- package/dist/platform/config/manager.d.ts +9 -0
- package/dist/platform/config/manager.d.ts.map +1 -1
- package/dist/platform/config/manager.js +15 -0
- package/dist/platform/control-plane/approval-broker.d.ts +1 -0
- package/dist/platform/control-plane/approval-broker.d.ts.map +1 -1
- package/dist/platform/control-plane/approval-broker.js +2 -0
- package/dist/platform/core/adaptive-planner.d.ts +50 -0
- package/dist/platform/core/adaptive-planner.d.ts.map +1 -1
- package/dist/platform/core/adaptive-planner.js +49 -0
- package/dist/platform/core/index.d.ts +1 -0
- package/dist/platform/core/index.d.ts.map +1 -1
- package/dist/platform/core/index.js +1 -0
- package/dist/platform/core/orchestrator-runtime.d.ts +11 -0
- package/dist/platform/core/orchestrator-runtime.d.ts.map +1 -1
- package/dist/platform/core/orchestrator-turn-loop.d.ts +28 -1
- package/dist/platform/core/orchestrator-turn-loop.d.ts.map +1 -1
- package/dist/platform/core/orchestrator-turn-loop.js +115 -3
- package/dist/platform/core/orchestrator.d.ts +61 -0
- package/dist/platform/core/orchestrator.d.ts.map +1 -1
- package/dist/platform/core/orchestrator.js +74 -1
- package/dist/platform/core/plan-proposal.d.ts +165 -0
- package/dist/platform/core/plan-proposal.d.ts.map +1 -0
- package/dist/platform/core/plan-proposal.js +296 -0
- package/dist/platform/knowledge/knowledge-api.d.ts +26 -0
- package/dist/platform/knowledge/knowledge-api.d.ts.map +1 -1
- package/dist/platform/knowledge/knowledge-api.js +11 -0
- package/dist/platform/orchestration/budget.d.ts +22 -0
- package/dist/platform/orchestration/budget.d.ts.map +1 -0
- package/dist/platform/orchestration/budget.js +35 -0
- package/dist/platform/orchestration/cancellation.d.ts +31 -0
- package/dist/platform/orchestration/cancellation.d.ts.map +1 -0
- package/dist/platform/orchestration/cancellation.js +25 -0
- package/dist/platform/orchestration/controller-compat.d.ts +32 -0
- package/dist/platform/orchestration/controller-compat.d.ts.map +1 -0
- package/dist/platform/orchestration/controller-compat.js +13 -0
- package/dist/platform/orchestration/dirty-guard.d.ts +32 -0
- package/dist/platform/orchestration/dirty-guard.d.ts.map +1 -0
- package/dist/platform/orchestration/dirty-guard.js +147 -0
- package/dist/platform/orchestration/engine.d.ts +57 -0
- package/dist/platform/orchestration/engine.d.ts.map +1 -0
- package/dist/platform/orchestration/engine.js +418 -0
- package/dist/platform/orchestration/index.d.ts +18 -0
- package/dist/platform/orchestration/index.d.ts.map +1 -0
- package/dist/platform/orchestration/index.js +10 -0
- package/dist/platform/orchestration/persistence.d.ts +24 -0
- package/dist/platform/orchestration/persistence.d.ts.map +1 -0
- package/dist/platform/orchestration/persistence.js +176 -0
- package/dist/platform/orchestration/phase-runner.d.ts +87 -0
- package/dist/platform/orchestration/phase-runner.d.ts.map +1 -0
- package/dist/platform/orchestration/phase-runner.js +274 -0
- package/dist/platform/orchestration/scheduler.d.ts +45 -0
- package/dist/platform/orchestration/scheduler.d.ts.map +1 -0
- package/dist/platform/orchestration/scheduler.js +57 -0
- package/dist/platform/orchestration/types.d.ts +250 -0
- package/dist/platform/orchestration/types.d.ts.map +1 -0
- package/dist/platform/orchestration/types.js +15 -0
- package/dist/platform/runtime/emitters/communication.d.ts +11 -0
- package/dist/platform/runtime/emitters/communication.d.ts.map +1 -1
- package/dist/platform/runtime/emitters/communication.js +9 -0
- package/dist/platform/runtime/feature-flags/flags.d.ts.map +1 -1
- package/dist/platform/runtime/feature-flags/flags.js +17 -0
- package/dist/platform/runtime/fleet/adapters/agent.d.ts +56 -0
- package/dist/platform/runtime/fleet/adapters/agent.d.ts.map +1 -0
- package/dist/platform/runtime/fleet/adapters/agent.js +143 -0
- package/dist/platform/runtime/fleet/adapters/automation.d.ts +30 -0
- package/dist/platform/runtime/fleet/adapters/automation.d.ts.map +1 -0
- package/dist/platform/runtime/fleet/adapters/automation.js +41 -0
- package/dist/platform/runtime/fleet/adapters/background-process.d.ts +12 -0
- package/dist/platform/runtime/fleet/adapters/background-process.d.ts.map +1 -0
- package/dist/platform/runtime/fleet/adapters/background-process.js +46 -0
- package/dist/platform/runtime/fleet/adapters/code-index.d.ts +21 -0
- package/dist/platform/runtime/fleet/adapters/code-index.d.ts.map +1 -0
- package/dist/platform/runtime/fleet/adapters/code-index.js +44 -0
- package/dist/platform/runtime/fleet/adapters/orchestration.d.ts +47 -0
- package/dist/platform/runtime/fleet/adapters/orchestration.d.ts.map +1 -0
- package/dist/platform/runtime/fleet/adapters/orchestration.js +225 -0
- package/dist/platform/runtime/fleet/adapters/schedule.d.ts +14 -0
- package/dist/platform/runtime/fleet/adapters/schedule.d.ts.map +1 -0
- package/dist/platform/runtime/fleet/adapters/schedule.js +28 -0
- package/dist/platform/runtime/fleet/adapters/trigger.d.ts +12 -0
- package/dist/platform/runtime/fleet/adapters/trigger.d.ts.map +1 -0
- package/dist/platform/runtime/fleet/adapters/trigger.js +22 -0
- package/dist/platform/runtime/fleet/adapters/watcher.d.ts +13 -0
- package/dist/platform/runtime/fleet/adapters/watcher.d.ts.map +1 -0
- package/dist/platform/runtime/fleet/adapters/watcher.js +47 -0
- package/dist/platform/runtime/fleet/adapters/workflow.d.ts +11 -0
- package/dist/platform/runtime/fleet/adapters/workflow.d.ts.map +1 -0
- package/dist/platform/runtime/fleet/adapters/workflow.js +34 -0
- package/dist/platform/runtime/fleet/adapters/wrfc.d.ts +22 -0
- package/dist/platform/runtime/fleet/adapters/wrfc.d.ts.map +1 -0
- package/dist/platform/runtime/fleet/adapters/wrfc.js +228 -0
- package/dist/platform/runtime/fleet/index.d.ts +10 -0
- package/dist/platform/runtime/fleet/index.d.ts.map +1 -0
- package/dist/platform/runtime/fleet/index.js +6 -0
- package/dist/platform/runtime/fleet/registry.d.ts +113 -0
- package/dist/platform/runtime/fleet/registry.d.ts.map +1 -0
- package/dist/platform/runtime/fleet/registry.js +630 -0
- package/dist/platform/runtime/fleet/types.d.ts +199 -0
- package/dist/platform/runtime/fleet/types.d.ts.map +1 -0
- package/dist/platform/runtime/fleet/types.js +2 -0
- package/dist/platform/runtime/runtime-knowledge-api.d.ts +1 -1
- package/dist/platform/runtime/runtime-knowledge-api.d.ts.map +1 -1
- package/dist/platform/runtime/runtime-knowledge-api.js +1 -0
- package/dist/platform/runtime/services.d.ts +46 -0
- package/dist/platform/runtime/services.d.ts.map +1 -1
- package/dist/platform/runtime/services.js +78 -0
- package/dist/platform/state/code-index-chunking.d.ts +49 -0
- package/dist/platform/state/code-index-chunking.d.ts.map +1 -0
- package/dist/platform/state/code-index-chunking.js +111 -0
- package/dist/platform/state/code-index-db.d.ts +53 -0
- package/dist/platform/state/code-index-db.d.ts.map +1 -0
- package/dist/platform/state/code-index-db.js +101 -0
- package/dist/platform/state/code-index-store.d.ts +175 -0
- package/dist/platform/state/code-index-store.d.ts.map +1 -0
- package/dist/platform/state/code-index-store.js +612 -0
- package/dist/platform/state/index.d.ts +4 -2
- package/dist/platform/state/index.d.ts.map +1 -1
- package/dist/platform/state/index.js +2 -1
- package/dist/platform/state/knowledge-injection.d.ts +23 -0
- package/dist/platform/state/knowledge-injection.d.ts.map +1 -1
- package/dist/platform/state/knowledge-injection.js +34 -19
- package/dist/platform/state/memory-vector-store.d.ts +1 -13
- package/dist/platform/state/memory-vector-store.d.ts.map +1 -1
- package/dist/platform/state/memory-vector-store.js +6 -38
- package/dist/platform/state/sqlite-vec-loader.d.ts +25 -0
- package/dist/platform/state/sqlite-vec-loader.d.ts.map +1 -0
- package/dist/platform/state/sqlite-vec-loader.js +43 -0
- package/dist/platform/tools/agent/manager.d.ts +128 -1
- package/dist/platform/tools/agent/manager.d.ts.map +1 -1
- package/dist/platform/tools/agent/manager.js +137 -1
- package/dist/platform/tools/exec/runtime.d.ts.map +1 -1
- package/dist/platform/tools/exec/runtime.js +139 -44
- package/dist/platform/tools/exec/schema.d.ts +2 -0
- package/dist/platform/tools/exec/schema.d.ts.map +1 -1
- package/dist/platform/tools/fetch/runtime.d.ts +7 -0
- package/dist/platform/tools/fetch/runtime.d.ts.map +1 -1
- package/dist/platform/tools/fetch/runtime.js +8 -6
- package/dist/platform/tools/registry.d.ts +9 -3
- package/dist/platform/tools/registry.d.ts.map +1 -1
- package/dist/platform/tools/registry.js +9 -3
- package/dist/platform/types/tools.d.ts +14 -1
- package/dist/platform/types/tools.d.ts.map +1 -1
- package/dist/platform/version.js +1 -1
- package/dist/platform/workspace/checkpoint/side-git.d.ts +20 -8
- package/dist/platform/workspace/checkpoint/side-git.d.ts.map +1 -1
- package/dist/platform/workspace/checkpoint/side-git.js +21 -11
- package/package.json +17 -9
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"background-process.d.ts","sourceRoot":"","sources":["../../../../../src/platform/runtime/fleet/adapters/background-process.ts"],"names":[],"mappings":"AAAA,qFAAqF;AAErF,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0CAA0C,CAAC;AAClF,OAAO,KAAK,EAAE,WAAW,EAAgB,MAAM,aAAa,CAAC;AAE7D,0FAA0F;AAC1F,wBAAgB,cAAc,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,GAAG,SAAS,CAU5E;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,iBAAiB,EAAE,GAAG,EAAE,MAAM,GAAG,WAAW,CAuB1F"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/** SDK-owned platform module. This implementation is maintained in goodvibes-sdk. */
|
|
2
|
+
/** Last non-empty stdout line — already tracked on the record, no new emission needed. */
|
|
3
|
+
export function lastOutputLine(stdout) {
|
|
4
|
+
// stdout is an array of chunks; join a bounded tail and take the last
|
|
5
|
+
// non-empty line so the scan stays cheap even for chatty processes.
|
|
6
|
+
const tail = stdout.slice(-8).join('');
|
|
7
|
+
const lines = tail.split('\n');
|
|
8
|
+
for (let i = lines.length - 1; i >= 0; i--) {
|
|
9
|
+
const line = lines[i]?.trim();
|
|
10
|
+
if (line)
|
|
11
|
+
return line;
|
|
12
|
+
}
|
|
13
|
+
return undefined;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* BackgroundProcess → ProcessNode. Silent source (no bus emission): liveness
|
|
17
|
+
* rides the registry tick; currentActivity is the last stdout line the
|
|
18
|
+
* ProcessManager already buffers.
|
|
19
|
+
*/
|
|
20
|
+
export function adaptBackgroundProcess(record, now) {
|
|
21
|
+
let state;
|
|
22
|
+
if (!record.done)
|
|
23
|
+
state = 'executing-tool';
|
|
24
|
+
else if (record.exitCode !== null && record.exitCode !== 0)
|
|
25
|
+
state = 'failed';
|
|
26
|
+
else
|
|
27
|
+
state = 'done';
|
|
28
|
+
const line = lastOutputLine(record.stdout);
|
|
29
|
+
return {
|
|
30
|
+
id: record.id,
|
|
31
|
+
kind: 'background-process',
|
|
32
|
+
parentId: undefined,
|
|
33
|
+
label: record.cmd,
|
|
34
|
+
state,
|
|
35
|
+
startedAt: record.startTime,
|
|
36
|
+
completedAt: record.completedAt,
|
|
37
|
+
elapsedMs: Math.max(0, (record.completedAt ?? now) - record.startTime),
|
|
38
|
+
costUsd: null,
|
|
39
|
+
costState: 'unpriced',
|
|
40
|
+
// Silent source: anchored to a stable timestamp (chunk arrival times are
|
|
41
|
+
// not tracked), so an unchanged line never looks like fresh activity.
|
|
42
|
+
currentActivity: line ? { kind: 'output-line', text: line, at: record.completedAt ?? record.startTime } : undefined,
|
|
43
|
+
capabilities: { interruptible: false, killable: !record.done, pausable: false, resumable: false, steerable: false },
|
|
44
|
+
raw: record,
|
|
45
|
+
};
|
|
46
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/** SDK-owned platform module. This implementation is maintained in goodvibes-sdk. */
|
|
2
|
+
import type { CodeIndexBuildProgress, CodeIndexStats } from '../../../state/code-index-store.js';
|
|
3
|
+
import type { ProcessNode } from '../types.js';
|
|
4
|
+
/** Narrow view of CodeIndexStore the fleet needs — Pick<CodeIndexStore, ...>, same pattern as the other adapter deps. */
|
|
5
|
+
export interface CodeIndexProcessSource {
|
|
6
|
+
isBuilding(): boolean;
|
|
7
|
+
buildProgress(): CodeIndexBuildProgress | null;
|
|
8
|
+
buildStartedAt(): number | null;
|
|
9
|
+
stats(): CodeIndexStats;
|
|
10
|
+
}
|
|
11
|
+
/** Single well-known id: one code index per working directory (no per-workspace fan-out in Stage A). */
|
|
12
|
+
export declare function codeIndexNodeId(): string;
|
|
13
|
+
/**
|
|
14
|
+
* CodeIndexStore → ProcessNode. Silent source (no bus emission, like
|
|
15
|
+
* background-process): liveness rides the registry tick. An index build has
|
|
16
|
+
* no pid, so it is NOT a 'background-process' node (ProcessManager is
|
|
17
|
+
* shell/OS-process-only) — it gets its own ProcessKind, mirroring the
|
|
18
|
+
* Wave-4 orchestrationEngine-dep precedent.
|
|
19
|
+
*/
|
|
20
|
+
export declare function adaptCodeIndex(service: CodeIndexProcessSource, now: number): ProcessNode;
|
|
21
|
+
//# sourceMappingURL=code-index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"code-index.d.ts","sourceRoot":"","sources":["../../../../../src/platform/runtime/fleet/adapters/code-index.ts"],"names":[],"mappings":"AAAA,qFAAqF;AAErF,OAAO,KAAK,EAAE,sBAAsB,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AACjG,OAAO,KAAK,EAAE,WAAW,EAAgB,MAAM,aAAa,CAAC;AAE7D,yHAAyH;AACzH,MAAM,WAAW,sBAAsB;IACrC,UAAU,IAAI,OAAO,CAAC;IACtB,aAAa,IAAI,sBAAsB,GAAG,IAAI,CAAC;IAC/C,cAAc,IAAI,MAAM,GAAG,IAAI,CAAC;IAChC,KAAK,IAAI,cAAc,CAAC;CACzB;AAED,wGAAwG;AACxG,wBAAgB,eAAe,IAAI,MAAM,CAExC;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,sBAAsB,EAAE,GAAG,EAAE,MAAM,GAAG,WAAW,CAkCxF"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/** SDK-owned platform module. This implementation is maintained in goodvibes-sdk. */
|
|
2
|
+
/** Single well-known id: one code index per working directory (no per-workspace fan-out in Stage A). */
|
|
3
|
+
export function codeIndexNodeId() {
|
|
4
|
+
return 'code-index:main';
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* CodeIndexStore → ProcessNode. Silent source (no bus emission, like
|
|
8
|
+
* background-process): liveness rides the registry tick. An index build has
|
|
9
|
+
* no pid, so it is NOT a 'background-process' node (ProcessManager is
|
|
10
|
+
* shell/OS-process-only) — it gets its own ProcessKind, mirroring the
|
|
11
|
+
* Wave-4 orchestrationEngine-dep precedent.
|
|
12
|
+
*/
|
|
13
|
+
export function adaptCodeIndex(service, now) {
|
|
14
|
+
const building = service.isBuilding();
|
|
15
|
+
const progress = service.buildProgress();
|
|
16
|
+
const startedAt = service.buildStartedAt();
|
|
17
|
+
const stats = service.stats();
|
|
18
|
+
const lastBuild = stats.lastBuild;
|
|
19
|
+
const state = building ? 'executing-tool' : lastBuild ? 'done' : 'idle';
|
|
20
|
+
const label = building
|
|
21
|
+
? progress
|
|
22
|
+
? `Code index: building ${progress.scanned}/${progress.total} files`
|
|
23
|
+
: 'Code index: building'
|
|
24
|
+
: lastBuild
|
|
25
|
+
? `Code index: ${stats.indexedFiles} files, ${stats.indexedChunks} chunks`
|
|
26
|
+
: 'Code index: idle';
|
|
27
|
+
return {
|
|
28
|
+
id: codeIndexNodeId(),
|
|
29
|
+
kind: 'code-index',
|
|
30
|
+
parentId: undefined,
|
|
31
|
+
label,
|
|
32
|
+
state,
|
|
33
|
+
startedAt: building ? (startedAt ?? undefined) : (lastBuild?.startedAt ?? undefined),
|
|
34
|
+
completedAt: building ? undefined : (lastBuild?.completedAt ?? undefined),
|
|
35
|
+
elapsedMs: building ? Math.max(0, now - (startedAt ?? now)) : Math.max(0, lastBuild?.durationMs ?? 0),
|
|
36
|
+
costUsd: null,
|
|
37
|
+
costState: 'unpriced',
|
|
38
|
+
currentActivity: building
|
|
39
|
+
? { kind: 'phase', text: progress ? `Indexing ${progress.scanned}/${progress.total}` : 'Indexing', at: now }
|
|
40
|
+
: undefined,
|
|
41
|
+
capabilities: { interruptible: false, killable: false, pausable: false, resumable: false, steerable: false },
|
|
42
|
+
raw: stats,
|
|
43
|
+
};
|
|
44
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/** SDK-owned platform module. This implementation is maintained in goodvibes-sdk. */
|
|
2
|
+
/**
|
|
3
|
+
* Orchestration-engine fleet adapters (Wave 4, wo701) — Workstream/Phase/
|
|
4
|
+
* WorkItem -> ProcessNode, mirroring adapters/wrfc.ts's chain/subtask
|
|
5
|
+
* pattern: a workstream is a root node (no native cancel of its own, so kill
|
|
6
|
+
* is DERIVED — cascades AgentManager.cancel over every agent any item ever
|
|
7
|
+
* spawned, same shape as adaptChain/cancelAgents), a phase is a pure grouping
|
|
8
|
+
* node (no lifecycle, no usage — same "report nothing" choice adaptSubtask
|
|
9
|
+
* makes, since attributing a work-item's CUMULATIVE usage to whichever phase
|
|
10
|
+
* it currently sits in would double-count across phases), and a work-item is
|
|
11
|
+
* the WRFC-subtask analogue: it delegates interrupt/kill/steer to its
|
|
12
|
+
* current live agent when it has one.
|
|
13
|
+
*/
|
|
14
|
+
import type { Phase, WorkItem, Workstream } from '../../../orchestration/types.js';
|
|
15
|
+
import type { ProcessNode } from '../types.js';
|
|
16
|
+
import { workItemNodeId } from './agent.js';
|
|
17
|
+
/** Workstream node ids are namespaced to avoid colliding with agent/process ids. */
|
|
18
|
+
export declare function workstreamNodeId(workstreamId: string): string;
|
|
19
|
+
/**
|
|
20
|
+
* Phase node ids are namespaced by their owning workstream — phase ids are
|
|
21
|
+
* only unique WITHIN a workstream, so two workstreams' phases must not
|
|
22
|
+
* collide in the flat node list.
|
|
23
|
+
*/
|
|
24
|
+
export declare function phaseNodeId(workstreamId: string, phaseId: string): string;
|
|
25
|
+
export { workItemNodeId };
|
|
26
|
+
/** The work-item's currently-active agent, i.e. the one driving its live phase run. Undefined once terminal or between phases. */
|
|
27
|
+
export declare function activeWorkItemAgentId(item: WorkItem): string | undefined;
|
|
28
|
+
/** WorkItem -> ProcessNode. Delegates interruptible/killable/steerable to its currently-active agent, mirroring adaptSubtask. */
|
|
29
|
+
export declare function adaptWorkItem(item: WorkItem, workstreamId: string, parentId: string, opts: {
|
|
30
|
+
steerable: boolean;
|
|
31
|
+
}): ProcessNode;
|
|
32
|
+
/**
|
|
33
|
+
* Phase -> ProcessNode. Deliberately reports NO usage/cost (mirrors
|
|
34
|
+
* adaptSubtask's "report nothing" choice): a work-item's usage is cumulative
|
|
35
|
+
* across every phase it has visited, so attributing it to whichever phase it
|
|
36
|
+
* currently occupies would double-count against both the phase and the
|
|
37
|
+
* workstream total. Real numbers live on the workstream (sums every item
|
|
38
|
+
* exactly once) and the work-item (its own direct total) — never on phase.
|
|
39
|
+
*/
|
|
40
|
+
export declare function adaptPhase(phase: Phase, workstream: Workstream): ProcessNode;
|
|
41
|
+
/**
|
|
42
|
+
* Workstream -> ProcessNode. Root node (no parentId). Sums every item's
|
|
43
|
+
* usage/cost exactly once (never through an intermediate phase bucket — see
|
|
44
|
+
* adaptPhase) so this total can never double-count.
|
|
45
|
+
*/
|
|
46
|
+
export declare function adaptWorkstream(workstream: Workstream, now: number): ProcessNode;
|
|
47
|
+
//# sourceMappingURL=orchestration.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"orchestration.d.ts","sourceRoot":"","sources":["../../../../../src/platform/runtime/fleet/adapters/orchestration.ts"],"names":[],"mappings":"AAAA,qFAAqF;AAErF;;;;;;;;;;;GAWG;AACH,OAAO,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AACnF,OAAO,KAAK,EAAE,WAAW,EAA8B,MAAM,aAAa,CAAC;AAC3E,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAE5C,oFAAoF;AACpF,wBAAgB,gBAAgB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAE7D;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,YAAY,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAEzE;AAED,OAAO,EAAE,cAAc,EAAE,CAAC;AAI1B,kIAAkI;AAClI,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,QAAQ,GAAG,MAAM,GAAG,SAAS,CAExE;AA6FD,iIAAiI;AACjI,wBAAgB,aAAa,CAAC,IAAI,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE;IAAE,SAAS,EAAE,OAAO,CAAA;CAAE,GAAG,WAAW,CA6C/H;AAED;;;;;;;GAOG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,UAAU,GAAG,WAAW,CAuB5E;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,UAAU,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,GAAG,WAAW,CA+BhF"}
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
/** SDK-owned platform module. This implementation is maintained in goodvibes-sdk. */
|
|
2
|
+
import { workItemNodeId } from './agent.js';
|
|
3
|
+
/** Workstream node ids are namespaced to avoid colliding with agent/process ids. */
|
|
4
|
+
export function workstreamNodeId(workstreamId) {
|
|
5
|
+
return `workstream:${workstreamId}`;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Phase node ids are namespaced by their owning workstream — phase ids are
|
|
9
|
+
* only unique WITHIN a workstream, so two workstreams' phases must not
|
|
10
|
+
* collide in the flat node list.
|
|
11
|
+
*/
|
|
12
|
+
export function phaseNodeId(workstreamId, phaseId) {
|
|
13
|
+
return `phase:${workstreamId}:${phaseId}`;
|
|
14
|
+
}
|
|
15
|
+
export { workItemNodeId };
|
|
16
|
+
const TERMINAL_ITEM_STATES = new Set(['passed', 'failed']);
|
|
17
|
+
/** The work-item's currently-active agent, i.e. the one driving its live phase run. Undefined once terminal or between phases. */
|
|
18
|
+
export function activeWorkItemAgentId(item) {
|
|
19
|
+
return item.state === 'in-phase' ? item.agentId : undefined;
|
|
20
|
+
}
|
|
21
|
+
function workItemState(item) {
|
|
22
|
+
switch (item.state) {
|
|
23
|
+
case 'passed':
|
|
24
|
+
return 'done';
|
|
25
|
+
case 'failed':
|
|
26
|
+
return 'failed';
|
|
27
|
+
case 'pending':
|
|
28
|
+
case 'awaiting-capacity':
|
|
29
|
+
return 'queued';
|
|
30
|
+
case 'blocked-budget':
|
|
31
|
+
// Honest "stuck, not progressing" signal reusing an existing state
|
|
32
|
+
// rather than adding a new one (charter: prefer existing-contract
|
|
33
|
+
// reuse). Distinct from 'queued': a queued item WILL be claimed by
|
|
34
|
+
// free capacity; a blocked-budget item will not until its workstream's
|
|
35
|
+
// ceiling rises (or is cleared) via OrchestrationEngine.updateBudget —
|
|
36
|
+
// computeClaims (scheduler.ts) keeps it in the waiting set so that
|
|
37
|
+
// reconsideration is automatic the instant the ceiling changes, but a
|
|
38
|
+
// fixed ceiling on its own never lifts the block (usage only grows).
|
|
39
|
+
return 'stalled';
|
|
40
|
+
case 'in-phase':
|
|
41
|
+
return 'executing-tool';
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
function workstreamState(workstream) {
|
|
45
|
+
if (workstream.items.length === 0)
|
|
46
|
+
return 'idle';
|
|
47
|
+
if (workstream.items.some((item) => item.state === 'in-phase'))
|
|
48
|
+
return 'executing-tool';
|
|
49
|
+
if (workstream.items.some((item) => item.state === 'pending' || item.state === 'awaiting-capacity'))
|
|
50
|
+
return 'queued';
|
|
51
|
+
if (workstream.items.some((item) => item.state === 'blocked-budget'))
|
|
52
|
+
return 'stalled';
|
|
53
|
+
return workstream.items.some((item) => item.state === 'failed') ? 'failed' : 'done';
|
|
54
|
+
}
|
|
55
|
+
function phaseState(workstream, phase) {
|
|
56
|
+
const occupants = workstream.items.filter((item) => item.currentPhaseId === phase.id && item.state === 'in-phase');
|
|
57
|
+
if (occupants.length > 0)
|
|
58
|
+
return 'executing-tool';
|
|
59
|
+
const everVisited = workstream.items.some((item) => (item.visits.get(phase.id) ?? 0) > 0);
|
|
60
|
+
if (!everVisited)
|
|
61
|
+
return 'idle';
|
|
62
|
+
const allTerminal = workstream.items.every((item) => TERMINAL_ITEM_STATES.has(item.state));
|
|
63
|
+
return allTerminal ? 'done' : 'idle';
|
|
64
|
+
}
|
|
65
|
+
/** token-count-only rollup over a workstream's items (cost handled separately — see aggregateWorkItemCost). */
|
|
66
|
+
function sumWorkItemUsage(items) {
|
|
67
|
+
if (items.length === 0)
|
|
68
|
+
return undefined;
|
|
69
|
+
const total = {
|
|
70
|
+
inputTokens: 0,
|
|
71
|
+
outputTokens: 0,
|
|
72
|
+
cacheReadTokens: 0,
|
|
73
|
+
cacheWriteTokens: 0,
|
|
74
|
+
reasoningTokens: 0,
|
|
75
|
+
llmCallCount: 0,
|
|
76
|
+
turnCount: 0,
|
|
77
|
+
toolCallCount: 0,
|
|
78
|
+
};
|
|
79
|
+
let sawReasoning = false;
|
|
80
|
+
for (const item of items) {
|
|
81
|
+
const usage = item.usage;
|
|
82
|
+
total.inputTokens += usage.inputTokens;
|
|
83
|
+
total.outputTokens += usage.outputTokens;
|
|
84
|
+
total.cacheReadTokens += usage.cacheReadTokens;
|
|
85
|
+
total.cacheWriteTokens += usage.cacheWriteTokens;
|
|
86
|
+
if (usage.reasoningTokens !== undefined) {
|
|
87
|
+
sawReasoning = true;
|
|
88
|
+
total.reasoningTokens += usage.reasoningTokens;
|
|
89
|
+
}
|
|
90
|
+
total.llmCallCount += usage.llmCallCount;
|
|
91
|
+
total.turnCount += usage.turnCount;
|
|
92
|
+
total.toolCallCount += usage.toolCallCount;
|
|
93
|
+
}
|
|
94
|
+
return {
|
|
95
|
+
inputTokens: total.inputTokens,
|
|
96
|
+
outputTokens: total.outputTokens,
|
|
97
|
+
cacheReadTokens: total.cacheReadTokens,
|
|
98
|
+
cacheWriteTokens: total.cacheWriteTokens,
|
|
99
|
+
reasoningTokens: sawReasoning ? total.reasoningTokens : undefined,
|
|
100
|
+
llmCallCount: total.llmCallCount,
|
|
101
|
+
turnCount: total.turnCount,
|
|
102
|
+
toolCallCount: total.toolCallCount,
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
/** Honest cost rollup: all-priced -> 'priced'; none -> null/'unpriced'; mixed -> summed subset, 'estimated'. Mirrors adapters/wrfc.ts aggregateCost. */
|
|
106
|
+
function aggregateWorkItemCost(items) {
|
|
107
|
+
const withUsage = items.filter((item) => item.usage.costState !== 'unpriced' || item.usage.inputTokens > 0 || item.usage.outputTokens > 0);
|
|
108
|
+
if (withUsage.length === 0)
|
|
109
|
+
return { costUsd: null, costState: 'unpriced' };
|
|
110
|
+
const priced = withUsage.filter((item) => item.usage.costState === 'priced' && item.usage.costUsd !== null);
|
|
111
|
+
if (priced.length === 0)
|
|
112
|
+
return { costUsd: null, costState: 'unpriced' };
|
|
113
|
+
const total = priced.reduce((sum, item) => sum + item.usage.costUsd, 0);
|
|
114
|
+
return { costUsd: total, costState: priced.length === withUsage.length ? 'priced' : 'estimated' };
|
|
115
|
+
}
|
|
116
|
+
/** WorkItem -> ProcessNode. Delegates interruptible/killable/steerable to its currently-active agent, mirroring adaptSubtask. */
|
|
117
|
+
export function adaptWorkItem(item, workstreamId, parentId, opts) {
|
|
118
|
+
const state = workItemState(item);
|
|
119
|
+
const killable = !TERMINAL_ITEM_STATES.has(item.state);
|
|
120
|
+
const activeAgentId = activeWorkItemAgentId(item);
|
|
121
|
+
return {
|
|
122
|
+
id: workItemNodeId(item.id),
|
|
123
|
+
kind: 'work-item',
|
|
124
|
+
parentId,
|
|
125
|
+
label: item.title,
|
|
126
|
+
task: item.task,
|
|
127
|
+
state,
|
|
128
|
+
startedAt: item.createdAt,
|
|
129
|
+
completedAt: item.completedAt,
|
|
130
|
+
elapsedMs: Math.max(0, (item.completedAt ?? Date.now()) - item.createdAt),
|
|
131
|
+
usage: item.usage.inputTokens > 0 || item.usage.outputTokens > 0
|
|
132
|
+
? {
|
|
133
|
+
inputTokens: item.usage.inputTokens,
|
|
134
|
+
outputTokens: item.usage.outputTokens,
|
|
135
|
+
cacheReadTokens: item.usage.cacheReadTokens,
|
|
136
|
+
cacheWriteTokens: item.usage.cacheWriteTokens,
|
|
137
|
+
reasoningTokens: item.usage.reasoningTokens,
|
|
138
|
+
llmCallCount: item.usage.llmCallCount,
|
|
139
|
+
turnCount: item.usage.turnCount,
|
|
140
|
+
toolCallCount: item.usage.toolCallCount,
|
|
141
|
+
}
|
|
142
|
+
: undefined,
|
|
143
|
+
costUsd: item.usage.costUsd,
|
|
144
|
+
costState: item.usage.costState,
|
|
145
|
+
// Blocked-budget items surface their reason (set/cleared by the engine
|
|
146
|
+
// alongside the state transition, types.ts WorkItem.blockedReason) in
|
|
147
|
+
// place of the bare phase id — the phase id alone doesn't tell an
|
|
148
|
+
// operator WHY the item stopped moving.
|
|
149
|
+
currentActivity: item.currentPhaseId
|
|
150
|
+
? { kind: 'phase', text: item.state === 'blocked-budget' && item.blockedReason ? item.blockedReason : item.currentPhaseId, at: item.createdAt }
|
|
151
|
+
: undefined,
|
|
152
|
+
capabilities: {
|
|
153
|
+
interruptible: activeAgentId !== undefined,
|
|
154
|
+
killable,
|
|
155
|
+
pausable: false,
|
|
156
|
+
resumable: false,
|
|
157
|
+
steerable: activeAgentId !== undefined && opts.steerable,
|
|
158
|
+
},
|
|
159
|
+
sessionRef: activeAgentId ? { agentId: activeAgentId } : undefined,
|
|
160
|
+
raw: { item, workstreamId },
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Phase -> ProcessNode. Deliberately reports NO usage/cost (mirrors
|
|
165
|
+
* adaptSubtask's "report nothing" choice): a work-item's usage is cumulative
|
|
166
|
+
* across every phase it has visited, so attributing it to whichever phase it
|
|
167
|
+
* currently occupies would double-count against both the phase and the
|
|
168
|
+
* workstream total. Real numbers live on the workstream (sums every item
|
|
169
|
+
* exactly once) and the work-item (its own direct total) — never on phase.
|
|
170
|
+
*/
|
|
171
|
+
export function adaptPhase(phase, workstream) {
|
|
172
|
+
const state = phaseState(workstream, phase);
|
|
173
|
+
return {
|
|
174
|
+
id: phaseNodeId(workstream.id, phase.id),
|
|
175
|
+
kind: 'phase',
|
|
176
|
+
parentId: workstreamNodeId(workstream.id),
|
|
177
|
+
label: `${phase.kind} (${phase.role})`,
|
|
178
|
+
state,
|
|
179
|
+
startedAt: workstream.createdAt,
|
|
180
|
+
completedAt: state === 'done' ? workstream.items.reduce((latest, item) => (item.completedAt !== undefined && (latest === undefined || item.completedAt > latest) ? item.completedAt : latest), undefined) : undefined,
|
|
181
|
+
elapsedMs: 0,
|
|
182
|
+
usage: undefined,
|
|
183
|
+
costUsd: null,
|
|
184
|
+
costState: 'unpriced',
|
|
185
|
+
currentActivity: undefined,
|
|
186
|
+
// Pure grouping node: no conversation loop, no native single-phase
|
|
187
|
+
// cancel (killing work belongs to the work-items running IN the phase).
|
|
188
|
+
capabilities: { interruptible: false, killable: false, pausable: false, resumable: false, steerable: false },
|
|
189
|
+
raw: phase,
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Workstream -> ProcessNode. Root node (no parentId). Sums every item's
|
|
194
|
+
* usage/cost exactly once (never through an intermediate phase bucket — see
|
|
195
|
+
* adaptPhase) so this total can never double-count.
|
|
196
|
+
*/
|
|
197
|
+
export function adaptWorkstream(workstream, now) {
|
|
198
|
+
const state = workstreamState(workstream);
|
|
199
|
+
const killable = state !== 'done' && state !== 'failed';
|
|
200
|
+
const completedAt = (state === 'done' || state === 'failed')
|
|
201
|
+
? workstream.items.reduce((latest, item) => (item.completedAt !== undefined && (latest === undefined || item.completedAt > latest) ? item.completedAt : latest), undefined)
|
|
202
|
+
: undefined;
|
|
203
|
+
const { costUsd, costState } = aggregateWorkItemCost(workstream.items);
|
|
204
|
+
return {
|
|
205
|
+
id: workstreamNodeId(workstream.id),
|
|
206
|
+
kind: 'workstream',
|
|
207
|
+
parentId: undefined,
|
|
208
|
+
label: workstream.title,
|
|
209
|
+
state,
|
|
210
|
+
startedAt: workstream.createdAt,
|
|
211
|
+
completedAt,
|
|
212
|
+
elapsedMs: Math.max(0, (completedAt ?? now) - workstream.createdAt),
|
|
213
|
+
usage: sumWorkItemUsage(workstream.items),
|
|
214
|
+
costUsd,
|
|
215
|
+
costState,
|
|
216
|
+
currentActivity: undefined,
|
|
217
|
+
// A workstream is an FSM coordinating work-items, not itself a
|
|
218
|
+
// conversation loop — steer a work-item instead (mirrors wrfc-chain).
|
|
219
|
+
// Kill is DERIVED (no native single-call cancel): cascades
|
|
220
|
+
// AgentManager.cancel over every agent any item ever spawned — see
|
|
221
|
+
// registry.ts killNode's 'workstream' case.
|
|
222
|
+
capabilities: { interruptible: false, killable, pausable: false, resumable: false, steerable: false },
|
|
223
|
+
raw: workstream,
|
|
224
|
+
};
|
|
225
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/** SDK-owned platform module. This implementation is maintained in goodvibes-sdk. */
|
|
2
|
+
import type { ScheduleEntry } from '../../../tools/workflow/index.js';
|
|
3
|
+
import type { ProcessNode } from '../types.js';
|
|
4
|
+
/** Schedule node ids are namespaced: entries are keyed by user-chosen names. */
|
|
5
|
+
export declare function scheduleNodeId(name: string): string;
|
|
6
|
+
/**
|
|
7
|
+
* ScheduleEntry → ProcessNode. A schedule between runs is honestly 'idle'
|
|
8
|
+
* (not force-fit into an active state); disabled maps to 'paused' (Wave 6,
|
|
9
|
+
* wo-F item d2 — NOT 'killed': the entry still exists and ScheduleManager.
|
|
10
|
+
* enable() can re-arm it, so collapsing it into a terminal state was
|
|
11
|
+
* dishonest). resumable mirrors the inverse of pausable.
|
|
12
|
+
*/
|
|
13
|
+
export declare function adaptSchedule(entry: ScheduleEntry): ProcessNode;
|
|
14
|
+
//# sourceMappingURL=schedule.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schedule.d.ts","sourceRoot":"","sources":["../../../../../src/platform/runtime/fleet/adapters/schedule.ts"],"names":[],"mappings":"AAAA,qFAAqF;AAErF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kCAAkC,CAAC;AACtE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C,gFAAgF;AAChF,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEnD;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,aAAa,GAAG,WAAW,CAe/D"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/** SDK-owned platform module. This implementation is maintained in goodvibes-sdk. */
|
|
2
|
+
/** Schedule node ids are namespaced: entries are keyed by user-chosen names. */
|
|
3
|
+
export function scheduleNodeId(name) {
|
|
4
|
+
return `schedule:${name}`;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* ScheduleEntry → ProcessNode. A schedule between runs is honestly 'idle'
|
|
8
|
+
* (not force-fit into an active state); disabled maps to 'paused' (Wave 6,
|
|
9
|
+
* wo-F item d2 — NOT 'killed': the entry still exists and ScheduleManager.
|
|
10
|
+
* enable() can re-arm it, so collapsing it into a terminal state was
|
|
11
|
+
* dishonest). resumable mirrors the inverse of pausable.
|
|
12
|
+
*/
|
|
13
|
+
export function adaptSchedule(entry) {
|
|
14
|
+
return {
|
|
15
|
+
id: scheduleNodeId(entry.name),
|
|
16
|
+
kind: 'schedule',
|
|
17
|
+
parentId: undefined,
|
|
18
|
+
label: `${entry.name} (${entry.interval})`,
|
|
19
|
+
task: entry.command,
|
|
20
|
+
state: entry.enabled ? 'idle' : 'paused',
|
|
21
|
+
startedAt: entry.lastRun,
|
|
22
|
+
elapsedMs: 0,
|
|
23
|
+
costUsd: null,
|
|
24
|
+
costState: 'unpriced',
|
|
25
|
+
capabilities: { interruptible: false, killable: true, pausable: entry.enabled, resumable: !entry.enabled, steerable: false },
|
|
26
|
+
raw: entry,
|
|
27
|
+
};
|
|
28
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/** SDK-owned platform module. This implementation is maintained in goodvibes-sdk. */
|
|
2
|
+
import type { TriggerDefinition } from '../../../tools/workflow/index.js';
|
|
3
|
+
import type { ProcessNode } from '../types.js';
|
|
4
|
+
/**
|
|
5
|
+
* TriggerDefinition → ProcessNode. Triggers have no timestamps and no run
|
|
6
|
+
* state — enabled means armed ('idle'), disabled maps to 'paused' (Wave 6,
|
|
7
|
+
* wo-F item d2 — NOT 'killed': the definition still exists and
|
|
8
|
+
* TriggerManager.enable() can re-arm it). resumable mirrors the inverse of
|
|
9
|
+
* pausable.
|
|
10
|
+
*/
|
|
11
|
+
export declare function adaptTrigger(def: TriggerDefinition): ProcessNode;
|
|
12
|
+
//# sourceMappingURL=trigger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trigger.d.ts","sourceRoot":"","sources":["../../../../../src/platform/runtime/fleet/adapters/trigger.ts"],"names":[],"mappings":"AAAA,qFAAqF;AAErF,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;AAC1E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,iBAAiB,GAAG,WAAW,CAahE"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/** SDK-owned platform module. This implementation is maintained in goodvibes-sdk. */
|
|
2
|
+
/**
|
|
3
|
+
* TriggerDefinition → ProcessNode. Triggers have no timestamps and no run
|
|
4
|
+
* state — enabled means armed ('idle'), disabled maps to 'paused' (Wave 6,
|
|
5
|
+
* wo-F item d2 — NOT 'killed': the definition still exists and
|
|
6
|
+
* TriggerManager.enable() can re-arm it). resumable mirrors the inverse of
|
|
7
|
+
* pausable.
|
|
8
|
+
*/
|
|
9
|
+
export function adaptTrigger(def) {
|
|
10
|
+
return {
|
|
11
|
+
id: def.id,
|
|
12
|
+
kind: 'trigger',
|
|
13
|
+
parentId: undefined,
|
|
14
|
+
label: `on ${def.event} → ${def.action}`,
|
|
15
|
+
state: def.enabled ? 'idle' : 'paused',
|
|
16
|
+
elapsedMs: 0,
|
|
17
|
+
costUsd: null,
|
|
18
|
+
costState: 'unpriced',
|
|
19
|
+
capabilities: { interruptible: false, killable: true, pausable: def.enabled, resumable: !def.enabled, steerable: false },
|
|
20
|
+
raw: def,
|
|
21
|
+
};
|
|
22
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/** SDK-owned platform module. This implementation is maintained in goodvibes-sdk. */
|
|
2
|
+
import type { WatcherRecord } from '../../store/domains/watchers.js';
|
|
3
|
+
import type { ProcessNode } from '../types.js';
|
|
4
|
+
/**
|
|
5
|
+
* WatcherRecord → ProcessNode. WatcherRegistry.list() already normalizes each
|
|
6
|
+
* record through its sourceStatusFor derivation (healthy/lagging/stale/
|
|
7
|
+
* failed), so the mapping here reads the post-derivation state:
|
|
8
|
+
* running → 'idle' (alive, armed between checks), starting → 'queued',
|
|
9
|
+
* degraded → 'stalled' (heartbeat lagging/stale is the watcher-shaped stall),
|
|
10
|
+
* failed → 'failed', stopped → 'killed'.
|
|
11
|
+
*/
|
|
12
|
+
export declare function adaptWatcher(record: WatcherRecord, now: number): ProcessNode;
|
|
13
|
+
//# sourceMappingURL=watcher.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"watcher.d.ts","sourceRoot":"","sources":["../../../../../src/platform/runtime/fleet/adapters/watcher.ts"],"names":[],"mappings":"AAAA,qFAAqF;AAErF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AACrE,OAAO,KAAK,EAAE,WAAW,EAAgB,MAAM,aAAa,CAAC;AAE7D;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,aAAa,EAAE,GAAG,EAAE,MAAM,GAAG,WAAW,CAqC5E"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/** SDK-owned platform module. This implementation is maintained in goodvibes-sdk. */
|
|
2
|
+
/**
|
|
3
|
+
* WatcherRecord → ProcessNode. WatcherRegistry.list() already normalizes each
|
|
4
|
+
* record through its sourceStatusFor derivation (healthy/lagging/stale/
|
|
5
|
+
* failed), so the mapping here reads the post-derivation state:
|
|
6
|
+
* running → 'idle' (alive, armed between checks), starting → 'queued',
|
|
7
|
+
* degraded → 'stalled' (heartbeat lagging/stale is the watcher-shaped stall),
|
|
8
|
+
* failed → 'failed', stopped → 'killed'.
|
|
9
|
+
*/
|
|
10
|
+
export function adaptWatcher(record, now) {
|
|
11
|
+
let state;
|
|
12
|
+
switch (record.state) {
|
|
13
|
+
case 'running':
|
|
14
|
+
state = 'idle';
|
|
15
|
+
break;
|
|
16
|
+
case 'starting':
|
|
17
|
+
state = 'queued';
|
|
18
|
+
break;
|
|
19
|
+
case 'degraded':
|
|
20
|
+
state = 'stalled';
|
|
21
|
+
break;
|
|
22
|
+
case 'failed':
|
|
23
|
+
state = 'failed';
|
|
24
|
+
break;
|
|
25
|
+
case 'stopped':
|
|
26
|
+
state = 'killed';
|
|
27
|
+
break;
|
|
28
|
+
}
|
|
29
|
+
const alive = record.state === 'running' || record.state === 'starting' || record.state === 'degraded';
|
|
30
|
+
const statusText = record.degradedReason ?? record.sourceStatus;
|
|
31
|
+
return {
|
|
32
|
+
id: record.id,
|
|
33
|
+
kind: 'watcher',
|
|
34
|
+
parentId: undefined,
|
|
35
|
+
label: record.label,
|
|
36
|
+
state,
|
|
37
|
+
startedAt: record.source.createdAt,
|
|
38
|
+
elapsedMs: alive ? Math.max(0, now - record.source.createdAt) : 0,
|
|
39
|
+
costUsd: null,
|
|
40
|
+
costState: 'unpriced',
|
|
41
|
+
currentActivity: statusText
|
|
42
|
+
? { kind: 'phase', text: statusText, at: record.lastHeartbeatAt ?? record.source.createdAt }
|
|
43
|
+
: undefined,
|
|
44
|
+
capabilities: { interruptible: false, killable: alive, pausable: false, resumable: false, steerable: false },
|
|
45
|
+
raw: record,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/** SDK-owned platform module. This implementation is maintained in goodvibes-sdk. */
|
|
2
|
+
import type { WorkflowInstance } from '../../../tools/workflow/index.js';
|
|
3
|
+
import type { ProcessNode } from '../types.js';
|
|
4
|
+
/**
|
|
5
|
+
* WorkflowInstance → ProcessNode. Workflow FSMs are a SILENT source (no bus
|
|
6
|
+
* emission); their liveness rides the registry's coalesced tick, and the
|
|
7
|
+
* manager self-evicts completed entries (1 h TTL / 50 cap) so terminal nodes
|
|
8
|
+
* eventually disappear from the snapshot.
|
|
9
|
+
*/
|
|
10
|
+
export declare function adaptWorkflow(instance: WorkflowInstance, now: number): ProcessNode;
|
|
11
|
+
//# sourceMappingURL=workflow.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workflow.d.ts","sourceRoot":"","sources":["../../../../../src/platform/runtime/fleet/adapters/workflow.ts"],"names":[],"mappings":"AAAA,qFAAqF;AAErF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAC;AACzE,OAAO,KAAK,EAAE,WAAW,EAAgB,MAAM,aAAa,CAAC;AAE7D;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,gBAAgB,EAAE,GAAG,EAAE,MAAM,GAAG,WAAW,CAuBlF"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/** SDK-owned platform module. This implementation is maintained in goodvibes-sdk. */
|
|
2
|
+
/**
|
|
3
|
+
* WorkflowInstance → ProcessNode. Workflow FSMs are a SILENT source (no bus
|
|
4
|
+
* emission); their liveness rides the registry's coalesced tick, and the
|
|
5
|
+
* manager self-evicts completed entries (1 h TTL / 50 cap) so terminal nodes
|
|
6
|
+
* eventually disappear from the snapshot.
|
|
7
|
+
*/
|
|
8
|
+
export function adaptWorkflow(instance, now) {
|
|
9
|
+
let state;
|
|
10
|
+
if (instance.cancelled)
|
|
11
|
+
state = 'killed';
|
|
12
|
+
else if (instance.completedAt !== undefined)
|
|
13
|
+
state = 'done';
|
|
14
|
+
else
|
|
15
|
+
state = 'executing-tool';
|
|
16
|
+
const active = state === 'executing-tool';
|
|
17
|
+
return {
|
|
18
|
+
id: instance.id,
|
|
19
|
+
kind: 'workflow',
|
|
20
|
+
parentId: undefined,
|
|
21
|
+
label: instance.definition,
|
|
22
|
+
task: instance.task,
|
|
23
|
+
state,
|
|
24
|
+
startedAt: instance.startedAt,
|
|
25
|
+
completedAt: instance.completedAt,
|
|
26
|
+
elapsedMs: Math.max(0, (instance.completedAt ?? now) - instance.startedAt),
|
|
27
|
+
costUsd: null,
|
|
28
|
+
costState: 'unpriced',
|
|
29
|
+
// Silent source: anchored to startedAt (no state-transition timestamp).
|
|
30
|
+
currentActivity: active ? { kind: 'phase', text: instance.currentState, at: instance.startedAt } : undefined,
|
|
31
|
+
capabilities: { interruptible: false, killable: active, pausable: false, resumable: false, steerable: false },
|
|
32
|
+
raw: instance,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/** SDK-owned platform module. This implementation is maintained in goodvibes-sdk. */
|
|
2
|
+
import type { WrfcChain, WrfcSubtask } from '../../../agents/wrfc-types.js';
|
|
3
|
+
import type { ProcessNode } from '../types.js';
|
|
4
|
+
/**
|
|
5
|
+
* The subtask's currently-active member agent, i.e. whichever role is
|
|
6
|
+
* driving its current phase. Undefined when the subtask has no phase
|
|
7
|
+
* currently in flight (pending/passed/failed) — matches subtaskState()'s
|
|
8
|
+
* own phase mapping above.
|
|
9
|
+
*/
|
|
10
|
+
export declare function activeSubtaskMemberAgentId(subtask: WrfcSubtask): string | undefined;
|
|
11
|
+
/** WrfcSubtask → ProcessNode (child of its chain node). */
|
|
12
|
+
export declare function adaptSubtask(subtask: WrfcSubtask, chain: WrfcChain, opts: {
|
|
13
|
+
steerable: boolean;
|
|
14
|
+
}): ProcessNode;
|
|
15
|
+
/**
|
|
16
|
+
* WrfcChain → ProcessNode. `memberNodes` are the already-adapted agent nodes
|
|
17
|
+
* whose ids appear in chain.allAgentIds, EXCLUDING the owner agent (see
|
|
18
|
+
* aggregateCost). Chain nodes are roots (the owner agent hangs under the
|
|
19
|
+
* chain via its wrfcId edge, not the other way around).
|
|
20
|
+
*/
|
|
21
|
+
export declare function adaptChain(chain: WrfcChain, memberNodes: readonly ProcessNode[], now: number): ProcessNode;
|
|
22
|
+
//# sourceMappingURL=wrfc.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wrfc.d.ts","sourceRoot":"","sources":["../../../../../src/platform/runtime/fleet/adapters/wrfc.ts"],"names":[],"mappings":"AAAA,qFAAqF;AAErF,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AAC5E,OAAO,KAAK,EAAE,WAAW,EAA8B,MAAM,aAAa,CAAC;AAmJ3E;;;;;GAKG;AACH,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,WAAW,GAAG,MAAM,GAAG,SAAS,CAWnF;AAED,2DAA2D;AAC3D,wBAAgB,YAAY,CAAC,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE;IAAE,SAAS,EAAE,OAAO,CAAA;CAAE,GAAG,WAAW,CAwB9G;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,SAAS,WAAW,EAAE,EAAE,GAAG,EAAE,MAAM,GAAG,WAAW,CAgC1G"}
|