@borgee/agents-host 0.2.2 → 0.2.28
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/README.md +184 -21
- package/dist/agents-host-supervisor.d.ts +7 -5
- package/dist/agents-host-supervisor.js +24 -4
- package/dist/agents-host.d.ts +114 -15
- package/dist/agents-host.js +2712 -141
- package/dist/chat/chat-control-plane.d.ts +13 -2
- package/dist/chat/sdk-chat-control-plane.d.ts +14 -3
- package/dist/chat/sdk-chat-control-plane.js +54 -2
- package/dist/cli-args.d.ts +46 -5
- package/dist/cli-args.js +313 -32
- package/dist/cli.d.ts +9 -0
- package/dist/cli.js +112 -5
- package/dist/compatibility-gates.d.ts +39 -0
- package/dist/compatibility-gates.js +131 -0
- package/dist/config.d.ts +1 -0
- package/dist/config.js +23 -5
- package/dist/connections-state-store.d.ts +81 -0
- package/dist/connections-state-store.js +228 -0
- package/dist/context/attention.d.ts +12 -0
- package/dist/context/attention.js +137 -0
- package/dist/context/collaboration-capabilities-diagnostics.d.ts +3 -0
- package/dist/context/collaboration-capabilities-diagnostics.js +18 -0
- package/dist/context/collaboration-outcome.d.ts +2 -0
- package/dist/context/collaboration-outcome.js +26 -0
- package/dist/context/injection.d.ts +134 -0
- package/dist/context/injection.js +355 -0
- package/dist/context/prompt.d.ts +4 -1
- package/dist/context/prompt.js +231 -1
- package/dist/context/task-thread-collaboration.d.ts +6 -0
- package/dist/context/task-thread-collaboration.js +31 -0
- package/dist/context/turn-preparation.d.ts +9 -0
- package/dist/context/turn-preparation.js +135 -0
- package/dist/debug.d.ts +44 -0
- package/dist/debug.js +135 -0
- package/dist/gateway/localhost-gateway.d.ts +52 -0
- package/dist/gateway/localhost-gateway.js +857 -0
- package/dist/index.js +7 -5
- package/dist/local-config.d.ts +4 -1
- package/dist/local-config.js +24 -7
- package/dist/managed-daemon-log.d.ts +34 -0
- package/dist/managed-daemon-log.js +261 -0
- package/dist/managed-daemon.d.ts +220 -0
- package/dist/managed-daemon.js +1601 -0
- package/dist/policy/authorization-audit.d.ts +63 -0
- package/dist/policy/authorization-audit.js +94 -0
- package/dist/policy/copilot-permission.d.ts +15 -0
- package/dist/policy/copilot-permission.js +193 -0
- package/dist/policy/gateway-authorization.d.ts +42 -0
- package/dist/policy/gateway-authorization.js +162 -0
- package/dist/providers/awaiting-user.d.ts +12 -0
- package/dist/providers/awaiting-user.js +192 -0
- package/dist/providers/claude/adapter.d.ts +3 -1
- package/dist/providers/claude/adapter.js +8 -12
- package/dist/providers/claude/cli-client.d.ts +12 -5
- package/dist/providers/claude/cli-client.js +184 -37
- package/dist/providers/claude/session-store.d.ts +1 -0
- package/dist/providers/codex/adapter.d.ts +11 -0
- package/dist/providers/codex/adapter.js +19 -0
- package/dist/providers/codex/cli-client.d.ts +103 -0
- package/dist/providers/codex/cli-client.js +1133 -0
- package/dist/providers/codex/project-doc.d.ts +3 -0
- package/dist/providers/codex/project-doc.js +90 -0
- package/dist/providers/codex/session-store.d.ts +38 -0
- package/dist/providers/codex/session-store.js +150 -0
- package/dist/providers/copilot/adapter.d.ts +3 -1
- package/dist/providers/copilot/adapter.js +8 -12
- package/dist/providers/copilot/cli-client.d.ts +20 -2
- package/dist/providers/copilot/cli-client.js +251 -71
- package/dist/providers/copilot/session-store.d.ts +1 -0
- package/dist/providers/create-provider.d.ts +11 -2
- package/dist/providers/create-provider.js +131 -12
- package/dist/run.d.ts +1 -0
- package/dist/run.js +5 -2
- package/dist/state-paths.d.ts +14 -1
- package/dist/state-paths.js +87 -3
- package/dist/task-thread-resolution.d.ts +10 -0
- package/dist/task-thread-resolution.js +48 -0
- package/dist/types.d.ts +267 -1
- package/dist/visible-mentions.d.ts +3 -0
- package/dist/visible-mentions.js +15 -0
- package/package.json +19 -17
- package/skills/borgee-agent/SKILL.md +33 -0
- package/skills/borgee-agent/borgee-agent.mjs +473 -0
- package/skills/borgee-agent/borgee-agent.py +409 -0
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Minimal local runtime host for Borgee agents.
|
|
4
4
|
|
|
5
|
-
- **
|
|
5
|
+
- **Standalone env mode** keeps the existing one-process / one-agent flow.
|
|
6
6
|
- **Local-config mode** adds first-step multi-agent local hosting from a host
|
|
7
7
|
config file plus one config file per agent, with hot reload.
|
|
8
8
|
|
|
@@ -15,14 +15,15 @@ Borgee channel message
|
|
|
15
15
|
→ /ws/plugin (BPP)
|
|
16
16
|
→ @borgee/plugin-sdk
|
|
17
17
|
→ AgentsHost.handleMessage
|
|
18
|
-
→ local claude / copilot
|
|
18
|
+
→ local claude / codex-acp / copilot runtime
|
|
19
19
|
→ BPP reply
|
|
20
20
|
→ Borgee channel
|
|
21
21
|
```
|
|
22
22
|
|
|
23
23
|
**In scope:**
|
|
24
24
|
|
|
25
|
-
-
|
|
25
|
+
- standalone env startup
|
|
26
|
+
- foreground CLI startup for one hosted agent
|
|
26
27
|
- local-config multi-agent startup
|
|
27
28
|
- one isolated `AgentsHost` per effective agent key
|
|
28
29
|
- per-channel conversation memory via each provider's native session mechanism
|
|
@@ -48,14 +49,22 @@ For the published CLI entry point:
|
|
|
48
49
|
|
|
49
50
|
```bash
|
|
50
51
|
agents-host start <serverUrl> <apiKey> [options]
|
|
51
|
-
agents-host start
|
|
52
|
+
agents-host start-managed <serverUrl>
|
|
53
|
+
agents-host start-managed <serverUrl> <apiKey> [agent-options]
|
|
54
|
+
agents-host describe-managed <serverUrl>
|
|
55
|
+
agents-host apply-managed <serverUrl> --stdin
|
|
56
|
+
agents-host apply-managed <serverUrl> --spec-json <json>
|
|
57
|
+
agents-host log <serverUrl> [--lines <n>] [--follow]
|
|
58
|
+
agents-host log <serverUrl> --path
|
|
59
|
+
agents-host start --config <path-to-host-config> [--debug]
|
|
52
60
|
agents-host validate --config <path-to-host-config>
|
|
61
|
+
agents-host describe --config <path-to-host-config>
|
|
53
62
|
agents-host print-layout --root <dir>
|
|
54
63
|
agents-host generate-config --root <dir> --stdin
|
|
55
64
|
agents-host generate-config --root <dir> --spec-json <json>
|
|
56
65
|
```
|
|
57
66
|
|
|
58
|
-
##
|
|
67
|
+
## Standalone env mode
|
|
59
68
|
|
|
60
69
|
Use the existing env-var flow when you want exactly one hosted agent per
|
|
61
70
|
process.
|
|
@@ -68,21 +77,142 @@ RUNTIME_PROVIDER=claude \
|
|
|
68
77
|
pnpm --filter @borgee/agents-host dev
|
|
69
78
|
```
|
|
70
79
|
|
|
80
|
+
Codex remains opt-in. Select `RUNTIME_PROVIDER=codex` only when `AGENTS_HOST_INTERNAL_COMPATIBILITY_GATES` includes `codex-provider`.
|
|
81
|
+
|
|
71
82
|
Or with the CLI:
|
|
72
83
|
|
|
73
84
|
```bash
|
|
74
|
-
agents-host start https://your-borgee-server bgr_xxxxxxxx --provider copilot
|
|
85
|
+
agents-host start https://your-borgee-server bgr_xxxxxxxx --provider copilot --debug
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## Managed daemon bootstrap mode
|
|
89
|
+
|
|
90
|
+
`agents-host start-managed` has two forms:
|
|
91
|
+
|
|
92
|
+
- `agents-host start-managed <serverUrl> <apiKey> [agent-options]` bootstraps or
|
|
93
|
+
reuses the per-server managed daemon, then upserts the requested agent
|
|
94
|
+
- `agents-host start-managed <serverUrl>` restarts or resumes an already-managed
|
|
95
|
+
runtime for that server without re-supplying the agent API key or options
|
|
96
|
+
|
|
97
|
+
Unlike foreground `start`, both forms exit after the managed daemon is ready,
|
|
98
|
+
and the full form additionally waits for the requested agent reconcile.
|
|
99
|
+
|
|
100
|
+
It:
|
|
101
|
+
|
|
102
|
+
1. resolves a managed runtime root under `~/.borgee/agents-host/managed/`
|
|
103
|
+
specific to that normalized `serverUrl`
|
|
104
|
+
2. reuses the daemon already serving that runtime root when it is alive
|
|
105
|
+
3. otherwise starts one local supervisor daemon for that managed root and waits
|
|
106
|
+
for it to become ready
|
|
107
|
+
4. for the full `<serverUrl> <apiKey> ...` form only, upserts the requested
|
|
108
|
+
agent and waits for that reconcile before reporting success
|
|
109
|
+
|
|
110
|
+
The short resume form does **not** auto-seed a new managed runtime. It fails
|
|
111
|
+
clearly unless that serverUrl already has a persisted managed config with at
|
|
112
|
+
least one persisted agent entry from an earlier full
|
|
113
|
+
`start-managed <serverUrl> <apiKey> ...` bootstrap. Those persisted agents may
|
|
114
|
+
all currently be disabled; the managed runtime is still considered bootstrapped
|
|
115
|
+
and resumable in that case.
|
|
116
|
+
|
|
117
|
+
Each managed runtime root keeps:
|
|
118
|
+
|
|
119
|
+
- `agents-host.yaml` and `agents/` as the stable generated local-config entrypoints
|
|
120
|
+
- `daemon.log` as the detached managed daemon stdout/stderr log file
|
|
121
|
+
- `.state/` as the per-agent runtime state base
|
|
122
|
+
- `ctl.sock` as the local control socket
|
|
123
|
+
|
|
124
|
+
Detached `start-managed` daemon launches append both stdout and stderr to
|
|
125
|
+
`<managed-root>/daemon.log`. This change does not add rotation or truncation;
|
|
126
|
+
the daemon keeps appending to the same private log file until tooling or the
|
|
127
|
+
operator moves or clears it.
|
|
128
|
+
|
|
129
|
+
This MVP does not migrate legacy `~/.borgee/agents-host/single-agent` state
|
|
130
|
+
into the managed runtime root.
|
|
131
|
+
|
|
132
|
+
Agent identities generated through `start-managed` are internal and stable for
|
|
133
|
+
the same API key within one server runtime root; repeated starts with the same
|
|
134
|
+
API key replace that generated agent entry instead of appending duplicates.
|
|
135
|
+
|
|
136
|
+
Example:
|
|
137
|
+
|
|
138
|
+
```bash
|
|
139
|
+
agents-host start-managed https://your-borgee-server bgr_xxxxxxxx --provider copilot
|
|
140
|
+
agents-host start-managed https://your-borgee-server
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### Machine-oriented managed-runtime commands
|
|
144
|
+
|
|
145
|
+
`describe-managed` and `apply-managed` are JSON-only commands for machine callers.
|
|
146
|
+
They operate on the same per-server managed runtime root as `start-managed`, but
|
|
147
|
+
they expose full-set managed-runtime state instead of the legacy single-agent
|
|
148
|
+
upsert flow.
|
|
149
|
+
|
|
150
|
+
```bash
|
|
151
|
+
agents-host describe-managed https://your-borgee-server
|
|
152
|
+
printf '%s' '{"host":{"borgeeBaseUrl":"https://your-borgee-server"},"agents":[{"key":"cp1","name":"Copilot","apiKey":"bgr_xxx","provider":"copilot"}]}' \
|
|
153
|
+
| agents-host apply-managed https://your-borgee-server --stdin
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
- `describe-managed` prints one JSON object to stdout only:
|
|
157
|
+
- `{ "ok": true, "present": false }`
|
|
158
|
+
- `{ "ok": true, "present": true, "spec": { ... } }`
|
|
159
|
+
- `{ "ok": false, "error": { "code": "...", "message": "..." } }`
|
|
160
|
+
- `apply-managed` accepts one full-set managed spec, validates that its
|
|
161
|
+
`host.borgeeBaseUrl` matches the requested runtime binding, rejects empty
|
|
162
|
+
full-set specs, then prints one JSON object to stdout only
|
|
163
|
+
- expected managed failures are reported as structured JSON on stdout and exit 0
|
|
164
|
+
- malformed CLI usage still follows the normal usage stderr + non-zero exit path
|
|
165
|
+
- `--stdin` is preferred because `--spec-json` exposes the JSON in process
|
|
166
|
+
arguments
|
|
167
|
+
|
|
168
|
+
### Managed daemon logs
|
|
169
|
+
|
|
170
|
+
Resolve or stream the managed daemon log for one server runtime directly from the
|
|
171
|
+
managed runtime root helpers:
|
|
172
|
+
|
|
173
|
+
```bash
|
|
174
|
+
agents-host log https://your-borgee-server
|
|
175
|
+
agents-host log https://your-borgee-server --lines 0 --follow
|
|
176
|
+
agents-host log https://your-borgee-server --path
|
|
75
177
|
```
|
|
76
178
|
|
|
77
|
-
|
|
179
|
+
- default output prints the last 100 log lines
|
|
180
|
+
- `--follow` keeps polling for appended content and resumes after truncation or
|
|
181
|
+
replacement
|
|
182
|
+
- `--lines <n>` accepts non-negative integers only; `0` suppresses the initial
|
|
183
|
+
tail before follow mode
|
|
184
|
+
- `--path` prints only the resolved log path and does not require the file to
|
|
185
|
+
exist yet
|
|
186
|
+
|
|
187
|
+
### Debug mode
|
|
188
|
+
|
|
189
|
+
Enable extra host/provider lifecycle logs with either:
|
|
190
|
+
|
|
191
|
+
```bash
|
|
192
|
+
agents-host start https://your-borgee-server bgr_xxxxxxxx --provider copilot --debug
|
|
193
|
+
AGENTS_HOST_DEBUG=1 agents-host start --config ./agents-host.yaml
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
Notes:
|
|
197
|
+
|
|
198
|
+
- `--debug` applies to foreground `start <serverUrl> <apiKey>` and `start --config <path>`
|
|
199
|
+
- `AGENTS_HOST_DEBUG=1` is the env fallback for both the CLI and `pnpm --filter @borgee/agents-host dev`
|
|
200
|
+
- `start-managed` intentionally does not accept `--debug` or `AGENTS_HOST_DEBUG=1`, because it may reuse an already-running daemon whose log mode is already fixed
|
|
201
|
+
- host-authored debug logs stay secret-safe: they avoid API keys, raw prompt text, raw replies, and other sensitive tokens
|
|
202
|
+
- Copilot child-process stderr is passed through only in debug mode
|
|
203
|
+
- local-config mode prefixes debug logs with the managed agent key so interleaved output stays readable
|
|
204
|
+
|
|
205
|
+
### Environment variables / equivalent single-agent agent options
|
|
78
206
|
|
|
79
207
|
| Variable | CLI flag | Required | Default | Description |
|
|
80
208
|
| ---------------------------------- | -------------------------------------- | -------- | --------------------------------------------- | ------------------------------------------------------------------------------------------------ |
|
|
81
209
|
| `BORGEE_BASE_URL` | positional `<serverUrl>` | yes | — | Borgee server base URL |
|
|
82
210
|
| `BORGEE_AGENT_API_KEY` | positional `<apiKey>` | yes | — | Agent API key from the web UI |
|
|
211
|
+
| `AGENTS_HOST_DEBUG` | `--debug` | no | off | Extra host/provider lifecycle logs. Set `AGENTS_HOST_DEBUG=1` to enable without the CLI flag. |
|
|
83
212
|
| `BORGEE_AGENT_NAME` | `--name` | no | `Assistant` | Display name used in prompts |
|
|
84
|
-
| `RUNTIME_PROVIDER` | `--provider` | no | `claude` | `claude` or `
|
|
213
|
+
| `RUNTIME_PROVIDER` | `--provider` | no | `claude` | `claude`, `copilot`, or `codex` when `codex-provider` is enabled |
|
|
85
214
|
| `CLAUDE_COMMAND` / `CLAUDE_ARGS` | `--claude-command` / `--claude-args` | no | `claude` / `--print` | Local Claude CLI command + args |
|
|
215
|
+
| `CODEX_COMMAND` / `CODEX_ARGS` | `--codex-command` / `--codex-args` | no | `codex-acp` / empty | Local Codex ACP adapter command + args. The default launch resolves the bundled `@agentclientprotocol/codex-acp` entrypoint. |
|
|
86
216
|
| `COPILOT_COMMAND` / `COPILOT_ARGS` | `--copilot-command` / `--copilot-args` | no | `copilot` / parsed but ignored by ACP runtime | Local Copilot CLI command. The persistent Copilot ACP prototype always launches `copilot --acp`. |
|
|
87
217
|
| `COPILOT_SESSION_TTL_MINUTES` | `--copilot-session-ttl-minutes` | no | `2880` | Idle TTL for per-channel Copilot ACP sessions |
|
|
88
218
|
|
|
@@ -165,7 +295,9 @@ The spec shape is:
|
|
|
165
295
|
"borgeeBaseUrl": "https://borgee.example.com",
|
|
166
296
|
"defaults": {
|
|
167
297
|
"claudeCommand": "claude",
|
|
168
|
-
"claudeArgs": ["--print"],
|
|
298
|
+
"claudeArgs": ["--print", "--permission-mode", "bypassPermissions"],
|
|
299
|
+
"codexCommand": "codex-acp",
|
|
300
|
+
"codexArgs": [],
|
|
169
301
|
"copilotCommand": "copilot",
|
|
170
302
|
"copilotArgs": ["-s", "--no-color", "--allow-all-tools", "--output-format", "text"],
|
|
171
303
|
"copilotSessionTtlMinutes": 2880
|
|
@@ -232,6 +364,10 @@ defaults:
|
|
|
232
364
|
claudeCommand: claude
|
|
233
365
|
claudeArgs:
|
|
234
366
|
- --print
|
|
367
|
+
- --permission-mode
|
|
368
|
+
- bypassPermissions
|
|
369
|
+
codexCommand: codex-acp
|
|
370
|
+
codexArgs: []
|
|
235
371
|
copilotCommand: copilot
|
|
236
372
|
copilotArgs:
|
|
237
373
|
- -s
|
|
@@ -248,12 +384,14 @@ Host config fields:
|
|
|
248
384
|
- `agentsDir` (optional, default `./agents` relative to the host config file)
|
|
249
385
|
- `defaults.claudeCommand`
|
|
250
386
|
- `defaults.claudeArgs`
|
|
387
|
+
- `defaults.codexCommand`
|
|
388
|
+
- `defaults.codexArgs`
|
|
251
389
|
- `defaults.copilotCommand`
|
|
252
390
|
- `defaults.copilotArgs`
|
|
253
391
|
- `defaults.copilotSessionTtlMinutes`
|
|
254
392
|
|
|
255
393
|
Absent host defaults fall back to the same code-level defaults used by the
|
|
256
|
-
|
|
394
|
+
standalone env flow, foreground `start`, and `start-managed`.
|
|
257
395
|
|
|
258
396
|
### Agent config
|
|
259
397
|
|
|
@@ -265,6 +403,8 @@ provider: claude
|
|
|
265
403
|
enabled: true
|
|
266
404
|
claudeArgs:
|
|
267
405
|
- --print
|
|
406
|
+
- --permission-mode
|
|
407
|
+
- bypassPermissions
|
|
268
408
|
- --model
|
|
269
409
|
- sonnet
|
|
270
410
|
```
|
|
@@ -274,10 +414,11 @@ Agent config fields:
|
|
|
274
414
|
- `key` (**required**): stable identity used for diffing and reload decisions
|
|
275
415
|
- `name` (**required**)
|
|
276
416
|
- `apiKey` (**required**)
|
|
277
|
-
- `provider` (**required**): `claude` or `
|
|
417
|
+
- `provider` (**required**): `claude`, `copilot`, or gated `codex`
|
|
278
418
|
- `enabled` (optional, default `true`)
|
|
279
|
-
- optional overrides for `claudeCommand`, `claudeArgs`, `
|
|
280
|
-
`copilotArgs`, and
|
|
419
|
+
- optional overrides for `claudeCommand`, `claudeArgs`, `codexCommand`,
|
|
420
|
+
`codexArgs`, `copilotCommand`, `copilotArgs`, and
|
|
421
|
+
`copilotSessionTtlMinutes`
|
|
281
422
|
|
|
282
423
|
Array overrides are **replacement**, not concatenation. For example, an agent
|
|
283
424
|
`claudeArgs` value replaces the host default `claudeArgs` entirely.
|
|
@@ -318,16 +459,38 @@ active:
|
|
|
318
459
|
after uses `-r/--resume <uuid>`. The host persists the channel→session map in
|
|
319
460
|
its state root, serializes cross-channel map rewrites, and retries once with a
|
|
320
461
|
fresh session immediately if Claude reports a stale `--resume` target.
|
|
462
|
+
- **Codex**: one persistent `@agentclientprotocol/codex-acp` subprocess is
|
|
463
|
+
shared by a single `AgentsHost`, with one ACP session per Borgee channel. When
|
|
464
|
+
the current turn has a materialized channel context payload, Codex refreshes a
|
|
465
|
+
same-directory `AGENTS.md` project document inside a provider-visible
|
|
466
|
+
per-channel projection directory and exposes that directory to Codex through
|
|
467
|
+
ACP `additionalDirectories`. Ordinary threads keep the shared runtime
|
|
468
|
+
workspace as the ACP session cwd, while eligible `task_assignment` threads
|
|
469
|
+
switch the real ACP session cwd to a hidden local task workspace under
|
|
470
|
+
`<startup-workspace>/.borgee-task-workspaces/<thread>/<task>/`; that local
|
|
471
|
+
writable workspace is explicitly not a claim that the target repository is
|
|
472
|
+
already checked out there. The host persists the channel→ACP-session map in
|
|
473
|
+
its state root and attempts ACP `session/resume` first when the adapter
|
|
474
|
+
advertises it, otherwise `session/load`.
|
|
321
475
|
- **Copilot**: one persistent `copilot --acp` subprocess is shared by a single
|
|
322
476
|
`AgentsHost`, with one ACP session per Borgee channel. Same-channel turns are
|
|
323
|
-
serialized; different channels keep isolated ACP sessions.
|
|
324
|
-
the
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
477
|
+
serialized; different channels keep isolated ACP sessions. Ordinary threads
|
|
478
|
+
keep the shared runtime workspace cwd, while eligible `task_assignment`
|
|
479
|
+
threads switch the real ACP session cwd to that same hidden local
|
|
480
|
+
task-scoped workspace. The host persists the channel→ACP-session map in its
|
|
481
|
+
state root and restores same-host continuity with ACP `session/resume` when
|
|
482
|
+
available, otherwise `session/load` plus local replay cleanup on runtimes
|
|
483
|
+
that advertise only load support.
|
|
484
|
+
- **Claude**: Claude still keeps one provider-native session mapping per Borgee
|
|
485
|
+
channel, but unlike the ACP-backed adapters it spawns a fresh CLI process for
|
|
486
|
+
each turn. Ordinary threads inherit the host runtime cwd; eligible
|
|
487
|
+
`task_assignment` threads run the CLI process with the hidden local
|
|
488
|
+
task-scoped workspace as the process cwd, again without implying that the
|
|
489
|
+
target repository is already checked out there.
|
|
490
|
+
|
|
491
|
+
There is no separate transcript/history store on our side. Claude, Codex, and
|
|
492
|
+
Copilot only persist the native session ids they should try to resume later;
|
|
493
|
+
cross-host continuity still does not exist in this runtime.
|
|
331
494
|
|
|
332
495
|
## Testing
|
|
333
496
|
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { AgentsHostRuntimeOptions, LoggerLike } from './debug.js';
|
|
1
2
|
import type { AgentsHostConfig, LocalConfigSnapshot } from './types.js';
|
|
2
3
|
export interface HostRunner {
|
|
3
4
|
start(): Promise<void>;
|
|
@@ -10,15 +11,12 @@ export interface WatchEventInfo {
|
|
|
10
11
|
eventType?: string;
|
|
11
12
|
filename?: string;
|
|
12
13
|
}
|
|
13
|
-
export interface LoggerLike {
|
|
14
|
-
log(...args: unknown[]): void;
|
|
15
|
-
error(...args: unknown[]): void;
|
|
16
|
-
}
|
|
17
14
|
export interface AgentsHostSupervisorDeps {
|
|
18
|
-
createHost?: (config: AgentsHostConfig) => HostRunner;
|
|
15
|
+
createHost?: (config: AgentsHostConfig, runtimeOptions?: AgentsHostRuntimeOptions) => HostRunner;
|
|
19
16
|
loadSnapshot?: (configPath: string) => Promise<LocalConfigSnapshot>;
|
|
20
17
|
watchPath?: (path: string, onEvent: (event?: WatchEventInfo) => void) => WatchHandle;
|
|
21
18
|
logger?: LoggerLike;
|
|
19
|
+
debug?: boolean;
|
|
22
20
|
}
|
|
23
21
|
export declare class AgentsHostSupervisor {
|
|
24
22
|
private readonly hostConfigPath;
|
|
@@ -26,18 +24,22 @@ export declare class AgentsHostSupervisor {
|
|
|
26
24
|
private readonly loadSnapshot;
|
|
27
25
|
private readonly watchPath;
|
|
28
26
|
private readonly logger;
|
|
27
|
+
private readonly debug;
|
|
29
28
|
private readonly activeHosts;
|
|
30
29
|
private readonly watchers;
|
|
31
30
|
private currentSnapshot;
|
|
32
31
|
private reloadTimer;
|
|
33
32
|
private reloadInFlight;
|
|
34
33
|
private pendingReload;
|
|
34
|
+
private pendingReloadFailOnStartError;
|
|
35
35
|
private runningReloadPromise;
|
|
36
36
|
private shuttingDown;
|
|
37
37
|
private started;
|
|
38
38
|
constructor(hostConfigPath: string, deps?: AgentsHostSupervisorDeps);
|
|
39
39
|
start(): Promise<void>;
|
|
40
40
|
stop(): Promise<void>;
|
|
41
|
+
reloadNow(failOnStartError?: boolean): Promise<void>;
|
|
42
|
+
hasActiveAgent(key: string): boolean;
|
|
41
43
|
private scheduleReload;
|
|
42
44
|
private clearReloadTimer;
|
|
43
45
|
private runReloadLoop;
|
|
@@ -12,18 +12,20 @@ export class AgentsHostSupervisor {
|
|
|
12
12
|
loadSnapshot;
|
|
13
13
|
watchPath;
|
|
14
14
|
logger;
|
|
15
|
+
debug;
|
|
15
16
|
activeHosts = new Map();
|
|
16
17
|
watchers = new Map();
|
|
17
18
|
currentSnapshot = null;
|
|
18
19
|
reloadTimer = null;
|
|
19
20
|
reloadInFlight = false;
|
|
20
21
|
pendingReload = false;
|
|
22
|
+
pendingReloadFailOnStartError = false;
|
|
21
23
|
runningReloadPromise = null;
|
|
22
24
|
shuttingDown = false;
|
|
23
25
|
started = false;
|
|
24
26
|
constructor(hostConfigPath, deps = {}) {
|
|
25
27
|
this.hostConfigPath = resolve(hostConfigPath);
|
|
26
|
-
this.createHost = deps.createHost ?? ((config) => new AgentsHost(config));
|
|
28
|
+
this.createHost = deps.createHost ?? ((config, runtimeOptions) => new AgentsHost(config, { runtimeOptions }));
|
|
27
29
|
this.loadSnapshot = deps.loadSnapshot ?? ((configPath) => loadLocalConfigSnapshot(configPath));
|
|
28
30
|
this.watchPath =
|
|
29
31
|
deps.watchPath ??
|
|
@@ -34,6 +36,7 @@ export class AgentsHostSupervisor {
|
|
|
34
36
|
});
|
|
35
37
|
}));
|
|
36
38
|
this.logger = deps.logger ?? console;
|
|
39
|
+
this.debug = deps.debug === true;
|
|
37
40
|
}
|
|
38
41
|
async start() {
|
|
39
42
|
if (this.started) {
|
|
@@ -81,6 +84,12 @@ export class AgentsHostSupervisor {
|
|
|
81
84
|
await this.stopActiveHost(key, activeHost);
|
|
82
85
|
}
|
|
83
86
|
}
|
|
87
|
+
async reloadNow(failOnStartError = false) {
|
|
88
|
+
await this.runReloadLoop(failOnStartError);
|
|
89
|
+
}
|
|
90
|
+
hasActiveAgent(key) {
|
|
91
|
+
return this.activeHosts.has(key);
|
|
92
|
+
}
|
|
84
93
|
scheduleReload() {
|
|
85
94
|
if (this.shuttingDown) {
|
|
86
95
|
return;
|
|
@@ -88,7 +97,7 @@ export class AgentsHostSupervisor {
|
|
|
88
97
|
this.clearReloadTimer();
|
|
89
98
|
this.reloadTimer = setTimeout(() => {
|
|
90
99
|
this.reloadTimer = null;
|
|
91
|
-
void this.runReloadLoop();
|
|
100
|
+
void this.runReloadLoop().catch(() => undefined);
|
|
92
101
|
}, RELOAD_DEBOUNCE_MS);
|
|
93
102
|
}
|
|
94
103
|
clearReloadTimer() {
|
|
@@ -100,18 +109,25 @@ export class AgentsHostSupervisor {
|
|
|
100
109
|
async runReloadLoop(failOnStartError = false) {
|
|
101
110
|
if (this.reloadInFlight) {
|
|
102
111
|
this.pendingReload = true;
|
|
112
|
+
this.pendingReloadFailOnStartError ||= failOnStartError;
|
|
113
|
+
await this.runningReloadPromise;
|
|
103
114
|
return;
|
|
104
115
|
}
|
|
105
116
|
this.reloadInFlight = true;
|
|
117
|
+
let nextFailOnStartError = failOnStartError;
|
|
106
118
|
this.runningReloadPromise = (async () => {
|
|
107
119
|
try {
|
|
108
120
|
do {
|
|
121
|
+
const currentFailOnStartError = nextFailOnStartError;
|
|
109
122
|
this.pendingReload = false;
|
|
110
|
-
|
|
123
|
+
this.pendingReloadFailOnStartError = false;
|
|
124
|
+
await this.reloadOnce(currentFailOnStartError);
|
|
125
|
+
nextFailOnStartError = this.pendingReloadFailOnStartError;
|
|
111
126
|
} while (this.pendingReload && !this.shuttingDown);
|
|
112
127
|
}
|
|
113
128
|
finally {
|
|
114
129
|
this.reloadInFlight = false;
|
|
130
|
+
this.pendingReloadFailOnStartError = false;
|
|
115
131
|
this.runningReloadPromise = null;
|
|
116
132
|
}
|
|
117
133
|
})();
|
|
@@ -256,7 +272,11 @@ export class AgentsHostSupervisor {
|
|
|
256
272
|
if (this.shuttingDown) {
|
|
257
273
|
return;
|
|
258
274
|
}
|
|
259
|
-
const runner = this.createHost(agent.config
|
|
275
|
+
const runner = this.createHost(agent.config, {
|
|
276
|
+
debug: this.debug,
|
|
277
|
+
logger: this.logger,
|
|
278
|
+
logPrefix: `[agents-host][agent:${agent.key}]`,
|
|
279
|
+
});
|
|
260
280
|
try {
|
|
261
281
|
await runner.start();
|
|
262
282
|
this.activeHosts.set(agent.key, {
|
package/dist/agents-host.d.ts
CHANGED
|
@@ -1,44 +1,143 @@
|
|
|
1
1
|
import type { ChatControlPlane } from './chat/chat-control-plane.js';
|
|
2
|
+
import { type AgentsHostRuntimeOptions } from './debug.js';
|
|
2
3
|
import type { ProviderAdapter } from './providers/provider-adapter.js';
|
|
3
4
|
import type { AgentsHostConfig } from './types.js';
|
|
4
5
|
/**
|
|
5
6
|
* Minimal single-agent agents host: connects one local Claude/Copilot CLI
|
|
6
7
|
* to exactly one Borgee agent over `@borgee/plugin-sdk` (BPP / `/ws/plugin`).
|
|
7
|
-
*
|
|
8
|
-
* Conversation memory is handled entirely by each provider's native
|
|
9
|
-
* per-channel CLI session (Claude `--resume`, Copilot `--session-id`) — see
|
|
10
|
-
* the cli-client.ts file under each provider's folder. This class does not
|
|
11
|
-
* keep any message history itself.
|
|
12
|
-
*
|
|
13
|
-
* Out of scope for this single-agent runner (see README): execution/remote-command
|
|
14
|
-
* dispatch, node provisioning, systemd install, and scheduled (periodic)
|
|
15
|
-
* prompts. Multi-agent local hosting is handled one level up by the local-config
|
|
16
|
-
* supervisor, which creates one isolated `AgentsHost` per effective agent key.
|
|
17
|
-
*
|
|
18
|
-
* Message gating (mention-only / DM rules) is NOT done here: the server
|
|
19
|
-
* enforces per-agent + per-channel `require_mention` at BPP fan-out, so this
|
|
20
|
-
* host simply replies to every message it is handed (minus its own).
|
|
21
8
|
*/
|
|
22
9
|
export declare class AgentsHost {
|
|
23
10
|
private readonly config;
|
|
11
|
+
private readonly runtime;
|
|
24
12
|
private readonly provider;
|
|
25
13
|
private readonly borgee;
|
|
14
|
+
private readonly logger;
|
|
15
|
+
private readonly contextInjectionEnabled;
|
|
16
|
+
private readonly collaborationEnabled;
|
|
17
|
+
private readonly collaborationOutcomeModelEnabled;
|
|
18
|
+
private readonly attentionFollowSemanticsEnabled;
|
|
19
|
+
private readonly taskThreadCollaborationContractEnabled;
|
|
20
|
+
private readonly collaborationCapabilitiesDiagnosticsEnabled;
|
|
26
21
|
private readonly activeTurns;
|
|
22
|
+
private readonly awaitingUserByChannel;
|
|
23
|
+
private readonly collaborationOutcomeByChannel;
|
|
24
|
+
private readonly attentionSnapshotByChannel;
|
|
25
|
+
private readonly missedCollaborationDiagnosticByChannel;
|
|
27
26
|
private readonly progressChannelQueues;
|
|
28
27
|
private readonly progressDrafts;
|
|
28
|
+
private readonly collaborationDrafts;
|
|
29
|
+
private readonly collaborationChannels;
|
|
30
|
+
private readonly participantDirectoryByUserId;
|
|
31
|
+
private readonly participantKindsByUserId;
|
|
32
|
+
private readonly participantRefreshBackoffByUserId;
|
|
33
|
+
private participantRefreshPromise;
|
|
34
|
+
private participantDirectorySupported;
|
|
29
35
|
private selfAgentId;
|
|
36
|
+
private selfAgentProfile;
|
|
30
37
|
private selfAgentIdPromise;
|
|
31
38
|
private started;
|
|
32
39
|
private controlPlaneClosed;
|
|
33
40
|
constructor(config: AgentsHostConfig, deps?: {
|
|
34
41
|
borgee?: ChatControlPlane;
|
|
35
42
|
provider?: ProviderAdapter;
|
|
43
|
+
runtimeOptions?: AgentsHostRuntimeOptions;
|
|
36
44
|
});
|
|
37
45
|
start(): Promise<void>;
|
|
38
46
|
stop(): Promise<void>;
|
|
39
|
-
private handleMessage;
|
|
40
47
|
private trackActiveTurn;
|
|
48
|
+
private dispatchMessage;
|
|
49
|
+
private handleLegacyMessage;
|
|
50
|
+
private handleCollaborationMessage;
|
|
51
|
+
private detectProtocolKickoffCandidate;
|
|
52
|
+
private validateProtocolKickoffCandidate;
|
|
53
|
+
private resolveProtocolKickoffRequest;
|
|
54
|
+
private validateProtocolKickoffRounds;
|
|
55
|
+
private protocolRequestFromKickoffDecision;
|
|
56
|
+
private evaluateIssuerProtocolKickoff;
|
|
57
|
+
private waitForProtocolKickoffDecision;
|
|
58
|
+
private ensureProtocolKickoffDecisionRecord;
|
|
59
|
+
private finalizeProtocolKickoffDecision;
|
|
60
|
+
private matchesProtocolKickoffDecisionRecord;
|
|
61
|
+
private resolveProtocolKickoffDecisionPath;
|
|
62
|
+
private resolveSharedProtocolStatusPath;
|
|
63
|
+
private readProtocolKickoffDecisionRecord;
|
|
64
|
+
private writeProtocolKickoffDecisionRecord;
|
|
65
|
+
private handleActiveProtocolAnchorReplay;
|
|
66
|
+
private startProtocolForAnchor;
|
|
67
|
+
private deliverDeferredTurnReply;
|
|
68
|
+
private handleActiveProtocolParticipantMessage;
|
|
69
|
+
private enqueueCollaborationMessage;
|
|
70
|
+
private ensureCollaborationChannelState;
|
|
71
|
+
private ensureCollaborationProcessor;
|
|
72
|
+
private processCollaborationQueue;
|
|
73
|
+
private tryResumeBlockedFromQueue;
|
|
74
|
+
private runCollaborationTurn;
|
|
75
|
+
private runProtocolManagedTurn;
|
|
76
|
+
private buildIncomingContent;
|
|
77
|
+
private otherProtocolParticipant;
|
|
78
|
+
private resolveProtocolStatePath;
|
|
79
|
+
private ensureProtocolStateLoaded;
|
|
80
|
+
private reconcileOwnProtocolStateFromPeers;
|
|
81
|
+
private loadPersistedProtocolStates;
|
|
82
|
+
private resumeOwnedProtocolTurns;
|
|
83
|
+
private buildResumedProtocolMessage;
|
|
84
|
+
private persistProtocolState;
|
|
85
|
+
private persistSharedProtocolStatus;
|
|
86
|
+
private readSharedProtocolStatus;
|
|
87
|
+
private clearProtocolFallback;
|
|
88
|
+
private armProtocolFallback;
|
|
89
|
+
private runProtocolFallback;
|
|
90
|
+
private handleProtocolFallbackFailure;
|
|
91
|
+
private finishProtocolState;
|
|
92
|
+
private cancelProtocolState;
|
|
93
|
+
private confirmProtocolMessage;
|
|
94
|
+
private resolveAttentionStatePath;
|
|
95
|
+
private buildDefaultAttentionSnapshot;
|
|
96
|
+
private buildTurnTaskThreadContext;
|
|
97
|
+
private ensureAttentionSnapshotLoaded;
|
|
98
|
+
private revalidateAttentionSnapshotForTurn;
|
|
99
|
+
private getAttentionSnapshotForTurn;
|
|
100
|
+
private isHumanWakeFiltered;
|
|
101
|
+
private applyAttentionUpdate;
|
|
102
|
+
private commitAttentionSnapshot;
|
|
103
|
+
private resolveTaskThreadCollaborationContractForTurn;
|
|
104
|
+
private resolveCollaborationCapabilityDeclarationForTurn;
|
|
105
|
+
private resolveMissedCollaborationDiagnosticForTurn;
|
|
106
|
+
private updateMissedCollaborationDiagnostic;
|
|
107
|
+
private noteWakeSuppressedAttentionPolicy;
|
|
108
|
+
private runUngatedTurn;
|
|
109
|
+
private executeTurn;
|
|
110
|
+
private canAcceptTurnOutput;
|
|
111
|
+
private canAcceptCompletedTurnOutput;
|
|
112
|
+
private canContinueSharedProtocol;
|
|
41
113
|
private enqueueProgressChannelTurn;
|
|
42
114
|
private ensureProgressDraft;
|
|
115
|
+
private publishCollaborationDraft;
|
|
116
|
+
private finalizeCollaborationDraft;
|
|
117
|
+
private clearCollaborationDraft;
|
|
118
|
+
private readCollaborationDraft;
|
|
119
|
+
private discardDraft;
|
|
120
|
+
private supersedeActiveTurn;
|
|
121
|
+
private invalidateChannelTurn;
|
|
122
|
+
private rememberRecentTurn;
|
|
123
|
+
private resolveAuthorizedCollaborationTurn;
|
|
124
|
+
private updateAwaitingUserState;
|
|
125
|
+
private recordBlockedSuppressionOutcome;
|
|
126
|
+
private recordCollaborationOutcome;
|
|
127
|
+
private syncMissedCollaborationDiagnosticFromOutcome;
|
|
128
|
+
private resolveVisibleTurnBody;
|
|
129
|
+
private shouldRelayProtocolReply;
|
|
130
|
+
private normalizeMessage;
|
|
131
|
+
private markAssignedTaskInProgress;
|
|
43
132
|
private ensureSelfAgentId;
|
|
133
|
+
private classifyAuthor;
|
|
134
|
+
private refreshParticipantDirectory;
|
|
135
|
+
private classifyBlockedWakeAuthor;
|
|
136
|
+
private classifyQueuedBlockedWakeCandidate;
|
|
137
|
+
private inferAuthorKind;
|
|
138
|
+
private buildCollaborationGrounding;
|
|
139
|
+
private hydratePromptIdentityCache;
|
|
140
|
+
private resolvePromptIdentity;
|
|
141
|
+
private isUnsupportedSemanticOperation;
|
|
142
|
+
private authorizeCollaborationSend;
|
|
44
143
|
}
|