agent-tempo 1.3.1 → 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 +39 -5
- package/README.md +6 -2
- 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 +1 -1
- package/dashboard/package.json +1 -1
- 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/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/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 +32 -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/server-tools.d.ts +2 -0
- package/dist/server-tools.js +50 -46
- package/dist/spawn.d.ts +55 -0
- package/dist/spawn.js +72 -0
- 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 +29 -24
- package/dist/tools/coat-check-get.d.ts +2 -2
- package/dist/tools/coat-check-get.js +38 -33
- 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 +38 -33
- 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 +42 -37
- 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 +31 -26
- 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/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/package.json +4 -1
- package/workflow-bundle.js +97 -6
- package/dashboard/dist/assets/index-D6Xyje_n.js.map +0 -1
- package/dist/tools/helpers.d.ts +0 -21
- package/dist/tools/helpers.js +0 -25
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.UnsupportedZodFeatureError = void 0;
|
|
4
|
+
exports.zodShapeToTypeBox = zodShapeToTypeBox;
|
|
5
|
+
const typebox_1 = require("typebox");
|
|
6
|
+
/**
|
|
7
|
+
* Thrown when a tool param schema uses a zod construct outside the audited
|
|
8
|
+
* subset. Carries the field path + offending feature so CI / callers can point
|
|
9
|
+
* at the exact source. A named class lets the parity test assert "raised on
|
|
10
|
+
* nothing" precisely.
|
|
11
|
+
*/
|
|
12
|
+
class UnsupportedZodFeatureError extends Error {
|
|
13
|
+
context;
|
|
14
|
+
feature;
|
|
15
|
+
constructor(context, feature) {
|
|
16
|
+
const where = `${context.tool ? `${context.tool}.` : ''}${context.path || '<root>'}`;
|
|
17
|
+
super(`zod→TypeBox: unsupported feature "${feature}" at ${where}. ` +
|
|
18
|
+
`Extend src/pi/zod-to-typebox.ts (and a unit test) if this construct is intentional.`);
|
|
19
|
+
this.context = context;
|
|
20
|
+
this.feature = feature;
|
|
21
|
+
this.name = 'UnsupportedZodFeatureError';
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
exports.UnsupportedZodFeatureError = UnsupportedZodFeatureError;
|
|
25
|
+
function defOf(zt) {
|
|
26
|
+
return zt._def;
|
|
27
|
+
}
|
|
28
|
+
const SCALAR_TYPE_NAMES = new Set([
|
|
29
|
+
'ZodString',
|
|
30
|
+
'ZodNumber',
|
|
31
|
+
'ZodBoolean',
|
|
32
|
+
'ZodEnum',
|
|
33
|
+
'ZodLiteral',
|
|
34
|
+
]);
|
|
35
|
+
/**
|
|
36
|
+
* Convert a tool's zod param shape into a TypeBox object schema suitable for
|
|
37
|
+
* `pi.registerTool({ parameters })`. This is the public entry point consumed by
|
|
38
|
+
* the Pi front-end (`src/pi/render-tools.ts`).
|
|
39
|
+
*
|
|
40
|
+
* @param shape The tool's `z.ZodRawShape` (the `paramsSchema` from `defineTool`).
|
|
41
|
+
* @param toolName Optional tool name, woven into error messages.
|
|
42
|
+
* @throws {UnsupportedZodFeatureError} on any zod construct outside the subset.
|
|
43
|
+
*/
|
|
44
|
+
function zodShapeToTypeBox(shape, toolName) {
|
|
45
|
+
return buildObject(shape, { tool: toolName, path: '' });
|
|
46
|
+
}
|
|
47
|
+
function buildObject(shape, ctx, meta = {}) {
|
|
48
|
+
const props = {};
|
|
49
|
+
for (const [key, zt] of Object.entries(shape)) {
|
|
50
|
+
const fieldCtx = {
|
|
51
|
+
tool: ctx.tool,
|
|
52
|
+
path: ctx.path ? `${ctx.path}.${key}` : key,
|
|
53
|
+
};
|
|
54
|
+
const { inner, isOptional, outerDescription } = stripOptional(zt);
|
|
55
|
+
const schema = convert(inner, fieldCtx, outerDescription);
|
|
56
|
+
props[key] = isOptional ? typebox_1.Type.Optional(schema) : schema;
|
|
57
|
+
}
|
|
58
|
+
return typebox_1.Type.Object(props, meta);
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Peel a single `.optional()` wrapper. Captures the description authored on the
|
|
62
|
+
* wrapper (e.g. `z.string().optional().describe('…')` puts it on the optional)
|
|
63
|
+
* so it survives onto the inner schema.
|
|
64
|
+
*/
|
|
65
|
+
function stripOptional(zt) {
|
|
66
|
+
const def = defOf(zt);
|
|
67
|
+
if (def?.typeName === 'ZodOptional') {
|
|
68
|
+
return { inner: def.innerType, isOptional: true, outerDescription: def.description };
|
|
69
|
+
}
|
|
70
|
+
return { inner: zt, isOptional: false };
|
|
71
|
+
}
|
|
72
|
+
/** Convert a NON-optional zod type. `descOverride` wins over the node's own description. */
|
|
73
|
+
function convert(zt, ctx, descOverride) {
|
|
74
|
+
const def = defOf(zt);
|
|
75
|
+
const typeName = def?.typeName;
|
|
76
|
+
const description = descOverride ?? def?.description;
|
|
77
|
+
const meta = description !== undefined ? { description } : {};
|
|
78
|
+
switch (typeName) {
|
|
79
|
+
case 'ZodString':
|
|
80
|
+
return typebox_1.Type.String({ ...meta, ...stringConstraints(zt, ctx) });
|
|
81
|
+
case 'ZodNumber': {
|
|
82
|
+
const { isInt, opts } = numberConstraints(zt, ctx);
|
|
83
|
+
const numMeta = { ...meta, ...opts };
|
|
84
|
+
return isInt ? typebox_1.Type.Integer(numMeta) : typebox_1.Type.Number(numMeta);
|
|
85
|
+
}
|
|
86
|
+
case 'ZodBoolean':
|
|
87
|
+
return typebox_1.Type.Boolean(meta);
|
|
88
|
+
case 'ZodEnum': {
|
|
89
|
+
const values = def.values;
|
|
90
|
+
return typebox_1.Type.Union(values.map((v) => typebox_1.Type.Literal(v)), meta);
|
|
91
|
+
}
|
|
92
|
+
case 'ZodLiteral':
|
|
93
|
+
return typebox_1.Type.Literal(def.value, meta);
|
|
94
|
+
case 'ZodArray':
|
|
95
|
+
return typebox_1.Type.Array(arrayElement(def.type, ctx), {
|
|
96
|
+
...meta,
|
|
97
|
+
...arrayConstraints(zt, ctx),
|
|
98
|
+
});
|
|
99
|
+
case 'ZodObject':
|
|
100
|
+
return buildObject(def.shape(), ctx, meta);
|
|
101
|
+
case 'ZodUnion':
|
|
102
|
+
return convertUnion(zt, ctx, meta);
|
|
103
|
+
default:
|
|
104
|
+
throw new UnsupportedZodFeatureError(ctx, typeName ?? 'unknown (not a zod type)');
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
/** Array elements are converted as non-optional types; an optional element is rejected. */
|
|
108
|
+
function arrayElement(el, ctx) {
|
|
109
|
+
const { inner, isOptional } = stripOptional(el);
|
|
110
|
+
if (isOptional) {
|
|
111
|
+
throw new UnsupportedZodFeatureError({ ...ctx, path: `${ctx.path}[]` }, 'optional array element');
|
|
112
|
+
}
|
|
113
|
+
return convert(inner, { ...ctx, path: `${ctx.path}[]` });
|
|
114
|
+
}
|
|
115
|
+
function stringConstraints(zt, ctx) {
|
|
116
|
+
const out = {};
|
|
117
|
+
for (const check of (defOf(zt).checks ?? [])) {
|
|
118
|
+
switch (check.kind) {
|
|
119
|
+
case 'min':
|
|
120
|
+
out.minLength = check.value;
|
|
121
|
+
break;
|
|
122
|
+
case 'max':
|
|
123
|
+
out.maxLength = check.value;
|
|
124
|
+
break;
|
|
125
|
+
case 'regex':
|
|
126
|
+
out.pattern = check.regex.source;
|
|
127
|
+
break;
|
|
128
|
+
default:
|
|
129
|
+
throw new UnsupportedZodFeatureError(ctx, `z.string().${String(check.kind)}()`);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
return out;
|
|
133
|
+
}
|
|
134
|
+
function numberConstraints(zt, ctx) {
|
|
135
|
+
let isInt = false;
|
|
136
|
+
const opts = {};
|
|
137
|
+
for (const check of (defOf(zt).checks ?? [])) {
|
|
138
|
+
switch (check.kind) {
|
|
139
|
+
case 'int':
|
|
140
|
+
isInt = true;
|
|
141
|
+
break;
|
|
142
|
+
case 'min':
|
|
143
|
+
if (check.inclusive === false) {
|
|
144
|
+
throw new UnsupportedZodFeatureError(ctx, 'z.number() exclusive minimum (.gt)');
|
|
145
|
+
}
|
|
146
|
+
opts.minimum = check.value;
|
|
147
|
+
break;
|
|
148
|
+
case 'max':
|
|
149
|
+
if (check.inclusive === false) {
|
|
150
|
+
throw new UnsupportedZodFeatureError(ctx, 'z.number() exclusive maximum (.lt)');
|
|
151
|
+
}
|
|
152
|
+
opts.maximum = check.value;
|
|
153
|
+
break;
|
|
154
|
+
default:
|
|
155
|
+
throw new UnsupportedZodFeatureError(ctx, `z.number().${String(check.kind)}()`);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
return { isInt, opts };
|
|
159
|
+
}
|
|
160
|
+
function arrayConstraints(zt, ctx) {
|
|
161
|
+
// NOTE: zod stores array length bounds as named `_def` FIELDS
|
|
162
|
+
// (`minLength`/`maxLength`/`exactLength`), NOT as `_def.checks[]` entries like
|
|
163
|
+
// string and number bounds. Don't "unify" this with stringConstraints /
|
|
164
|
+
// numberConstraints — they read a genuinely different zod representation.
|
|
165
|
+
const def = defOf(zt);
|
|
166
|
+
const out = {};
|
|
167
|
+
if (def.exactLength) {
|
|
168
|
+
throw new UnsupportedZodFeatureError(ctx, 'z.array().length() (exact length)');
|
|
169
|
+
}
|
|
170
|
+
if (def.minLength)
|
|
171
|
+
out.minItems = def.minLength.value;
|
|
172
|
+
if (def.maxLength)
|
|
173
|
+
out.maxItems = def.maxLength.value;
|
|
174
|
+
return out;
|
|
175
|
+
}
|
|
176
|
+
function convertUnion(zt, ctx, meta) {
|
|
177
|
+
const options = defOf(zt).options;
|
|
178
|
+
const members = options.map((member, i) => {
|
|
179
|
+
const memberCtx = { ...ctx, path: `${ctx.path}|${i}` };
|
|
180
|
+
const { inner, isOptional } = stripOptional(member);
|
|
181
|
+
if (isOptional) {
|
|
182
|
+
throw new UnsupportedZodFeatureError(memberCtx, 'optional union member');
|
|
183
|
+
}
|
|
184
|
+
const memberTypeName = defOf(inner)?.typeName;
|
|
185
|
+
if (memberTypeName === undefined || !SCALAR_TYPE_NAMES.has(memberTypeName)) {
|
|
186
|
+
throw new UnsupportedZodFeatureError(memberCtx, `non-scalar union member (${memberTypeName ?? 'unknown'}); only string/number/boolean/enum/literal members are supported`);
|
|
187
|
+
}
|
|
188
|
+
return convert(inner, memberCtx);
|
|
189
|
+
});
|
|
190
|
+
return typebox_1.Type.Union(members, meta);
|
|
191
|
+
}
|
package/dist/server-tools.d.ts
CHANGED
|
@@ -20,6 +20,7 @@ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
|
20
20
|
import { Client, WorkflowHandle } from '@temporalio/client';
|
|
21
21
|
import { Config } from './config';
|
|
22
22
|
import { AgentType } from './types';
|
|
23
|
+
import { type TempoToolDescriptor } from './tools/descriptor';
|
|
23
24
|
/**
|
|
24
25
|
* Identity + state context every tool registration consumes. The two
|
|
25
26
|
* surfaces (stdio MCP server in `src/server.ts`, in-process MCP server in
|
|
@@ -57,6 +58,7 @@ export interface RegisterAllTempoToolsOpts {
|
|
|
57
58
|
* `opts.isConductor` — non-conductor players don't see them on either
|
|
58
59
|
* surface.
|
|
59
60
|
*/
|
|
61
|
+
export declare function buildAllTempoTools(opts: RegisterAllTempoToolsOpts): TempoToolDescriptor[];
|
|
60
62
|
export declare function registerAllTempoTools(server: McpServer, opts: RegisterAllTempoToolsOpts): void;
|
|
61
63
|
/**
|
|
62
64
|
* Identity + ensemble context for {@link buildServerInstructions}.
|
package/dist/server-tools.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.buildAllTempoTools = buildAllTempoTools;
|
|
3
4
|
exports.registerAllTempoTools = registerAllTempoTools;
|
|
4
5
|
exports.buildServerInstructions = buildServerInstructions;
|
|
6
|
+
const descriptor_1 = require("./tools/descriptor");
|
|
5
7
|
const ensemble_1 = require("./tools/ensemble");
|
|
6
8
|
const cue_1 = require("./tools/cue");
|
|
7
9
|
const set_part_1 = require("./tools/set-part");
|
|
@@ -32,6 +34,7 @@ const stages_1 = require("./tools/stages");
|
|
|
32
34
|
const cancel_stage_1 = require("./tools/cancel-stage");
|
|
33
35
|
const restart_1 = require("./tools/restart");
|
|
34
36
|
const destroy_1 = require("./tools/destroy");
|
|
37
|
+
const reset_1 = require("./tools/reset");
|
|
35
38
|
const migrate_1 = require("./tools/migrate");
|
|
36
39
|
const attachment_info_1 = require("./tools/attachment-info");
|
|
37
40
|
const hosts_1 = require("./tools/hosts");
|
|
@@ -55,55 +58,56 @@ const coat_check_evict_1 = require("./tools/coat-check-evict");
|
|
|
55
58
|
* `opts.isConductor` — non-conductor players don't see them on either
|
|
56
59
|
* surface.
|
|
57
60
|
*/
|
|
58
|
-
function
|
|
61
|
+
function buildAllTempoTools(opts) {
|
|
59
62
|
const { client, config, getPlayerId, setPlayerId, handle, workflowId, ownAgentType, isConductor } = opts;
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
63
|
+
const tools = [
|
|
64
|
+
(0, ensemble_1.buildEnsembleTool)(client, config, getPlayerId, workflowId),
|
|
65
|
+
(0, cue_1.buildCueTool)(client, config, getPlayerId, handle),
|
|
66
|
+
(0, set_part_1.buildSetPartTool)(handle),
|
|
67
|
+
(0, set_name_1.buildSetNameTool)(client, config, handle, getPlayerId, setPlayerId),
|
|
68
|
+
(0, listen_1.buildListenTool)(handle),
|
|
69
|
+
(0, recruit_1.buildRecruitTool)(client, config, getPlayerId, handle, ownAgentType),
|
|
70
|
+
(0, report_1.buildReportTool)(handle),
|
|
71
|
+
(0, schedule_1.buildScheduleTool)(client, config, getPlayerId),
|
|
72
|
+
(0, unschedule_1.buildUnscheduleTool)(client, config),
|
|
73
|
+
(0, schedules_1.buildSchedulesTool)(client, config),
|
|
74
|
+
(0, save_lineup_1.buildSaveLineupTool)(client, config, getPlayerId, isConductor),
|
|
75
|
+
(0, load_lineup_1.buildLoadLineupTool)(client, config, getPlayerId, ownAgentType, handle, setPlayerId, isConductor),
|
|
76
|
+
(0, agent_types_1.buildAgentTypesTool)(),
|
|
77
|
+
(0, who_am_i_1.buildWhoAmITool)(handle, getPlayerId),
|
|
78
|
+
(0, broadcast_1.buildBroadcastTool)(client, config, getPlayerId, handle),
|
|
79
|
+
(0, recall_1.buildRecallTool)(handle, getPlayerId),
|
|
80
|
+
(0, release_1.buildReleaseTool)(client, config, getPlayerId, handle),
|
|
81
|
+
(0, pause_1.buildPauseTool)(client, config, getPlayerId),
|
|
82
|
+
(0, play_1.buildPlayTool)(client, config, getPlayerId),
|
|
83
|
+
(0, shutdown_1.buildShutdownTool)(client, config, getPlayerId),
|
|
84
|
+
(0, restore_1.buildRestoreTool)(client, config, getPlayerId),
|
|
85
|
+
(0, restart_1.buildRestartTool)(client, config, getPlayerId, handle),
|
|
86
|
+
(0, destroy_1.buildDestroyTool)(client, config, getPlayerId, handle),
|
|
87
|
+
(0, reset_1.buildResetTool)(handle, getPlayerId),
|
|
88
|
+
(0, migrate_1.buildMigrateTool)(client, config, getPlayerId, handle),
|
|
89
|
+
(0, attachment_info_1.buildAttachmentInfoTool)(client, config),
|
|
90
|
+
(0, hosts_1.buildHostsTool)(client, config),
|
|
91
|
+
(0, set_ensemble_description_1.buildSetEnsembleDescriptionTool)(client, config),
|
|
92
|
+
// #334 PR-1 — owner-write / peer-read player saveable state.
|
|
93
|
+
(0, save_state_1.buildSaveStateTool)(handle, getPlayerId),
|
|
94
|
+
(0, fetch_state_1.buildFetchStateTool)(client, config, handle, getPlayerId),
|
|
95
|
+
(0, clear_state_1.buildClearStateTool)(handle),
|
|
96
|
+
// #318 — ensemble-shared coat-check (put/get/list/evict). Any player can put;
|
|
97
|
+
// any player can get/list; owner-or-conductor can evict. Audit identity is
|
|
98
|
+
// set at the tool layer via getPlayerId() — no playerId arg on any schema.
|
|
99
|
+
(0, coat_check_put_1.buildCoatCheckPutTool)(client, config, getPlayerId),
|
|
100
|
+
(0, coat_check_get_1.buildCoatCheckGetTool)(client, config, getPlayerId),
|
|
101
|
+
(0, coat_check_list_1.buildCoatCheckListTool)(client, config),
|
|
102
|
+
(0, coat_check_evict_1.buildCoatCheckEvictTool)(client, config, getPlayerId),
|
|
103
|
+
];
|
|
98
104
|
if (isConductor) {
|
|
99
|
-
(0, quality_gate_1.
|
|
100
|
-
(0, evaluate_gate_1.registerEvaluateGateTool)(server, handle, getPlayerId);
|
|
101
|
-
(0, gates_1.registerGatesTool)(server, handle);
|
|
102
|
-
(0, worktree_1.registerWorktreeTool)(server, client, config, handle, getPlayerId);
|
|
103
|
-
(0, stage_1.registerStageTool)(server, handle, getPlayerId);
|
|
104
|
-
(0, stages_1.registerStagesTool)(server, handle);
|
|
105
|
-
(0, cancel_stage_1.registerCancelStageTool)(server, handle);
|
|
105
|
+
tools.push((0, quality_gate_1.buildQualityGateTool)(handle, getPlayerId), (0, evaluate_gate_1.buildEvaluateGateTool)(handle, getPlayerId), (0, gates_1.buildGatesTool)(handle), (0, worktree_1.buildWorktreeTool)(client, config, handle, getPlayerId), (0, stage_1.buildStageTool)(handle, getPlayerId), (0, stages_1.buildStagesTool)(handle), (0, cancel_stage_1.buildCancelStageTool)(handle));
|
|
106
106
|
}
|
|
107
|
+
return tools;
|
|
108
|
+
}
|
|
109
|
+
function registerAllTempoTools(server, opts) {
|
|
110
|
+
(0, descriptor_1.renderToMcp)(server, buildAllTempoTools(opts));
|
|
107
111
|
}
|
|
108
112
|
/**
|
|
109
113
|
* Build the `instructions` string that lands in `McpServer`'s `instructions`
|
package/dist/spawn.d.ts
CHANGED
|
@@ -236,6 +236,61 @@ export interface OpenCodeAdapterResult {
|
|
|
236
236
|
* specific provider key since the model is opaque pass-through).
|
|
237
237
|
*/
|
|
238
238
|
export declare function spawnOpenCodeAdapter(opts: OpenCodeAdapterOpts): OpenCodeAdapterResult;
|
|
239
|
+
/**
|
|
240
|
+
* Options for {@link spawnPiHeadless}. Mirrors {@link OpenCodeAdapterOpts} for
|
|
241
|
+
* identity + Temporal connection + attachment handoff; adds Pi-specific knobs:
|
|
242
|
+
* `model` (provider/model via `AGENT_TEMPO_PI_MODEL`), `continueSessionId`
|
|
243
|
+
* (restart-resume via `AGENT_TEMPO_PI_CONTINUE_SESSION` → Pi `continueSession`),
|
|
244
|
+
* and `toolAccess` (MD-C tool-class policy via `AGENT_TEMPO_TOOL_ACCESS`).
|
|
245
|
+
*
|
|
246
|
+
* Unlike the other headless adapters, the Pi entry does NOT drive a
|
|
247
|
+
* `BaseAttachment` loop — it injects the `src/pi` extension into Pi's
|
|
248
|
+
* `createAgentSession`; the module-scope extension singleton owns the lifecycle.
|
|
249
|
+
*/
|
|
250
|
+
export interface PiHeadlessAdapterOpts {
|
|
251
|
+
name: string;
|
|
252
|
+
ensemble: string;
|
|
253
|
+
temporalAddress: string;
|
|
254
|
+
temporalNamespace?: string;
|
|
255
|
+
temporalApiKey?: string;
|
|
256
|
+
temporalTlsCertPath?: string;
|
|
257
|
+
temporalTlsKeyPath?: string;
|
|
258
|
+
isConductor?: boolean;
|
|
259
|
+
workDir: string;
|
|
260
|
+
/** Directory for log + PID files. Defaults to `logs/` inside workDir. */
|
|
261
|
+
logDir?: string;
|
|
262
|
+
/** Pi provider/model selector (e.g. `anthropic/claude-opus-4-7`); absent → Pi default. */
|
|
263
|
+
model?: string;
|
|
264
|
+
/** Restart-resume: the Pi conversation id to continue (from `metadata.sessionId`). */
|
|
265
|
+
continueSessionId?: string;
|
|
266
|
+
/** MD-C tool-class policy: `restricted` (default) | `standard` | `full`. */
|
|
267
|
+
toolAccess?: string;
|
|
268
|
+
/**
|
|
269
|
+
* 3c Tier-2 ingest token (minted by the daemon outbox, scoped to this player's
|
|
270
|
+
* workflowId). Threaded into the subprocess env as `AGENT_TEMPO_INGEST_TOKEN`
|
|
271
|
+
* so the inner-loop publisher can authenticate `POST /inner/ingest`. NOTE:
|
|
272
|
+
* spawn.ts only THREADS the token — minting lives in the daemon-only outbox
|
|
273
|
+
* (this module runs outside the daemon and must not import the registry).
|
|
274
|
+
*/
|
|
275
|
+
ingestToken?: string;
|
|
276
|
+
/** PR-D attachment-lease handoff (renew rather than fresh-claim on boot). */
|
|
277
|
+
attachmentId?: string;
|
|
278
|
+
attachmentRunId?: string;
|
|
279
|
+
adapterId?: string;
|
|
280
|
+
}
|
|
281
|
+
export interface PiHeadlessAdapterResult {
|
|
282
|
+
pid: number | undefined;
|
|
283
|
+
logPath: string;
|
|
284
|
+
pidPath: string;
|
|
285
|
+
}
|
|
286
|
+
/**
|
|
287
|
+
* Spawn the headless Pi runtime as a detached subprocess. Pattern matches
|
|
288
|
+
* {@link spawnOpenCodeAdapter} — no TTY, log + PID files, env carries identity +
|
|
289
|
+
* Temporal settings + attachment handoff + the Pi model / continue-session /
|
|
290
|
+
* tool-access knobs. The entry constructs `createAgentSession` with the `src/pi`
|
|
291
|
+
* extension injected inline; the singleton claims + heartbeats + registers tools.
|
|
292
|
+
*/
|
|
293
|
+
export declare function spawnPiHeadless(opts: PiHeadlessAdapterOpts): PiHeadlessAdapterResult;
|
|
239
294
|
/**
|
|
240
295
|
* Options for {@link spawnClaudeCodeHeadlessAdapter}. Mirrors
|
|
241
296
|
* {@link ClaudeApiAdapterOpts} for identity + Temporal connection +
|
package/dist/spawn.js
CHANGED
|
@@ -12,6 +12,7 @@ exports.spawnCopilotBridge = spawnCopilotBridge;
|
|
|
12
12
|
exports.spawnMockAdapter = spawnMockAdapter;
|
|
13
13
|
exports.spawnClaudeApiAdapter = spawnClaudeApiAdapter;
|
|
14
14
|
exports.spawnOpenCodeAdapter = spawnOpenCodeAdapter;
|
|
15
|
+
exports.spawnPiHeadless = spawnPiHeadless;
|
|
15
16
|
exports.spawnClaudeCodeHeadlessAdapter = spawnClaudeCodeHeadlessAdapter;
|
|
16
17
|
const child_process_1 = require("child_process");
|
|
17
18
|
const fs_1 = require("fs");
|
|
@@ -671,6 +672,77 @@ function spawnOpenCodeAdapter(opts) {
|
|
|
671
672
|
log(`Spawned opencode adapter (pid ${child.pid}) in ${opts.workDir} as "${opts.name}"${opts.model ? ` (model=${opts.model})` : ''}${opts.attachmentId ? ` (attachmentId=${opts.attachmentId})` : ''}`);
|
|
672
673
|
return { pid: child.pid, logPath, pidPath };
|
|
673
674
|
}
|
|
675
|
+
/**
|
|
676
|
+
* Resolve the path to the Pi headless adapter entry point. Mirrors
|
|
677
|
+
* {@link resolveOpenCodePath} — dev (ts-node) + prod (compiled .js) both launch
|
|
678
|
+
* the same code through the same `require.main === module` gate.
|
|
679
|
+
*/
|
|
680
|
+
function resolvePiPath() {
|
|
681
|
+
const isDev = __filename.endsWith('.ts');
|
|
682
|
+
if (isDev) {
|
|
683
|
+
return { cmd: 'npx', args: ['ts-node', (0, path_1.resolve)(__dirname, 'adapters', 'pi', 'adapter.ts')] };
|
|
684
|
+
}
|
|
685
|
+
return { cmd: 'node', args: [(0, path_1.resolve)(__dirname, 'adapters', 'pi', 'adapter.js')] };
|
|
686
|
+
}
|
|
687
|
+
/**
|
|
688
|
+
* Spawn the headless Pi runtime as a detached subprocess. Pattern matches
|
|
689
|
+
* {@link spawnOpenCodeAdapter} — no TTY, log + PID files, env carries identity +
|
|
690
|
+
* Temporal settings + attachment handoff + the Pi model / continue-session /
|
|
691
|
+
* tool-access knobs. The entry constructs `createAgentSession` with the `src/pi`
|
|
692
|
+
* extension injected inline; the singleton claims + heartbeats + registers tools.
|
|
693
|
+
*/
|
|
694
|
+
function spawnPiHeadless(opts) {
|
|
695
|
+
const { cmd, args } = resolvePiPath();
|
|
696
|
+
const logDirPath = opts.logDir || (0, path_1.join)(opts.workDir, 'logs');
|
|
697
|
+
const logName = opts.name || `pi-${Date.now()}`;
|
|
698
|
+
const logPath = (0, path_1.join)(logDirPath, `${logName}.log`);
|
|
699
|
+
const pidPath = (0, path_1.join)(logDirPath, `${logName}.pid`);
|
|
700
|
+
(0, fs_1.mkdirSync)(logDirPath, { recursive: true });
|
|
701
|
+
const logFd = (0, fs_1.openSync)(logPath, 'a');
|
|
702
|
+
const toolAccess = opts.toolAccess || 'restricted';
|
|
703
|
+
let child;
|
|
704
|
+
try {
|
|
705
|
+
child = (0, child_process_1.spawn)(cmd, args, {
|
|
706
|
+
cwd: opts.workDir,
|
|
707
|
+
detached: true,
|
|
708
|
+
stdio: ['ignore', logFd, logFd],
|
|
709
|
+
env: {
|
|
710
|
+
...process.env,
|
|
711
|
+
[config_1.ENV.ENSEMBLE]: opts.ensemble,
|
|
712
|
+
[config_1.ENV.PLAYER_NAME]: opts.name,
|
|
713
|
+
[config_1.ENV.CONDUCTOR]: opts.isConductor ? 'true' : '',
|
|
714
|
+
[config_1.ENV.TEMPORAL_ADDRESS]: opts.temporalAddress,
|
|
715
|
+
...(opts.temporalNamespace ? { [config_1.ENV.TEMPORAL_NAMESPACE]: opts.temporalNamespace } : {}),
|
|
716
|
+
...(opts.temporalApiKey ? { [config_1.ENV.TEMPORAL_API_KEY]: opts.temporalApiKey } : {}),
|
|
717
|
+
...(opts.temporalTlsCertPath ? { [config_1.ENV.TEMPORAL_TLS_CERT_PATH]: opts.temporalTlsCertPath } : {}),
|
|
718
|
+
...(opts.temporalTlsKeyPath ? { [config_1.ENV.TEMPORAL_TLS_KEY_PATH]: opts.temporalTlsKeyPath } : {}),
|
|
719
|
+
// Model selection: recruit-arg → AGENT_TEMPO_PI_MODEL → Pi default.
|
|
720
|
+
...(opts.model ? { [config_1.ENV.PI_MODEL]: opts.model } : {}),
|
|
721
|
+
// Restart-resume: continue the prior Pi conversation.
|
|
722
|
+
...(opts.continueSessionId ? { [config_1.ENV.PI_CONTINUE_SESSION]: opts.continueSessionId } : {}),
|
|
723
|
+
// MD-C: tool-class policy. ALWAYS set (default 'restricted' — the safe
|
|
724
|
+
// unsupervised default + an explicit value for the gate + audit trail).
|
|
725
|
+
[config_1.ENV.TOOL_ACCESS]: toolAccess,
|
|
726
|
+
// 3c Tier-2: per-player ingest token (minted by the daemon outbox).
|
|
727
|
+
// Absent → the inner-loop publisher's HTTP client no-ops (no fine tail).
|
|
728
|
+
...(opts.ingestToken ? { [config_1.ENV.INGEST_TOKEN]: opts.ingestToken } : {}),
|
|
729
|
+
// Attachment handoff — extension renews via claimAttachment(expectedAttachmentId).
|
|
730
|
+
...(opts.attachmentId ? { [config_1.ENV.ATTACHMENT_ID]: opts.attachmentId } : {}),
|
|
731
|
+
...(opts.attachmentRunId ? { [config_1.ENV.ATTACHMENT_RUN_ID]: opts.attachmentRunId } : {}),
|
|
732
|
+
...(opts.adapterId ? { [config_1.ENV.ADAPTER_ID]: opts.adapterId } : {}),
|
|
733
|
+
},
|
|
734
|
+
});
|
|
735
|
+
child.unref();
|
|
736
|
+
}
|
|
737
|
+
finally {
|
|
738
|
+
(0, fs_1.closeSync)(logFd);
|
|
739
|
+
}
|
|
740
|
+
if (child.pid != null) {
|
|
741
|
+
(0, fs_1.writeFileSync)(pidPath, String(child.pid));
|
|
742
|
+
}
|
|
743
|
+
log(`Spawned pi headless adapter (pid ${child.pid}) in ${opts.workDir} as "${opts.name}" (toolAccess=${toolAccess})${opts.model ? ` (model=${opts.model})` : ''}${opts.continueSessionId ? ` (continue=${opts.continueSessionId})` : ''}${opts.attachmentId ? ` (attachmentId=${opts.attachmentId})` : ''}`);
|
|
744
|
+
return { pid: child.pid, logPath, pidPath };
|
|
745
|
+
}
|
|
674
746
|
/**
|
|
675
747
|
* Resolve the path to the claude-code-headless adapter entry point.
|
|
676
748
|
* Mirrors {@link resolveClaudeApiPath} so dev (ts-node) and prod
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export declare function
|
|
1
|
+
import { type TempoToolDescriptor } from './descriptor';
|
|
2
|
+
export declare function buildAgentTypesTool(): TempoToolDescriptor;
|
|
@@ -1,21 +1,26 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
4
|
-
const
|
|
3
|
+
exports.buildAgentTypesTool = buildAgentTypesTool;
|
|
4
|
+
const descriptor_1 = require("./descriptor");
|
|
5
5
|
const agent_types_1 = require("../ensemble/agent-types");
|
|
6
|
-
function
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
6
|
+
function buildAgentTypesTool() {
|
|
7
|
+
return {
|
|
8
|
+
name: 'agent_types',
|
|
9
|
+
description: 'List available player types (agent definitions) that can be used when recruiting',
|
|
10
|
+
params: {},
|
|
11
|
+
handler: async () => {
|
|
12
|
+
const types = (0, agent_types_1.listAgentTypes)();
|
|
13
|
+
if (types.length === 0) {
|
|
14
|
+
return (0, descriptor_1.ok)('No agent types found.');
|
|
15
|
+
}
|
|
16
|
+
const lines = types.map(t => {
|
|
17
|
+
const src = t.source === 'shipped' ? '(shipped)' : t.source === 'user' ? '(user)' : '(project)';
|
|
18
|
+
const tools = t.allowedTools && t.allowedTools.length > 0
|
|
19
|
+
? `\n Allowed tools: ${t.allowedTools.join(', ')}`
|
|
20
|
+
: '';
|
|
21
|
+
return `**${t.name}** ${src}\n ${t.description || 'No description'}${tools}`;
|
|
22
|
+
});
|
|
23
|
+
return (0, descriptor_1.ok)(lines.join('\n\n'));
|
|
24
|
+
},
|
|
25
|
+
};
|
|
21
26
|
}
|
|
@@ -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 buildAttachmentInfoTool(client: Client, config: Config): TempoToolDescriptor;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.buildAttachmentInfoTool = buildAttachmentInfoTool;
|
|
4
4
|
/**
|
|
5
5
|
* `attachment_info` — diagnostic query for the V2 attachment lifecycle (design §§2.2, 2.4).
|
|
6
6
|
*
|
|
@@ -11,38 +11,43 @@ exports.registerAttachmentInfoTool = registerAttachmentInfoTool;
|
|
|
11
11
|
const zod_1 = require("zod");
|
|
12
12
|
const resolve_1 = require("./resolve");
|
|
13
13
|
const signals_1 = require("../workflows/signals");
|
|
14
|
-
const
|
|
14
|
+
const descriptor_1 = require("./descriptor");
|
|
15
15
|
const validation_1 = require("../utils/validation");
|
|
16
|
-
function
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
const
|
|
26
|
-
if (
|
|
27
|
-
return (0,
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
16
|
+
function buildAttachmentInfoTool(client, config) {
|
|
17
|
+
return {
|
|
18
|
+
name: 'attachment_info',
|
|
19
|
+
description: 'Query the V2 attachment lifecycle state of a session — phase (booting/attached/processing/awaiting/draining/detached/gone), current attachment holder (host + adapter + lease expiry), preferred host, and in-flight message count. Read-only diagnostic.',
|
|
20
|
+
params: {
|
|
21
|
+
playerId: zod_1.z.string().max(validation_1.PLAYER_NAME_MAX).describe('The player name to inspect'),
|
|
22
|
+
},
|
|
23
|
+
handler: async (args) => {
|
|
24
|
+
const { playerId } = args;
|
|
25
|
+
const nameError = (0, validation_1.validatePlayerName)(playerId);
|
|
26
|
+
if (nameError)
|
|
27
|
+
return (0, descriptor_1.fail)(nameError);
|
|
28
|
+
try {
|
|
29
|
+
const resolved = await (0, resolve_1.resolveSession)(client, config.ensemble, playerId);
|
|
30
|
+
if (!resolved)
|
|
31
|
+
return (0, descriptor_1.fail)(`No session found with name "${playerId}".`);
|
|
32
|
+
const info = await resolved.query(signals_1.attachmentInfoQuery);
|
|
33
|
+
const lines = [
|
|
34
|
+
`**${playerId}** — phase: \`${info.phase}\``,
|
|
35
|
+
`in-flight messages: ${info.inFlightCount}`,
|
|
36
|
+
];
|
|
37
|
+
if (info.currentAttachment) {
|
|
38
|
+
const a = info.currentAttachment;
|
|
39
|
+
lines.push(`attached on: **${a.hostname}** (adapter: ${a.adapterId}/${a.adapterClass}, attachmentId: \`${a.attachmentId.slice(0, 8)}…\`)`);
|
|
40
|
+
lines.push(`lease expires: ${a.expiresAt}`);
|
|
41
|
+
}
|
|
42
|
+
if (info.preferredHost)
|
|
43
|
+
lines.push(`preferred host: ${info.preferredHost}`);
|
|
44
|
+
if (info.processingSince)
|
|
45
|
+
lines.push(`processing since: ${info.processingSince}`);
|
|
46
|
+
return (0, descriptor_1.ok)(lines.join('\n'));
|
|
37
47
|
}
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
}
|
|
44
|
-
catch (err) {
|
|
45
|
-
return (0, helpers_1.fail)(`Failed to query attachment info: ${(0, helpers_1.formatError)(err)}`);
|
|
46
|
-
}
|
|
47
|
-
});
|
|
48
|
+
catch (err) {
|
|
49
|
+
return (0, descriptor_1.fail)(`Failed to query attachment info: ${(0, descriptor_1.formatError)(err)}`);
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
};
|
|
48
53
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
1
|
import { Client, WorkflowHandle } from '@temporalio/client';
|
|
3
2
|
import { Config } from '../config';
|
|
4
|
-
|
|
3
|
+
import { type TempoToolDescriptor } from './descriptor';
|
|
4
|
+
export declare function buildBroadcastTool(client: Client, config: Config, getPlayerId: () => string, handle: WorkflowHandle): TempoToolDescriptor;
|