@openscout/protocol 0.2.16 → 0.2.17
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 +2 -1
- package/src/actors.ts +85 -0
- package/src/agent-address.ts +1 -0
- package/src/agent-identity.test.ts +265 -0
- package/src/agent-identity.ts +508 -0
- package/src/agent-selectors.ts +1 -0
- package/src/collaboration.ts +272 -0
- package/src/common.ts +71 -0
- package/src/conversations.ts +37 -0
- package/src/deliveries.ts +46 -0
- package/src/events.ts +84 -0
- package/src/index.ts +14 -0
- package/src/invocations.ts +55 -0
- package/src/mesh.ts +16 -0
- package/src/messages.ts +55 -0
- package/src/relay-agent-card.test.ts +54 -0
- package/src/relay-agent-card.ts +76 -0
- package/src/transports.ts +92 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openscout/protocol",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.17",
|
|
4
4
|
"description": "Typed protocol for the OpenScout local control plane",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
},
|
|
13
13
|
"types": "./src/index.ts",
|
|
14
14
|
"files": [
|
|
15
|
+
"src",
|
|
15
16
|
"dist",
|
|
16
17
|
"README.md"
|
|
17
18
|
],
|
package/src/actors.ts
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
ActorKind,
|
|
3
|
+
AdvertiseScope,
|
|
4
|
+
AgentState,
|
|
5
|
+
MetadataMap,
|
|
6
|
+
ScoutId,
|
|
7
|
+
} from "./common.js";
|
|
8
|
+
|
|
9
|
+
export type AgentClass =
|
|
10
|
+
| "general"
|
|
11
|
+
| "builder"
|
|
12
|
+
| "reviewer"
|
|
13
|
+
| "researcher"
|
|
14
|
+
| "operator"
|
|
15
|
+
| "bridge"
|
|
16
|
+
| "system";
|
|
17
|
+
|
|
18
|
+
export type AgentCapability =
|
|
19
|
+
| "chat"
|
|
20
|
+
| "invoke"
|
|
21
|
+
| "deliver"
|
|
22
|
+
| "speak"
|
|
23
|
+
| "listen"
|
|
24
|
+
| "bridge"
|
|
25
|
+
| "summarize"
|
|
26
|
+
| "review"
|
|
27
|
+
| "execute";
|
|
28
|
+
|
|
29
|
+
export type AgentHarness =
|
|
30
|
+
| "codex"
|
|
31
|
+
| "claude"
|
|
32
|
+
| "native"
|
|
33
|
+
| "worker"
|
|
34
|
+
| "bridge"
|
|
35
|
+
| "http";
|
|
36
|
+
|
|
37
|
+
export type WakePolicy = "manual" | "on_demand" | "keep_warm";
|
|
38
|
+
|
|
39
|
+
export interface ActorIdentity {
|
|
40
|
+
id: ScoutId;
|
|
41
|
+
kind: ActorKind;
|
|
42
|
+
displayName: string;
|
|
43
|
+
handle?: string;
|
|
44
|
+
labels?: string[];
|
|
45
|
+
metadata?: MetadataMap;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export interface AgentDefinition extends ActorIdentity {
|
|
49
|
+
kind: "agent";
|
|
50
|
+
definitionId: ScoutId;
|
|
51
|
+
nodeQualifier?: string;
|
|
52
|
+
workspaceQualifier?: string;
|
|
53
|
+
selector?: string;
|
|
54
|
+
defaultSelector?: string;
|
|
55
|
+
agentClass: AgentClass;
|
|
56
|
+
capabilities: AgentCapability[];
|
|
57
|
+
wakePolicy: WakePolicy;
|
|
58
|
+
homeNodeId: ScoutId;
|
|
59
|
+
authorityNodeId: ScoutId;
|
|
60
|
+
advertiseScope: AdvertiseScope;
|
|
61
|
+
ownerId?: ScoutId;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export interface HelperDefinition extends ActorIdentity {
|
|
65
|
+
kind: "helper";
|
|
66
|
+
ownerId: ScoutId;
|
|
67
|
+
nodeId: ScoutId;
|
|
68
|
+
engine: AgentHarness;
|
|
69
|
+
capabilities: AgentCapability[];
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export interface AgentEndpoint {
|
|
73
|
+
id: ScoutId;
|
|
74
|
+
agentId: ScoutId;
|
|
75
|
+
nodeId: ScoutId;
|
|
76
|
+
harness: AgentHarness;
|
|
77
|
+
transport: "local_socket" | "http" | "websocket" | "claude_stream_json" | "codex_app_server" | "codex_exec" | "claude_resume" | "tmux";
|
|
78
|
+
state: AgentState;
|
|
79
|
+
address?: string;
|
|
80
|
+
sessionId?: string;
|
|
81
|
+
pane?: string;
|
|
82
|
+
cwd?: string;
|
|
83
|
+
projectRoot?: string;
|
|
84
|
+
metadata?: MetadataMap;
|
|
85
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./agent-identity.js";
|
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
import { describe, expect, test } from "bun:test";
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
constructAgentAlias,
|
|
5
|
+
constructAgentIdentity,
|
|
6
|
+
extractAgentIdentities,
|
|
7
|
+
formatAgentAlias,
|
|
8
|
+
formatAgentIdentity,
|
|
9
|
+
formatMinimalAgentIdentity,
|
|
10
|
+
parseAgentIdentity,
|
|
11
|
+
parseAgentSelector,
|
|
12
|
+
resolveAgentAlias,
|
|
13
|
+
resolveAgentIdentity,
|
|
14
|
+
resolveAgentSelector,
|
|
15
|
+
} from "./agent-identity.js";
|
|
16
|
+
|
|
17
|
+
describe("agent identity grammar", () => {
|
|
18
|
+
test("parses bare, positional, and typed identities", () => {
|
|
19
|
+
expect(parseAgentIdentity("@arc")).toEqual({
|
|
20
|
+
raw: "arc",
|
|
21
|
+
label: "@arc",
|
|
22
|
+
definitionId: "arc",
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
expect(parseAgentIdentity("@arc.main")).toEqual({
|
|
26
|
+
raw: "arc.main",
|
|
27
|
+
label: "@arc.main",
|
|
28
|
+
definitionId: "arc",
|
|
29
|
+
workspaceQualifier: "main",
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
expect(parseAgentIdentity("@arc.main.profile:dev-browser.harness:claude")).toEqual({
|
|
33
|
+
raw: "arc.main.profile:dev-browser.harness:claude",
|
|
34
|
+
label: "@arc.main.profile:dev-browser.harness:claude",
|
|
35
|
+
definitionId: "arc",
|
|
36
|
+
workspaceQualifier: "main",
|
|
37
|
+
profile: "dev-browser",
|
|
38
|
+
harness: "claude",
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
expect(parseAgentIdentity("@arc.profile:dev.main")).toEqual({
|
|
42
|
+
raw: "arc.profile:dev.main",
|
|
43
|
+
label: "@arc.main.profile:dev",
|
|
44
|
+
definitionId: "arc",
|
|
45
|
+
workspaceQualifier: "main",
|
|
46
|
+
profile: "dev",
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
expect(parseAgentIdentity("@arc.branch:super/refactor.persona:dev-browser.runtime:codex.node:mini")).toEqual({
|
|
50
|
+
raw: "arc.branch:super/refactor.persona:dev-browser.runtime:codex.node:mini",
|
|
51
|
+
label: "@arc.super-refactor.profile:dev-browser.harness:codex.node:mini",
|
|
52
|
+
definitionId: "arc",
|
|
53
|
+
workspaceQualifier: "super-refactor",
|
|
54
|
+
profile: "dev-browser",
|
|
55
|
+
harness: "codex",
|
|
56
|
+
nodeQualifier: "mini",
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
test("rejects invalid and legacy-shaped identities", () => {
|
|
61
|
+
expect(parseAgentIdentity("")).toBeNull();
|
|
62
|
+
expect(parseAgentIdentity("@arc.main.dev")).toBeNull();
|
|
63
|
+
expect(parseAgentIdentity("@arc.profile:")).toBeNull();
|
|
64
|
+
expect(parseAgentIdentity("@arc@mini#main")).toBeNull();
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
test("constructs canonical agent identities", () => {
|
|
68
|
+
expect(constructAgentIdentity({
|
|
69
|
+
definitionId: "Arc",
|
|
70
|
+
workspaceQualifier: "Super Refactor",
|
|
71
|
+
profile: "Dev Browser",
|
|
72
|
+
harness: "Claude",
|
|
73
|
+
nodeQualifier: "Mini.local",
|
|
74
|
+
})).toEqual({
|
|
75
|
+
raw: "arc.super-refactor.profile:dev-browser.harness:claude.node:mini-local",
|
|
76
|
+
label: "@arc.super-refactor.profile:dev-browser.harness:claude.node:mini-local",
|
|
77
|
+
definitionId: "arc",
|
|
78
|
+
workspaceQualifier: "super-refactor",
|
|
79
|
+
profile: "dev-browser",
|
|
80
|
+
harness: "claude",
|
|
81
|
+
nodeQualifier: "mini-local",
|
|
82
|
+
});
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
test("formats canonical identities", () => {
|
|
86
|
+
expect(formatAgentIdentity({
|
|
87
|
+
definitionId: "arc",
|
|
88
|
+
workspaceQualifier: "main",
|
|
89
|
+
profile: "dev-browser",
|
|
90
|
+
harness: "claude",
|
|
91
|
+
nodeQualifier: "mini",
|
|
92
|
+
})).toBe("@arc.main.profile:dev-browser.harness:claude.node:mini");
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
test("extracts unique identities from text", () => {
|
|
96
|
+
expect(extractAgentIdentities(
|
|
97
|
+
"Compare @arc.main.profile:dev-browser with @hudson, then ping @arc.main.profile:dev-browser.",
|
|
98
|
+
)).toEqual([
|
|
99
|
+
{
|
|
100
|
+
raw: "arc.main.profile:dev-browser",
|
|
101
|
+
label: "@arc.main.profile:dev-browser",
|
|
102
|
+
definitionId: "arc",
|
|
103
|
+
workspaceQualifier: "main",
|
|
104
|
+
profile: "dev-browser",
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
raw: "hudson",
|
|
108
|
+
label: "@hudson",
|
|
109
|
+
definitionId: "hudson",
|
|
110
|
+
},
|
|
111
|
+
]);
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
test("keeps selector aliases as thin compatibility exports", () => {
|
|
115
|
+
expect(parseAgentSelector("@arc.main.profile:dev")).toEqual({
|
|
116
|
+
raw: "arc.main.profile:dev",
|
|
117
|
+
label: "@arc.main.profile:dev",
|
|
118
|
+
definitionId: "arc",
|
|
119
|
+
workspaceQualifier: "main",
|
|
120
|
+
profile: "dev",
|
|
121
|
+
});
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
test("constructs and formats explicit aliases", () => {
|
|
125
|
+
const alias = constructAgentAlias({
|
|
126
|
+
alias: "@Huddy",
|
|
127
|
+
target: {
|
|
128
|
+
definitionId: "hudson",
|
|
129
|
+
workspaceQualifier: "main",
|
|
130
|
+
profile: "dev-browser",
|
|
131
|
+
},
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
expect(alias).toEqual({
|
|
135
|
+
alias: "huddy",
|
|
136
|
+
target: {
|
|
137
|
+
definitionId: "hudson",
|
|
138
|
+
workspaceQualifier: "main",
|
|
139
|
+
profile: "dev-browser",
|
|
140
|
+
},
|
|
141
|
+
});
|
|
142
|
+
expect(formatAgentAlias(alias!)).toBe("@huddy");
|
|
143
|
+
});
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
describe("agent identity resolution", () => {
|
|
147
|
+
const candidates = [
|
|
148
|
+
{
|
|
149
|
+
agentId: "arc.default",
|
|
150
|
+
definitionId: "arc",
|
|
151
|
+
workspaceQualifier: "main",
|
|
152
|
+
profile: "base",
|
|
153
|
+
harness: "codex",
|
|
154
|
+
aliases: [formatAgentIdentity({ definitionId: "arc" })],
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
agentId: "arc.browser",
|
|
158
|
+
definitionId: "arc",
|
|
159
|
+
workspaceQualifier: "main",
|
|
160
|
+
profile: "dev-browser",
|
|
161
|
+
harness: "codex",
|
|
162
|
+
},
|
|
163
|
+
{
|
|
164
|
+
agentId: "arc.claude",
|
|
165
|
+
definitionId: "arc",
|
|
166
|
+
workspaceQualifier: "super-refactor",
|
|
167
|
+
profile: "dev-browser",
|
|
168
|
+
harness: "claude",
|
|
169
|
+
nodeQualifier: "mini",
|
|
170
|
+
},
|
|
171
|
+
{
|
|
172
|
+
agentId: "hudson.main",
|
|
173
|
+
definitionId: "hudson",
|
|
174
|
+
workspaceQualifier: "hudson-main-8012ac",
|
|
175
|
+
harness: "codex",
|
|
176
|
+
nodeQualifier: "arachs-mac-mini-local",
|
|
177
|
+
aliases: ["@huddy"],
|
|
178
|
+
},
|
|
179
|
+
{
|
|
180
|
+
agentId: "hudson.browser",
|
|
181
|
+
definitionId: "hudson",
|
|
182
|
+
workspaceQualifier: "hudson-main-8012ac",
|
|
183
|
+
profile: "dev-browser",
|
|
184
|
+
harness: "codex",
|
|
185
|
+
nodeQualifier: "arachs-mac-mini-local",
|
|
186
|
+
},
|
|
187
|
+
{
|
|
188
|
+
agentId: "hudson.other-node",
|
|
189
|
+
definitionId: "hudson",
|
|
190
|
+
workspaceQualifier: "hudson-main-8012ac",
|
|
191
|
+
harness: "codex",
|
|
192
|
+
nodeQualifier: "backup-mac-mini",
|
|
193
|
+
},
|
|
194
|
+
];
|
|
195
|
+
|
|
196
|
+
test("prefers explicit default aliases for bare identities", () => {
|
|
197
|
+
const identity = parseAgentIdentity("@arc");
|
|
198
|
+
expect(identity).not.toBeNull();
|
|
199
|
+
expect(resolveAgentIdentity(identity!, candidates)).toEqual(candidates[0]);
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
test("resolves typed qualifiers to the matching concrete agent", () => {
|
|
203
|
+
const identity = parseAgentIdentity("@arc.main.profile:dev-browser");
|
|
204
|
+
expect(identity).not.toBeNull();
|
|
205
|
+
expect(resolveAgentIdentity(identity!, candidates)).toEqual(candidates[1]);
|
|
206
|
+
});
|
|
207
|
+
|
|
208
|
+
test("resolves fully qualified identities including harness and node", () => {
|
|
209
|
+
const identity = parseAgentIdentity("@arc.super-refactor.profile:dev-browser.harness:claude.node:mini");
|
|
210
|
+
expect(identity).not.toBeNull();
|
|
211
|
+
expect(resolveAgentIdentity(identity!, candidates)).toEqual(candidates[2]);
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
test("returns null for ambiguous non-default partial identities", () => {
|
|
215
|
+
const identity = parseAgentIdentity("@arc.profile:dev-browser");
|
|
216
|
+
expect(identity).not.toBeNull();
|
|
217
|
+
expect(resolveAgentIdentity(identity!, candidates)).toBeNull();
|
|
218
|
+
});
|
|
219
|
+
|
|
220
|
+
test("keeps selector resolution aliases as thin compatibility exports", () => {
|
|
221
|
+
const identity = parseAgentSelector("@arc.main.profile:dev-browser");
|
|
222
|
+
expect(identity).not.toBeNull();
|
|
223
|
+
expect(resolveAgentSelector(identity!, candidates)).toEqual(candidates[1]);
|
|
224
|
+
});
|
|
225
|
+
|
|
226
|
+
test("resolves exact human aliases before canonical matching", () => {
|
|
227
|
+
const identity = parseAgentIdentity("@huddy");
|
|
228
|
+
expect(identity).not.toBeNull();
|
|
229
|
+
expect(resolveAgentIdentity(identity!, candidates)).toEqual(candidates[3]);
|
|
230
|
+
});
|
|
231
|
+
|
|
232
|
+
test("resolves aliases through the explicit alias table", () => {
|
|
233
|
+
const identity = resolveAgentAlias("@huddy", [
|
|
234
|
+
{
|
|
235
|
+
alias: "huddy",
|
|
236
|
+
target: {
|
|
237
|
+
definitionId: "hudson",
|
|
238
|
+
workspaceQualifier: "hudson-main-8012ac",
|
|
239
|
+
harness: "codex",
|
|
240
|
+
nodeQualifier: "arachs-mac-mini-local",
|
|
241
|
+
},
|
|
242
|
+
},
|
|
243
|
+
]);
|
|
244
|
+
|
|
245
|
+
expect(identity).toEqual({
|
|
246
|
+
raw: "hudson.hudson-main-8012ac.harness:codex.node:arachs-mac-mini-local",
|
|
247
|
+
label: "@hudson.hudson-main-8012ac.harness:codex.node:arachs-mac-mini-local",
|
|
248
|
+
definitionId: "hudson",
|
|
249
|
+
workspaceQualifier: "hudson-main-8012ac",
|
|
250
|
+
harness: "codex",
|
|
251
|
+
nodeQualifier: "arachs-mac-mini-local",
|
|
252
|
+
});
|
|
253
|
+
});
|
|
254
|
+
|
|
255
|
+
test("formats the shortest unambiguous identity for a candidate", () => {
|
|
256
|
+
expect(formatMinimalAgentIdentity(candidates[0], candidates)).toBe("@arc");
|
|
257
|
+
expect(formatMinimalAgentIdentity(candidates[1], candidates)).toBe("@arc.main.profile:dev-browser");
|
|
258
|
+
expect(formatMinimalAgentIdentity(candidates[2], candidates)).toBe("@arc.super-refactor");
|
|
259
|
+
expect(formatMinimalAgentIdentity(candidates[3], candidates)).toBe("@huddy");
|
|
260
|
+
expect(formatMinimalAgentIdentity(candidates[4], candidates)).toBe(
|
|
261
|
+
"@hudson.profile:dev-browser",
|
|
262
|
+
);
|
|
263
|
+
expect(formatMinimalAgentIdentity(candidates[5], candidates)).toBe("@hudson.node:backup-mac-mini");
|
|
264
|
+
});
|
|
265
|
+
});
|