agent-tempo 1.7.0 → 2.0.0-beta.2
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 +10 -13
- package/README.md +21 -15
- package/dashboard/dist/assets/index-BbR7zIdK.js.map +1 -1
- package/dashboard/package.json +1 -1
- package/dist/activities/hard-terminate.d.ts +2 -2
- package/dist/activities/hard-terminate.js +3 -9
- package/dist/activities/maestro.d.ts +8 -13
- package/dist/activities/maestro.js +3 -10
- package/dist/activities/outbox.js +16 -2
- package/dist/activities/resolve.d.ts +18 -7
- package/dist/activities/resolve.js +58 -46
- package/dist/adapters/base.js +3 -0
- package/dist/adapters/claude-code/adapter.js +7 -0
- package/dist/cli/command-center-command.js +15 -1
- package/dist/cli/commands.d.ts +8 -0
- package/dist/cli/commands.js +79 -11
- package/dist/cli/daemon-command.js +19 -33
- package/dist/cli/help-text.js +9 -7
- package/dist/cli/home-command.d.ts +26 -0
- package/dist/cli/home-command.js +156 -0
- package/dist/cli/removed-verbs.d.ts +0 -4
- package/dist/cli/removed-verbs.js +23 -12
- package/dist/cli/sa-preflight.d.ts +0 -14
- package/dist/cli/sa-preflight.js +1 -17
- package/dist/cli/startup.d.ts +1 -10
- package/dist/cli/startup.js +0 -40
- package/dist/cli.js +34 -80
- package/dist/client/core.js +13 -15
- package/dist/client/index.d.ts +2 -1
- package/dist/client/interface.d.ts +5 -14
- package/dist/client/with-spawn.d.ts +9 -4
- package/dist/client/with-spawn.js +7 -10
- package/dist/config.d.ts +14 -13
- package/dist/config.js +14 -0
- package/dist/constants.d.ts +50 -0
- package/dist/constants.js +60 -1
- package/dist/daemon.js +81 -0
- package/dist/http/auth.d.ts +3 -21
- package/dist/http/auth.js +10 -31
- package/dist/http/event-types.d.ts +38 -4
- package/dist/http/orphans.d.ts +3 -3
- package/dist/http/orphans.js +3 -3
- package/dist/http/server.d.ts +0 -5
- package/dist/http/server.js +79 -29
- package/dist/http/snapshot.js +3 -0
- package/dist/http/writes.d.ts +1 -1
- package/dist/http/writes.js +25 -2
- package/dist/observability/nondeterminism-alarm.d.ts +113 -0
- package/dist/observability/nondeterminism-alarm.js +162 -0
- package/dist/palette/index.d.ts +6 -7
- package/dist/palette/index.js +6 -7
- package/dist/pi/mission-control/actions.d.ts +67 -1
- package/dist/pi/mission-control/actions.js +61 -0
- package/dist/pi/mission-control/extension.d.ts +77 -0
- package/dist/pi/mission-control/extension.js +171 -0
- package/dist/pi/workflow-client.d.ts +14 -16
- package/dist/pi/workflow-client.js +18 -44
- package/dist/server-tools.js +30 -29
- package/dist/server.js +42 -0
- package/dist/tools/action-guard.d.ts +23 -0
- package/dist/tools/action-guard.js +33 -0
- package/dist/tools/coat-check.d.ts +20 -0
- package/dist/tools/coat-check.js +129 -0
- package/dist/tools/gate.d.ts +13 -0
- package/dist/tools/gate.js +88 -0
- package/dist/tools/schedule.d.ts +18 -0
- package/dist/tools/schedule.js +93 -1
- package/dist/tools/stage.d.ts +17 -0
- package/dist/tools/stage.js +85 -1
- package/dist/tools/state.d.ts +14 -0
- package/dist/tools/state.js +95 -0
- package/dist/types.d.ts +54 -7
- package/dist/upgrade/boot-guard.d.ts +95 -0
- package/dist/upgrade/boot-guard.js +88 -0
- package/dist/upgrade/from-upgrade.d.ts +95 -0
- package/dist/upgrade/from-upgrade.js +330 -0
- package/dist/upgrade/phase-engine.js +4 -1
- package/dist/utils/duration.d.ts +3 -6
- package/dist/utils/duration.js +3 -6
- package/dist/utils/format-hosts.d.ts +1 -1
- package/dist/utils/format-hosts.js +0 -2
- package/dist/utils/grpc-shutdown-guard.js +0 -4
- package/dist/utils/hosts.d.ts +4 -10
- package/dist/utils/hosts.js +12 -28
- package/dist/utils/orphan-guard.d.ts +37 -0
- package/dist/utils/orphan-guard.js +26 -0
- package/dist/utils/search-attributes.d.ts +28 -18
- package/dist/utils/search-attributes.js +48 -18
- package/dist/utils/visibility-deadline.d.ts +16 -0
- package/dist/utils/visibility-deadline.js +16 -0
- package/dist/workflows/maestro-signals.d.ts +0 -13
- package/dist/workflows/maestro-signals.js +6 -14
- package/dist/workflows/maestro.js +27 -32
- package/dist/workflows/scheduler.js +7 -1
- package/dist/workflows/session.js +237 -153
- package/dist/workflows/signals.d.ts +9 -1
- package/dist/workflows/signals.js +8 -6
- package/package.json +1 -6
- package/workflow-bundle.js +478 -225
- package/dist/cli/legacy-migration.d.ts +0 -35
- package/dist/cli/legacy-migration.js +0 -341
- package/dist/client/ensure-conductor-spawned.d.ts +0 -35
- package/dist/client/ensure-conductor-spawned.js +0 -48
- package/dist/tui/App.d.ts +0 -85
- package/dist/tui/App.js +0 -1791
- package/dist/tui/bootstrap-types.d.ts +0 -46
- package/dist/tui/bootstrap-types.js +0 -7
- package/dist/tui/commands.d.ts +0 -71
- package/dist/tui/commands.js +0 -1375
- package/dist/tui/components/ChatView.d.ts +0 -35
- package/dist/tui/components/ChatView.js +0 -54
- package/dist/tui/components/CommandPalette.d.ts +0 -21
- package/dist/tui/components/CommandPalette.js +0 -67
- package/dist/tui/components/ConversationStream.d.ts +0 -114
- package/dist/tui/components/ConversationStream.js +0 -307
- package/dist/tui/components/CreateEnsembleWizard.d.ts +0 -19
- package/dist/tui/components/CreateEnsembleWizard.js +0 -223
- package/dist/tui/components/DestroyConfirmModal.d.ts +0 -17
- package/dist/tui/components/DestroyConfirmModal.js +0 -62
- package/dist/tui/components/ErrorView.d.ts +0 -31
- package/dist/tui/components/ErrorView.js +0 -129
- package/dist/tui/components/HomeView.d.ts +0 -54
- package/dist/tui/components/HomeView.js +0 -306
- package/dist/tui/components/LoadLineupModal.d.ts +0 -18
- package/dist/tui/components/LoadLineupModal.js +0 -79
- package/dist/tui/components/MainView.d.ts +0 -21
- package/dist/tui/components/MainView.js +0 -107
- package/dist/tui/components/NewEnsembleModal.d.ts +0 -9
- package/dist/tui/components/NewEnsembleModal.js +0 -73
- package/dist/tui/components/Picker.d.ts +0 -23
- package/dist/tui/components/Picker.js +0 -70
- package/dist/tui/components/PlayerDetailView.d.ts +0 -26
- package/dist/tui/components/PlayerDetailView.js +0 -118
- package/dist/tui/components/PromptArea.d.ts +0 -50
- package/dist/tui/components/PromptArea.js +0 -303
- package/dist/tui/components/RecruitWizard.d.ts +0 -17
- package/dist/tui/components/RecruitWizard.js +0 -221
- package/dist/tui/components/RestoreConfirmModal.d.ts +0 -18
- package/dist/tui/components/RestoreConfirmModal.js +0 -71
- package/dist/tui/components/ScheduleWizard.d.ts +0 -19
- package/dist/tui/components/ScheduleWizard.js +0 -259
- package/dist/tui/components/Splash.d.ts +0 -23
- package/dist/tui/components/Splash.js +0 -221
- package/dist/tui/components/StatusBar.d.ts +0 -48
- package/dist/tui/components/StatusBar.js +0 -128
- package/dist/tui/components/StatusOverlay.d.ts +0 -15
- package/dist/tui/components/StatusOverlay.js +0 -76
- package/dist/tui/components/TitleBar.d.ts +0 -10
- package/dist/tui/components/TitleBar.js +0 -21
- package/dist/tui/index.d.ts +0 -15
- package/dist/tui/index.js +0 -162
- package/dist/tui/ink-context.d.ts +0 -18
- package/dist/tui/ink-context.js +0 -59
- package/dist/tui/ink-loader.d.ts +0 -26
- package/dist/tui/ink-loader.js +0 -42
- package/dist/tui/removed-commands.d.ts +0 -9
- package/dist/tui/removed-commands.js +0 -22
- package/dist/tui/sse-handler.d.ts +0 -52
- package/dist/tui/sse-handler.js +0 -157
- package/dist/tui/store.d.ts +0 -598
- package/dist/tui/store.js +0 -753
- package/dist/tui/utils/format.d.ts +0 -56
- package/dist/tui/utils/format.js +0 -155
- package/dist/tui/utils/fullscreen.d.ts +0 -23
- package/dist/tui/utils/fullscreen.js +0 -71
- package/dist/tui/utils/history.d.ts +0 -10
- package/dist/tui/utils/history.js +0 -85
- package/dist/tui/utils/platform.d.ts +0 -45
- package/dist/tui/utils/platform.js +0 -258
- package/dist/tui/utils/theme.d.ts +0 -21
- package/dist/tui/utils/theme.js +0 -24
package/dist/server-tools.js
CHANGED
|
@@ -11,9 +11,8 @@ const listen_1 = require("./tools/listen");
|
|
|
11
11
|
const recruit_1 = require("./tools/recruit");
|
|
12
12
|
const report_1 = require("./tools/report");
|
|
13
13
|
const set_name_1 = require("./tools/set-name");
|
|
14
|
+
// #793 — canonical `schedule` (action create|cancel|list) + unschedule/schedules aliases.
|
|
14
15
|
const schedule_1 = require("./tools/schedule");
|
|
15
|
-
const unschedule_1 = require("./tools/unschedule");
|
|
16
|
-
const schedules_1 = require("./tools/schedules");
|
|
17
16
|
const save_lineup_1 = require("./tools/save-lineup");
|
|
18
17
|
const load_lineup_1 = require("./tools/load-lineup");
|
|
19
18
|
const agent_types_1 = require("./tools/agent-types");
|
|
@@ -25,13 +24,13 @@ const pause_1 = require("./tools/pause");
|
|
|
25
24
|
const play_1 = require("./tools/play");
|
|
26
25
|
const shutdown_1 = require("./tools/shutdown");
|
|
27
26
|
const restore_1 = require("./tools/restore");
|
|
28
|
-
|
|
27
|
+
// #793 — canonical `gate` (action define|list) + quality_gate/gates aliases.
|
|
28
|
+
// `evaluate_gate` stays a SEPARATE tool (partial merge — runtime op, not CRUD).
|
|
29
|
+
const gate_1 = require("./tools/gate");
|
|
29
30
|
const evaluate_gate_1 = require("./tools/evaluate-gate");
|
|
30
|
-
const gates_1 = require("./tools/gates");
|
|
31
31
|
const worktree_1 = require("./tools/worktree");
|
|
32
|
+
// #793 — canonical `stage` (action create|list|cancel) + stages/cancel_stage aliases.
|
|
32
33
|
const stage_1 = require("./tools/stage");
|
|
33
|
-
const stages_1 = require("./tools/stages");
|
|
34
|
-
const cancel_stage_1 = require("./tools/cancel-stage");
|
|
35
34
|
const restart_1 = require("./tools/restart");
|
|
36
35
|
const destroy_1 = require("./tools/destroy");
|
|
37
36
|
const reset_1 = require("./tools/reset");
|
|
@@ -39,15 +38,12 @@ const migrate_1 = require("./tools/migrate");
|
|
|
39
38
|
const attachment_info_1 = require("./tools/attachment-info");
|
|
40
39
|
const hosts_1 = require("./tools/hosts");
|
|
41
40
|
const set_ensemble_description_1 = require("./tools/set-ensemble-description");
|
|
42
|
-
// #334 PR-1 —
|
|
43
|
-
|
|
44
|
-
const
|
|
45
|
-
|
|
46
|
-
//
|
|
47
|
-
const
|
|
48
|
-
const coat_check_get_1 = require("./tools/coat-check-get");
|
|
49
|
-
const coat_check_list_1 = require("./tools/coat-check-list");
|
|
50
|
-
const coat_check_evict_1 = require("./tools/coat-check-evict");
|
|
41
|
+
// #334 PR-1 / #793 — canonical `state` (action save|fetch|clear) + save_state/
|
|
42
|
+
// fetch_state/clear_state aliases.
|
|
43
|
+
const state_1 = require("./tools/state");
|
|
44
|
+
// #318 / #793 — canonical `coat_check` (action put|get|list|evict) +
|
|
45
|
+
// coat_check_put/get/list/evict aliases.
|
|
46
|
+
const coat_check_1 = require("./tools/coat-check");
|
|
51
47
|
const respond_1 = require("./tools/respond");
|
|
52
48
|
/**
|
|
53
49
|
* Register every tempo MCP tool onto `server`. Single source of truth — the
|
|
@@ -69,9 +65,10 @@ function buildAllTempoTools(opts) {
|
|
|
69
65
|
(0, listen_1.buildListenTool)(handle),
|
|
70
66
|
(0, recruit_1.buildRecruitTool)(client, config, getPlayerId, handle, ownAgentType, defaultAgentSource),
|
|
71
67
|
(0, report_1.buildReportTool)(handle),
|
|
68
|
+
// #793 — canonical `schedule` (action defaults to "create") + legacy
|
|
69
|
+
// unschedule/schedules forwarding aliases.
|
|
72
70
|
(0, schedule_1.buildScheduleTool)(client, config, getPlayerId),
|
|
73
|
-
(0,
|
|
74
|
-
(0, schedules_1.buildSchedulesTool)(client, config),
|
|
71
|
+
...(0, schedule_1.buildScheduleAliasTools)(client, config),
|
|
75
72
|
(0, save_lineup_1.buildSaveLineupTool)(client, config, getPlayerId, isConductor),
|
|
76
73
|
(0, load_lineup_1.buildLoadLineupTool)(client, config, getPlayerId, ownAgentType, handle, setPlayerId, isConductor),
|
|
77
74
|
(0, agent_types_1.buildAgentTypesTool)(),
|
|
@@ -90,23 +87,27 @@ function buildAllTempoTools(opts) {
|
|
|
90
87
|
(0, attachment_info_1.buildAttachmentInfoTool)(client, config),
|
|
91
88
|
(0, hosts_1.buildHostsTool)(client, config),
|
|
92
89
|
(0, set_ensemble_description_1.buildSetEnsembleDescriptionTool)(client, config),
|
|
93
|
-
// #334 PR-1 — owner-write / peer-read
|
|
94
|
-
|
|
95
|
-
(0,
|
|
96
|
-
(0,
|
|
97
|
-
// #318 —
|
|
98
|
-
//
|
|
99
|
-
// set at the tool layer via
|
|
100
|
-
(
|
|
101
|
-
(0,
|
|
102
|
-
(0,
|
|
103
|
-
(0, coat_check_evict_1.buildCoatCheckEvictTool)(client, config, getPlayerId),
|
|
90
|
+
// #334 PR-1 / #793 — canonical `state` (owner-write / peer-read) + legacy
|
|
91
|
+
// save_state/fetch_state/clear_state forwarding aliases.
|
|
92
|
+
(0, state_1.buildStateTool)(client, config, handle, getPlayerId),
|
|
93
|
+
...(0, state_1.buildStateAliasTools)(client, config, handle, getPlayerId),
|
|
94
|
+
// #318 / #793 — canonical `coat_check` (put/get/list/evict) + legacy
|
|
95
|
+
// coat_check_* forwarding aliases. Any player can put/get/list;
|
|
96
|
+
// owner-or-conductor can evict. Audit identity is set at the tool layer via
|
|
97
|
+
// getPlayerId() — no playerId arg on any schema.
|
|
98
|
+
(0, coat_check_1.buildCoatCheckTool)(client, config, getPlayerId),
|
|
99
|
+
...(0, coat_check_1.buildCoatCheckAliasTools)(client, config, getPlayerId),
|
|
104
100
|
// #700 P2 — answer a planner's correlated `[Q <id>]` question (writes the
|
|
105
101
|
// maestro Q&A mailbox directly; from = getPlayerId(), no spoofable arg).
|
|
106
102
|
(0, respond_1.buildRespondTool)(client, config, getPlayerId),
|
|
107
103
|
];
|
|
108
104
|
if (isConductor) {
|
|
109
|
-
tools.push(
|
|
105
|
+
tools.push(
|
|
106
|
+
// #793 — canonical `gate` (define|list) + quality_gate/gates aliases.
|
|
107
|
+
// `evaluate_gate` stays a separate tool (partial-merge boundary).
|
|
108
|
+
(0, gate_1.buildGateTool)(handle, getPlayerId), (0, evaluate_gate_1.buildEvaluateGateTool)(handle, getPlayerId), ...(0, gate_1.buildGateAliasTools)(handle, getPlayerId), (0, worktree_1.buildWorktreeTool)(client, config, handle, getPlayerId),
|
|
109
|
+
// #793 — canonical `stage` (create|list|cancel) + stages/cancel_stage aliases.
|
|
110
|
+
(0, stage_1.buildStageTool)(handle, getPlayerId), ...(0, stage_1.buildStageAliasTools)(handle));
|
|
110
111
|
}
|
|
111
112
|
return tools;
|
|
112
113
|
}
|
package/dist/server.js
CHANGED
|
@@ -59,6 +59,7 @@ const parent_death_watchdog_1 = require("./utils/parent-death-watchdog");
|
|
|
59
59
|
const grpc_shutdown_guard_1 = require("./utils/grpc-shutdown-guard");
|
|
60
60
|
const action_counters_1 = require("./utils/action-counters");
|
|
61
61
|
const search_attributes_1 = require("./utils/search-attributes");
|
|
62
|
+
const orphan_guard_1 = require("./utils/orphan-guard");
|
|
62
63
|
const log = (...args) => console.error('[agent-tempo]', ...args);
|
|
63
64
|
async function main() {
|
|
64
65
|
(0, parent_death_watchdog_1.installParentDeathWatchdog)();
|
|
@@ -157,6 +158,12 @@ async function main() {
|
|
|
157
158
|
isConductor,
|
|
158
159
|
agentType: isBridgeMode ? 'copilot' : 'claude',
|
|
159
160
|
adapterId,
|
|
161
|
+
// #704 — thread the adapter descriptor's dialog-blocking property onto
|
|
162
|
+
// durable metadata so the session workflow can ARM/DISARM the booting
|
|
163
|
+
// watchdog without importing the client-side registry. This self-bootstrap
|
|
164
|
+
// path is interactive `claude-code` (or the Copilot bridge), so it resolves
|
|
165
|
+
// to disarmed; recruited headless sessions arm via `startRecruitedSession`.
|
|
166
|
+
canBlockOnDialog: adapterDescriptor?.canBlockOnDialog === true,
|
|
160
167
|
},
|
|
161
168
|
// Issue #450 — self-bootstrap path has no resolved player type, so
|
|
162
169
|
// this falls through to `'Conductor session'` for conductors and
|
|
@@ -170,6 +177,41 @@ async function main() {
|
|
|
170
177
|
taskQueue: config.taskQueue,
|
|
171
178
|
},
|
|
172
179
|
};
|
|
180
|
+
// #704 Item 1b — late-orphan self-tombstone guard. A recruited process can
|
|
181
|
+
// launch LONG after its recruit was cancelled (slow / wedged cold start). If
|
|
182
|
+
// this derived id's latest run is CLOSED with a destroy / boot-timeout tombstone
|
|
183
|
+
// MEMO and NO newer RUNNING run exists, this process is that orphan — exit before
|
|
184
|
+
// `start(USE_EXISTING)` bootstraps a brand-new run that collides with whoever took
|
|
185
|
+
// over the worktree. The running-run × close-reason PAIR is the discriminator:
|
|
186
|
+
// every managed re-creation (recruit / restart / migrate / up) pre-creates a
|
|
187
|
+
// RUNNING run, so a legit reuse is seen as RUNNING and simply attaches — it never
|
|
188
|
+
// reaches this branch. Gated `!isConductor` (conductors are operator-driven via
|
|
189
|
+
// `up`, never a recruited orphan). A generous wall-clock TTL bounds a stale
|
|
190
|
+
// tombstone so a much-later legit manual reuse of the same name isn't blocked
|
|
191
|
+
// forever (observed orphan delay ~100min; default 6h, env-overridable).
|
|
192
|
+
if (!isConductor) {
|
|
193
|
+
const ttlMsRaw = Number(process.env[config_1.ENV.ORPHAN_TOMBSTONE_TTL_MS]);
|
|
194
|
+
const orphanTombstoneTtlMs = Number.isFinite(ttlMsRaw) && ttlMsRaw > 0 ? ttlMsRaw : 6 * 60 * 60 * 1000;
|
|
195
|
+
try {
|
|
196
|
+
const desc = await client.workflow.getHandle(workflowId).describe();
|
|
197
|
+
const closeReason = desc.memo?.[search_attributes_1.MEMO_KEYS.closeReason];
|
|
198
|
+
const orphan = (0, orphan_guard_1.shouldSelfExitAsOrphan)({
|
|
199
|
+
statusName: desc.status.name,
|
|
200
|
+
closeReason,
|
|
201
|
+
closeTimeMs: desc.closeTime ? desc.closeTime.getTime() : 0,
|
|
202
|
+
}, orphanTombstoneTtlMs, Date.now());
|
|
203
|
+
if (orphan) {
|
|
204
|
+
log(`recruit was cancelled (close-reason: ${closeReason}) — exiting to avoid ` +
|
|
205
|
+
`re-registering an orphan session for ${workflowId}`);
|
|
206
|
+
process.exit(0);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
catch {
|
|
210
|
+
// No prior run (NotFound) → first-ever start for this id → proceed. Any other
|
|
211
|
+
// describe() failure is non-fatal: the guard is a best-effort backstop, not a
|
|
212
|
+
// correctness gate — fall through and let the start proceed.
|
|
213
|
+
}
|
|
214
|
+
}
|
|
173
215
|
const startedHandle = await client.workflow.start('agentSessionWorkflow', {
|
|
174
216
|
workflowId,
|
|
175
217
|
taskQueue: config.taskQueue,
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-action runtime field guard for the canonical multi-action tools (#793).
|
|
3
|
+
*
|
|
4
|
+
* The tool-family merge (#793) collapses each family into one canonical tool
|
|
5
|
+
* with a flat `{ action, ...per-action optional fields }` param shape. Because
|
|
6
|
+
* the union makes every per-action field optional at the zod boundary (we do
|
|
7
|
+
* NOT use `z.discriminatedUnion` — see docs/design/793-tool-family-merge-brief.md
|
|
8
|
+
* §2), cross-field "this action requires that field" rules are enforced at
|
|
9
|
+
* RUNTIME inside the handler, before dispatch.
|
|
10
|
+
*
|
|
11
|
+
* {@link firstMissing} returns the first required field that is absent so the
|
|
12
|
+
* handler can return a friendly, actionable `fail(...)` message naming the
|
|
13
|
+
* exact tool, action, and field — instead of a cryptic downstream error.
|
|
14
|
+
*/
|
|
15
|
+
/**
|
|
16
|
+
* Return the first field name in `fields` whose value in `args` is "missing"
|
|
17
|
+
* (`undefined`, `null`, or an empty string), or `null` when all are present.
|
|
18
|
+
*
|
|
19
|
+
* Empty-string counts as missing so a canonical handler rejects e.g.
|
|
20
|
+
* `coat_check{action:'get', ticket:''}` with the same friendly error a wholly
|
|
21
|
+
* omitted ticket would produce.
|
|
22
|
+
*/
|
|
23
|
+
export declare function firstMissing(args: Record<string, unknown>, fields: readonly string[]): string | null;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Per-action runtime field guard for the canonical multi-action tools (#793).
|
|
4
|
+
*
|
|
5
|
+
* The tool-family merge (#793) collapses each family into one canonical tool
|
|
6
|
+
* with a flat `{ action, ...per-action optional fields }` param shape. Because
|
|
7
|
+
* the union makes every per-action field optional at the zod boundary (we do
|
|
8
|
+
* NOT use `z.discriminatedUnion` — see docs/design/793-tool-family-merge-brief.md
|
|
9
|
+
* §2), cross-field "this action requires that field" rules are enforced at
|
|
10
|
+
* RUNTIME inside the handler, before dispatch.
|
|
11
|
+
*
|
|
12
|
+
* {@link firstMissing} returns the first required field that is absent so the
|
|
13
|
+
* handler can return a friendly, actionable `fail(...)` message naming the
|
|
14
|
+
* exact tool, action, and field — instead of a cryptic downstream error.
|
|
15
|
+
*/
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.firstMissing = firstMissing;
|
|
18
|
+
/**
|
|
19
|
+
* Return the first field name in `fields` whose value in `args` is "missing"
|
|
20
|
+
* (`undefined`, `null`, or an empty string), or `null` when all are present.
|
|
21
|
+
*
|
|
22
|
+
* Empty-string counts as missing so a canonical handler rejects e.g.
|
|
23
|
+
* `coat_check{action:'get', ticket:''}` with the same friendly error a wholly
|
|
24
|
+
* omitted ticket would produce.
|
|
25
|
+
*/
|
|
26
|
+
function firstMissing(args, fields) {
|
|
27
|
+
for (const field of fields) {
|
|
28
|
+
const v = args[field];
|
|
29
|
+
if (v === undefined || v === null || v === '')
|
|
30
|
+
return field;
|
|
31
|
+
}
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Client } from '@temporalio/client';
|
|
2
|
+
import { Config } from '../config';
|
|
3
|
+
import { type TempoToolDescriptor } from './descriptor';
|
|
4
|
+
/**
|
|
5
|
+
* Canonical `coat_check` tool. Dispatches on `action` to the same per-action
|
|
6
|
+
* logic the legacy tools used. Per-action required fields are runtime-guarded
|
|
7
|
+
* (the flat union makes them optional at the zod boundary).
|
|
8
|
+
*/
|
|
9
|
+
export declare function buildCoatCheckTool(client: Client, config: Config, getPlayerId: () => string): TempoToolDescriptor;
|
|
10
|
+
/**
|
|
11
|
+
* Legacy forwarding aliases — `coat_check_put` / `coat_check_get` /
|
|
12
|
+
* `coat_check_list` / `coat_check_evict`. Each keeps its EXACT original param
|
|
13
|
+
* schema and handler (reused verbatim from the legacy descriptor); only the
|
|
14
|
+
* description gains a deprecation note pointing at the canonical tool.
|
|
15
|
+
*
|
|
16
|
+
* Authored as explicit object literals (not loop-generated) so the
|
|
17
|
+
* surface-drift name scrape and any future static analysis see each alias name
|
|
18
|
+
* adjacent to its description (docs/design/793-tool-family-merge-brief.md §6).
|
|
19
|
+
*/
|
|
20
|
+
export declare function buildCoatCheckAliasTools(client: Client, config: Config, getPlayerId: () => string): TempoToolDescriptor[];
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.buildCoatCheckTool = buildCoatCheckTool;
|
|
4
|
+
exports.buildCoatCheckAliasTools = buildCoatCheckAliasTools;
|
|
5
|
+
/**
|
|
6
|
+
* `coat_check` — canonical multi-action coat-check tool (#793 tool-family merge).
|
|
7
|
+
*
|
|
8
|
+
* Merges the four legacy per-action tools (`coat_check_put` / `coat_check_get` /
|
|
9
|
+
* `coat_check_list` / `coat_check_evict`) into ONE canonical tool with a flat
|
|
10
|
+
* `{ action, ...per-action optional fields }` param shape (NOT a discriminated
|
|
11
|
+
* union — see docs/design/793-tool-family-merge-brief.md §2). The canonical name
|
|
12
|
+
* is **net-new**, so `action` is REQUIRED (no legacy caller to keep compatible).
|
|
13
|
+
*
|
|
14
|
+
* The legacy tools stay registered as thin forwarding aliases
|
|
15
|
+
* ({@link buildCoatCheckAliasTools}) so every existing caller keeps its exact
|
|
16
|
+
* original schema and behaviour — the alias-not-remove invariant (#793). Both the
|
|
17
|
+
* canonical handler and the aliases reuse the legacy descriptors' handler bodies
|
|
18
|
+
* verbatim, so there is a single implementation per action.
|
|
19
|
+
*/
|
|
20
|
+
const zod_1 = require("zod");
|
|
21
|
+
const descriptor_1 = require("./descriptor");
|
|
22
|
+
const action_guard_1 = require("./action-guard");
|
|
23
|
+
const validation_1 = require("../utils/validation");
|
|
24
|
+
const coat_check_put_1 = require("./coat-check-put");
|
|
25
|
+
const coat_check_get_1 = require("./coat-check-get");
|
|
26
|
+
const coat_check_list_1 = require("./coat-check-list");
|
|
27
|
+
const coat_check_evict_1 = require("./coat-check-evict");
|
|
28
|
+
/**
|
|
29
|
+
* Canonical `coat_check` tool. Dispatches on `action` to the same per-action
|
|
30
|
+
* logic the legacy tools used. Per-action required fields are runtime-guarded
|
|
31
|
+
* (the flat union makes them optional at the zod boundary).
|
|
32
|
+
*/
|
|
33
|
+
function buildCoatCheckTool(client, config, getPlayerId) {
|
|
34
|
+
const put = (0, coat_check_put_1.buildCoatCheckPutTool)(client, config, getPlayerId);
|
|
35
|
+
const get = (0, coat_check_get_1.buildCoatCheckGetTool)(client, config, getPlayerId);
|
|
36
|
+
const list = (0, coat_check_list_1.buildCoatCheckListTool)(client, config);
|
|
37
|
+
const evict = (0, coat_check_evict_1.buildCoatCheckEvictTool)(client, config, getPlayerId);
|
|
38
|
+
return {
|
|
39
|
+
name: 'coat_check',
|
|
40
|
+
description: 'Ensemble-shared transient store (stash large artifacts past the cue size cap). ' +
|
|
41
|
+
'action="put" stashes content (summary+content[, contentType, ttlMs]) and returns a ticket; ' +
|
|
42
|
+
'action="get" redeems a ticket (bumps fetch audit); ' +
|
|
43
|
+
'action="list" surveys entry headers (putBy/prefix/unfetchedOnly filters); ' +
|
|
44
|
+
'action="evict" removes an entry early (owner-or-conductor).',
|
|
45
|
+
params: {
|
|
46
|
+
action: zod_1.z.enum(['put', 'get', 'list', 'evict']).describe('Which coat-check operation to perform'),
|
|
47
|
+
// put:
|
|
48
|
+
summary: zod_1.z.string().min(1).max(validation_1.COAT_CHECK_SUMMARY_MAX).optional().describe('put: short human-readable label for the entry'),
|
|
49
|
+
content: zod_1.z.string().min(1).max(validation_1.COAT_CHECK_CONTENT_MAX).optional().describe('put: the body to stash (≤32 KiB)'),
|
|
50
|
+
contentType: zod_1.z.string().max(validation_1.COAT_CHECK_CONTENT_TYPE_MAX).optional().describe('put: optional MIME/content-type hint'),
|
|
51
|
+
ttlMs: zod_1.z.number().int().min(validation_1.COAT_CHECK_TTL_MIN_MS).max(validation_1.COAT_CHECK_TTL_MAX_MS).optional().describe('put: optional time-to-live in ms (default 7d)'),
|
|
52
|
+
// get / evict:
|
|
53
|
+
ticket: zod_1.z.string().regex(validation_1.COAT_CHECK_TICKET_REGEX).max(validation_1.COAT_CHECK_TICKET_MAX).optional().describe('get/evict: the ticket id returned by put'),
|
|
54
|
+
// list:
|
|
55
|
+
putBy: zod_1.z.string().max(validation_1.PLAYER_NAME_MAX).optional().describe('list: filter to entries stashed by this player'),
|
|
56
|
+
prefix: zod_1.z.string().max(validation_1.COAT_CHECK_SUMMARY_MAX).optional().describe('list: filter to entries whose summary starts with this prefix'),
|
|
57
|
+
unfetchedOnly: zod_1.z.boolean().optional().describe('list: only entries that have never been fetched'),
|
|
58
|
+
},
|
|
59
|
+
handler: async (args) => {
|
|
60
|
+
const action = args.action;
|
|
61
|
+
switch (action) {
|
|
62
|
+
case 'put': {
|
|
63
|
+
const m = (0, action_guard_1.firstMissing)(args, ['summary', 'content']);
|
|
64
|
+
if (m)
|
|
65
|
+
return (0, descriptor_1.fail)(`coat_check action="put" requires "${m}".`);
|
|
66
|
+
return put.handler(args);
|
|
67
|
+
}
|
|
68
|
+
case 'get': {
|
|
69
|
+
const m = (0, action_guard_1.firstMissing)(args, ['ticket']);
|
|
70
|
+
if (m)
|
|
71
|
+
return (0, descriptor_1.fail)(`coat_check action="get" requires "${m}".`);
|
|
72
|
+
return get.handler(args);
|
|
73
|
+
}
|
|
74
|
+
case 'list':
|
|
75
|
+
return list.handler(args);
|
|
76
|
+
case 'evict': {
|
|
77
|
+
const m = (0, action_guard_1.firstMissing)(args, ['ticket']);
|
|
78
|
+
if (m)
|
|
79
|
+
return (0, descriptor_1.fail)(`coat_check action="evict" requires "${m}".`);
|
|
80
|
+
return evict.handler(args);
|
|
81
|
+
}
|
|
82
|
+
default:
|
|
83
|
+
return (0, descriptor_1.fail)(`Unknown coat_check action: ${String(action)}. Expected put | get | list | evict.`);
|
|
84
|
+
}
|
|
85
|
+
},
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Legacy forwarding aliases — `coat_check_put` / `coat_check_get` /
|
|
90
|
+
* `coat_check_list` / `coat_check_evict`. Each keeps its EXACT original param
|
|
91
|
+
* schema and handler (reused verbatim from the legacy descriptor); only the
|
|
92
|
+
* description gains a deprecation note pointing at the canonical tool.
|
|
93
|
+
*
|
|
94
|
+
* Authored as explicit object literals (not loop-generated) so the
|
|
95
|
+
* surface-drift name scrape and any future static analysis see each alias name
|
|
96
|
+
* adjacent to its description (docs/design/793-tool-family-merge-brief.md §6).
|
|
97
|
+
*/
|
|
98
|
+
function buildCoatCheckAliasTools(client, config, getPlayerId) {
|
|
99
|
+
const put = (0, coat_check_put_1.buildCoatCheckPutTool)(client, config, getPlayerId);
|
|
100
|
+
const get = (0, coat_check_get_1.buildCoatCheckGetTool)(client, config, getPlayerId);
|
|
101
|
+
const list = (0, coat_check_list_1.buildCoatCheckListTool)(client, config);
|
|
102
|
+
const evict = (0, coat_check_evict_1.buildCoatCheckEvictTool)(client, config, getPlayerId);
|
|
103
|
+
return [
|
|
104
|
+
{
|
|
105
|
+
name: 'coat_check_put',
|
|
106
|
+
description: 'DEPRECATED — use `coat_check` with action="put". ' + put.description,
|
|
107
|
+
params: put.params,
|
|
108
|
+
handler: put.handler,
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
name: 'coat_check_get',
|
|
112
|
+
description: 'DEPRECATED — use `coat_check` with action="get". ' + get.description,
|
|
113
|
+
params: get.params,
|
|
114
|
+
handler: get.handler,
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
name: 'coat_check_list',
|
|
118
|
+
description: 'DEPRECATED — use `coat_check` with action="list". ' + list.description,
|
|
119
|
+
params: list.params,
|
|
120
|
+
handler: list.handler,
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
name: 'coat_check_evict',
|
|
124
|
+
description: 'DEPRECATED — use `coat_check` with action="evict". ' + evict.description,
|
|
125
|
+
params: evict.params,
|
|
126
|
+
handler: evict.handler,
|
|
127
|
+
},
|
|
128
|
+
];
|
|
129
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { WorkflowHandle } from '@temporalio/client';
|
|
2
|
+
import { type TempoToolDescriptor } from './descriptor';
|
|
3
|
+
/**
|
|
4
|
+
* Canonical `gate` tool. Dispatches on `action` (define | list); `evaluate_gate`
|
|
5
|
+
* is intentionally excluded (separate tool).
|
|
6
|
+
*/
|
|
7
|
+
export declare function buildGateTool(handle: WorkflowHandle, getPlayerId: () => string): TempoToolDescriptor;
|
|
8
|
+
/**
|
|
9
|
+
* Legacy forwarding aliases — `quality_gate` → define, `gates` → list. Each
|
|
10
|
+
* keeps its exact original schema + handler; description gains a deprecation
|
|
11
|
+
* note. Explicit object literals (see §6 drift note).
|
|
12
|
+
*/
|
|
13
|
+
export declare function buildGateAliasTools(handle: WorkflowHandle, getPlayerId: () => string): TempoToolDescriptor[];
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.buildGateTool = buildGateTool;
|
|
4
|
+
exports.buildGateAliasTools = buildGateAliasTools;
|
|
5
|
+
/**
|
|
6
|
+
* `gate` — canonical multi-action quality-gate tool (#793 merge, PARTIAL).
|
|
7
|
+
*
|
|
8
|
+
* Merges the two gate-DEFINITION tools (`quality_gate` → define, `gates` → list)
|
|
9
|
+
* into ONE canonical tool. The canonical name is **net-new**, so `action` is
|
|
10
|
+
* REQUIRED.
|
|
11
|
+
*
|
|
12
|
+
* PARTIAL merge: `evaluate_gate` STAYS A SEPARATE TOOL and is NOT folded in.
|
|
13
|
+
* Rationale (brief §3⑤): evaluate is a distinct runtime *operation* — record
|
|
14
|
+
* pass/fail + notes against criteria — not CRUD on the gate *definition*. The
|
|
15
|
+
* define/list-the-gate vs act-on-the-gate line is the partial boundary.
|
|
16
|
+
*
|
|
17
|
+
* Legacy tools stay registered as forwarding aliases ({@link buildGateAliasTools});
|
|
18
|
+
* both paths reuse the legacy handler bodies. Conductor-only (gated in
|
|
19
|
+
* server-tools.ts alongside the other gate/stage tools).
|
|
20
|
+
*/
|
|
21
|
+
const zod_1 = require("zod");
|
|
22
|
+
const descriptor_1 = require("./descriptor");
|
|
23
|
+
const action_guard_1 = require("./action-guard");
|
|
24
|
+
const validation_1 = require("../utils/validation");
|
|
25
|
+
const quality_gate_1 = require("./quality-gate");
|
|
26
|
+
const gates_1 = require("./gates");
|
|
27
|
+
/**
|
|
28
|
+
* Canonical `gate` tool. Dispatches on `action` (define | list); `evaluate_gate`
|
|
29
|
+
* is intentionally excluded (separate tool).
|
|
30
|
+
*/
|
|
31
|
+
function buildGateTool(handle, getPlayerId) {
|
|
32
|
+
const define = (0, quality_gate_1.buildQualityGateTool)(handle, getPlayerId);
|
|
33
|
+
const list = (0, gates_1.buildGatesTool)(handle);
|
|
34
|
+
return {
|
|
35
|
+
name: 'gate',
|
|
36
|
+
description: 'Define and inspect quality gates for a task (conductor only). ' +
|
|
37
|
+
'action="define" sets/replaces a gate (task + criteria); ' +
|
|
38
|
+
'action="list" shows gates and per-criterion status (optional task/status filters). ' +
|
|
39
|
+
'To record pass/fail on criteria, use the separate `evaluate_gate` tool.',
|
|
40
|
+
params: {
|
|
41
|
+
action: zod_1.z.enum(['define', 'list']).describe('Which gate operation to perform'),
|
|
42
|
+
// define / list (filter):
|
|
43
|
+
task: zod_1.z.string().max(validation_1.GATE_TASK_MAX).optional().describe('define: the task this gate guards (required). list: optional task filter.'),
|
|
44
|
+
// define:
|
|
45
|
+
criteria: zod_1.z.array(zod_1.z.string().max(validation_1.GATE_CRITERION_TEXT_MAX)).min(1).max(validation_1.GATE_CRITERIA_MAX).optional().describe('define: the list of criteria that must pass (required)'),
|
|
46
|
+
// list:
|
|
47
|
+
status: zod_1.z.enum(['open', 'passed', 'failed']).optional().describe('list: optional status filter'),
|
|
48
|
+
},
|
|
49
|
+
handler: async (args) => {
|
|
50
|
+
const action = args.action;
|
|
51
|
+
switch (action) {
|
|
52
|
+
case 'define': {
|
|
53
|
+
const m = (0, action_guard_1.firstMissing)(args, ['task', 'criteria']);
|
|
54
|
+
if (m)
|
|
55
|
+
return (0, descriptor_1.fail)(`gate action="define" requires "${m}".`);
|
|
56
|
+
return define.handler(args);
|
|
57
|
+
}
|
|
58
|
+
case 'list':
|
|
59
|
+
return list.handler(args);
|
|
60
|
+
default:
|
|
61
|
+
return (0, descriptor_1.fail)(`Unknown gate action: ${String(action)}. Expected define | list.`);
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Legacy forwarding aliases — `quality_gate` → define, `gates` → list. Each
|
|
68
|
+
* keeps its exact original schema + handler; description gains a deprecation
|
|
69
|
+
* note. Explicit object literals (see §6 drift note).
|
|
70
|
+
*/
|
|
71
|
+
function buildGateAliasTools(handle, getPlayerId) {
|
|
72
|
+
const define = (0, quality_gate_1.buildQualityGateTool)(handle, getPlayerId);
|
|
73
|
+
const list = (0, gates_1.buildGatesTool)(handle);
|
|
74
|
+
return [
|
|
75
|
+
{
|
|
76
|
+
name: 'quality_gate',
|
|
77
|
+
description: 'DEPRECATED — use `gate` with action="define". ' + define.description,
|
|
78
|
+
params: define.params,
|
|
79
|
+
handler: define.handler,
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
name: 'gates',
|
|
83
|
+
description: 'DEPRECATED — use `gate` with action="list". ' + list.description,
|
|
84
|
+
params: list.params,
|
|
85
|
+
handler: list.handler,
|
|
86
|
+
},
|
|
87
|
+
];
|
|
88
|
+
}
|
package/dist/tools/schedule.d.ts
CHANGED
|
@@ -1,4 +1,22 @@
|
|
|
1
1
|
import { Client } from '@temporalio/client';
|
|
2
2
|
import { Config } from '../config';
|
|
3
3
|
import { type TempoToolDescriptor } from './descriptor';
|
|
4
|
+
/**
|
|
5
|
+
* Canonical `schedule` tool (#793 merge) — **reused** name, so `action` defaults
|
|
6
|
+
* to `'create'` for backward-compat (existing callers omit `action` → the legacy
|
|
7
|
+
* bare-`schedule` create behaviour). Actions: `create | cancel | list`.
|
|
8
|
+
*
|
|
9
|
+
* The rich one-of timing validation lives in the create handler (reused
|
|
10
|
+
* verbatim); `cancel` reuses `unschedule`, `list` reuses `schedules`. The legacy
|
|
11
|
+
* `unschedule` / `schedules` names stay registered as forwarding aliases
|
|
12
|
+
* ({@link buildScheduleAliasTools}); there is no alias for `create` — the bare
|
|
13
|
+
* `schedule` IS create.
|
|
14
|
+
*/
|
|
4
15
|
export declare function buildScheduleTool(client: Client, config: Config, getPlayerId: () => string): TempoToolDescriptor;
|
|
16
|
+
/**
|
|
17
|
+
* Legacy forwarding aliases — `unschedule` → cancel, `schedules` → list. Each
|
|
18
|
+
* keeps its exact original schema + handler; description gains a deprecation
|
|
19
|
+
* note. No alias for `create` — the bare `schedule` IS create. Explicit object
|
|
20
|
+
* literals (see #793 brief §6 drift note).
|
|
21
|
+
*/
|
|
22
|
+
export declare function buildScheduleAliasTools(client: Client, config: Config): TempoToolDescriptor[];
|
package/dist/tools/schedule.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.buildScheduleTool = buildScheduleTool;
|
|
4
|
+
exports.buildScheduleAliasTools = buildScheduleAliasTools;
|
|
4
5
|
const zod_1 = require("zod");
|
|
5
6
|
const croner_1 = require("croner");
|
|
6
7
|
const client_1 = require("@temporalio/client");
|
|
@@ -8,9 +9,18 @@ const config_1 = require("../config");
|
|
|
8
9
|
const duration_1 = require("../utils/duration");
|
|
9
10
|
const resolve_1 = require("./resolve");
|
|
10
11
|
const descriptor_1 = require("./descriptor");
|
|
12
|
+
const action_guard_1 = require("./action-guard");
|
|
13
|
+
const unschedule_1 = require("./unschedule");
|
|
14
|
+
const schedules_1 = require("./schedules");
|
|
11
15
|
const validation_1 = require("../utils/validation");
|
|
12
16
|
const log = (...args) => console.error('[agent-tempo:schedule]', ...args);
|
|
13
|
-
|
|
17
|
+
/**
|
|
18
|
+
* Internal create-only descriptor (the legacy bare-`schedule` behaviour). Its
|
|
19
|
+
* `.handler` is reused verbatim by the canonical {@link buildScheduleTool}
|
|
20
|
+
* dispatch under `action="create"`. Not exported — the canonical tool is the
|
|
21
|
+
* public surface.
|
|
22
|
+
*/
|
|
23
|
+
function buildScheduleCreateTool(client, config, getPlayerId) {
|
|
14
24
|
return {
|
|
15
25
|
name: 'schedule',
|
|
16
26
|
description: 'Schedule a message to be sent to a player at a specific time, after a delay, on a recurring interval, or via cron expression.',
|
|
@@ -155,3 +165,85 @@ function buildScheduleTool(client, config, getPlayerId) {
|
|
|
155
165
|
},
|
|
156
166
|
};
|
|
157
167
|
}
|
|
168
|
+
/**
|
|
169
|
+
* Canonical `schedule` tool (#793 merge) — **reused** name, so `action` defaults
|
|
170
|
+
* to `'create'` for backward-compat (existing callers omit `action` → the legacy
|
|
171
|
+
* bare-`schedule` create behaviour). Actions: `create | cancel | list`.
|
|
172
|
+
*
|
|
173
|
+
* The rich one-of timing validation lives in the create handler (reused
|
|
174
|
+
* verbatim); `cancel` reuses `unschedule`, `list` reuses `schedules`. The legacy
|
|
175
|
+
* `unschedule` / `schedules` names stay registered as forwarding aliases
|
|
176
|
+
* ({@link buildScheduleAliasTools}); there is no alias for `create` — the bare
|
|
177
|
+
* `schedule` IS create.
|
|
178
|
+
*/
|
|
179
|
+
function buildScheduleTool(client, config, getPlayerId) {
|
|
180
|
+
const create = buildScheduleCreateTool(client, config, getPlayerId);
|
|
181
|
+
const cancel = (0, unschedule_1.buildUnscheduleTool)(client, config);
|
|
182
|
+
const list = (0, schedules_1.buildSchedulesTool)(client, config);
|
|
183
|
+
return {
|
|
184
|
+
name: 'schedule',
|
|
185
|
+
description: 'Schedule messages to players (one-shot, delay, recurring, or cron). ' +
|
|
186
|
+
'action="create" (default) schedules a message (name+message+target + one timing of at/delay/every/cron); ' +
|
|
187
|
+
'action="cancel" removes a named schedule; ' +
|
|
188
|
+
'action="list" shows all active schedules.',
|
|
189
|
+
params: {
|
|
190
|
+
action: zod_1.z.enum(['create', 'cancel', 'list']).optional().describe('Which schedule operation to perform (defaults to "create" when omitted)'),
|
|
191
|
+
// create:
|
|
192
|
+
name: zod_1.z.string().max(validation_1.SCHEDULE_NAME_MAX).optional().describe('create/cancel: unique name for this schedule'),
|
|
193
|
+
message: zod_1.z.string().max(validation_1.SCHEDULE_MESSAGE_MAX).optional().describe('create: the message to deliver'),
|
|
194
|
+
target: zod_1.z.string().max(validation_1.PLAYER_NAME_MAX).optional().describe('create: player to deliver to ("self" = this session)'),
|
|
195
|
+
at: zod_1.z.string().optional().describe('create: ISO datetime for one-shot delivery'),
|
|
196
|
+
delay: zod_1.z.string().optional().describe('create: duration until first delivery (e.g. "10m", "2h", "1d")'),
|
|
197
|
+
every: zod_1.z.string().optional().describe('create: recurring interval (e.g. "5m", "1h")'),
|
|
198
|
+
cron: zod_1.z.string().max(validation_1.CRON_EXPRESSION_MAX).optional().describe('create: cron expression. Mutually exclusive with at/delay/every.'),
|
|
199
|
+
timezone: zod_1.z.string().optional().describe('create: IANA timezone for cron evaluation (default UTC). Only with cron.'),
|
|
200
|
+
until: zod_1.z.string().optional().describe('create: ISO datetime — stop recurring after this time'),
|
|
201
|
+
count: zod_1.z.number().optional().describe('create: max number of deliveries for recurring schedules'),
|
|
202
|
+
},
|
|
203
|
+
handler: async (args) => {
|
|
204
|
+
const action = args.action ?? 'create';
|
|
205
|
+
switch (action) {
|
|
206
|
+
case 'create': {
|
|
207
|
+
const m = (0, action_guard_1.firstMissing)(args, ['name', 'message', 'target']);
|
|
208
|
+
if (m)
|
|
209
|
+
return (0, descriptor_1.fail)(`schedule action="create" requires "${m}".`);
|
|
210
|
+
return create.handler(args);
|
|
211
|
+
}
|
|
212
|
+
case 'cancel': {
|
|
213
|
+
const m = (0, action_guard_1.firstMissing)(args, ['name']);
|
|
214
|
+
if (m)
|
|
215
|
+
return (0, descriptor_1.fail)(`schedule action="cancel" requires "${m}".`);
|
|
216
|
+
return cancel.handler(args);
|
|
217
|
+
}
|
|
218
|
+
case 'list':
|
|
219
|
+
return list.handler(args);
|
|
220
|
+
default:
|
|
221
|
+
return (0, descriptor_1.fail)(`Unknown schedule action: ${String(action)}. Expected create | cancel | list.`);
|
|
222
|
+
}
|
|
223
|
+
},
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* Legacy forwarding aliases — `unschedule` → cancel, `schedules` → list. Each
|
|
228
|
+
* keeps its exact original schema + handler; description gains a deprecation
|
|
229
|
+
* note. No alias for `create` — the bare `schedule` IS create. Explicit object
|
|
230
|
+
* literals (see #793 brief §6 drift note).
|
|
231
|
+
*/
|
|
232
|
+
function buildScheduleAliasTools(client, config) {
|
|
233
|
+
const cancel = (0, unschedule_1.buildUnscheduleTool)(client, config);
|
|
234
|
+
const list = (0, schedules_1.buildSchedulesTool)(client, config);
|
|
235
|
+
return [
|
|
236
|
+
{
|
|
237
|
+
name: 'unschedule',
|
|
238
|
+
description: 'DEPRECATED — use `schedule` with action="cancel". ' + cancel.description,
|
|
239
|
+
params: cancel.params,
|
|
240
|
+
handler: cancel.handler,
|
|
241
|
+
},
|
|
242
|
+
{
|
|
243
|
+
name: 'schedules',
|
|
244
|
+
description: 'DEPRECATED — use `schedule` with action="list". ' + list.description,
|
|
245
|
+
params: list.params,
|
|
246
|
+
handler: list.handler,
|
|
247
|
+
},
|
|
248
|
+
];
|
|
249
|
+
}
|
package/dist/tools/stage.d.ts
CHANGED
|
@@ -1,3 +1,20 @@
|
|
|
1
1
|
import { WorkflowHandle } from '@temporalio/client';
|
|
2
2
|
import { type TempoToolDescriptor } from './descriptor';
|
|
3
|
+
/**
|
|
4
|
+
* Canonical `stage` tool (#793 merge) — **reused** name, so `action` defaults to
|
|
5
|
+
* `'create'` for backward-compat. Actions: `create | list | cancel` (all CRUD
|
|
6
|
+
* peers on the same StageEntry — see #793 brief §4). Conductor-only (gated in
|
|
7
|
+
* server-tools.ts).
|
|
8
|
+
*
|
|
9
|
+
* The legacy `stages` / `cancel_stage` names stay registered as forwarding
|
|
10
|
+
* aliases ({@link buildStageAliasTools}); there is no alias for `create` — the
|
|
11
|
+
* bare `stage` IS create.
|
|
12
|
+
*/
|
|
3
13
|
export declare function buildStageTool(handle: WorkflowHandle, getPlayerId: () => string): TempoToolDescriptor;
|
|
14
|
+
/**
|
|
15
|
+
* Legacy forwarding aliases — `stages` → list, `cancel_stage` → cancel. Each
|
|
16
|
+
* keeps its exact original schema + handler; description gains a deprecation
|
|
17
|
+
* note. No alias for `create` — the bare `stage` IS create. Explicit object
|
|
18
|
+
* literals (see #793 brief §6 drift note).
|
|
19
|
+
*/
|
|
20
|
+
export declare function buildStageAliasTools(handle: WorkflowHandle): TempoToolDescriptor[];
|