@agimon-ai/doompi-workflow 0.0.1-alpha.103 → 0.0.1-alpha.105
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +31 -8
- package/dist/extensions/pi.cjs +33 -20
- package/dist/extensions/pi.cjs.map +1 -1
- package/dist/extensions/pi.d.mts.map +1 -1
- package/dist/extensions/pi.mjs +33 -20
- package/dist/extensions/pi.mjs.map +1 -1
- package/dist/extensions/server.cjs +433 -33
- package/dist/extensions/server.cjs.map +1 -1
- package/dist/extensions/server.d.mts.map +1 -1
- package/dist/extensions/server.mjs +434 -34
- package/dist/extensions/server.mjs.map +1 -1
- package/dist/extensions/web.mjs +3234 -3251
- package/dist/extensions/web.mjs.map +1 -1
- package/dist/{workflowTerminal-Bm4iASfr.mjs → workflowTerminal-Cuc79Gog.mjs} +31 -2
- package/dist/workflowTerminal-Cuc79Gog.mjs.map +1 -0
- package/dist/{workflowTerminal-Dse-ahCB.cjs → workflowTerminal-DeJ9BBta.cjs} +72 -1
- package/dist/workflowTerminal-DeJ9BBta.cjs.map +1 -0
- package/package.json +5 -5
- package/src/types/webWorkflows.ts +4 -0
- package/dist/workflowTerminal-Bm4iASfr.mjs.map +0 -1
- package/dist/workflowTerminal-Dse-ahCB.cjs.map +0 -1
package/README.md
CHANGED
|
@@ -97,10 +97,31 @@ adopts the eligible failure, validates the evidence, and transfers ownership to
|
|
|
97
97
|
Live controls remain scoped to the owning session. Recovery does not launch a second copy beside a
|
|
98
98
|
still-running job and does not guarantee that parent-session work survives shutdown.
|
|
99
99
|
|
|
100
|
-
The package publishes `workflow-recovery` for
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
100
|
+
The package publishes `workflow-recovery`, `doompi-author-workflow` for writing workflow
|
|
101
|
+
definitions, and `doompi-use-workflow` for launching, monitoring, and recovering runs while Workflow
|
|
102
|
+
mode is active. Deactivating Workflow mode hides them; cached files may remain.
|
|
103
|
+
|
|
104
|
+
## Workflow sessions
|
|
105
|
+
|
|
106
|
+
In a server (web cockpit) session, a launch does not run in the session that asked for it. The
|
|
107
|
+
session creates a child **workflow session** (provenance `workflow-session`), nested under it in the
|
|
108
|
+
rail, and hands it the launch. The workflow session owns the run (`PI_SESSION_ID`), runs its step
|
|
109
|
+
sessions, and has Workflow mode on, so its agent can troubleshoot and recover the run. The run's
|
|
110
|
+
environment also carries `DOOMPI_WORKFLOW_LAUNCHER_SESSION_ID`, naming the launching session, which
|
|
111
|
+
lists the run in its Activity group, is told when it ends, and may read its status.
|
|
112
|
+
|
|
113
|
+
- The workflow session's rail row shows the run (`workflow · build › test · 4m`, or a failure or
|
|
114
|
+
pause marked like a pending question) through the host's per-session activity line.
|
|
115
|
+
- A failure or finish is posted into the workflow session's conversation as a notice, without
|
|
116
|
+
starting an agent turn. The owner agent also gets a live brief of its runs on every turn.
|
|
117
|
+
- After a success, a workflow session nobody interacted with asks its launcher to release it, and it
|
|
118
|
+
becomes `stopped · open to wake`. A session whose run failed or paused, or whose agent you
|
|
119
|
+
prompted, stays live until you remove it. Removing or restarting a live workflow session stops its
|
|
120
|
+
run.
|
|
121
|
+
- Recovery is refused from any session other than the owner while the owner is live.
|
|
122
|
+
|
|
123
|
+
Launches from inside a workflow session, and launches in hosts without a session service (the TUI
|
|
124
|
+
and CLI), run in place as before.
|
|
104
125
|
|
|
105
126
|
Each Pi extension instance uses the runner's shared Doom lifecycle. Reload or shutdown stops retained
|
|
106
127
|
callbacks, interrupts bounded inline work, removes UI and service registrations, and releases
|
|
@@ -126,10 +147,12 @@ Maintained by [Agimon](https://agimon.ai/about).
|
|
|
126
147
|
## Web cockpit plugin
|
|
127
148
|
|
|
128
149
|
The `.web` routed files under `src/extensions/workspaces/sessions/(frontend)` are this package's
|
|
129
|
-
DoomPi web cockpit plugin: the
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
stores and
|
|
150
|
+
DoomPi web cockpit plugin: the `workflow` dock face beside Activity and Context (the owned run's
|
|
151
|
+
jobs, active steps and artifacts, each opening its own tab), the workflow catalog and launch
|
|
152
|
+
dialog in the overlay slot, the Activity group's run rows (a handed-off run opens its workflow
|
|
153
|
+
session), their stores, and the `workflow_runs` session channel, compiled into the cockpit bundle
|
|
154
|
+
by `doompi-web`'s build. Each surface keeps its components in a colocated `_components` folder and
|
|
155
|
+
its stores and helpers in `_lib`.
|
|
133
156
|
The hub-side data source ships behind the `./web-hub` subpath and reads the workflow registry
|
|
134
157
|
(run.json plus progress.ndjson) exactly as the engine writes it. Both halves are declared by the
|
|
135
158
|
`doompiWeb` block in package.json.
|
package/dist/extensions/pi.cjs
CHANGED
|
@@ -2,7 +2,7 @@ Object.defineProperties(exports, {
|
|
|
2
2
|
__esModule: { value: true },
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
|
-
const require_workflowTerminal = require("../workflowTerminal-
|
|
5
|
+
const require_workflowTerminal = require("../workflowTerminal-DeJ9BBta.cjs");
|
|
6
6
|
const require_workflowLaunchCommand = require("../workflowLaunchCommand-DJyDB96d.cjs");
|
|
7
7
|
let _agimon_ai_doompi_core_piExtension = require("@agimon-ai/doompi-core/piExtension");
|
|
8
8
|
let _agimon_ai_doompi_core_extensionFile = require("@agimon-ai/doompi-core/extensionFile");
|
|
@@ -3462,12 +3462,13 @@ function createWorkflowPiRuntime(pi, options) {
|
|
|
3462
3462
|
if (!refreshIsCurrent()) return;
|
|
3463
3463
|
const sessionId = (0, _agimon_ai_doompi_core_childProcess.resolveRootSessionId)(ctx.sessionManager.getSessionId(), options.environment);
|
|
3464
3464
|
const rootProcess = isRootProcess(ctx, sessionId);
|
|
3465
|
-
const
|
|
3466
|
-
const
|
|
3467
|
-
const
|
|
3465
|
+
const ownRecords = records.filter((record) => require_workflowTerminal.isSessionRun(record, sessionId));
|
|
3466
|
+
const sessionRecords = records.filter((record) => require_workflowTerminal.isSessionRun(record, sessionId) || require_workflowTerminal.isLaunchedRun(record, sessionId));
|
|
3467
|
+
const running = ownRecords.filter((record) => record.stage === RUNNING_STATUS && !record.stale);
|
|
3468
|
+
const failed = ownRecords.filter((record) => record.stage === ERROR_STAGE);
|
|
3468
3469
|
if (activeRevisionAtRead === activeRunRevision) replaceActiveRecords(running);
|
|
3469
3470
|
activeTelemetry.recordEvent("doom_workflow.monitor_counts", {
|
|
3470
|
-
"workflow.run_count":
|
|
3471
|
+
"workflow.run_count": ownRecords.length,
|
|
3471
3472
|
"workflow.running_count": running.length,
|
|
3472
3473
|
"workflow.failed_count": failed.length,
|
|
3473
3474
|
mode: workflowMode ? "on" : "off"
|
|
@@ -3482,11 +3483,12 @@ function createWorkflowPiRuntime(pi, options) {
|
|
|
3482
3483
|
const previous = previousStages.get(identity);
|
|
3483
3484
|
const startedAt = Date.parse(record.startedAt);
|
|
3484
3485
|
const startedDuringSession = previous === void 0 && (sessionStartedAt === 0 || !Number.isFinite(startedAt) || startedAt >= sessionStartedAt);
|
|
3485
|
-
if (lifecycleNarrationReady) narrateWorkflowTransition(narrationSink, record, previous === RUNNING_STATUS || previous === COMPLETED_STATUS || previous === ERROR_STAGE ? previous : void 0, startedDuringSession);
|
|
3486
|
+
if (lifecycleNarrationReady && require_workflowTerminal.isSessionRun(record, sessionId)) narrateWorkflowTransition(narrationSink, record, previous === RUNNING_STATUS || previous === COMPLETED_STATUS || previous === ERROR_STAGE ? previous : void 0, startedDuringSession);
|
|
3486
3487
|
if (!notifyChanges || !rootProcess || record.stage === RUNNING_STATUS) continue;
|
|
3487
3488
|
if (!deliveredTerminalRuns.has(identity) && (previous === RUNNING_STATUS || startedDuringSession)) pendingTerminalRuns.set(identity, record);
|
|
3488
3489
|
}
|
|
3489
3490
|
const retainedWork = new Map(mine.map((record) => [runIdentity(record), record]));
|
|
3491
|
+
for (const record of sessionRecords) if (require_workflowTerminal.isLaunchedRun(record, sessionId) && record.stage === RUNNING_STATUS && !record.stale) retainedWork.set(runIdentity(record), record);
|
|
3490
3492
|
for (const [identity, record] of pendingTerminalRuns) retainedWork.set(identity, record);
|
|
3491
3493
|
if (!refreshIsCurrent()) return;
|
|
3492
3494
|
runProvider?.update([...retainedWork.values()].map((record) => ({
|
|
@@ -3505,28 +3507,39 @@ function createWorkflowPiRuntime(pi, options) {
|
|
|
3505
3507
|
if (rootProcess && pendingTerminalRuns.size > 0) try {
|
|
3506
3508
|
const terminalRecords = [...pendingTerminalRuns.values()];
|
|
3507
3509
|
const summaries = await Promise.all(terminalRecords.map(async (record) => {
|
|
3508
|
-
if (record.stage === COMPLETED_STATUS)
|
|
3510
|
+
if (record.stage === COMPLETED_STATUS) {
|
|
3511
|
+
const summary = require_workflowTerminal.finishedRunSummary(record, []);
|
|
3512
|
+
return require_workflowTerminal.isLaunchedRun(record, sessionId) ? `${summary}\n${require_workflowTerminal.launchedRunHint(record)}` : summary;
|
|
3513
|
+
}
|
|
3509
3514
|
const identity = runIdentity(record);
|
|
3510
3515
|
const events = runEvents.get(identity) ?? progressEventsForRun(record, await (0, _agimon_ai_workflow_mcp.readWorkflowProgress)(registry.runDirectoryFor(record)));
|
|
3511
|
-
|
|
3516
|
+
const summary = require_workflowTerminal.finishedRunSummary(record, (0, _agimon_ai_workflow_mcp.summarizeWorkflowProgress)(events));
|
|
3517
|
+
return require_workflowTerminal.isLaunchedRun(record, sessionId) ? `${summary}\n${require_workflowTerminal.launchedRunHint(record)}` : summary;
|
|
3512
3518
|
}));
|
|
3513
3519
|
if (!refreshIsCurrent()) return;
|
|
3514
|
-
|
|
3520
|
+
const message = (indexes) => ({
|
|
3515
3521
|
customType: WORKFLOW_FINISHED_MESSAGE$1,
|
|
3516
|
-
content: summaries.join("\n\n"),
|
|
3522
|
+
content: indexes.map((index) => summaries[index]).join("\n\n"),
|
|
3517
3523
|
display: true,
|
|
3518
3524
|
details: {
|
|
3519
|
-
runIds:
|
|
3520
|
-
runs:
|
|
3521
|
-
|
|
3522
|
-
|
|
3523
|
-
|
|
3524
|
-
|
|
3525
|
-
|
|
3526
|
-
|
|
3527
|
-
|
|
3525
|
+
runIds: indexes.map((index) => terminalRecords[index].runId ?? runIdentity(terminalRecords[index])),
|
|
3526
|
+
runs: indexes.map((index) => {
|
|
3527
|
+
const record = terminalRecords[index];
|
|
3528
|
+
return {
|
|
3529
|
+
runKey: record.runKey,
|
|
3530
|
+
workspace: record.workspace,
|
|
3531
|
+
stage: record.stage,
|
|
3532
|
+
...record.workflowId ? { workflowId: record.workflowId } : {},
|
|
3533
|
+
...record.failedJob ? { failedJob: record.failedJob } : {},
|
|
3534
|
+
...record.errorMessage ? { error: record.errorMessage } : {}
|
|
3535
|
+
};
|
|
3536
|
+
})
|
|
3528
3537
|
}
|
|
3529
|
-
}
|
|
3538
|
+
});
|
|
3539
|
+
const quiet = terminalRecords.flatMap((record, index) => require_workflowTerminal.isOwnedDelegatedRun(record, sessionId) ? [index] : []);
|
|
3540
|
+
const loud = terminalRecords.flatMap((record, index) => require_workflowTerminal.isOwnedDelegatedRun(record, sessionId) ? [] : [index]);
|
|
3541
|
+
if (quiet.length > 0) pi.sendMessage(message(quiet), { triggerTurn: false });
|
|
3542
|
+
if (loud.length > 0) pi.sendMessage(message(loud), {
|
|
3530
3543
|
triggerTurn: true,
|
|
3531
3544
|
deliverAs: "steer"
|
|
3532
3545
|
});
|