agent-orchestrator-mcp-server 0.7.3 → 0.7.9
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agent-orchestrator-mcp-server",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.9",
|
|
4
4
|
"description": "Local implementation of agent-orchestrator MCP server",
|
|
5
5
|
"main": "build/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"stage-publish": "npm version"
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"@modelcontextprotocol/sdk": "^1.
|
|
32
|
+
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
33
33
|
"zod": "^3.24.1"
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|
|
@@ -241,8 +241,8 @@ export function createIntegrationMockOrchestratorClient(initialMockData) {
|
|
|
241
241
|
if (!session) {
|
|
242
242
|
throw new Error(`API Error (404): Session not found`);
|
|
243
243
|
}
|
|
244
|
-
if (session.status !== 'needs_input') {
|
|
245
|
-
throw new Error(`API Error (422): Session must be in needs_input state to sleep`);
|
|
244
|
+
if (session.status !== 'needs_input' && session.status !== 'running') {
|
|
245
|
+
throw new Error(`API Error (422): Session must be in needs_input or running state to sleep (current: ${session.status})`);
|
|
246
246
|
}
|
|
247
247
|
session.status = 'waiting';
|
|
248
248
|
session.updated_at = new Date().toISOString();
|
|
@@ -633,7 +633,7 @@ export function createIntegrationMockOrchestratorClient(initialMockData) {
|
|
|
633
633
|
return {
|
|
634
634
|
id: 1,
|
|
635
635
|
name: data.name,
|
|
636
|
-
trigger_type: data.trigger_type,
|
|
636
|
+
trigger_type: data.trigger_type || 'schedule',
|
|
637
637
|
status: data.status || 'enabled',
|
|
638
638
|
agent_root_name: data.agent_root_name,
|
|
639
639
|
prompt_template: data.prompt_template,
|
|
@@ -642,7 +642,7 @@ export function createIntegrationMockOrchestratorClient(initialMockData) {
|
|
|
642
642
|
mcp_servers: data.mcp_servers || [],
|
|
643
643
|
configuration: data.configuration || {},
|
|
644
644
|
schedule_description: null,
|
|
645
|
-
last_session_id: null,
|
|
645
|
+
last_session_id: data.last_session_id ?? null,
|
|
646
646
|
last_triggered_at: null,
|
|
647
647
|
last_polled_at: null,
|
|
648
648
|
sessions_created_count: 0,
|
|
@@ -500,7 +500,12 @@ const SELF_SESSION_TOOL_DESCRIPTION = `Perform a self-management action on a ses
|
|
|
500
500
|
**Use cases:**
|
|
501
501
|
- Update session notes to record progress or context
|
|
502
502
|
- Set a meaningful session title
|
|
503
|
-
- Archive the session when work is complete
|
|
503
|
+
- Archive the session when work is complete
|
|
504
|
+
|
|
505
|
+
**Archive guidelines:**
|
|
506
|
+
- Only self-archive when explicitly instructed to (e.g., a stop condition says "archive yourself")
|
|
507
|
+
- Subagents that report results back to a parent agent via a tool call may self-archive, since no human needs to read the session output directly
|
|
508
|
+
- Do NOT self-archive if a human user needs to read your output. Sessions in \`needs_input\` appear on the user's homepage — archiving removes them before the user can see your work. If your work product is a message the user should read, let the session stay in \`needs_input\``;
|
|
504
509
|
export function selfSessionActionSessionTool(_server, clientFactory) {
|
|
505
510
|
return {
|
|
506
511
|
name: 'action_session',
|
|
@@ -11,6 +11,13 @@ function buildToolDescription() {
|
|
|
11
11
|
const utcNow = now.toISOString().replace(/\.\d{3}Z$/, 'Z');
|
|
12
12
|
return `Schedule this session to be woken up at a specific time. The session will be put to sleep (waiting status) and a one-time trigger will fire at the specified time to resume it with the given prompt. If the session is manually resumed before the scheduled time, the trigger will be silently dropped.
|
|
13
13
|
|
|
14
|
+
**IMPORTANT — Use this tool instead of workarounds.** When this tool is available, it is the correct way to schedule a delayed wake-up in an Agent Orchestrator context. Do NOT use these alternatives:
|
|
15
|
+
- **Bash \`sleep\`**: Blocks the process and wastes compute resources for the entire sleep duration. The session remains "running" and cannot be reclaimed.
|
|
16
|
+
- **Claude Code \`ScheduleWakeup\` tool**: Does not integrate with AO's session lifecycle — it won't transition the session to sleeping/waiting state or create an AO trigger, so AO cannot track or manage the wake-up.
|
|
17
|
+
- **Claude Code \`Monitor\` tool**: Same problem — it operates outside AO's session state management.
|
|
18
|
+
|
|
19
|
+
This tool creates a one-time AO wake-up trigger bound to the target session. The AO API atomically transitions the session to sleeping (waiting) state as part of creating the trigger, so AO can reclaim resources and the trigger is guaranteed to resume the correct session at the specified time.
|
|
20
|
+
|
|
14
21
|
**Current server time:** ${utcNow} (UTC). Use this as your reference point when calculating wake-up times.
|
|
15
22
|
|
|
16
23
|
**Timezone handling:**
|
|
@@ -21,16 +28,15 @@ function buildToolDescription() {
|
|
|
21
28
|
- If you omit timezone, wake_at is treated as UTC.
|
|
22
29
|
|
|
23
30
|
**Parameters:**
|
|
24
|
-
- **session_id**: The session to wake up
|
|
31
|
+
- **session_id**: The session to wake up. Works from either \`needs_input\` or \`running\` state — if you call this tool from within your own currently-running session, the sleep transition is recorded and takes effect after the current turn ends.
|
|
25
32
|
- **wake_at**: ISO 8601 datetime without offset for when to wake up (e.g., "2026-04-15T14:30:00")
|
|
26
33
|
- **timezone**: IANA timezone for interpreting wake_at (default: "UTC", e.g., "America/New_York")
|
|
27
34
|
- **prompt**: The prompt to send when waking up the session
|
|
28
35
|
|
|
29
36
|
**What happens:**
|
|
30
|
-
1.
|
|
31
|
-
2.
|
|
32
|
-
3.
|
|
33
|
-
4. The trigger resumes the session with the provided prompt`;
|
|
37
|
+
1. Creates a one-time schedule trigger bound to this session that fires at the specified time.
|
|
38
|
+
2. As a side effect of creating the trigger, the AO API transitions the session to sleeping (waiting) status — immediately if currently \`needs_input\`, or after the current turn ends if currently \`running\`.
|
|
39
|
+
3. At the scheduled time, the trigger resumes the session with the provided prompt.`;
|
|
34
40
|
}
|
|
35
41
|
export function wakeMeUpLaterTool(_server, clientFactory) {
|
|
36
42
|
return {
|
|
@@ -41,7 +47,7 @@ export function wakeMeUpLaterTool(_server, clientFactory) {
|
|
|
41
47
|
properties: {
|
|
42
48
|
session_id: {
|
|
43
49
|
oneOf: [{ type: 'string' }, { type: 'number' }],
|
|
44
|
-
description: 'Session ID (numeric) or slug (string).
|
|
50
|
+
description: 'Session ID (numeric) or slug (string). Accepts sessions in needs_input or running state — from a running session, the sleep takes effect after the current turn ends.',
|
|
45
51
|
},
|
|
46
52
|
wake_at: {
|
|
47
53
|
type: 'string',
|
|
@@ -76,30 +82,49 @@ export function wakeMeUpLaterTool(_server, clientFactory) {
|
|
|
76
82
|
};
|
|
77
83
|
}
|
|
78
84
|
const session = await client.getSession(session_id);
|
|
79
|
-
|
|
85
|
+
// Reject states the Rails API can't auto-sleep from. `needs_input` →
|
|
86
|
+
// immediate sleep; `running` → deferred sleep via pending_sleep metadata;
|
|
87
|
+
// `waiting` → already dormant, trigger fires normally. Anything else
|
|
88
|
+
// (failed, archived) would silently no-op the auto-sleep and leave the
|
|
89
|
+
// caller with a trigger targeting a session that can't be woken.
|
|
90
|
+
const WAKEABLE_STATUSES = ['needs_input', 'running', 'waiting'];
|
|
91
|
+
if (!WAKEABLE_STATUSES.includes(session.status)) {
|
|
80
92
|
return {
|
|
81
93
|
content: [
|
|
82
94
|
{
|
|
83
95
|
type: 'text',
|
|
84
|
-
text: `Error: Session
|
|
96
|
+
text: `Error: Session ${session.id} is in "${session.status}" state and cannot be scheduled for wake-up. Only sessions in ${WAKEABLE_STATUSES.join(', ')} can be woken up.`,
|
|
85
97
|
},
|
|
86
98
|
],
|
|
87
99
|
isError: true,
|
|
88
100
|
};
|
|
89
101
|
}
|
|
90
|
-
|
|
102
|
+
// The Rails Trigger model requires agent_root_name, but for per-session
|
|
103
|
+
// wake-up triggers (reuse_session + last_session_id + one-time schedule)
|
|
104
|
+
// the value is never used to spawn a session — the target session is
|
|
105
|
+
// always reused. Prefer the canonical metadata value. The agent_type
|
|
106
|
+
// fallback is a best-effort for pre-migration sessions without an
|
|
107
|
+
// agent_root_key; if agent_type isn't a registered agent root, the
|
|
108
|
+
// createTrigger call will fail loudly with a 422 rather than proceed
|
|
109
|
+
// with a bad value — which is what we want.
|
|
110
|
+
const agentRootName = session.metadata?.agent_root_key || session.agent_type;
|
|
91
111
|
let trigger;
|
|
92
112
|
try {
|
|
93
113
|
trigger = await client.createTrigger({
|
|
94
|
-
name: `Wake session #${
|
|
95
|
-
|
|
96
|
-
agent_root_name: session.agent_type,
|
|
114
|
+
name: `Wake session #${session.id} at ${wake_at}`,
|
|
115
|
+
agent_root_name: agentRootName,
|
|
97
116
|
prompt_template: prompt,
|
|
98
117
|
reuse_session: true,
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
118
|
+
last_session_id: session.id,
|
|
119
|
+
trigger_conditions_attributes: [
|
|
120
|
+
{
|
|
121
|
+
condition_type: 'schedule',
|
|
122
|
+
configuration: {
|
|
123
|
+
scheduled_at: wake_at,
|
|
124
|
+
timezone,
|
|
125
|
+
},
|
|
126
|
+
},
|
|
127
|
+
],
|
|
103
128
|
});
|
|
104
129
|
}
|
|
105
130
|
catch (triggerError) {
|
|
@@ -107,28 +132,23 @@ export function wakeMeUpLaterTool(_server, clientFactory) {
|
|
|
107
132
|
content: [
|
|
108
133
|
{
|
|
109
134
|
type: 'text',
|
|
110
|
-
text: `Error:
|
|
135
|
+
text: `Error: Trigger creation failed: ${triggerError instanceof Error ? triggerError.message : 'Unknown error'}. The session is still in its original state — no changes were made.`,
|
|
111
136
|
},
|
|
112
137
|
],
|
|
113
138
|
isError: true,
|
|
114
139
|
};
|
|
115
140
|
}
|
|
116
|
-
await client.updateSession(session_id, {
|
|
117
|
-
custom_metadata: {
|
|
118
|
-
...session.custom_metadata,
|
|
119
|
-
wake_trigger_id: trigger.id,
|
|
120
|
-
},
|
|
121
|
-
});
|
|
122
141
|
const lines = [
|
|
123
|
-
'##
|
|
142
|
+
'## Wake-Up Scheduled Successfully',
|
|
124
143
|
'',
|
|
125
|
-
`- **Session ID:** ${
|
|
126
|
-
`- **Session Status:** ${sleepingSession.status}`,
|
|
144
|
+
`- **Session ID:** ${session.id}`,
|
|
127
145
|
`- **Wake At:** ${wake_at} (${timezone})`,
|
|
128
146
|
`- **Trigger ID:** ${trigger.id}`,
|
|
129
147
|
`- **Trigger Name:** ${trigger.name}`,
|
|
130
148
|
'',
|
|
131
|
-
'
|
|
149
|
+
'**You must end your conversation turn now.** The session will be automatically transitioned to waiting (immediately if currently needs_input; after the current turn ends if currently running) and resumed at the scheduled time with the provided prompt.',
|
|
150
|
+
'',
|
|
151
|
+
'⚠️ **Warning:** If you do not end your conversation turn, the session may still be running when the scheduled wake-up fires. A wake-up cannot be delivered to a session that is not in a wakeable (sleeping/waiting) state — it will be silently dropped, and you will never receive it.',
|
|
132
152
|
];
|
|
133
153
|
return { content: [{ type: 'text', text: lines.join('\n') }] };
|
|
134
154
|
}
|
package/shared/types.d.ts
CHANGED
|
@@ -251,9 +251,13 @@ export interface TriggerChannelsResponse {
|
|
|
251
251
|
num_members: number;
|
|
252
252
|
}>;
|
|
253
253
|
}
|
|
254
|
+
export interface TriggerConditionAttributes {
|
|
255
|
+
condition_type: 'slack' | 'schedule' | 'ao_event';
|
|
256
|
+
configuration: Record<string, unknown>;
|
|
257
|
+
}
|
|
254
258
|
export interface CreateTriggerRequest {
|
|
255
259
|
name: string;
|
|
256
|
-
trigger_type
|
|
260
|
+
trigger_type?: TriggerType;
|
|
257
261
|
agent_root_name: string;
|
|
258
262
|
prompt_template: string;
|
|
259
263
|
status?: TriggerStatus;
|
|
@@ -261,6 +265,8 @@ export interface CreateTriggerRequest {
|
|
|
261
265
|
reuse_session?: boolean;
|
|
262
266
|
mcp_servers?: string[];
|
|
263
267
|
configuration?: Record<string, unknown>;
|
|
268
|
+
last_session_id?: number;
|
|
269
|
+
trigger_conditions_attributes?: TriggerConditionAttributes[];
|
|
264
270
|
}
|
|
265
271
|
export interface UpdateTriggerRequest {
|
|
266
272
|
name?: string;
|