@namzu/sdk 0.4.2 → 0.4.3
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/CHANGELOG.md +10 -0
- package/dist/advisory/context.test.d.ts +16 -0
- package/dist/advisory/context.test.d.ts.map +1 -0
- package/dist/advisory/context.test.js +92 -0
- package/dist/advisory/context.test.js.map +1 -0
- package/dist/advisory/evaluator.test.d.ts +34 -0
- package/dist/advisory/evaluator.test.d.ts.map +1 -0
- package/dist/advisory/evaluator.test.js +172 -0
- package/dist/advisory/evaluator.test.js.map +1 -0
- package/dist/advisory/executor.test.d.ts +35 -0
- package/dist/advisory/executor.test.d.ts.map +1 -0
- package/dist/advisory/executor.test.js +233 -0
- package/dist/advisory/executor.test.js.map +1 -0
- package/dist/advisory/registry.test.d.ts +16 -0
- package/dist/advisory/registry.test.d.ts.map +1 -0
- package/dist/advisory/registry.test.js +62 -0
- package/dist/advisory/registry.test.js.map +1 -0
- package/dist/bridge/a2a/agent-card.test.d.ts +24 -0
- package/dist/bridge/a2a/agent-card.test.d.ts.map +1 -0
- package/dist/bridge/a2a/agent-card.test.js +118 -0
- package/dist/bridge/a2a/agent-card.test.js.map +1 -0
- package/dist/bridge/a2a/mapper.test.d.ts +29 -0
- package/dist/bridge/a2a/mapper.test.d.ts.map +1 -0
- package/dist/bridge/a2a/mapper.test.js +265 -0
- package/dist/bridge/a2a/mapper.test.js.map +1 -0
- package/dist/bridge/a2a/message.test.d.ts +20 -0
- package/dist/bridge/a2a/message.test.d.ts.map +1 -0
- package/dist/bridge/a2a/message.test.js +116 -0
- package/dist/bridge/a2a/message.test.js.map +1 -0
- package/dist/bridge/a2a/task.test.d.ts +29 -0
- package/dist/bridge/a2a/task.test.d.ts.map +1 -0
- package/dist/bridge/a2a/task.test.js +198 -0
- package/dist/bridge/a2a/task.test.js.map +1 -0
- package/dist/bridge/mcp/connector/adapter.test.d.ts +27 -0
- package/dist/bridge/mcp/connector/adapter.test.d.ts.map +1 -0
- package/dist/bridge/mcp/connector/adapter.test.js +203 -0
- package/dist/bridge/mcp/connector/adapter.test.js.map +1 -0
- package/dist/bridge/sse/mapper.test.d.ts +27 -0
- package/dist/bridge/sse/mapper.test.d.ts.map +1 -0
- package/dist/bridge/sse/mapper.test.js +271 -0
- package/dist/bridge/sse/mapper.test.js.map +1 -0
- package/dist/bridge/tools/connector/adapter.test.d.ts +28 -0
- package/dist/bridge/tools/connector/adapter.test.d.ts.map +1 -0
- package/dist/bridge/tools/connector/adapter.test.js +182 -0
- package/dist/bridge/tools/connector/adapter.test.js.map +1 -0
- package/dist/bridge/tools/connector/definitions.test.d.ts +23 -0
- package/dist/bridge/tools/connector/definitions.test.d.ts.map +1 -0
- package/dist/bridge/tools/connector/definitions.test.js +158 -0
- package/dist/bridge/tools/connector/definitions.test.js.map +1 -0
- package/dist/bridge/tools/connector/router.test.d.ts +21 -0
- package/dist/bridge/tools/connector/router.test.d.ts.map +1 -0
- package/dist/bridge/tools/connector/router.test.js +139 -0
- package/dist/bridge/tools/connector/router.test.js.map +1 -0
- package/dist/bus/breaker.test.d.ts +41 -0
- package/dist/bus/breaker.test.d.ts.map +1 -0
- package/dist/bus/breaker.test.js +242 -0
- package/dist/bus/breaker.test.js.map +1 -0
- package/dist/bus/index.test.d.ts +25 -0
- package/dist/bus/index.test.d.ts.map +1 -0
- package/dist/bus/index.test.js +151 -0
- package/dist/bus/index.test.js.map +1 -0
- package/dist/bus/lock.test.d.ts +44 -0
- package/dist/bus/lock.test.d.ts.map +1 -0
- package/dist/bus/lock.test.js +226 -0
- package/dist/bus/lock.test.js.map +1 -0
- package/dist/bus/ownership.test.d.ts +26 -0
- package/dist/bus/ownership.test.d.ts.map +1 -0
- package/dist/bus/ownership.test.js +205 -0
- package/dist/bus/ownership.test.js.map +1 -0
- package/dist/connector/BaseConnector.test.d.ts +21 -0
- package/dist/connector/BaseConnector.test.d.ts.map +1 -0
- package/dist/connector/BaseConnector.test.js +108 -0
- package/dist/connector/BaseConnector.test.js.map +1 -0
- package/dist/connector/builtins/http.test.d.ts +30 -0
- package/dist/connector/builtins/http.test.d.ts.map +1 -0
- package/dist/connector/builtins/http.test.js +232 -0
- package/dist/connector/builtins/http.test.js.map +1 -0
- package/dist/connector/builtins/webhook.test.d.ts +20 -0
- package/dist/connector/builtins/webhook.test.d.ts.map +1 -0
- package/dist/connector/builtins/webhook.test.js +113 -0
- package/dist/connector/builtins/webhook.test.js.map +1 -0
- package/dist/connector/execution/factory.test.d.ts +16 -0
- package/dist/connector/execution/factory.test.d.ts.map +1 -0
- package/dist/connector/execution/factory.test.js +64 -0
- package/dist/connector/execution/factory.test.js.map +1 -0
- package/dist/connector/execution/remote.test.d.ts +16 -0
- package/dist/connector/execution/remote.test.d.ts.map +1 -0
- package/dist/connector/execution/remote.test.js +53 -0
- package/dist/connector/execution/remote.test.js.map +1 -0
- package/dist/connector/mcp/adapter.test.d.ts +34 -0
- package/dist/connector/mcp/adapter.test.d.ts.map +1 -0
- package/dist/connector/mcp/adapter.test.js +199 -0
- package/dist/connector/mcp/adapter.test.js.map +1 -0
- package/dist/rag/chunking.test.d.ts +20 -0
- package/dist/rag/chunking.test.d.ts.map +1 -0
- package/dist/rag/chunking.test.js +92 -0
- package/dist/rag/chunking.test.js.map +1 -0
- package/dist/rag/context-assembler.test.d.ts +19 -0
- package/dist/rag/context-assembler.test.d.ts.map +1 -0
- package/dist/rag/context-assembler.test.js +98 -0
- package/dist/rag/context-assembler.test.js.map +1 -0
- package/dist/rag/embedding.test.d.ts +19 -0
- package/dist/rag/embedding.test.d.ts.map +1 -0
- package/dist/rag/embedding.test.js +115 -0
- package/dist/rag/embedding.test.js.map +1 -0
- package/dist/rag/ingestion.test.d.ts +22 -0
- package/dist/rag/ingestion.test.d.ts.map +1 -0
- package/dist/rag/ingestion.test.js +99 -0
- package/dist/rag/ingestion.test.js.map +1 -0
- package/dist/rag/knowledge-base.test.d.ts +17 -0
- package/dist/rag/knowledge-base.test.d.ts.map +1 -0
- package/dist/rag/knowledge-base.test.js +77 -0
- package/dist/rag/knowledge-base.test.js.map +1 -0
- package/dist/rag/rag-tool.test.d.ts +21 -0
- package/dist/rag/rag-tool.test.d.ts.map +1 -0
- package/dist/rag/rag-tool.test.js +149 -0
- package/dist/rag/rag-tool.test.js.map +1 -0
- package/dist/rag/retriever.test.d.ts +26 -0
- package/dist/rag/retriever.test.d.ts.map +1 -0
- package/dist/rag/retriever.test.js +180 -0
- package/dist/rag/retriever.test.js.map +1 -0
- package/dist/rag/vector-store.test.d.ts +38 -0
- package/dist/rag/vector-store.test.d.ts.map +1 -0
- package/dist/rag/vector-store.test.js +175 -0
- package/dist/rag/vector-store.test.js.map +1 -0
- package/dist/registry/ManagedRegistry.test.d.ts +21 -0
- package/dist/registry/ManagedRegistry.test.d.ts.map +1 -0
- package/dist/registry/ManagedRegistry.test.js +98 -0
- package/dist/registry/ManagedRegistry.test.js.map +1 -0
- package/dist/registry/Registry.test.d.ts +18 -0
- package/dist/registry/Registry.test.d.ts.map +1 -0
- package/dist/registry/Registry.test.js +79 -0
- package/dist/registry/Registry.test.js.map +1 -0
- package/dist/registry/agent/definitions.test.d.ts +15 -0
- package/dist/registry/agent/definitions.test.d.ts.map +1 -0
- package/dist/registry/agent/definitions.test.js +84 -0
- package/dist/registry/agent/definitions.test.js.map +1 -0
- package/dist/registry/connector/definitions.test.d.ts +13 -0
- package/dist/registry/connector/definitions.test.d.ts.map +1 -0
- package/dist/registry/connector/definitions.test.js +41 -0
- package/dist/registry/connector/definitions.test.js.map +1 -0
- package/dist/registry/connector/scoped.test.d.ts +21 -0
- package/dist/registry/connector/scoped.test.d.ts.map +1 -0
- package/dist/registry/connector/scoped.test.js +115 -0
- package/dist/registry/connector/scoped.test.js.map +1 -0
- package/dist/registry/plugin/index.test.d.ts +12 -0
- package/dist/registry/plugin/index.test.d.ts.map +1 -0
- package/dist/registry/plugin/index.test.js +69 -0
- package/dist/registry/plugin/index.test.js.map +1 -0
- package/dist/registry/tool/execute.test.d.ts +42 -0
- package/dist/registry/tool/execute.test.d.ts.map +1 -0
- package/dist/registry/tool/execute.test.js +281 -0
- package/dist/registry/tool/execute.test.js.map +1 -0
- package/dist/runtime/query/iteration/phases/advisory.test.d.ts +42 -0
- package/dist/runtime/query/iteration/phases/advisory.test.d.ts.map +1 -0
- package/dist/runtime/query/iteration/phases/advisory.test.js +334 -0
- package/dist/runtime/query/iteration/phases/advisory.test.js.map +1 -0
- package/dist/test-setup.d.ts +22 -0
- package/dist/test-setup.d.ts.map +1 -0
- package/dist/test-setup.js +23 -0
- package/dist/test-setup.js.map +1 -0
- package/dist/utils/logger.d.ts +1 -1
- package/dist/utils/logger.d.ts.map +1 -1
- package/dist/utils/logger.js +5 -0
- package/dist/utils/logger.js.map +1 -1
- package/package.json +4 -1
- package/src/advisory/context.test.ts +109 -0
- package/src/advisory/evaluator.test.ts +192 -0
- package/src/advisory/executor.test.ts +272 -0
- package/src/advisory/registry.test.ts +75 -0
- package/src/bridge/a2a/agent-card.test.ts +140 -0
- package/src/bridge/a2a/mapper.test.ts +293 -0
- package/src/bridge/a2a/message.test.ts +138 -0
- package/src/bridge/a2a/task.test.ts +235 -0
- package/src/bridge/mcp/connector/adapter.test.ts +230 -0
- package/src/bridge/sse/mapper.test.ts +422 -0
- package/src/bridge/tools/connector/adapter.test.ts +224 -0
- package/src/bridge/tools/connector/definitions.test.ts +183 -0
- package/src/bridge/tools/connector/router.test.ts +159 -0
- package/src/bus/breaker.test.ts +274 -0
- package/src/bus/index.test.ts +183 -0
- package/src/bus/lock.test.ts +265 -0
- package/src/bus/ownership.test.ts +243 -0
- package/src/connector/BaseConnector.test.ts +130 -0
- package/src/connector/builtins/http.test.ts +290 -0
- package/src/connector/builtins/webhook.test.ts +138 -0
- package/src/connector/execution/factory.test.ts +75 -0
- package/src/connector/execution/remote.test.ts +63 -0
- package/src/connector/mcp/adapter.test.ts +249 -0
- package/src/rag/chunking.test.ts +107 -0
- package/src/rag/context-assembler.test.ts +114 -0
- package/src/rag/embedding.test.ts +130 -0
- package/src/rag/ingestion.test.ts +114 -0
- package/src/rag/knowledge-base.test.ts +106 -0
- package/src/rag/rag-tool.test.ts +167 -0
- package/src/rag/retriever.test.ts +210 -0
- package/src/rag/vector-store.test.ts +196 -0
- package/src/registry/ManagedRegistry.test.ts +118 -0
- package/src/registry/Registry.test.ts +91 -0
- package/src/registry/agent/definitions.test.ts +100 -0
- package/src/registry/connector/definitions.test.ts +51 -0
- package/src/registry/connector/scoped.test.ts +129 -0
- package/src/registry/plugin/index.test.ts +85 -0
- package/src/registry/tool/execute.test.ts +330 -0
- package/src/runtime/query/iteration/phases/advisory.test.ts +412 -0
- package/src/test-setup.ts +24 -0
- package/src/utils/logger.ts +6 -1
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Current-code invariants asserted (2026-04-21, ses_006 Phase 2):
|
|
3
|
+
*
|
|
4
|
+
* - `messageToA2A(msg)` role mapping: user → user; assistant / system /
|
|
5
|
+
* tool → agent. Any other MessageRole triggers the exhaustive-check
|
|
6
|
+
* throw (unreachable via types).
|
|
7
|
+
* - Non-empty `content` produces one text part.
|
|
8
|
+
* - Assistant with `toolCalls`: one data part per tool call with
|
|
9
|
+
* mimeType `application/x-namzu-tool-call` and fields
|
|
10
|
+
* `{toolCallId, name, arguments}`.
|
|
11
|
+
* - If the message would produce zero parts (null content, no tool
|
|
12
|
+
* calls), a fallback empty-text part is added.
|
|
13
|
+
* - `extractTextFromA2AMessage(msg)` joins text parts with '\n' and
|
|
14
|
+
* ignores non-text parts entirely.
|
|
15
|
+
* - `a2aMessageToInput` is a pure alias for `extractTextFromA2AMessage`.
|
|
16
|
+
* - Only SDK → A2A direction is covered (design.md §2.7: no reverse
|
|
17
|
+
* mapper exists).
|
|
18
|
+
*/
|
|
19
|
+
import { describe, expect, it } from 'vitest';
|
|
20
|
+
import { a2aMessageToInput, extractTextFromA2AMessage, messageToA2A } from './message.js';
|
|
21
|
+
describe('messageToA2A', () => {
|
|
22
|
+
it('maps user role to user', () => {
|
|
23
|
+
const msg = { role: 'user', content: 'hi' };
|
|
24
|
+
expect(messageToA2A(msg).role).toBe('user');
|
|
25
|
+
});
|
|
26
|
+
it.each([['system'], ['assistant'], ['tool']])('maps %s role to agent', (role) => {
|
|
27
|
+
const msg = { role, content: 'x', ...(role === 'tool' && { toolCallId: 'c' }) };
|
|
28
|
+
expect(messageToA2A(msg).role).toBe('agent');
|
|
29
|
+
});
|
|
30
|
+
it('emits a single text part for content-only messages', () => {
|
|
31
|
+
const msg = { role: 'user', content: 'hello' };
|
|
32
|
+
const a2a = messageToA2A(msg);
|
|
33
|
+
expect(a2a.parts).toEqual([{ kind: 'text', text: 'hello' }]);
|
|
34
|
+
});
|
|
35
|
+
it('emits text + data parts when the assistant has tool calls', () => {
|
|
36
|
+
const msg = {
|
|
37
|
+
role: 'assistant',
|
|
38
|
+
content: 'let me check',
|
|
39
|
+
toolCalls: [
|
|
40
|
+
{ id: 'tc1', type: 'function', function: { name: 'read_file', arguments: '{"p":"/a"}' } },
|
|
41
|
+
{ id: 'tc2', type: 'function', function: { name: 'list_dir', arguments: '{}' } },
|
|
42
|
+
],
|
|
43
|
+
};
|
|
44
|
+
const a2a = messageToA2A(msg);
|
|
45
|
+
expect(a2a.parts).toEqual([
|
|
46
|
+
{ kind: 'text', text: 'let me check' },
|
|
47
|
+
{
|
|
48
|
+
kind: 'data',
|
|
49
|
+
data: { toolCallId: 'tc1', name: 'read_file', arguments: '{"p":"/a"}' },
|
|
50
|
+
mimeType: 'application/x-namzu-tool-call',
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
kind: 'data',
|
|
54
|
+
data: { toolCallId: 'tc2', name: 'list_dir', arguments: '{}' },
|
|
55
|
+
mimeType: 'application/x-namzu-tool-call',
|
|
56
|
+
},
|
|
57
|
+
]);
|
|
58
|
+
});
|
|
59
|
+
it('emits ONLY data parts (no text part) when content is null and tool calls exist', () => {
|
|
60
|
+
const msg = {
|
|
61
|
+
role: 'assistant',
|
|
62
|
+
content: null,
|
|
63
|
+
toolCalls: [{ id: 'tc1', type: 'function', function: { name: 'x', arguments: '{}' } }],
|
|
64
|
+
};
|
|
65
|
+
const a2a = messageToA2A(msg);
|
|
66
|
+
expect(a2a.parts.some((p) => p.kind === 'text')).toBe(false);
|
|
67
|
+
expect(a2a.parts.some((p) => p.kind === 'data')).toBe(true);
|
|
68
|
+
});
|
|
69
|
+
it('fallbacks to an empty text part when content is null and no tool calls', () => {
|
|
70
|
+
const msg = { role: 'assistant', content: null };
|
|
71
|
+
expect(messageToA2A(msg).parts).toEqual([{ kind: 'text', text: '' }]);
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
describe('extractTextFromA2AMessage', () => {
|
|
75
|
+
it('joins every text part with a newline', () => {
|
|
76
|
+
const msg = {
|
|
77
|
+
role: 'user',
|
|
78
|
+
parts: [
|
|
79
|
+
{ kind: 'text', text: 'line 1' },
|
|
80
|
+
{ kind: 'text', text: 'line 2' },
|
|
81
|
+
],
|
|
82
|
+
};
|
|
83
|
+
expect(extractTextFromA2AMessage(msg)).toBe('line 1\nline 2');
|
|
84
|
+
});
|
|
85
|
+
it('ignores non-text parts', () => {
|
|
86
|
+
const msg = {
|
|
87
|
+
role: 'agent',
|
|
88
|
+
parts: [
|
|
89
|
+
{ kind: 'text', text: 'hello' },
|
|
90
|
+
{ kind: 'data', data: { foo: 1 }, mimeType: 'application/json' },
|
|
91
|
+
],
|
|
92
|
+
};
|
|
93
|
+
expect(extractTextFromA2AMessage(msg)).toBe('hello');
|
|
94
|
+
});
|
|
95
|
+
it('returns empty string when there are no text parts', () => {
|
|
96
|
+
const msg = {
|
|
97
|
+
role: 'agent',
|
|
98
|
+
parts: [{ kind: 'data', data: {}, mimeType: 'x' }],
|
|
99
|
+
};
|
|
100
|
+
expect(extractTextFromA2AMessage(msg)).toBe('');
|
|
101
|
+
});
|
|
102
|
+
});
|
|
103
|
+
describe('a2aMessageToInput', () => {
|
|
104
|
+
it('behaves identically to extractTextFromA2AMessage', () => {
|
|
105
|
+
const msg = {
|
|
106
|
+
role: 'user',
|
|
107
|
+
parts: [
|
|
108
|
+
{ kind: 'text', text: 'a' },
|
|
109
|
+
{ kind: 'text', text: 'b' },
|
|
110
|
+
{ kind: 'data', data: {}, mimeType: 'x' },
|
|
111
|
+
],
|
|
112
|
+
};
|
|
113
|
+
expect(a2aMessageToInput(msg)).toBe(extractTextFromA2AMessage(msg));
|
|
114
|
+
});
|
|
115
|
+
});
|
|
116
|
+
//# sourceMappingURL=message.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"message.test.js","sourceRoot":"","sources":["../../../src/bridge/a2a/message.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Current-code invariants asserted (2026-04-21, ses_006 Phase 2):
|
|
3
|
+
*
|
|
4
|
+
* - `isTerminalState(state)` returns true iff state ∈ {completed,
|
|
5
|
+
* failed, canceled, rejected}.
|
|
6
|
+
* - `runStatusToA2AState(status)` is a table lookup:
|
|
7
|
+
* queued → pending; running → running; completed → completed;
|
|
8
|
+
* failed → failed; cancelled → canceled; cancelling → running;
|
|
9
|
+
* expired → failed.
|
|
10
|
+
* - `runToA2ATask(run, messages?)`:
|
|
11
|
+
* - `id` comes from `run.id`; `contextId` comes from
|
|
12
|
+
* `run.project_id ?? undefined`.
|
|
13
|
+
* - `status.timestamp` picks the first defined of
|
|
14
|
+
* `completed_at`, `started_at`, `created_at` (in that order).
|
|
15
|
+
* - `status.message` is agent-text of `run.result` if present,
|
|
16
|
+
* else of `run.last_error` if present, else undefined.
|
|
17
|
+
* - `artifacts` is present iff `run.result` is present; the single
|
|
18
|
+
* artifact carries a subset of usage + timing metadata.
|
|
19
|
+
* - `history` is mapped through `messageToA2A` only when `messages`
|
|
20
|
+
* is supplied.
|
|
21
|
+
* - Top-level `metadata` carries agent_id, agent_name, stop_reason
|
|
22
|
+
* (even if undefined).
|
|
23
|
+
* - `a2aMessageToCreateRun(agentId, params)` only sets a metadata
|
|
24
|
+
* field on `config` when the source value has the expected type
|
|
25
|
+
* (string for model/systemPrompt; number for numeric fields;
|
|
26
|
+
* 'plan' | 'auto' for permissionMode). Everything else is omitted.
|
|
27
|
+
*/
|
|
28
|
+
export {};
|
|
29
|
+
//# sourceMappingURL=task.test.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"task.test.d.ts","sourceRoot":"","sources":["../../../src/bridge/a2a/task.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG"}
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Current-code invariants asserted (2026-04-21, ses_006 Phase 2):
|
|
3
|
+
*
|
|
4
|
+
* - `isTerminalState(state)` returns true iff state ∈ {completed,
|
|
5
|
+
* failed, canceled, rejected}.
|
|
6
|
+
* - `runStatusToA2AState(status)` is a table lookup:
|
|
7
|
+
* queued → pending; running → running; completed → completed;
|
|
8
|
+
* failed → failed; cancelled → canceled; cancelling → running;
|
|
9
|
+
* expired → failed.
|
|
10
|
+
* - `runToA2ATask(run, messages?)`:
|
|
11
|
+
* - `id` comes from `run.id`; `contextId` comes from
|
|
12
|
+
* `run.project_id ?? undefined`.
|
|
13
|
+
* - `status.timestamp` picks the first defined of
|
|
14
|
+
* `completed_at`, `started_at`, `created_at` (in that order).
|
|
15
|
+
* - `status.message` is agent-text of `run.result` if present,
|
|
16
|
+
* else of `run.last_error` if present, else undefined.
|
|
17
|
+
* - `artifacts` is present iff `run.result` is present; the single
|
|
18
|
+
* artifact carries a subset of usage + timing metadata.
|
|
19
|
+
* - `history` is mapped through `messageToA2A` only when `messages`
|
|
20
|
+
* is supplied.
|
|
21
|
+
* - Top-level `metadata` carries agent_id, agent_name, stop_reason
|
|
22
|
+
* (even if undefined).
|
|
23
|
+
* - `a2aMessageToCreateRun(agentId, params)` only sets a metadata
|
|
24
|
+
* field on `config` when the source value has the expected type
|
|
25
|
+
* (string for model/systemPrompt; number for numeric fields;
|
|
26
|
+
* 'plan' | 'auto' for permissionMode). Everything else is omitted.
|
|
27
|
+
*/
|
|
28
|
+
import { describe, expect, it } from 'vitest';
|
|
29
|
+
import { a2aMessageToCreateRun, isTerminalState, runStatusToA2AState, runToA2ATask, } from './task.js';
|
|
30
|
+
const baseRun = {
|
|
31
|
+
id: 'run_1',
|
|
32
|
+
project_id: null,
|
|
33
|
+
agent_id: 'coder',
|
|
34
|
+
status: 'running',
|
|
35
|
+
created_at: '2026-04-21T12:00:00Z',
|
|
36
|
+
config: {},
|
|
37
|
+
};
|
|
38
|
+
describe('isTerminalState', () => {
|
|
39
|
+
const terminals = ['completed', 'failed', 'canceled', 'rejected'];
|
|
40
|
+
const nonTerminals = ['input-required', 'running', 'pending'];
|
|
41
|
+
it.each(terminals.map((s) => [s]))('%s is terminal', (state) => {
|
|
42
|
+
expect(isTerminalState(state)).toBe(true);
|
|
43
|
+
});
|
|
44
|
+
it.each(nonTerminals.map((s) => [s]))('%s is not terminal', (state) => {
|
|
45
|
+
expect(isTerminalState(state)).toBe(false);
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
describe('runStatusToA2AState', () => {
|
|
49
|
+
it.each([
|
|
50
|
+
['queued', 'pending'],
|
|
51
|
+
['running', 'running'],
|
|
52
|
+
['completed', 'completed'],
|
|
53
|
+
['failed', 'failed'],
|
|
54
|
+
['cancelled', 'canceled'],
|
|
55
|
+
['cancelling', 'running'],
|
|
56
|
+
['expired', 'failed'],
|
|
57
|
+
])('%s → %s', (wire, a2a) => {
|
|
58
|
+
expect(runStatusToA2AState(wire)).toBe(a2a);
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
describe('runToA2ATask', () => {
|
|
62
|
+
it('sets id + contextId from run.id + run.project_id', () => {
|
|
63
|
+
const task = runToA2ATask({ ...baseRun, project_id: 'proj_9' });
|
|
64
|
+
expect(task.id).toBe('run_1');
|
|
65
|
+
expect(task.contextId).toBe('proj_9');
|
|
66
|
+
});
|
|
67
|
+
it('contextId is undefined when project_id is null', () => {
|
|
68
|
+
const task = runToA2ATask(baseRun);
|
|
69
|
+
expect(task.contextId).toBeUndefined();
|
|
70
|
+
});
|
|
71
|
+
it('timestamp prefers completed_at > started_at > created_at', () => {
|
|
72
|
+
const created = '2026-04-21T10:00:00Z';
|
|
73
|
+
const started = '2026-04-21T10:05:00Z';
|
|
74
|
+
const completed = '2026-04-21T10:10:00Z';
|
|
75
|
+
expect(runToA2ATask({
|
|
76
|
+
...baseRun,
|
|
77
|
+
created_at: created,
|
|
78
|
+
started_at: started,
|
|
79
|
+
completed_at: completed,
|
|
80
|
+
}).status.timestamp).toBe(completed);
|
|
81
|
+
expect(runToA2ATask({ ...baseRun, created_at: created, started_at: started }).status.timestamp).toBe(started);
|
|
82
|
+
expect(runToA2ATask({ ...baseRun, created_at: created }).status.timestamp).toBe(created);
|
|
83
|
+
});
|
|
84
|
+
it('status.message is the result text when result is present', () => {
|
|
85
|
+
const task = runToA2ATask({ ...baseRun, status: 'completed', result: 'all done' });
|
|
86
|
+
expect(task.status.message?.parts).toEqual([{ kind: 'text', text: 'all done' }]);
|
|
87
|
+
expect(task.status.message?.role).toBe('agent');
|
|
88
|
+
});
|
|
89
|
+
it('status.message falls back to last_error when result is absent', () => {
|
|
90
|
+
const task = runToA2ATask({ ...baseRun, status: 'failed', last_error: 'boom' });
|
|
91
|
+
expect(task.status.message?.parts).toEqual([{ kind: 'text', text: 'boom' }]);
|
|
92
|
+
});
|
|
93
|
+
it('status.message is undefined when neither result nor last_error is set', () => {
|
|
94
|
+
const task = runToA2ATask(baseRun);
|
|
95
|
+
expect(task.status.message).toBeUndefined();
|
|
96
|
+
});
|
|
97
|
+
it('attaches an artifact iff result is present', () => {
|
|
98
|
+
expect(runToA2ATask(baseRun).artifacts).toBeUndefined();
|
|
99
|
+
const withResult = runToA2ATask({
|
|
100
|
+
...baseRun,
|
|
101
|
+
status: 'completed',
|
|
102
|
+
result: 'done',
|
|
103
|
+
model: 'claude-opus-4-7',
|
|
104
|
+
iterations: 3,
|
|
105
|
+
duration_ms: 1200,
|
|
106
|
+
usage: { input_tokens: 10, output_tokens: 20, total_tokens: 30, total_cost_usd: 0.05 },
|
|
107
|
+
});
|
|
108
|
+
expect(withResult.artifacts).toHaveLength(1);
|
|
109
|
+
const artifact = withResult.artifacts?.[0];
|
|
110
|
+
expect(artifact?.artifactId).toBe('run_1-result');
|
|
111
|
+
expect(artifact?.name).toBe('Agent Response');
|
|
112
|
+
expect(artifact?.parts).toEqual([{ kind: 'text', text: 'done' }]);
|
|
113
|
+
expect(artifact?.metadata).toMatchObject({
|
|
114
|
+
model: 'claude-opus-4-7',
|
|
115
|
+
iterations: 3,
|
|
116
|
+
duration_ms: 1200,
|
|
117
|
+
input_tokens: 10,
|
|
118
|
+
output_tokens: 20,
|
|
119
|
+
total_cost_usd: 0.05,
|
|
120
|
+
});
|
|
121
|
+
});
|
|
122
|
+
it('history is undefined when messages are not supplied', () => {
|
|
123
|
+
expect(runToA2ATask(baseRun).history).toBeUndefined();
|
|
124
|
+
});
|
|
125
|
+
it('history maps through messageToA2A for every message', () => {
|
|
126
|
+
const task = runToA2ATask(baseRun, [
|
|
127
|
+
{ role: 'user', content: 'hi' },
|
|
128
|
+
{ role: 'assistant', content: 'ack' },
|
|
129
|
+
]);
|
|
130
|
+
expect(task.history).toHaveLength(2);
|
|
131
|
+
expect(task.history?.[0]?.role).toBe('user');
|
|
132
|
+
expect(task.history?.[1]?.role).toBe('agent');
|
|
133
|
+
});
|
|
134
|
+
it('top-level metadata carries agent_id + stop_reason', () => {
|
|
135
|
+
const task = runToA2ATask({ ...baseRun, agent_name: 'Coder', stop_reason: 'end_turn' });
|
|
136
|
+
expect(task.metadata).toMatchObject({
|
|
137
|
+
agent_id: 'coder',
|
|
138
|
+
agent_name: 'Coder',
|
|
139
|
+
stop_reason: 'end_turn',
|
|
140
|
+
});
|
|
141
|
+
});
|
|
142
|
+
});
|
|
143
|
+
describe('a2aMessageToCreateRun', () => {
|
|
144
|
+
const baseMsg = { role: 'user', parts: [{ kind: 'text', text: 'do a thing' }] };
|
|
145
|
+
it('extracts input text from the message', () => {
|
|
146
|
+
const params = { message: baseMsg };
|
|
147
|
+
const result = a2aMessageToCreateRun('agent_1', params);
|
|
148
|
+
expect(result.agentId).toBe('agent_1');
|
|
149
|
+
expect(result.input).toBe('do a thing');
|
|
150
|
+
expect(result.config).toEqual({});
|
|
151
|
+
});
|
|
152
|
+
it('threads contextId from params into projectId', () => {
|
|
153
|
+
const params = { message: baseMsg, contextId: 'proj_2' };
|
|
154
|
+
expect(a2aMessageToCreateRun('agent_1', params).projectId).toBe('proj_2');
|
|
155
|
+
});
|
|
156
|
+
it('only includes typed metadata fields in config', () => {
|
|
157
|
+
const params = {
|
|
158
|
+
message: baseMsg,
|
|
159
|
+
metadata: {
|
|
160
|
+
model: 'opus',
|
|
161
|
+
tokenBudget: 1000,
|
|
162
|
+
timeoutMs: 5000,
|
|
163
|
+
temperature: 0.2,
|
|
164
|
+
maxResponseTokens: 2048,
|
|
165
|
+
permissionMode: 'plan',
|
|
166
|
+
systemPrompt: 'be terse',
|
|
167
|
+
},
|
|
168
|
+
};
|
|
169
|
+
const config = a2aMessageToCreateRun('a', params).config;
|
|
170
|
+
expect(config).toEqual({
|
|
171
|
+
model: 'opus',
|
|
172
|
+
tokenBudget: 1000,
|
|
173
|
+
timeoutMs: 5000,
|
|
174
|
+
temperature: 0.2,
|
|
175
|
+
maxResponseTokens: 2048,
|
|
176
|
+
permissionMode: 'plan',
|
|
177
|
+
systemPrompt: 'be terse',
|
|
178
|
+
});
|
|
179
|
+
});
|
|
180
|
+
it('drops metadata fields with wrong types', () => {
|
|
181
|
+
const params = {
|
|
182
|
+
message: baseMsg,
|
|
183
|
+
metadata: {
|
|
184
|
+
model: 123, // wrong type → dropped
|
|
185
|
+
tokenBudget: 'big', // wrong type → dropped
|
|
186
|
+
permissionMode: 'invalid', // not 'plan'|'auto' → dropped
|
|
187
|
+
},
|
|
188
|
+
};
|
|
189
|
+
expect(a2aMessageToCreateRun('a', params).config).toEqual({});
|
|
190
|
+
});
|
|
191
|
+
it('accepts permissionMode only for "plan" or "auto"', () => {
|
|
192
|
+
for (const mode of ['plan', 'auto']) {
|
|
193
|
+
const params = { message: baseMsg, metadata: { permissionMode: mode } };
|
|
194
|
+
expect(a2aMessageToCreateRun('a', params).config.permissionMode).toBe(mode);
|
|
195
|
+
}
|
|
196
|
+
});
|
|
197
|
+
});
|
|
198
|
+
//# sourceMappingURL=task.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"task.test.js","sourceRoot":"","sources":["../../../src/bridge/a2a/task.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Current-code invariants asserted (2026-04-21, ses_006 Phase 2):
|
|
3
|
+
*
|
|
4
|
+
* - `MCPConnectorBridge` wraps a `ConnectorManager` and exposes
|
|
5
|
+
* connector methods as MCP tools with a name pattern
|
|
6
|
+
* `<prefix>_<connectorId>_<methodName>`; prefix defaults to 'namzu'.
|
|
7
|
+
* - `listTools()` with no instanceId iterates
|
|
8
|
+
* `manager.listConnectedInstances()`; `listTools(instanceId)` uses
|
|
9
|
+
* `manager.getInstance(instanceId)` and filters Boolean (missing
|
|
10
|
+
* instance → empty output).
|
|
11
|
+
* - `listTools()` rebuilds `mappings` from scratch on each call.
|
|
12
|
+
* - Schema conversion via `zodToJsonSchema` is best-effort; on
|
|
13
|
+
* conversion failure the schema falls back to `{type: 'object'}`.
|
|
14
|
+
* - `getMappings()` returns a COPY (mutation of the returned array
|
|
15
|
+
* does not affect internal state).
|
|
16
|
+
* - `callTool(name, args)`:
|
|
17
|
+
* - Returns `{content: [text], isError: true}` for unknown tools.
|
|
18
|
+
* - On manager success, returns `{content: [text], isError: false}`
|
|
19
|
+
* with the output stringified if non-string.
|
|
20
|
+
* - On manager failure, returns `{content: [text with error],
|
|
21
|
+
* isError: true}`; falls back to 'Unknown error' when the
|
|
22
|
+
* manager error is undefined.
|
|
23
|
+
* - Method descriptions include the connector DEFINITION name
|
|
24
|
+
* bracketed (not the instance name): `[<def.name>] <method.description>`.
|
|
25
|
+
*/
|
|
26
|
+
export {};
|
|
27
|
+
//# sourceMappingURL=adapter.test.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter.test.d.ts","sourceRoot":"","sources":["../../../../src/bridge/mcp/connector/adapter.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG"}
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Current-code invariants asserted (2026-04-21, ses_006 Phase 2):
|
|
3
|
+
*
|
|
4
|
+
* - `MCPConnectorBridge` wraps a `ConnectorManager` and exposes
|
|
5
|
+
* connector methods as MCP tools with a name pattern
|
|
6
|
+
* `<prefix>_<connectorId>_<methodName>`; prefix defaults to 'namzu'.
|
|
7
|
+
* - `listTools()` with no instanceId iterates
|
|
8
|
+
* `manager.listConnectedInstances()`; `listTools(instanceId)` uses
|
|
9
|
+
* `manager.getInstance(instanceId)` and filters Boolean (missing
|
|
10
|
+
* instance → empty output).
|
|
11
|
+
* - `listTools()` rebuilds `mappings` from scratch on each call.
|
|
12
|
+
* - Schema conversion via `zodToJsonSchema` is best-effort; on
|
|
13
|
+
* conversion failure the schema falls back to `{type: 'object'}`.
|
|
14
|
+
* - `getMappings()` returns a COPY (mutation of the returned array
|
|
15
|
+
* does not affect internal state).
|
|
16
|
+
* - `callTool(name, args)`:
|
|
17
|
+
* - Returns `{content: [text], isError: true}` for unknown tools.
|
|
18
|
+
* - On manager success, returns `{content: [text], isError: false}`
|
|
19
|
+
* with the output stringified if non-string.
|
|
20
|
+
* - On manager failure, returns `{content: [text with error],
|
|
21
|
+
* isError: true}`; falls back to 'Unknown error' when the
|
|
22
|
+
* manager error is undefined.
|
|
23
|
+
* - Method descriptions include the connector DEFINITION name
|
|
24
|
+
* bracketed (not the instance name): `[<def.name>] <method.description>`.
|
|
25
|
+
*/
|
|
26
|
+
import { describe, expect, it, vi } from 'vitest';
|
|
27
|
+
import { z } from 'zod';
|
|
28
|
+
import { MCPConnectorBridge } from './adapter.js';
|
|
29
|
+
const CID = 'conn_http';
|
|
30
|
+
const IID = 'ci_abc';
|
|
31
|
+
function makeDefinition(overrides = {}) {
|
|
32
|
+
return {
|
|
33
|
+
id: CID,
|
|
34
|
+
name: 'HTTP',
|
|
35
|
+
description: 'HTTP connector',
|
|
36
|
+
connectionType: 'http',
|
|
37
|
+
configSchema: z.object({}),
|
|
38
|
+
methods: [
|
|
39
|
+
{
|
|
40
|
+
name: 'request',
|
|
41
|
+
description: 'make http request',
|
|
42
|
+
inputSchema: z.object({ url: z.string() }),
|
|
43
|
+
},
|
|
44
|
+
],
|
|
45
|
+
...overrides,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
function makeInstance() {
|
|
49
|
+
return {
|
|
50
|
+
id: IID,
|
|
51
|
+
connectorId: CID,
|
|
52
|
+
config: { connectorId: CID, name: 'svc' },
|
|
53
|
+
status: 'connected',
|
|
54
|
+
createdAt: Date.now(),
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
function makeManager(overrides = {}) {
|
|
58
|
+
const def = makeDefinition();
|
|
59
|
+
const registry = {
|
|
60
|
+
get: vi.fn(() => def),
|
|
61
|
+
};
|
|
62
|
+
const instance = makeInstance();
|
|
63
|
+
return {
|
|
64
|
+
getInstance: vi.fn(() => instance),
|
|
65
|
+
getRegistry: vi.fn(() => registry),
|
|
66
|
+
listConnectedInstances: vi.fn(() => [instance]),
|
|
67
|
+
execute: vi.fn(),
|
|
68
|
+
...overrides,
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
describe('MCPConnectorBridge.listTools', () => {
|
|
72
|
+
it('builds one MCP tool per method per connected instance with default prefix namzu', () => {
|
|
73
|
+
const bridge = new MCPConnectorBridge({ manager: makeManager() });
|
|
74
|
+
const tools = bridge.listTools();
|
|
75
|
+
expect(tools).toHaveLength(1);
|
|
76
|
+
expect(tools[0]?.name).toBe(`namzu_${CID}_request`);
|
|
77
|
+
expect(tools[0]?.description).toBe('[HTTP] make http request');
|
|
78
|
+
});
|
|
79
|
+
it('honors a custom prefix', () => {
|
|
80
|
+
const bridge = new MCPConnectorBridge({ manager: makeManager(), prefix: 'acme' });
|
|
81
|
+
expect(bridge.listTools()[0]?.name).toBe(`acme_${CID}_request`);
|
|
82
|
+
});
|
|
83
|
+
it('single-instance lookup via listTools(instanceId) uses getInstance; missing instance → empty', () => {
|
|
84
|
+
const manager = makeManager({
|
|
85
|
+
getInstance: vi.fn(() => undefined),
|
|
86
|
+
});
|
|
87
|
+
const bridge = new MCPConnectorBridge({ manager });
|
|
88
|
+
expect(bridge.listTools(IID)).toEqual([]);
|
|
89
|
+
});
|
|
90
|
+
it('mappings are rebuilt on every listTools() call (not appended)', () => {
|
|
91
|
+
const bridge = new MCPConnectorBridge({ manager: makeManager() });
|
|
92
|
+
bridge.listTools();
|
|
93
|
+
bridge.listTools();
|
|
94
|
+
expect(bridge.getMappings()).toHaveLength(1);
|
|
95
|
+
});
|
|
96
|
+
it('skips instances whose connectorId is missing in the registry', () => {
|
|
97
|
+
const manager = makeManager({
|
|
98
|
+
getRegistry: vi.fn(() => ({ get: vi.fn(() => undefined) })),
|
|
99
|
+
});
|
|
100
|
+
const bridge = new MCPConnectorBridge({ manager });
|
|
101
|
+
expect(bridge.listTools()).toEqual([]);
|
|
102
|
+
});
|
|
103
|
+
it('getMappings returns a copy — external mutation does not leak', () => {
|
|
104
|
+
const bridge = new MCPConnectorBridge({ manager: makeManager() });
|
|
105
|
+
bridge.listTools();
|
|
106
|
+
const copy = bridge.getMappings();
|
|
107
|
+
copy.length = 0;
|
|
108
|
+
expect(bridge.getMappings()).toHaveLength(1);
|
|
109
|
+
});
|
|
110
|
+
it('schema conversion falls back to {type: object} when zodToJsonSchema throws', () => {
|
|
111
|
+
const bad = makeDefinition({
|
|
112
|
+
methods: [
|
|
113
|
+
{
|
|
114
|
+
name: 'broken',
|
|
115
|
+
description: 'd',
|
|
116
|
+
// Not a real zod type — intentionally misleads zodToJsonSchema.
|
|
117
|
+
inputSchema: null,
|
|
118
|
+
},
|
|
119
|
+
],
|
|
120
|
+
});
|
|
121
|
+
const manager = makeManager({
|
|
122
|
+
getRegistry: vi.fn(() => ({ get: vi.fn(() => bad) })),
|
|
123
|
+
});
|
|
124
|
+
const bridge = new MCPConnectorBridge({ manager });
|
|
125
|
+
const tools = bridge.listTools();
|
|
126
|
+
expect(tools[0]?.inputSchema).toEqual({ type: 'object' });
|
|
127
|
+
});
|
|
128
|
+
});
|
|
129
|
+
describe('MCPConnectorBridge.callTool', () => {
|
|
130
|
+
it('unknown tool → isError true + explanatory text', async () => {
|
|
131
|
+
const bridge = new MCPConnectorBridge({ manager: makeManager() });
|
|
132
|
+
const result = await bridge.callTool('nope');
|
|
133
|
+
expect(result.isError).toBe(true);
|
|
134
|
+
expect(result.content[0]).toMatchObject({ type: 'text', text: expect.stringContaining('nope') });
|
|
135
|
+
});
|
|
136
|
+
it('happy path — string output passes through as text', async () => {
|
|
137
|
+
const manager = makeManager();
|
|
138
|
+
vi.mocked(manager.execute).mockResolvedValueOnce({
|
|
139
|
+
success: true,
|
|
140
|
+
output: 'hello',
|
|
141
|
+
durationMs: 5,
|
|
142
|
+
});
|
|
143
|
+
const bridge = new MCPConnectorBridge({ manager });
|
|
144
|
+
bridge.listTools();
|
|
145
|
+
const result = await bridge.callTool(`namzu_${CID}_request`, { url: 'x' });
|
|
146
|
+
expect(result.isError).toBe(false);
|
|
147
|
+
expect(result.content[0]).toEqual({ type: 'text', text: 'hello' });
|
|
148
|
+
});
|
|
149
|
+
it('non-string success output is JSON-stringified', async () => {
|
|
150
|
+
const manager = makeManager();
|
|
151
|
+
vi.mocked(manager.execute).mockResolvedValueOnce({
|
|
152
|
+
success: true,
|
|
153
|
+
output: { status: 200 },
|
|
154
|
+
durationMs: 1,
|
|
155
|
+
});
|
|
156
|
+
const bridge = new MCPConnectorBridge({ manager });
|
|
157
|
+
bridge.listTools();
|
|
158
|
+
const result = await bridge.callTool(`namzu_${CID}_request`);
|
|
159
|
+
expect(result.content[0]).toEqual({
|
|
160
|
+
type: 'text',
|
|
161
|
+
text: JSON.stringify({ status: 200 }, null, 2),
|
|
162
|
+
});
|
|
163
|
+
});
|
|
164
|
+
it('manager failure → isError true with error text; falls back to "Unknown error" when error is undefined', async () => {
|
|
165
|
+
const manager = makeManager();
|
|
166
|
+
vi.mocked(manager.execute).mockResolvedValueOnce({
|
|
167
|
+
success: false,
|
|
168
|
+
output: undefined,
|
|
169
|
+
durationMs: 1,
|
|
170
|
+
});
|
|
171
|
+
const bridge = new MCPConnectorBridge({ manager });
|
|
172
|
+
bridge.listTools();
|
|
173
|
+
const result = await bridge.callTool(`namzu_${CID}_request`);
|
|
174
|
+
expect(result.isError).toBe(true);
|
|
175
|
+
expect(result.content[0]).toEqual({ type: 'text', text: 'Unknown error' });
|
|
176
|
+
});
|
|
177
|
+
it('carries the explicit error message when manager provides one', async () => {
|
|
178
|
+
const manager = makeManager();
|
|
179
|
+
vi.mocked(manager.execute).mockResolvedValueOnce({
|
|
180
|
+
success: false,
|
|
181
|
+
output: undefined,
|
|
182
|
+
durationMs: 1,
|
|
183
|
+
error: 'timeout',
|
|
184
|
+
});
|
|
185
|
+
const bridge = new MCPConnectorBridge({ manager });
|
|
186
|
+
bridge.listTools();
|
|
187
|
+
const result = await bridge.callTool(`namzu_${CID}_request`);
|
|
188
|
+
expect(result.content[0]).toEqual({ type: 'text', text: 'timeout' });
|
|
189
|
+
});
|
|
190
|
+
it('passes empty args through as {} when invoked without a second arg', async () => {
|
|
191
|
+
const manager = makeManager();
|
|
192
|
+
vi.mocked(manager.execute).mockResolvedValueOnce({
|
|
193
|
+
success: true,
|
|
194
|
+
output: 'ok',
|
|
195
|
+
durationMs: 1,
|
|
196
|
+
});
|
|
197
|
+
const bridge = new MCPConnectorBridge({ manager });
|
|
198
|
+
bridge.listTools();
|
|
199
|
+
await bridge.callTool(`namzu_${CID}_request`);
|
|
200
|
+
expect(manager.execute).toHaveBeenCalledWith(expect.objectContaining({ input: {} }));
|
|
201
|
+
});
|
|
202
|
+
});
|
|
203
|
+
//# sourceMappingURL=adapter.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter.test.js","sourceRoot":"","sources":["../../../../src/bridge/mcp/connector/adapter.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Current-code invariants asserted (2026-04-21, ses_006 Phase 2):
|
|
3
|
+
*
|
|
4
|
+
* - `mapRunToStreamEvent(event, runId)` returns `{wire, data}` or null.
|
|
5
|
+
* - Wire names match a fixed mapping (one per RunEvent.type):
|
|
6
|
+
* run.started, iteration.started, iteration.completed, message.delta,
|
|
7
|
+
* tool.executing, tool.completed, review.requested, review.completed,
|
|
8
|
+
* checkpoint.created, run.paused, run.resuming, token.usage,
|
|
9
|
+
* activity.created, activity.updated, plan.ready, plan.approved,
|
|
10
|
+
* plan.rejected, plan.step_updated, agent.pending, agent.completed,
|
|
11
|
+
* agent.failed, agent.canceled, task.created, task.updated,
|
|
12
|
+
* plugin.hook_executing, plugin.hook_completed, sandbox.created,
|
|
13
|
+
* sandbox.exec, sandbox.destroyed.
|
|
14
|
+
* - `run_completed` and `run_failed` produce null (final state is
|
|
15
|
+
* delivered by the task.* path, not the SSE delta).
|
|
16
|
+
* - Sub-session lifecycle events (spawned / messaged / idled) produce
|
|
17
|
+
* null — the SSE wire surface does not carry them today.
|
|
18
|
+
* - `data.run_id` is always set from the second arg.
|
|
19
|
+
* - `llm_response` data: `content` falls back to null when empty;
|
|
20
|
+
* `has_tool_calls` is a boolean.
|
|
21
|
+
* - If the event carries `sourceAgentId` or `parentTaskId` fields,
|
|
22
|
+
* they are mirrored onto `data.source_agent_id` / `data.parent_task_id`
|
|
23
|
+
* (snake-cased).
|
|
24
|
+
* - `mapSessionToStreamEvent` is a deprecated alias.
|
|
25
|
+
*/
|
|
26
|
+
export {};
|
|
27
|
+
//# sourceMappingURL=mapper.test.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mapper.test.d.ts","sourceRoot":"","sources":["../../../src/bridge/sse/mapper.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG"}
|