@orboto/mcp 0.213.0 → 0.214.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/dist/response-budget.js
CHANGED
|
@@ -239,7 +239,7 @@ export const TruncationBlockSchema = z.object({
|
|
|
239
239
|
*/
|
|
240
240
|
export const TruncationBlockAdvertisedSchema = z.object({ handle: z.string() })
|
|
241
241
|
.passthrough()
|
|
242
|
-
.describe('Response
|
|
242
|
+
.describe('Response cut; pass `handle` to orboto_response_expand.');
|
|
243
243
|
function stringMarker(omitted, handle, path) {
|
|
244
244
|
return `... [truncated ${omitted} chars - full value: orboto_response_expand handle="${handle}" path="${path}"]`;
|
|
245
245
|
}
|
|
@@ -10,7 +10,7 @@ import { mcpInstanceToken } from './shared.js';
|
|
|
10
10
|
import { AgentSessionScopeSchema } from './agent-session-scope.js';
|
|
11
11
|
export const agentHeartbeatToolConfig = {
|
|
12
12
|
title: 'Agent heartbeat (Multi-Agent Coordination)',
|
|
13
|
-
description: 'Register or refresh this agent\'s presence with status detail. A live connection already counts as online (an open MCP event stream, `orboto messages --follow`, the agent WebSocket) - the heartbeat adds status: idle (default) | working (+workingOnTicketId) | blocked, capabilities (free-form strings for operator filters) and clientInfo.name (the runtime), and is the only presence path for turn-based clients without a standing connection. Rows older than 90 s count as offline; persist the returned sessionToken and send it on later heartbeats. `scope` { projectKeys, ticketKeys, role } declares this session\'s responsibility (ORB-2136); an empty object clears it.',
|
|
13
|
+
description: 'Register or refresh this agent\'s presence with status detail. A live connection already counts as online (an open MCP event stream, `orboto messages --follow`, the agent WebSocket) - the heartbeat adds status: idle (default) | working (+workingOnTicketId) | blocked, capabilities (free-form strings for operator filters) and clientInfo.name (the runtime), and is the only presence path for turn-based clients without a standing connection. Rows older than 90 s count as offline; persist the returned sessionToken and send it on later heartbeats. `scope` { projectKeys, ticketKeys, role } declares this session\'s responsibility (ORB-2136); an empty object clears it. `startedBy`: starter session id, same account.',
|
|
14
14
|
inputSchema: z.object({
|
|
15
15
|
sessionToken: z.string().nullable().optional(),
|
|
16
16
|
scope: AgentSessionScopeSchema.optional(),
|
|
@@ -23,11 +23,13 @@ export const agentHeartbeatToolConfig = {
|
|
|
23
23
|
host: z.string().optional(),
|
|
24
24
|
user_agent: z.string().optional(),
|
|
25
25
|
}).optional(),
|
|
26
|
+
startedBy: z.string().uuid().optional(),
|
|
26
27
|
}).shape,
|
|
27
28
|
outputSchema: z.object({
|
|
28
29
|
sessionToken: z.string(),
|
|
29
30
|
sessionId: z.string().uuid(),
|
|
30
31
|
scope: AgentSessionScopeSchema.nullable(),
|
|
32
|
+
startedBy: z.string().uuid().nullable().optional(),
|
|
31
33
|
}).shape,
|
|
32
34
|
annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: true },
|
|
33
35
|
};
|
|
@@ -37,7 +39,7 @@ export function makeAgentHeartbeatHandler(client) {
|
|
|
37
39
|
const scope = res.scope ? ` scope=${JSON.stringify(res.scope)}` : '';
|
|
38
40
|
return {
|
|
39
41
|
content: [{ type: 'text', text: `heartbeat ack - sessionToken=${res.sessionToken.slice(0, 8)}… session ${res.sessionId.slice(0, 8)}${scope}` }],
|
|
40
|
-
structuredContent: { sessionToken: res.sessionToken, sessionId: res.sessionId, scope: res.scope ?? null },
|
|
42
|
+
structuredContent: { sessionToken: res.sessionToken, sessionId: res.sessionId, scope: res.scope ?? null, ...(res.startedBy !== undefined ? { startedBy: res.startedBy } : {}) },
|
|
41
43
|
};
|
|
42
44
|
};
|
|
43
45
|
}
|
|
@@ -266,6 +266,17 @@ describe('ORB-2136 - session addressing', () => {
|
|
|
266
266
|
expect(seen[0].headers['x-orboto-agent-session']).toBe('mcp-abc123');
|
|
267
267
|
expect(result.structuredContent).toMatchObject({ scope: { role: 'integrator', projectKeys: ['ORB'] } });
|
|
268
268
|
});
|
|
269
|
+
it('agent_heartbeat names the starter and answers the recorded one (ORB-2449)', async () => {
|
|
270
|
+
const starter = '5a1c0d2e-7b3f-4c11-9e2a-0c0ffee00001';
|
|
271
|
+
const seen = [];
|
|
272
|
+
vi.spyOn(globalThis, 'fetch').mockImplementation(async (_url, init) => {
|
|
273
|
+
seen.push(JSON.parse(init?.body ?? '{}'));
|
|
274
|
+
return { ok: true, status: 200, statusText: 'OK', json: async () => ({ sessionToken: 'mcp-abc123', sessionId: 'cbb52195-0000-4000-8000-000000000000', scope: { role: 'worker' }, startedBy: starter }), text: async () => '' };
|
|
275
|
+
});
|
|
276
|
+
const result = await makeAgentHeartbeatHandler(client)({ scope: { role: 'worker' }, startedBy: starter }, { sessionId: 'abc123' });
|
|
277
|
+
expect(seen[0]).toMatchObject({ startedBy: starter });
|
|
278
|
+
expect(result.structuredContent).toMatchObject({ startedBy: starter });
|
|
279
|
+
});
|
|
269
280
|
});
|
|
270
281
|
describe('orboto_agent_notify role addresses (ORB-2264)', () => {
|
|
271
282
|
it('sends `to` as written, lists every recipient and needs no targetEmail', async () => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@orboto/mcp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.214.0",
|
|
4
4
|
"description": "Model Context Protocol server for orboto - exposes tickets, projects, milestones, time, docs, primer-facts, alerts and absences as MCP tools for Claude Desktop / Cursor / Copilot Chat / any MCP-aware AI client.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|