agent-tempo 1.2.0 → 1.4.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/CLAUDE.md +253 -219
- package/LICENSE +21 -21
- package/README.md +293 -289
- package/assets/icon-dark.svg +9 -9
- package/assets/icon.svg +9 -9
- package/assets/logo-dark.svg +11 -11
- package/assets/logo-light.svg +11 -11
- package/dashboard/README.md +91 -91
- package/dashboard/dist/assets/{index-D6Xyje_n.js → index-jmYe6rmS.js} +2 -2
- package/dashboard/dist/assets/index-jmYe6rmS.js.map +1 -0
- package/dashboard/dist/index.html +20 -20
- package/dashboard/package.json +47 -47
- package/dist/activities/outbox.d.ts +30 -1
- package/dist/activities/outbox.js +96 -3
- package/dist/adapters/base.js +5 -0
- package/dist/adapters/copilot/adapter.js +12 -1
- package/dist/adapters/index.d.ts +1 -1
- package/dist/adapters/index.js +7 -0
- package/dist/adapters/pi/adapter.d.ts +2 -0
- package/dist/adapters/pi/adapter.js +43 -0
- package/dist/adapters/pi/index.d.ts +16 -0
- package/dist/adapters/pi/index.js +10 -0
- package/dist/cli/global-wrapper.d.ts +19 -0
- package/dist/cli/global-wrapper.js +169 -0
- package/dist/cli/help-text.js +97 -97
- package/dist/cli/startup.js +11 -0
- package/dist/cli/upgrade-command.js +81 -81
- package/dist/cli.js +12 -0
- package/dist/client/core.js +9 -2
- package/dist/client/interface.d.ts +6 -0
- package/dist/config.d.ts +79 -0
- package/dist/config.js +74 -0
- package/dist/daemon.js +37 -1
- package/dist/http/aggregate.d.ts +22 -1
- package/dist/http/aggregate.js +41 -0
- package/dist/http/auth.d.ts +94 -8
- package/dist/http/auth.js +93 -9
- package/dist/http/body.d.ts +4 -1
- package/dist/http/body.js +6 -3
- package/dist/http/event-bus.js +1 -0
- package/dist/http/event-types.d.ts +34 -2
- package/dist/http/event-types.js +1 -0
- package/dist/http/gate-audit.d.ts +12 -0
- package/dist/http/gate-audit.js +95 -0
- package/dist/http/gate-registry.d.ts +167 -0
- package/dist/http/gate-registry.js +163 -0
- package/dist/http/gate-routes.d.ts +48 -0
- package/dist/http/gate-routes.js +102 -0
- package/dist/http/ingest-registry.d.ts +30 -0
- package/dist/http/ingest-registry.js +108 -0
- package/dist/http/inner-loop-routes.d.ts +66 -0
- package/dist/http/inner-loop-routes.js +182 -0
- package/dist/http/inner-loop.d.ts +92 -0
- package/dist/http/inner-loop.js +155 -0
- package/dist/http/server.d.ts +38 -3
- package/dist/http/server.js +211 -6
- package/dist/http/snapshot.d.ts +6 -0
- package/dist/http/snapshot.js +6 -0
- package/dist/pi/cue-pump.d.ts +61 -0
- package/dist/pi/cue-pump.js +95 -0
- package/dist/pi/extension.d.ts +45 -0
- package/dist/pi/extension.js +407 -0
- package/dist/pi/gate-client.d.ts +54 -0
- package/dist/pi/gate-client.js +136 -0
- package/dist/pi/headless.d.ts +85 -0
- package/dist/pi/headless.js +224 -0
- package/dist/pi/index.d.ts +28 -0
- package/dist/pi/index.js +43 -0
- package/dist/pi/inner-loop-client.d.ts +67 -0
- package/dist/pi/inner-loop-client.js +164 -0
- package/dist/pi/inner-loop-publisher.d.ts +187 -0
- package/dist/pi/inner-loop-publisher.js +236 -0
- package/dist/pi/lazy-proxy.d.ts +37 -0
- package/dist/pi/lazy-proxy.js +55 -0
- package/dist/pi/mission-control/actions.d.ts +48 -0
- package/dist/pi/mission-control/actions.js +98 -0
- package/dist/pi/mission-control/board.d.ts +53 -0
- package/dist/pi/mission-control/board.js +104 -0
- package/dist/pi/mission-control/extension.d.ts +44 -0
- package/dist/pi/mission-control/extension.js +251 -0
- package/dist/pi/mission-control/index.d.ts +15 -0
- package/dist/pi/mission-control/index.js +32 -0
- package/dist/pi/mission-control/inner-tail.d.ts +48 -0
- package/dist/pi/mission-control/inner-tail.js +76 -0
- package/dist/pi/mission-control/pi-ui.d.ts +43 -0
- package/dist/pi/mission-control/pi-ui.js +10 -0
- package/dist/pi/mission-control/render.d.ts +6 -0
- package/dist/pi/mission-control/render.js +95 -0
- package/dist/pi/phase-driver.d.ts +74 -0
- package/dist/pi/phase-driver.js +122 -0
- package/dist/pi/pi-types.d.ts +208 -0
- package/dist/pi/pi-types.js +21 -0
- package/dist/pi/probe.d.ts +80 -0
- package/dist/pi/probe.js +154 -0
- package/dist/pi/render-tools.d.ts +17 -0
- package/dist/pi/render-tools.js +51 -0
- package/dist/pi/reset-pump.d.ts +47 -0
- package/dist/pi/reset-pump.js +85 -0
- package/dist/pi/tool-capability.d.ts +60 -0
- package/dist/pi/tool-capability.js +156 -0
- package/dist/pi/workflow-client.d.ts +158 -0
- package/dist/pi/workflow-client.js +289 -0
- package/dist/pi/zod-to-typebox.d.ts +74 -0
- package/dist/pi/zod-to-typebox.js +191 -0
- package/dist/scripts/verify-daemon-isolation-guard.js +24 -24
- package/dist/server-tools.d.ts +2 -0
- package/dist/server-tools.js +50 -46
- package/dist/server.js +4 -0
- package/dist/spawn.d.ts +55 -0
- package/dist/spawn.js +84 -12
- package/dist/tools/agent-types.d.ts +2 -2
- package/dist/tools/agent-types.js +22 -17
- package/dist/tools/attachment-info.d.ts +2 -2
- package/dist/tools/attachment-info.js +38 -33
- package/dist/tools/broadcast.d.ts +2 -2
- package/dist/tools/broadcast.js +69 -64
- package/dist/tools/cancel-stage.d.ts +2 -2
- package/dist/tools/cancel-stage.js +20 -15
- package/dist/tools/clear-state.d.ts +2 -2
- package/dist/tools/clear-state.js +25 -20
- package/dist/tools/coat-check-evict.d.ts +2 -2
- package/dist/tools/coat-check-evict.js +30 -25
- package/dist/tools/coat-check-get.d.ts +2 -2
- package/dist/tools/coat-check-get.js +39 -34
- package/dist/tools/coat-check-list.d.ts +2 -2
- package/dist/tools/coat-check-list.js +48 -43
- package/dist/tools/coat-check-put.d.ts +2 -2
- package/dist/tools/coat-check-put.js +41 -36
- package/dist/tools/cue.d.ts +2 -2
- package/dist/tools/cue.js +57 -52
- package/dist/tools/descriptor.d.ts +72 -0
- package/dist/tools/descriptor.js +39 -0
- package/dist/tools/destroy.d.ts +2 -2
- package/dist/tools/destroy.js +153 -148
- package/dist/tools/ensemble.d.ts +2 -2
- package/dist/tools/ensemble.js +71 -66
- package/dist/tools/evaluate-gate.d.ts +2 -2
- package/dist/tools/evaluate-gate.js +33 -27
- package/dist/tools/fetch-state.d.ts +2 -2
- package/dist/tools/fetch-state.js +43 -38
- package/dist/tools/gates.d.ts +2 -2
- package/dist/tools/gates.js +39 -34
- package/dist/tools/hosts.d.ts +2 -2
- package/dist/tools/hosts.js +25 -20
- package/dist/tools/listen.d.ts +2 -2
- package/dist/tools/listen.js +23 -18
- package/dist/tools/load-lineup.d.ts +2 -2
- package/dist/tools/load-lineup.js +324 -319
- package/dist/tools/migrate.d.ts +2 -2
- package/dist/tools/migrate.js +45 -40
- package/dist/tools/pause.d.ts +2 -2
- package/dist/tools/pause.js +34 -29
- package/dist/tools/play.d.ts +2 -2
- package/dist/tools/play.js +53 -48
- package/dist/tools/quality-gate.d.ts +2 -2
- package/dist/tools/quality-gate.js +26 -21
- package/dist/tools/recall.d.ts +2 -2
- package/dist/tools/recall.js +32 -27
- package/dist/tools/recruit.d.ts +2 -2
- package/dist/tools/recruit.js +325 -256
- package/dist/tools/release.d.ts +2 -2
- package/dist/tools/release.js +85 -80
- package/dist/tools/report.d.ts +2 -2
- package/dist/tools/report.js +28 -23
- package/dist/tools/reset.d.ts +3 -0
- package/dist/tools/reset.js +51 -0
- package/dist/tools/restart.d.ts +2 -2
- package/dist/tools/restart.js +51 -46
- package/dist/tools/restore.d.ts +2 -2
- package/dist/tools/restore.js +76 -71
- package/dist/tools/save-lineup.d.ts +2 -2
- package/dist/tools/save-lineup.js +32 -27
- package/dist/tools/save-state.d.ts +2 -2
- package/dist/tools/save-state.js +43 -38
- package/dist/tools/schedule.d.ts +2 -2
- package/dist/tools/schedule.js +133 -128
- package/dist/tools/schedules.d.ts +2 -2
- package/dist/tools/schedules.js +41 -36
- package/dist/tools/set-ensemble-description.d.ts +2 -2
- package/dist/tools/set-ensemble-description.js +26 -21
- package/dist/tools/set-name.d.ts +2 -2
- package/dist/tools/set-name.js +38 -33
- package/dist/tools/set-part.d.ts +2 -2
- package/dist/tools/set-part.js +20 -15
- package/dist/tools/shutdown.d.ts +2 -2
- package/dist/tools/shutdown.js +39 -34
- package/dist/tools/stage.d.ts +2 -2
- package/dist/tools/stage.js +28 -23
- package/dist/tools/stages.d.ts +2 -2
- package/dist/tools/stages.js +36 -31
- package/dist/tools/unschedule.d.ts +2 -2
- package/dist/tools/unschedule.js +30 -25
- package/dist/tools/who-am-i.d.ts +2 -2
- package/dist/tools/who-am-i.js +36 -31
- package/dist/tools/worktree.d.ts +2 -2
- package/dist/tools/worktree.js +134 -129
- package/dist/tui/index.js +6 -6
- package/dist/types.d.ts +47 -2
- package/dist/types.js +1 -1
- package/dist/utils/default-part.js +1 -0
- package/dist/utils/grpc-shutdown-guard.d.ts +52 -0
- package/dist/utils/grpc-shutdown-guard.js +88 -0
- package/dist/utils/sdk-probe.d.ts +23 -0
- package/dist/utils/sdk-probe.js +46 -7
- package/dist/worker.d.ts +3 -1
- package/dist/worker.js +6 -2
- package/dist/workflows/session.js +70 -2
- package/dist/workflows/signals.d.ts +32 -2
- package/dist/workflows/signals.js +25 -2
- package/examples/agents/tempo-composer.md +56 -56
- package/examples/agents/tempo-conductor.md +117 -117
- package/examples/agents/tempo-critic.md +73 -73
- package/examples/agents/tempo-improv.md +74 -74
- package/examples/agents/tempo-liner.md +75 -75
- package/examples/agents/tempo-roadie.md +61 -61
- package/examples/agents/tempo-soloist.md +71 -71
- package/examples/agents/tempo-tuner.md +94 -94
- package/examples/ensembles/tempo-big-band.yaml +146 -146
- package/examples/ensembles/tempo-dev-team.yaml +58 -58
- package/examples/ensembles/tempo-headless-jam.yaml +77 -77
- package/examples/ensembles/tempo-jam-session.yaml +41 -41
- package/examples/ensembles/tempo-mock-jam.yaml +79 -79
- package/examples/ensembles/tempo-review-squad.yaml +32 -32
- package/package.json +176 -173
- package/packaging/launchd/com.agent.tempo.plist +46 -46
- package/packaging/systemd/agent-tempo.service +32 -32
- package/packaging/windows/install-task.ps1 +71 -71
- package/scenarios/conductor-recruit-mock.yaml +33 -33
- package/scenarios/echo-roundtrip.yaml +15 -15
- package/scenarios/multi-player-handoff.yaml +38 -38
- package/scenarios/recruit-cascade.yaml +38 -38
- package/scenarios/two-player-conversation.yaml +33 -33
- package/workflow-bundle.js +97 -6
- package/dashboard/dist/assets/index-D6Xyje_n.js.map +0 -1
- package/dist/activities/claude-stop.d.ts +0 -21
- package/dist/activities/claude-stop.js +0 -94
- package/dist/channel.d.ts +0 -3
- package/dist/channel.js +0 -48
- package/dist/copilot-bridge.d.ts +0 -22
- package/dist/copilot-bridge.js +0 -565
- package/dist/scripts/258-spotcheck.js +0 -303
- package/dist/tools/detach.d.ts +0 -4
- package/dist/tools/detach.js +0 -45
- package/dist/tools/encore.d.ts +0 -4
- package/dist/tools/encore.js +0 -31
- package/dist/tools/helpers.d.ts +0 -21
- package/dist/tools/helpers.js +0 -25
- package/dist/tools/pause-ensemble.d.ts +0 -4
- package/dist/tools/pause-ensemble.js +0 -58
- package/dist/tools/resume-ensemble.d.ts +0 -4
- package/dist/tools/resume-ensemble.js +0 -79
- package/dist/tools/stop.d.ts +0 -4
- package/dist/tools/stop.js +0 -29
- package/dist/tui/client.d.ts +0 -6
- package/dist/tui/client.js +0 -9
- package/dist/tui/components/ActivityLog.d.ts +0 -16
- package/dist/tui/components/ActivityLog.js +0 -36
- package/dist/tui/components/CommandOverlay.d.ts +0 -15
- package/dist/tui/components/CommandOverlay.js +0 -34
- package/dist/tui/components/ConductorChat.d.ts +0 -16
- package/dist/tui/components/ConductorChat.js +0 -32
- package/dist/tui/components/EnsembleListView.d.ts +0 -14
- package/dist/tui/components/EnsembleListView.js +0 -32
- package/dist/tui/components/EnsemblePanel.d.ts +0 -12
- package/dist/tui/components/EnsemblePanel.js +0 -40
- package/dist/tui/components/InputBar.d.ts +0 -13
- package/dist/tui/components/InputBar.js +0 -58
- package/dist/tui/components/ScheduleOverlay.d.ts +0 -13
- package/dist/tui/components/ScheduleOverlay.js +0 -113
- package/dist/tui/components/TopBar.d.ts +0 -12
- package/dist/tui/components/TopBar.js +0 -15
- package/dist/tui/core-api.d.ts +0 -26
- package/dist/tui/core-api.js +0 -67
- package/dist/tui/hooks/useEnsembleDiscovery.d.ts +0 -3
- package/dist/tui/hooks/useEnsembleDiscovery.js +0 -30
- package/dist/tui/hooks/useMaestroPoller.d.ts +0 -3
- package/dist/tui/hooks/useMaestroPoller.js +0 -36
- package/dist/tui/hooks/useSendCommand.d.ts +0 -7
- package/dist/tui/hooks/useSendCommand.js +0 -29
- package/dist/utils/bg-preflight.d.ts +0 -25
- package/dist/utils/bg-preflight.js +0 -154
package/dist/tools/restore.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.buildRestoreTool = buildRestoreTool;
|
|
4
4
|
/**
|
|
5
5
|
* `restore` — ensemble-wide revive (#287).
|
|
6
6
|
*
|
|
@@ -28,80 +28,85 @@ const os_1 = require("os");
|
|
|
28
28
|
const zod_1 = require("zod");
|
|
29
29
|
const orphans_1 = require("../reconcile/orphans");
|
|
30
30
|
const signals_1 = require("../workflows/signals");
|
|
31
|
-
const
|
|
31
|
+
const descriptor_1 = require("./descriptor");
|
|
32
32
|
const ensemble_ops_1 = require("../utils/ensemble-ops");
|
|
33
33
|
const log = (...args) => console.error('[agent-tempo:restore]', ...args);
|
|
34
|
-
function
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
34
|
+
function buildRestoreTool(client, config, getPlayerId) {
|
|
35
|
+
return {
|
|
36
|
+
name: 'restore',
|
|
37
|
+
description: 'Revive the ensemble after `shutdown`: reattach orphaned sessions and unpause the maestro + scheduler. Defaults to scanning the local host; pass `hostname` to target a remote machine in distributed setups (per-host task queues). Does NOT spawn a conductor terminal — use the CLI for that.',
|
|
38
|
+
params: {
|
|
39
|
+
// #306 follow-up: cross-host restore. The default (omitted) preserves
|
|
40
|
+
// the original behavior — scan the local daemon's host. When supplied,
|
|
41
|
+
// we route the orphan-visibility query against the named host's
|
|
42
|
+
// `AgentTempoAttachedHost`/`AgentTempoHostname` search attributes,
|
|
43
|
+
// so an operator on host A can revive sessions parked on host B.
|
|
44
|
+
// Surfaced from my own #306 review (regression risk #2): "MCP
|
|
45
|
+
// restore hard-codes hostname: osHostname() — won't see orphans on
|
|
46
|
+
// other hosts in distributed setups."
|
|
47
|
+
hostname: zod_1.z.string().min(1).max(253).optional().describe('Target host whose orphans should be restored. Defaults to the local OS hostname. Use this when the conductor / TUI is on a different machine than the workers that owned the parked sessions.'),
|
|
48
|
+
},
|
|
49
|
+
handler: async (args) => {
|
|
50
|
+
const { hostname: explicitHostname } = args;
|
|
51
|
+
const targetHostname = explicitHostname ?? (0, os_1.hostname)();
|
|
50
52
|
try {
|
|
51
|
-
summary
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
53
|
+
let summary;
|
|
54
|
+
try {
|
|
55
|
+
summary = await (0, orphans_1.restoreOrphansOnce)(client, {
|
|
56
|
+
hostname: targetHostname,
|
|
57
|
+
invokerPlayerId: getPlayerId(),
|
|
58
|
+
policy: 'auto',
|
|
59
|
+
// #306: narrow to detached-only so a live attached/processing
|
|
60
|
+
// session is never flagged as an orphan by user-invoked
|
|
61
|
+
// `/restore`. Daemon reconcile-on-boot + CLI `up --resume`
|
|
62
|
+
// keep the broad live-phase default (no PID memory after
|
|
63
|
+
// crash → must treat every live phase as presumed orphan).
|
|
64
|
+
phases: ['detached'],
|
|
65
|
+
}, log);
|
|
66
|
+
}
|
|
67
|
+
catch (err) {
|
|
68
|
+
return (0, descriptor_1.fail)(`Failed to scan for orphans: ${(0, descriptor_1.formatError)(err)}`);
|
|
69
|
+
}
|
|
70
|
+
// Maestro/scheduler hub unpause + per-session `setPaused=false`
|
|
71
|
+
// fan-out run in parallel — independent calls and a slow session
|
|
72
|
+
// shouldn't gate the hub toggle (or vice-versa).
|
|
73
|
+
const [toggle, sessions] = await Promise.all([
|
|
74
|
+
(0, ensemble_ops_1.unpauseMaestroAndScheduler)(client, config.ensemble),
|
|
75
|
+
(0, ensemble_ops_1.signalAllSessions)(client, config.ensemble, signals_1.setPausedSignal.name, false),
|
|
76
|
+
]);
|
|
77
|
+
const hostSuffix = explicitHostname !== undefined
|
|
78
|
+
? ` (host: ${explicitHostname})`
|
|
79
|
+
: '';
|
|
80
|
+
const lines = [
|
|
81
|
+
`Ensemble **${config.ensemble}** restored${hostSuffix}.`,
|
|
82
|
+
`${summary.reattached} reattached, ${summary.skipped} skipped, ${summary.failed} failed`,
|
|
83
|
+
];
|
|
84
|
+
if (summary.details.length > 0) {
|
|
85
|
+
lines.push(...summary.details.map((d) => ` - ${d.playerId} (${d.ensemble}): ${(0, orphans_1.formatRestoreOutcome)(d.outcome)}`));
|
|
86
|
+
}
|
|
87
|
+
if (sessions.sent > 0) {
|
|
88
|
+
lines.push(`${sessions.sent} session(s) resumed`);
|
|
89
|
+
}
|
|
90
|
+
const unpausedBits = [];
|
|
91
|
+
if (toggle.maestro)
|
|
92
|
+
unpausedBits.push('maestro');
|
|
93
|
+
if (toggle.scheduler)
|
|
94
|
+
unpausedBits.push('scheduler');
|
|
95
|
+
if (unpausedBits.length > 0)
|
|
96
|
+
lines.push(`Unpaused: ${unpausedBits.join(', ')}`);
|
|
97
|
+
if (sessions.failed > 0) {
|
|
98
|
+
const errs = sessions.perSession
|
|
99
|
+
.filter((p) => p.outcome === 'failed')
|
|
100
|
+
.map((p) => ` - ${p.playerId}: ${'error' in p ? p.error : ''}`);
|
|
101
|
+
lines.push(`Errors:\n${errs.join('\n')}`);
|
|
102
|
+
}
|
|
103
|
+
log(`Restore by ${getPlayerId()} in "${config.ensemble}" on host "${targetHostname}": ` +
|
|
104
|
+
`${summary.reattached}/${summary.skipped}/${summary.failed}`);
|
|
105
|
+
return (0, descriptor_1.ok)(lines.join('\n'));
|
|
62
106
|
}
|
|
63
107
|
catch (err) {
|
|
64
|
-
return (0,
|
|
108
|
+
return (0, descriptor_1.fail)(`Failed to restore ensemble: ${(0, descriptor_1.formatError)(err)}`);
|
|
65
109
|
}
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
// shouldn't gate the hub toggle (or vice-versa).
|
|
69
|
-
const [toggle, sessions] = await Promise.all([
|
|
70
|
-
(0, ensemble_ops_1.unpauseMaestroAndScheduler)(client, config.ensemble),
|
|
71
|
-
(0, ensemble_ops_1.signalAllSessions)(client, config.ensemble, signals_1.setPausedSignal.name, false),
|
|
72
|
-
]);
|
|
73
|
-
const hostSuffix = explicitHostname !== undefined
|
|
74
|
-
? ` (host: ${explicitHostname})`
|
|
75
|
-
: '';
|
|
76
|
-
const lines = [
|
|
77
|
-
`Ensemble **${config.ensemble}** restored${hostSuffix}.`,
|
|
78
|
-
`${summary.reattached} reattached, ${summary.skipped} skipped, ${summary.failed} failed`,
|
|
79
|
-
];
|
|
80
|
-
if (summary.details.length > 0) {
|
|
81
|
-
lines.push(...summary.details.map((d) => ` - ${d.playerId} (${d.ensemble}): ${(0, orphans_1.formatRestoreOutcome)(d.outcome)}`));
|
|
82
|
-
}
|
|
83
|
-
if (sessions.sent > 0) {
|
|
84
|
-
lines.push(`${sessions.sent} session(s) resumed`);
|
|
85
|
-
}
|
|
86
|
-
const unpausedBits = [];
|
|
87
|
-
if (toggle.maestro)
|
|
88
|
-
unpausedBits.push('maestro');
|
|
89
|
-
if (toggle.scheduler)
|
|
90
|
-
unpausedBits.push('scheduler');
|
|
91
|
-
if (unpausedBits.length > 0)
|
|
92
|
-
lines.push(`Unpaused: ${unpausedBits.join(', ')}`);
|
|
93
|
-
if (sessions.failed > 0) {
|
|
94
|
-
const errs = sessions.perSession
|
|
95
|
-
.filter((p) => p.outcome === 'failed')
|
|
96
|
-
.map((p) => ` - ${p.playerId}: ${'error' in p ? p.error : ''}`);
|
|
97
|
-
lines.push(`Errors:\n${errs.join('\n')}`);
|
|
98
|
-
}
|
|
99
|
-
log(`Restore by ${getPlayerId()} in "${config.ensemble}" on host "${targetHostname}": ` +
|
|
100
|
-
`${summary.reattached}/${summary.skipped}/${summary.failed}`);
|
|
101
|
-
return (0, helpers_1.ok)(lines.join('\n'));
|
|
102
|
-
}
|
|
103
|
-
catch (err) {
|
|
104
|
-
return (0, helpers_1.fail)(`Failed to restore ensemble: ${(0, helpers_1.formatError)(err)}`);
|
|
105
|
-
}
|
|
106
|
-
});
|
|
110
|
+
},
|
|
111
|
+
};
|
|
107
112
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
1
|
import { Client } from '@temporalio/client';
|
|
3
2
|
import { Config } from '../config';
|
|
4
|
-
|
|
3
|
+
import { type TempoToolDescriptor } from './descriptor';
|
|
4
|
+
export declare function buildSaveLineupTool(client: Client, config: Config, getPlayerId: () => string, isConductor: boolean): TempoToolDescriptor;
|
|
@@ -1,36 +1,41 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.buildSaveLineupTool = buildSaveLineupTool;
|
|
4
4
|
const zod_1 = require("zod");
|
|
5
5
|
const saver_1 = require("../ensemble/saver");
|
|
6
6
|
const safe_path_1 = require("../utils/safe-path");
|
|
7
|
-
const
|
|
7
|
+
const descriptor_1 = require("./descriptor");
|
|
8
8
|
const validation_1 = require("../utils/validation");
|
|
9
9
|
const log = (...args) => console.error('[agent-tempo:save-lineup]', ...args);
|
|
10
|
-
function
|
|
11
|
-
|
|
12
|
-
name:
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
// Validate user-supplied path if provided
|
|
22
|
-
let validatedPath = filePath;
|
|
23
|
-
if (validatedPath) {
|
|
24
|
-
validatedPath = (0, safe_path_1.safeLineupPath)(validatedPath, process.cwd());
|
|
10
|
+
function buildSaveLineupTool(client, config, getPlayerId, isConductor) {
|
|
11
|
+
return {
|
|
12
|
+
name: 'save_lineup',
|
|
13
|
+
description: 'Save the current ensemble state as a YAML lineup. Only available to the conductor.',
|
|
14
|
+
params: {
|
|
15
|
+
name: zod_1.z.string().max(validation_1.PLAYER_NAME_MAX).optional().describe('Lineup name (defaults to ensemble name)'),
|
|
16
|
+
path: zod_1.z.string().max(validation_1.PATH_MAX).optional().describe('Explicit file path to save to'),
|
|
17
|
+
},
|
|
18
|
+
handler: async (args) => {
|
|
19
|
+
if (!isConductor) {
|
|
20
|
+
return (0, descriptor_1.fail)('Only the conductor can save ensemble lineups.');
|
|
25
21
|
}
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
22
|
+
const lineupName = args.name;
|
|
23
|
+
const filePath = args.path;
|
|
24
|
+
try {
|
|
25
|
+
// Validate user-supplied path if provided
|
|
26
|
+
let validatedPath = filePath;
|
|
27
|
+
if (validatedPath) {
|
|
28
|
+
validatedPath = (0, safe_path_1.safeLineupPath)(validatedPath, process.cwd());
|
|
29
|
+
}
|
|
30
|
+
// Pass lineupName as optional name override for the output filename.
|
|
31
|
+
// If no name or path is provided, saveLineup defaults to ensemble name.
|
|
32
|
+
const outputPath = await (0, saver_1.saveLineup)(client, config.ensemble, validatedPath, lineupName);
|
|
33
|
+
log(`Saved lineup to ${outputPath}`);
|
|
34
|
+
return (0, descriptor_1.ok)(`Ensemble lineup saved to **${outputPath}**.`);
|
|
35
|
+
}
|
|
36
|
+
catch (err) {
|
|
37
|
+
return (0, descriptor_1.fail)(`Failed to save ensemble: ${(0, descriptor_1.formatError)(err)}`);
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
};
|
|
36
41
|
}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
1
|
import { WorkflowHandle } from '@temporalio/client';
|
|
3
|
-
|
|
2
|
+
import { type TempoToolDescriptor } from './descriptor';
|
|
3
|
+
export declare function buildSaveStateTool(handle: WorkflowHandle, getPlayerId: () => string): TempoToolDescriptor;
|
package/dist/tools/save-state.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.buildSaveStateTool = buildSaveStateTool;
|
|
4
4
|
/**
|
|
5
5
|
* `save_state` — write a curated artifact to one of the calling player's
|
|
6
6
|
* saveable-state slots (#334 PR-1, ADR 0011).
|
|
@@ -16,42 +16,47 @@ exports.registerSaveStateTool = registerSaveStateTool;
|
|
|
16
16
|
*/
|
|
17
17
|
const zod_1 = require("zod");
|
|
18
18
|
const signals_1 = require("../workflows/signals");
|
|
19
|
-
const
|
|
19
|
+
const descriptor_1 = require("./descriptor");
|
|
20
20
|
const validation_1 = require("../utils/validation");
|
|
21
|
-
function
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
##
|
|
29
|
-
...
|
|
30
|
-
##
|
|
31
|
-
...
|
|
32
|
-
##
|
|
33
|
-
...
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
const
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
21
|
+
function buildSaveStateTool(handle, getPlayerId) {
|
|
22
|
+
return {
|
|
23
|
+
name: 'save_state',
|
|
24
|
+
description: `Save curated state for yourself into a named slot — a peer can later read it via \`fetch_state\`, and a future restart can seed itself from this artifact instead of replaying the transcript.
|
|
25
|
+
|
|
26
|
+
Recommended structure (markdown, not enforced):
|
|
27
|
+
|
|
28
|
+
## Current task
|
|
29
|
+
...
|
|
30
|
+
## Findings
|
|
31
|
+
...
|
|
32
|
+
## Next steps
|
|
33
|
+
...
|
|
34
|
+
## Open questions
|
|
35
|
+
...
|
|
36
|
+
|
|
37
|
+
Limits: ${validation_1.PLAYER_STATE_CONTENT_MAX} bytes per slot, max ${validation_1.PLAYER_STATE_SLOTS_MAX} slots per player. Slot key defaults to "${validation_1.PLAYER_STATE_DEFAULT_KEY}". When all ${validation_1.PLAYER_STATE_SLOTS_MAX} slots are full, saving a new key fails with \`PlayerStateSlotsFull\` — call \`clear_state\` to free a slot.`,
|
|
38
|
+
params: {
|
|
39
|
+
content: zod_1.z.string().min(1).max(validation_1.PLAYER_STATE_CONTENT_MAX).describe(`The state content — markdown encouraged, opaque to the system. Max ${validation_1.PLAYER_STATE_CONTENT_MAX} bytes (UTF-8).`),
|
|
40
|
+
key: zod_1.z.string().regex(validation_1.PLAYER_STATE_KEY_REGEX).max(validation_1.PLAYER_STATE_KEY_MAX).optional().describe(`Slot name (default "${validation_1.PLAYER_STATE_DEFAULT_KEY}"). Alphanumeric + underscore + hyphen, max ${validation_1.PLAYER_STATE_KEY_MAX} chars.`),
|
|
41
|
+
},
|
|
42
|
+
handler: async (args) => {
|
|
43
|
+
const { content, key } = args;
|
|
44
|
+
const slotKey = key ?? validation_1.PLAYER_STATE_DEFAULT_KEY;
|
|
45
|
+
const savedBy = getPlayerId();
|
|
46
|
+
try {
|
|
47
|
+
const result = await handle.executeUpdate(signals_1.savePlayerStateUpdate, {
|
|
48
|
+
args: [{ key: slotKey, content, savedBy }],
|
|
49
|
+
});
|
|
50
|
+
return (0, descriptor_1.ok)(`Saved to slot **"${slotKey}"** at ${result.savedAt}.`);
|
|
51
|
+
}
|
|
52
|
+
catch (err) {
|
|
53
|
+
// The workflow validator surfaces structured ApplicationFailure errors
|
|
54
|
+
// (`PlayerStateSlotsFull`, `PlayerStateContentTooLarge`,
|
|
55
|
+
// `PlayerStateInvalidKey`). The `formatError` message preserves the
|
|
56
|
+
// workflow-supplied text so the LLM sees the existing-keys list and
|
|
57
|
+
// can pick which slot to clear.
|
|
58
|
+
return (0, descriptor_1.fail)(`Failed to save state: ${(0, descriptor_1.formatError)(err)}`);
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
};
|
|
57
62
|
}
|
package/dist/tools/schedule.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
1
|
import { Client } from '@temporalio/client';
|
|
3
2
|
import { Config } from '../config';
|
|
4
|
-
|
|
3
|
+
import { type TempoToolDescriptor } from './descriptor';
|
|
4
|
+
export declare function buildScheduleTool(client: Client, config: Config, getPlayerId: () => string): TempoToolDescriptor;
|