@moxxy/core 0.3.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/LICENSE +21 -0
- package/README.md +125 -0
- package/dist/events/factory.d.ts +6 -0
- package/dist/events/factory.d.ts.map +1 -0
- package/dist/events/factory.js +14 -0
- package/dist/events/factory.js.map +1 -0
- package/dist/events/log.d.ts +92 -0
- package/dist/events/log.d.ts.map +1 -0
- package/dist/events/log.js +244 -0
- package/dist/events/log.js.map +1 -0
- package/dist/index.d.ts +40 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +41 -0
- package/dist/index.js.map +1 -0
- package/dist/logger.d.ts +16 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +27 -0
- package/dist/logger.js.map +1 -0
- package/dist/permissions/engine.d.ts +94 -0
- package/dist/permissions/engine.d.ts.map +1 -0
- package/dist/permissions/engine.js +203 -0
- package/dist/permissions/engine.js.map +1 -0
- package/dist/permissions/resolvers.d.ts +8 -0
- package/dist/permissions/resolvers.d.ts.map +1 -0
- package/dist/permissions/resolvers.js +8 -0
- package/dist/permissions/resolvers.js.map +1 -0
- package/dist/plugins/discovery.d.ts +9 -0
- package/dist/plugins/discovery.d.ts.map +1 -0
- package/dist/plugins/discovery.js +112 -0
- package/dist/plugins/discovery.js.map +1 -0
- package/dist/plugins/host-options.d.ts +72 -0
- package/dist/plugins/host-options.d.ts.map +1 -0
- package/dist/plugins/host-options.js +2 -0
- package/dist/plugins/host-options.js.map +1 -0
- package/dist/plugins/host.d.ts +53 -0
- package/dist/plugins/host.d.ts.map +1 -0
- package/dist/plugins/host.js +269 -0
- package/dist/plugins/host.js.map +1 -0
- package/dist/plugins/lifecycle.d.ts +31 -0
- package/dist/plugins/lifecycle.d.ts.map +1 -0
- package/dist/plugins/lifecycle.js +100 -0
- package/dist/plugins/lifecycle.js.map +1 -0
- package/dist/plugins/loader.d.ts +7 -0
- package/dist/plugins/loader.d.ts.map +1 -0
- package/dist/plugins/loader.js +68 -0
- package/dist/plugins/loader.js.map +1 -0
- package/dist/plugins/package-requirements.d.ts +16 -0
- package/dist/plugins/package-requirements.d.ts.map +1 -0
- package/dist/plugins/package-requirements.js +52 -0
- package/dist/plugins/package-requirements.js.map +1 -0
- package/dist/plugins/registry-kinds.d.ts +58 -0
- package/dist/plugins/registry-kinds.d.ts.map +1 -0
- package/dist/plugins/registry-kinds.js +139 -0
- package/dist/plugins/registry-kinds.js.map +1 -0
- package/dist/plugins/toposort.d.ts +24 -0
- package/dist/plugins/toposort.d.ts.map +1 -0
- package/dist/plugins/toposort.js +67 -0
- package/dist/plugins/toposort.js.map +1 -0
- package/dist/preferences.d.ts +40 -0
- package/dist/preferences.d.ts.map +1 -0
- package/dist/preferences.js +58 -0
- package/dist/preferences.js.map +1 -0
- package/dist/registries/active-backend-registry.d.ts +65 -0
- package/dist/registries/active-backend-registry.d.ts.map +1 -0
- package/dist/registries/active-backend-registry.js +108 -0
- package/dist/registries/active-backend-registry.js.map +1 -0
- package/dist/registries/active-def-registry.d.ts +59 -0
- package/dist/registries/active-def-registry.d.ts.map +1 -0
- package/dist/registries/active-def-registry.js +63 -0
- package/dist/registries/active-def-registry.js.map +1 -0
- package/dist/registries/agents.d.ts +16 -0
- package/dist/registries/agents.d.ts.map +1 -0
- package/dist/registries/agents.js +17 -0
- package/dist/registries/agents.js.map +1 -0
- package/dist/registries/cache-strategies.d.ts +12 -0
- package/dist/registries/cache-strategies.d.ts.map +1 -0
- package/dist/registries/cache-strategies.js +13 -0
- package/dist/registries/cache-strategies.js.map +1 -0
- package/dist/registries/channels.d.ts +16 -0
- package/dist/registries/channels.d.ts.map +1 -0
- package/dist/registries/channels.js +35 -0
- package/dist/registries/channels.js.map +1 -0
- package/dist/registries/commands.d.ts +29 -0
- package/dist/registries/commands.d.ts.map +1 -0
- package/dist/registries/commands.js +72 -0
- package/dist/registries/commands.js.map +1 -0
- package/dist/registries/compactors.d.ts +12 -0
- package/dist/registries/compactors.d.ts.map +1 -0
- package/dist/registries/compactors.js +13 -0
- package/dist/registries/compactors.js.map +1 -0
- package/dist/registries/def-map-registry.d.ts +33 -0
- package/dist/registries/def-map-registry.d.ts.map +1 -0
- package/dist/registries/def-map-registry.js +36 -0
- package/dist/registries/def-map-registry.js.map +1 -0
- package/dist/registries/embedders.d.ts +16 -0
- package/dist/registries/embedders.d.ts.map +1 -0
- package/dist/registries/embedders.js +17 -0
- package/dist/registries/embedders.js.map +1 -0
- package/dist/registries/isolators.d.ts +21 -0
- package/dist/registries/isolators.d.ts.map +1 -0
- package/dist/registries/isolators.js +32 -0
- package/dist/registries/isolators.js.map +1 -0
- package/dist/registries/modes.d.ts +28 -0
- package/dist/registries/modes.d.ts.map +1 -0
- package/dist/registries/modes.js +81 -0
- package/dist/registries/modes.js.map +1 -0
- package/dist/registries/providers.d.ts +44 -0
- package/dist/registries/providers.d.ts.map +1 -0
- package/dist/registries/providers.js +95 -0
- package/dist/registries/providers.js.map +1 -0
- package/dist/registries/skills.d.ts +24 -0
- package/dist/registries/skills.d.ts.map +1 -0
- package/dist/registries/skills.js +81 -0
- package/dist/registries/skills.js.map +1 -0
- package/dist/registries/surfaces.d.ts +13 -0
- package/dist/registries/surfaces.d.ts.map +1 -0
- package/dist/registries/surfaces.js +14 -0
- package/dist/registries/surfaces.js.map +1 -0
- package/dist/registries/synthesizers.d.ts +26 -0
- package/dist/registries/synthesizers.d.ts.map +1 -0
- package/dist/registries/synthesizers.js +34 -0
- package/dist/registries/synthesizers.js.map +1 -0
- package/dist/registries/tools.d.ts +49 -0
- package/dist/registries/tools.d.ts.map +1 -0
- package/dist/registries/tools.js +98 -0
- package/dist/registries/tools.js.map +1 -0
- package/dist/registries/transcribers.d.ts +17 -0
- package/dist/registries/transcribers.d.ts.map +1 -0
- package/dist/registries/transcribers.js +18 -0
- package/dist/registries/transcribers.js.map +1 -0
- package/dist/registries/tunnel-providers.d.ts +12 -0
- package/dist/registries/tunnel-providers.d.ts.map +1 -0
- package/dist/registries/tunnel-providers.js +13 -0
- package/dist/registries/tunnel-providers.js.map +1 -0
- package/dist/registries/view-renderers.d.ts +13 -0
- package/dist/registries/view-renderers.d.ts.map +1 -0
- package/dist/registries/view-renderers.js +14 -0
- package/dist/registries/view-renderers.js.map +1 -0
- package/dist/registries/workflow-executors.d.ts +13 -0
- package/dist/registries/workflow-executors.d.ts.map +1 -0
- package/dist/registries/workflow-executors.js +14 -0
- package/dist/registries/workflow-executors.js.map +1 -0
- package/dist/requirements.d.ts +59 -0
- package/dist/requirements.d.ts.map +1 -0
- package/dist/requirements.js +149 -0
- package/dist/requirements.js.map +1 -0
- package/dist/run-turn.d.ts +6 -0
- package/dist/run-turn.d.ts.map +1 -0
- package/dist/run-turn.js +141 -0
- package/dist/run-turn.js.map +1 -0
- package/dist/session-runtime.d.ts +67 -0
- package/dist/session-runtime.d.ts.map +1 -0
- package/dist/session-runtime.js +2 -0
- package/dist/session-runtime.js.map +1 -0
- package/dist/session.d.ts +203 -0
- package/dist/session.d.ts.map +1 -0
- package/dist/session.js +399 -0
- package/dist/session.js.map +1 -0
- package/dist/sessions/persistence.d.ts +184 -0
- package/dist/sessions/persistence.d.ts.map +1 -0
- package/dist/sessions/persistence.js +442 -0
- package/dist/sessions/persistence.js.map +1 -0
- package/dist/setup-agent.d.ts +91 -0
- package/dist/setup-agent.d.ts.map +1 -0
- package/dist/setup-agent.js +138 -0
- package/dist/setup-agent.js.map +1 -0
- package/dist/skills/index.d.ts +4 -0
- package/dist/skills/index.d.ts.map +1 -0
- package/dist/skills/index.js +4 -0
- package/dist/skills/index.js.map +1 -0
- package/dist/skills/loader.d.ts +16 -0
- package/dist/skills/loader.d.ts.map +1 -0
- package/dist/skills/loader.js +99 -0
- package/dist/skills/loader.js.map +1 -0
- package/dist/skills/parse.d.ts +5 -0
- package/dist/skills/parse.d.ts.map +1 -0
- package/dist/skills/parse.js +8 -0
- package/dist/skills/parse.js.map +1 -0
- package/dist/skills/synthesize-draft.d.ts +8 -0
- package/dist/skills/synthesize-draft.d.ts.map +1 -0
- package/dist/skills/synthesize-draft.js +32 -0
- package/dist/skills/synthesize-draft.js.map +1 -0
- package/dist/skills/synthesize.d.ts +33 -0
- package/dist/skills/synthesize.d.ts.map +1 -0
- package/dist/skills/synthesize.js +241 -0
- package/dist/skills/synthesize.js.map +1 -0
- package/dist/subagents/events.d.ts +20 -0
- package/dist/subagents/events.d.ts.map +1 -0
- package/dist/subagents/events.js +146 -0
- package/dist/subagents/events.js.map +1 -0
- package/dist/subagents/registry.d.ts +40 -0
- package/dist/subagents/registry.d.ts.map +1 -0
- package/dist/subagents/registry.js +42 -0
- package/dist/subagents/registry.js.map +1 -0
- package/dist/subagents/run-child.d.ts +43 -0
- package/dist/subagents/run-child.d.ts.map +1 -0
- package/dist/subagents/run-child.js +276 -0
- package/dist/subagents/run-child.js.map +1 -0
- package/dist/subagents/spawn.d.ts +8 -0
- package/dist/subagents/spawn.d.ts.map +1 -0
- package/dist/subagents/spawn.js +8 -0
- package/dist/subagents/spawn.js.map +1 -0
- package/dist/subagents/tools.d.ts +4 -0
- package/dist/subagents/tools.d.ts.map +1 -0
- package/dist/subagents/tools.js +13 -0
- package/dist/subagents/tools.js.map +1 -0
- package/dist/subagents.d.ts +3 -0
- package/dist/subagents.d.ts.map +1 -0
- package/dist/subagents.js +3 -0
- package/dist/subagents.js.map +1 -0
- package/dist/surfaces/host.d.ts +53 -0
- package/dist/surfaces/host.d.ts.map +1 -0
- package/dist/surfaces/host.js +177 -0
- package/dist/surfaces/host.js.map +1 -0
- package/dist/tunnel/localhost.d.ts +7 -0
- package/dist/tunnel/localhost.d.ts.map +1 -0
- package/dist/tunnel/localhost.js +21 -0
- package/dist/tunnel/localhost.js.map +1 -0
- package/dist/usage-stats.d.ts +42 -0
- package/dist/usage-stats.d.ts.map +1 -0
- package/dist/usage-stats.js +83 -0
- package/dist/usage-stats.js.map +1 -0
- package/dist/view/default-renderer.d.ts +7 -0
- package/dist/view/default-renderer.d.ts.map +1 -0
- package/dist/view/default-renderer.js +14 -0
- package/dist/view/default-renderer.js.map +1 -0
- package/dist/view/parse.d.ts +7 -0
- package/dist/view/parse.d.ts.map +1 -0
- package/dist/view/parse.js +479 -0
- package/dist/view/parse.js.map +1 -0
- package/package.json +61 -0
- package/src/events/factory.ts +27 -0
- package/src/events/log.test.ts +470 -0
- package/src/events/log.ts +256 -0
- package/src/index.ts +102 -0
- package/src/logger.ts +46 -0
- package/src/permissions/engine.test.ts +206 -0
- package/src/permissions/engine.ts +247 -0
- package/src/permissions/resolvers.test.ts +40 -0
- package/src/permissions/resolvers.ts +17 -0
- package/src/plugins/discovery.test.ts +115 -0
- package/src/plugins/discovery.ts +124 -0
- package/src/plugins/host-options.ts +73 -0
- package/src/plugins/host-view-tunnel.test.ts +86 -0
- package/src/plugins/host.test.ts +434 -0
- package/src/plugins/host.ts +327 -0
- package/src/plugins/lifecycle.test.ts +187 -0
- package/src/plugins/lifecycle.ts +136 -0
- package/src/plugins/loader.ts +79 -0
- package/src/plugins/package-requirements.ts +50 -0
- package/src/plugins/registry-kinds.test.ts +162 -0
- package/src/plugins/registry-kinds.ts +210 -0
- package/src/plugins/toposort.test.ts +66 -0
- package/src/plugins/toposort.ts +69 -0
- package/src/preferences.test.ts +105 -0
- package/src/preferences.ts +84 -0
- package/src/registries/active-backend-registry.ts +142 -0
- package/src/registries/active-def-registry.test.ts +103 -0
- package/src/registries/active-def-registry.ts +97 -0
- package/src/registries/agents.ts +18 -0
- package/src/registries/cache-strategies.ts +14 -0
- package/src/registries/channels.ts +42 -0
- package/src/registries/commands.test.ts +71 -0
- package/src/registries/commands.ts +78 -0
- package/src/registries/compactors.ts +14 -0
- package/src/registries/def-map-registry.test.ts +67 -0
- package/src/registries/def-map-registry.ts +59 -0
- package/src/registries/embedders.test.ts +54 -0
- package/src/registries/embedders.ts +18 -0
- package/src/registries/isolators.test.ts +43 -0
- package/src/registries/isolators.ts +38 -0
- package/src/registries/modes.test.ts +66 -0
- package/src/registries/modes.ts +80 -0
- package/src/registries/providers.test.ts +50 -0
- package/src/registries/providers.ts +97 -0
- package/src/registries/semantics.test.ts +117 -0
- package/src/registries/skills.ts +87 -0
- package/src/registries/surfaces.ts +18 -0
- package/src/registries/synthesizers.test.ts +63 -0
- package/src/registries/synthesizers.ts +36 -0
- package/src/registries/tools.test.ts +142 -0
- package/src/registries/tools.ts +145 -0
- package/src/registries/transcribers.test.ts +70 -0
- package/src/registries/transcribers.ts +19 -0
- package/src/registries/tunnel-providers.test.ts +30 -0
- package/src/registries/tunnel-providers.ts +14 -0
- package/src/registries/view-renderers.test.ts +68 -0
- package/src/registries/view-renderers.ts +15 -0
- package/src/registries/workflow-executors.test.ts +53 -0
- package/src/registries/workflow-executors.ts +15 -0
- package/src/requirements.targetinfo.test.ts +70 -0
- package/src/requirements.test.ts +111 -0
- package/src/requirements.ts +262 -0
- package/src/run-turn.test.ts +178 -0
- package/src/run-turn.ts +156 -0
- package/src/session-runtime.ts +75 -0
- package/src/session.test.ts +216 -0
- package/src/session.ts +491 -0
- package/src/sessions/persistence.flush.test.ts +100 -0
- package/src/sessions/persistence.ready.test.ts +91 -0
- package/src/sessions/persistence.test.ts +274 -0
- package/src/sessions/persistence.ts +498 -0
- package/src/setup-agent.test.ts +72 -0
- package/src/setup-agent.ts +189 -0
- package/src/skills/index.ts +14 -0
- package/src/skills/loader.test.ts +102 -0
- package/src/skills/loader.ts +114 -0
- package/src/skills/parse.test.ts +59 -0
- package/src/skills/parse.ts +11 -0
- package/src/skills/synthesize-draft.test.ts +79 -0
- package/src/skills/synthesize-draft.ts +46 -0
- package/src/skills/synthesize.test.ts +170 -0
- package/src/skills/synthesize.ts +304 -0
- package/src/subagents/events.test.ts +56 -0
- package/src/subagents/events.ts +194 -0
- package/src/subagents/registry.ts +62 -0
- package/src/subagents/run-child.test.ts +185 -0
- package/src/subagents/run-child.ts +425 -0
- package/src/subagents/spawn.ts +12 -0
- package/src/subagents/tools.ts +19 -0
- package/src/subagents.ts +2 -0
- package/src/surfaces/host.test.ts +330 -0
- package/src/surfaces/host.ts +192 -0
- package/src/tunnel/localhost.test.ts +22 -0
- package/src/tunnel/localhost.ts +21 -0
- package/src/usage-stats.test.ts +77 -0
- package/src/usage-stats.ts +119 -0
- package/src/view/default-renderer.test.ts +29 -0
- package/src/view/default-renderer.ts +14 -0
- package/src/view/parse-extended.test.ts +255 -0
- package/src/view/parse.test.ts +232 -0
- package/src/view/parse.ts +520 -0
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Subagent runtime — turns the SDK's `SubagentSpawner` interface into a
|
|
3
|
+
* working factory that spawns child modes sharing the parent Session's
|
|
4
|
+
* registries.
|
|
5
|
+
*
|
|
6
|
+
* Each child gets:
|
|
7
|
+
* - Its own `EventLog` (isolated history, no cross-talk).
|
|
8
|
+
* - Its own `sessionId` + `turnId` (so hooks / tool ctxs see distinct ids).
|
|
9
|
+
* - The parent's providers, tools (optionally filtered), skills, permissions,
|
|
10
|
+
* plugin host, and abort signal.
|
|
11
|
+
*
|
|
12
|
+
* As the child runs, this module streams its events into the parent's log
|
|
13
|
+
* as `plugin_event` records with `subagent_*` subtypes — so the TUI, JSON
|
|
14
|
+
* exporters, and other subscribers see live progress without waiting for
|
|
15
|
+
* the child's final message. The captured final assistant message is
|
|
16
|
+
* returned to the spawner caller via the `SubagentResult`.
|
|
17
|
+
*
|
|
18
|
+
* A child spawned with `retainSession: true` keeps its log + context alive in
|
|
19
|
+
* the {@link RetainedChildSession} registry so `continue()` can append an
|
|
20
|
+
* operator reply and run it again — the workflow `awaitInput` pause/resume
|
|
21
|
+
* flow. `subagent_completed` is deferred until that follow-up turn (or a
|
|
22
|
+
* `release()`).
|
|
23
|
+
*/
|
|
24
|
+
import { EventLog } from '../events/log.js';
|
|
25
|
+
import { newSessionId, newTurnId } from '../events/factory.js';
|
|
26
|
+
import { emitSubagentCompleted, emitSubagentStart, emitSubagentWarning, streamChildEventToParent, } from './events.js';
|
|
27
|
+
import { buildFilteredToolRegistry } from './tools.js';
|
|
28
|
+
import { getRetainedChild, registerRetainedChild, releaseRetainedChild, } from './registry.js';
|
|
29
|
+
export async function runChildTurn(args) {
|
|
30
|
+
const { rt, spec, retainSession } = args;
|
|
31
|
+
const { parentSession, parentTurnId } = rt;
|
|
32
|
+
const childSessionId = newSessionId();
|
|
33
|
+
const childTurnId = newTurnId();
|
|
34
|
+
const label = spec.label ?? `subagent-${String(childSessionId).slice(-6)}`;
|
|
35
|
+
const requestedStrategy = spec.mode ?? 'default';
|
|
36
|
+
const resolved = await resolveStrategy(parentSession, parentTurnId, label, childSessionId, spec, requestedStrategy);
|
|
37
|
+
if ('failure' in resolved)
|
|
38
|
+
return resolved.failure;
|
|
39
|
+
const { strategy, strategyName } = resolved;
|
|
40
|
+
const toolRegistry = spec.allowedTools && spec.allowedTools.length > 0
|
|
41
|
+
? buildFilteredToolRegistry(parentSession.tools, new Set(spec.allowedTools))
|
|
42
|
+
: parentSession.tools;
|
|
43
|
+
const childModel = await resolveChildModel(rt, spec, label, childSessionId);
|
|
44
|
+
const childLog = new EventLog();
|
|
45
|
+
// The nested spawner's parentModel must be the CHILD's effective model —
|
|
46
|
+
// building it from the original rt would make grandchildren silently
|
|
47
|
+
// revert to the grandparent's model.
|
|
48
|
+
const spawner = createSubagentSpawner({ ...rt, parentModel: childModel });
|
|
49
|
+
const childCtx = buildChildContext(rt, spec, childModel, childSessionId, childTurnId, toolRegistry, childLog, spawner);
|
|
50
|
+
const capture = await executeChildLoop({
|
|
51
|
+
rt,
|
|
52
|
+
spec,
|
|
53
|
+
label,
|
|
54
|
+
childSessionId,
|
|
55
|
+
childTurnId,
|
|
56
|
+
childLog,
|
|
57
|
+
childCtx,
|
|
58
|
+
strategy,
|
|
59
|
+
strategyName,
|
|
60
|
+
emitCompleted: !retainSession,
|
|
61
|
+
});
|
|
62
|
+
if (retainSession) {
|
|
63
|
+
registerRetainedChild({
|
|
64
|
+
label,
|
|
65
|
+
childSessionId,
|
|
66
|
+
childTurnId,
|
|
67
|
+
childLog,
|
|
68
|
+
childCtx,
|
|
69
|
+
spec,
|
|
70
|
+
strategy,
|
|
71
|
+
strategyName,
|
|
72
|
+
parentSession,
|
|
73
|
+
parentTurnId,
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
return capture.result;
|
|
77
|
+
}
|
|
78
|
+
export async function continueChildTurn(args) {
|
|
79
|
+
const retained = getRetainedChild(args.childSessionId);
|
|
80
|
+
if (!retained) {
|
|
81
|
+
throw new Error(`no retained subagent session for "${String(args.childSessionId)}"`);
|
|
82
|
+
}
|
|
83
|
+
await retained.childLog.append({
|
|
84
|
+
type: 'user_prompt',
|
|
85
|
+
sessionId: retained.childSessionId,
|
|
86
|
+
turnId: retained.childTurnId,
|
|
87
|
+
source: 'user',
|
|
88
|
+
text: args.prompt,
|
|
89
|
+
});
|
|
90
|
+
const rt = {
|
|
91
|
+
parentSession: retained.parentSession,
|
|
92
|
+
parentTurnId: retained.parentTurnId,
|
|
93
|
+
parentSignal: retained.childCtx.signal,
|
|
94
|
+
parentModel: retained.childCtx.model,
|
|
95
|
+
};
|
|
96
|
+
const capture = await executeChildLoop({
|
|
97
|
+
rt,
|
|
98
|
+
spec: retained.spec,
|
|
99
|
+
label: args.label ?? retained.label,
|
|
100
|
+
childSessionId: retained.childSessionId,
|
|
101
|
+
childTurnId: retained.childTurnId,
|
|
102
|
+
childLog: retained.childLog,
|
|
103
|
+
childCtx: retained.childCtx,
|
|
104
|
+
strategy: retained.strategy,
|
|
105
|
+
strategyName: retained.strategyName,
|
|
106
|
+
emitCompleted: true,
|
|
107
|
+
skipStartEvent: true,
|
|
108
|
+
});
|
|
109
|
+
releaseRetainedChild(args.childSessionId);
|
|
110
|
+
return capture.result;
|
|
111
|
+
}
|
|
112
|
+
async function executeChildLoop(args) {
|
|
113
|
+
const { rt, spec, label, childSessionId, childTurnId, childLog, childCtx, strategy, strategyName, emitCompleted, skipStartEvent, } = args;
|
|
114
|
+
const { parentSession, parentTurnId } = rt;
|
|
115
|
+
const capture = {
|
|
116
|
+
text: '',
|
|
117
|
+
stopReason: 'end_turn',
|
|
118
|
+
error: null,
|
|
119
|
+
tokensUsed: 0,
|
|
120
|
+
};
|
|
121
|
+
const unsubCapture = childLog.subscribe((e) => {
|
|
122
|
+
if (e.type === 'assistant_message') {
|
|
123
|
+
if (e.content)
|
|
124
|
+
capture.text = e.content;
|
|
125
|
+
if (e.stopReason)
|
|
126
|
+
capture.stopReason = e.stopReason;
|
|
127
|
+
}
|
|
128
|
+
else if (e.type === 'provider_response') {
|
|
129
|
+
// Sum every provider call's tokens so the parent can show how much this
|
|
130
|
+
// child consumed (input + output, matching a context-meter reading).
|
|
131
|
+
capture.tokensUsed += (e.inputTokens ?? 0) + (e.outputTokens ?? 0);
|
|
132
|
+
}
|
|
133
|
+
else if (e.type === 'error' && e.kind === 'fatal') {
|
|
134
|
+
capture.error = e.message;
|
|
135
|
+
}
|
|
136
|
+
});
|
|
137
|
+
const unsubStream = childLog.subscribe((childEvt) => streamChildEventToParent(parentSession, parentTurnId, label, childSessionId, childEvt));
|
|
138
|
+
if (!skipStartEvent) {
|
|
139
|
+
await emitSubagentStart(parentSession, parentTurnId, label, childSessionId, spec, strategyName);
|
|
140
|
+
// Seed the child's log with its user_prompt so projection works for
|
|
141
|
+
// tool-use-style strategies (which read user_prompt events from the log).
|
|
142
|
+
await childLog.append({
|
|
143
|
+
type: 'user_prompt',
|
|
144
|
+
sessionId: childSessionId,
|
|
145
|
+
turnId: childTurnId,
|
|
146
|
+
source: 'user',
|
|
147
|
+
text: spec.prompt,
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
try {
|
|
151
|
+
for await (const _ of strategy.run(childCtx)) {
|
|
152
|
+
void _;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
catch (err) {
|
|
156
|
+
capture.error = err instanceof Error ? err.message : String(err);
|
|
157
|
+
}
|
|
158
|
+
finally {
|
|
159
|
+
unsubStream();
|
|
160
|
+
unsubCapture();
|
|
161
|
+
}
|
|
162
|
+
const result = {
|
|
163
|
+
label,
|
|
164
|
+
childSessionId,
|
|
165
|
+
text: capture.text,
|
|
166
|
+
stopReason: capture.error ? 'error' : capture.stopReason,
|
|
167
|
+
...(capture.error ? { error: { message: capture.error } } : {}),
|
|
168
|
+
};
|
|
169
|
+
if (emitCompleted) {
|
|
170
|
+
await emitSubagentCompleted(parentSession, parentTurnId, label, childSessionId, capture.text, result.stopReason, capture.error, spec.agentType ?? 'default', capture.tokensUsed);
|
|
171
|
+
}
|
|
172
|
+
return { result };
|
|
173
|
+
}
|
|
174
|
+
async function resolveStrategy(parentSession, parentTurnId, label, childSessionId, spec, requestedStrategy) {
|
|
175
|
+
// Look up the requested strategy in the parent's loop registry. The
|
|
176
|
+
// registry only exposes list() / getActive(), so we scan.
|
|
177
|
+
const exact = parentSession.modes.list().find((s) => s.name === requestedStrategy);
|
|
178
|
+
if (exact)
|
|
179
|
+
return { strategy: exact, strategyName: requestedStrategy };
|
|
180
|
+
// Fall back to the default mode if the model invented a name
|
|
181
|
+
// (e.g. "react"). Failing the child outright wastes the user's turn —
|
|
182
|
+
// any reasonable agent task can run on the default mode. We surface the
|
|
183
|
+
// fallback as a non-fatal warning event so the operator sees it.
|
|
184
|
+
const fallback = parentSession.modes.list().find((s) => s.name === 'default');
|
|
185
|
+
if (fallback) {
|
|
186
|
+
await emitSubagentWarning(parentSession, parentTurnId, label, childSessionId, `unknown mode "${requestedStrategy}" — falling back to "default"`);
|
|
187
|
+
return { strategy: fallback, strategyName: 'default' };
|
|
188
|
+
}
|
|
189
|
+
// No default mode either — that's a config error, not a model mistake.
|
|
190
|
+
await emitSubagentStart(parentSession, parentTurnId, label, childSessionId, spec, requestedStrategy);
|
|
191
|
+
const errorMsg = `Subagent failed: unknown mode "${requestedStrategy}" and no fallback available`;
|
|
192
|
+
await emitSubagentCompleted(parentSession, parentTurnId, label, childSessionId, '', 'error', errorMsg, spec.agentType ?? 'default', 0);
|
|
193
|
+
return {
|
|
194
|
+
failure: {
|
|
195
|
+
label,
|
|
196
|
+
childSessionId,
|
|
197
|
+
text: '',
|
|
198
|
+
stopReason: 'error',
|
|
199
|
+
error: { message: errorMsg },
|
|
200
|
+
},
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Resolve the child's effective model. A `spec.model` usually comes from the
|
|
205
|
+
* calling LLM (dispatch_agent's free-form string field), which sometimes
|
|
206
|
+
* hallucinates training-era ids ("claude-3-5-sonnet", "gpt-4o") — running the
|
|
207
|
+
* child on those would 404 or silently land on a different vendor model. When
|
|
208
|
+
* the active provider publishes a models list and the requested id isn't in
|
|
209
|
+
* it, fall back to the parent's model with a warning (mirroring the
|
|
210
|
+
* unknown-mode fallback above) instead of hard-erroring. Providers with an
|
|
211
|
+
* EMPTY models list (sparse admin-registered vendors — see the
|
|
212
|
+
* resolveModelContext caveat in @moxxy/sdk) skip validation entirely: we
|
|
213
|
+
* can't tell a typo from a legitimate unlisted id there.
|
|
214
|
+
*/
|
|
215
|
+
async function resolveChildModel(rt, spec, label, childSessionId) {
|
|
216
|
+
const { parentSession, parentTurnId, parentModel } = rt;
|
|
217
|
+
const requested = spec.model;
|
|
218
|
+
if (requested === undefined || requested === parentModel)
|
|
219
|
+
return parentModel;
|
|
220
|
+
const models = parentSession.providers.getActive().models;
|
|
221
|
+
if (models.length > 0 && !models.some((m) => m.id === requested)) {
|
|
222
|
+
await emitSubagentWarning(parentSession, parentTurnId, label, childSessionId, `unknown model "${requested}" — falling back to parent model "${parentModel}"`);
|
|
223
|
+
return parentModel;
|
|
224
|
+
}
|
|
225
|
+
return requested;
|
|
226
|
+
}
|
|
227
|
+
function buildChildContext(rt, spec, model, childSessionId, childTurnId, toolRegistry, childLog, spawner) {
|
|
228
|
+
const { parentSession, parentSignal } = rt;
|
|
229
|
+
// Children share the parent's working dir + environment — mirror them onto
|
|
230
|
+
// the child ModeContext so its tool dispatcher hands onToolCall hooks the
|
|
231
|
+
// real cwd/env (matching the parent turn) rather than empty placeholders.
|
|
232
|
+
const parentAppCtx = parentSession.appContext();
|
|
233
|
+
return {
|
|
234
|
+
sessionId: childSessionId,
|
|
235
|
+
turnId: childTurnId,
|
|
236
|
+
cwd: parentAppCtx.cwd,
|
|
237
|
+
env: parentAppCtx.env,
|
|
238
|
+
model,
|
|
239
|
+
...(spec.systemPrompt !== undefined ? { systemPrompt: spec.systemPrompt } : {}),
|
|
240
|
+
provider: parentSession.providers.getActive(),
|
|
241
|
+
tools: toolRegistry,
|
|
242
|
+
skills: parentSession.skills,
|
|
243
|
+
log: childLog,
|
|
244
|
+
compactor: parentSession.compactors.getActive(),
|
|
245
|
+
cacheStrategy: parentSession.cacheStrategies.getActive(),
|
|
246
|
+
...(parentSession.elisionSettings ? { elision: parentSession.elisionSettings } : {}),
|
|
247
|
+
...(parentSession.lazyTools ? { lazyTools: true } : {}),
|
|
248
|
+
permissions: parentSession.resolver,
|
|
249
|
+
// Intentionally no `approval` — fanning approval gates out to N
|
|
250
|
+
// children in parallel would prompt the user N times. Strategies
|
|
251
|
+
// that absolutely need approval can be invoked at the parent level.
|
|
252
|
+
hooks: parentSession.dispatcher,
|
|
253
|
+
pluginHost: parentSession.pluginHost,
|
|
254
|
+
signal: parentSignal, // child cancels when parent cancels
|
|
255
|
+
maxIterations: spec.maxIterations ?? 50,
|
|
256
|
+
subagents: spawner,
|
|
257
|
+
emit: (event) => childLog.append(event),
|
|
258
|
+
};
|
|
259
|
+
}
|
|
260
|
+
export function createSubagentSpawner(rt) {
|
|
261
|
+
return {
|
|
262
|
+
async spawn(spec) {
|
|
263
|
+
return runChildTurn({ rt, spec, retainSession: spec.retainSession === true });
|
|
264
|
+
},
|
|
265
|
+
async spawnAll(specs) {
|
|
266
|
+
return Promise.all(specs.map((s) => runChildTurn({ rt, spec: s, retainSession: s.retainSession === true })));
|
|
267
|
+
},
|
|
268
|
+
async continue(args) {
|
|
269
|
+
return continueChildTurn(args);
|
|
270
|
+
},
|
|
271
|
+
release(childSessionId) {
|
|
272
|
+
releaseRetainedChild(childSessionId);
|
|
273
|
+
},
|
|
274
|
+
};
|
|
275
|
+
}
|
|
276
|
+
//# sourceMappingURL=run-child.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run-child.js","sourceRoot":"","sources":["../../src/subagents/run-child.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Back-compat entry point for the subagent runtime. The implementation lives
|
|
3
|
+
* in `run-child.ts` (which adds retained-session `continue()`/`release()` for
|
|
4
|
+
* the workflow `awaitInput` pause/resume flow); this module just re-exports it
|
|
5
|
+
* so existing `subagents/spawn.js` importers keep working.
|
|
6
|
+
*/
|
|
7
|
+
export { createSubagentSpawner, runChildTurn, continueChildTurn, type SubagentRuntime, } from './run-child.js';
|
|
8
|
+
//# sourceMappingURL=spawn.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spawn.d.ts","sourceRoot":"","sources":["../../src/subagents/spawn.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EACL,qBAAqB,EACrB,YAAY,EACZ,iBAAiB,EACjB,KAAK,eAAe,GACrB,MAAM,gBAAgB,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Back-compat entry point for the subagent runtime. The implementation lives
|
|
3
|
+
* in `run-child.ts` (which adds retained-session `continue()`/`release()` for
|
|
4
|
+
* the workflow `awaitInput` pause/resume flow); this module just re-exports it
|
|
5
|
+
* so existing `subagents/spawn.js` importers keep working.
|
|
6
|
+
*/
|
|
7
|
+
export { createSubagentSpawner, runChildTurn, continueChildTurn, } from './run-child.js';
|
|
8
|
+
//# sourceMappingURL=spawn.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spawn.js","sourceRoot":"","sources":["../../src/subagents/spawn.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EACL,qBAAqB,EACrB,YAAY,EACZ,iBAAiB,GAElB,MAAM,gBAAgB,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { ToolRegistry } from '@moxxy/sdk';
|
|
2
|
+
import type { ToolRegistry as CoreToolRegistry } from '../registries/tools.js';
|
|
3
|
+
export declare function buildFilteredToolRegistry(parent: CoreToolRegistry, allowed: Set<string>): ToolRegistry;
|
|
4
|
+
//# sourceMappingURL=tools.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../src/subagents/tools.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAW,YAAY,EAAE,MAAM,YAAY,CAAC;AACxD,OAAO,KAAK,EAAE,YAAY,IAAI,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAE/E,wBAAgB,yBAAyB,CACvC,MAAM,EAAE,gBAAgB,EACxB,OAAO,EAAE,GAAG,CAAC,MAAM,CAAC,GACnB,YAAY,CAYd"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export function buildFilteredToolRegistry(parent, allowed) {
|
|
2
|
+
return {
|
|
3
|
+
list: () => parent.list().filter((t) => allowed.has(t.name)),
|
|
4
|
+
get: (name) => allowed.has(name) ? parent.get(name) : undefined,
|
|
5
|
+
execute: (name, input, signal, opts) => {
|
|
6
|
+
if (!allowed.has(name)) {
|
|
7
|
+
return Promise.reject(new Error(`Tool ${name} not allowed in this subagent`));
|
|
8
|
+
}
|
|
9
|
+
return parent.execute(name, input, signal, opts);
|
|
10
|
+
},
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=tools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tools.js","sourceRoot":"","sources":["../../src/subagents/tools.ts"],"names":[],"mappings":"AAGA,MAAM,UAAU,yBAAyB,CACvC,MAAwB,EACxB,OAAoB;IAEpB,OAAO;QACL,IAAI,EAAE,GAA2B,EAAE,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QACpF,GAAG,EAAE,CAAC,IAAY,EAAuB,EAAE,CACzC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS;QAClD,OAAO,EAAE,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE;YACrC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;gBACvB,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,QAAQ,IAAI,+BAA+B,CAAC,CAAC,CAAC;YAChF,CAAC;YACD,OAAO,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC;QACnD,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"subagents.d.ts","sourceRoot":"","sources":["../src/subagents.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,KAAK,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACnF,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"subagents.js","sourceRoot":"","sources":["../src/subagents.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAwB,MAAM,sBAAsB,CAAC;AACnF,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import type { OpenSurfaceResult, SurfaceContext, SurfaceDataMessage, SurfaceHost, SurfaceInfo, SurfaceInputMessage, SurfaceKind, SurfaceSize } from '@moxxy/sdk';
|
|
2
|
+
import type { Logger } from '../logger.js';
|
|
3
|
+
import type { SurfaceRegistryImpl } from '../registries/surfaces.js';
|
|
4
|
+
/**
|
|
5
|
+
* Manages the live, open {@link SurfaceInstance}s for a Session and multiplexes
|
|
6
|
+
* every instance's output through a single {@link onData} fan-out. The runner
|
|
7
|
+
* subscribes once and rebroadcasts each frame as a `surface.data` notification;
|
|
8
|
+
* the agent's tools reach the SAME underlying resource (PTY, page) through their
|
|
9
|
+
* plugin's module state, so a `terminal`/`browser_session` tool call appears in
|
|
10
|
+
* the very pane the user is watching.
|
|
11
|
+
*
|
|
12
|
+
* Opening a kind is idempotent: a second `open` returns the instance the first
|
|
13
|
+
* created (surfaces are shared), so a late-joining viewer attaches to the
|
|
14
|
+
* existing resource and gets its {@link SurfaceInstance.snapshot}.
|
|
15
|
+
*/
|
|
16
|
+
export declare class SurfaceHostImpl implements SurfaceHost {
|
|
17
|
+
private readonly registry;
|
|
18
|
+
private readonly ctx;
|
|
19
|
+
private readonly logger?;
|
|
20
|
+
/** Open instances, keyed by kind (one shared instance per kind). */
|
|
21
|
+
private readonly instances;
|
|
22
|
+
/** Per-instance unsubscribe from its onData, dropped on close. */
|
|
23
|
+
private readonly unsubs;
|
|
24
|
+
private readonly dataListeners;
|
|
25
|
+
/** In-flight opens, so concurrent `open(kind)` calls share one instance. */
|
|
26
|
+
private readonly opening;
|
|
27
|
+
/**
|
|
28
|
+
* Viewer attach count per kind. A surface is SHARED (the agent's tool + every
|
|
29
|
+
* attached viewer drive the same PTY/page), so `open` retains and `close`
|
|
30
|
+
* releases; the instance is only torn down when the last viewer detaches.
|
|
31
|
+
* Without this, a single viewer's `close` would destroy the resource out from
|
|
32
|
+
* under the others — and React StrictMode (dev) makes that routine: it
|
|
33
|
+
* mounts → unmounts → remounts, so the first mount's late-resolving `open`
|
|
34
|
+
* closes the very instance the remount just attached to, leaving `input`/
|
|
35
|
+
* `resize` to hit a now-missing instance (output still flows from the
|
|
36
|
+
* snapshot, but keystrokes/navigation silently vanish).
|
|
37
|
+
*/
|
|
38
|
+
private readonly refs;
|
|
39
|
+
constructor(registry: SurfaceRegistryImpl, ctx: SurfaceContext, logger?: Logger | undefined);
|
|
40
|
+
list(): Promise<ReadonlyArray<SurfaceInfo>>;
|
|
41
|
+
open(kind: SurfaceKind): Promise<OpenSurfaceResult>;
|
|
42
|
+
input(surfaceId: string, msg: SurfaceInputMessage): Promise<void>;
|
|
43
|
+
resize(surfaceId: string, size: SurfaceSize): Promise<void>;
|
|
44
|
+
close(surfaceId: string): Promise<void>;
|
|
45
|
+
/** Bump the viewer attach count for an already-open kind. */
|
|
46
|
+
private retain;
|
|
47
|
+
private describe;
|
|
48
|
+
onData(cb: (msg: SurfaceDataMessage) => void): () => void;
|
|
49
|
+
closeAll(): Promise<void>;
|
|
50
|
+
private byId;
|
|
51
|
+
private emit;
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=host.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"host.d.ts","sourceRoot":"","sources":["../../src/surfaces/host.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,iBAAiB,EACjB,cAAc,EACd,kBAAkB,EAClB,WAAW,EACX,WAAW,EACX,mBAAmB,EAEnB,WAAW,EACX,WAAW,EACZ,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAErE;;;;;;;;;;;GAWG;AACH,qBAAa,eAAgB,YAAW,WAAW;IAsB/C,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,GAAG;IACpB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC;IAvB1B,oEAAoE;IACpE,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA2C;IACrE,kEAAkE;IAClE,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAiC;IACxD,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAgD;IAC9E,4EAA4E;IAC5E,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAsD;IAC9E;;;;;;;;;;OAUG;IACH,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAkC;gBAGpC,QAAQ,EAAE,mBAAmB,EAC7B,GAAG,EAAE,cAAc,EACnB,MAAM,CAAC,EAAE,MAAM,YAAA;IAG5B,IAAI,IAAI,OAAO,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC;IAyB3C,IAAI,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAoCnD,KAAK,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC;IAMjE,MAAM,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAM3D,KAAK,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAwB7C,6DAA6D;IAC7D,OAAO,CAAC,MAAM;IAId,OAAO,CAAC,QAAQ;IAQhB,MAAM,CAAC,EAAE,EAAE,CAAC,GAAG,EAAE,kBAAkB,KAAK,IAAI,GAAG,MAAM,IAAI;IAKnD,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAO/B,OAAO,CAAC,IAAI;IAOZ,OAAO,CAAC,IAAI;CASb"}
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Manages the live, open {@link SurfaceInstance}s for a Session and multiplexes
|
|
3
|
+
* every instance's output through a single {@link onData} fan-out. The runner
|
|
4
|
+
* subscribes once and rebroadcasts each frame as a `surface.data` notification;
|
|
5
|
+
* the agent's tools reach the SAME underlying resource (PTY, page) through their
|
|
6
|
+
* plugin's module state, so a `terminal`/`browser_session` tool call appears in
|
|
7
|
+
* the very pane the user is watching.
|
|
8
|
+
*
|
|
9
|
+
* Opening a kind is idempotent: a second `open` returns the instance the first
|
|
10
|
+
* created (surfaces are shared), so a late-joining viewer attaches to the
|
|
11
|
+
* existing resource and gets its {@link SurfaceInstance.snapshot}.
|
|
12
|
+
*/
|
|
13
|
+
export class SurfaceHostImpl {
|
|
14
|
+
registry;
|
|
15
|
+
ctx;
|
|
16
|
+
logger;
|
|
17
|
+
/** Open instances, keyed by kind (one shared instance per kind). */
|
|
18
|
+
instances = new Map();
|
|
19
|
+
/** Per-instance unsubscribe from its onData, dropped on close. */
|
|
20
|
+
unsubs = new Map();
|
|
21
|
+
dataListeners = new Set();
|
|
22
|
+
/** In-flight opens, so concurrent `open(kind)` calls share one instance. */
|
|
23
|
+
opening = new Map();
|
|
24
|
+
/**
|
|
25
|
+
* Viewer attach count per kind. A surface is SHARED (the agent's tool + every
|
|
26
|
+
* attached viewer drive the same PTY/page), so `open` retains and `close`
|
|
27
|
+
* releases; the instance is only torn down when the last viewer detaches.
|
|
28
|
+
* Without this, a single viewer's `close` would destroy the resource out from
|
|
29
|
+
* under the others — and React StrictMode (dev) makes that routine: it
|
|
30
|
+
* mounts → unmounts → remounts, so the first mount's late-resolving `open`
|
|
31
|
+
* closes the very instance the remount just attached to, leaving `input`/
|
|
32
|
+
* `resize` to hit a now-missing instance (output still flows from the
|
|
33
|
+
* snapshot, but keystrokes/navigation silently vanish).
|
|
34
|
+
*/
|
|
35
|
+
refs = new Map();
|
|
36
|
+
constructor(registry, ctx, logger) {
|
|
37
|
+
this.registry = registry;
|
|
38
|
+
this.ctx = ctx;
|
|
39
|
+
this.logger = logger;
|
|
40
|
+
}
|
|
41
|
+
async list() {
|
|
42
|
+
const out = [];
|
|
43
|
+
for (const def of this.registry.list()) {
|
|
44
|
+
let available = true;
|
|
45
|
+
let reason;
|
|
46
|
+
if (def.isAvailable) {
|
|
47
|
+
try {
|
|
48
|
+
const a = await def.isAvailable(this.ctx);
|
|
49
|
+
available = a.ok;
|
|
50
|
+
reason = a.reason;
|
|
51
|
+
}
|
|
52
|
+
catch (err) {
|
|
53
|
+
available = false;
|
|
54
|
+
reason = err instanceof Error ? err.message : String(err);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
out.push({
|
|
58
|
+
kind: def.kind,
|
|
59
|
+
...(def.description ? { description: def.description } : {}),
|
|
60
|
+
available,
|
|
61
|
+
...(reason ? { reason } : {}),
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
return out;
|
|
65
|
+
}
|
|
66
|
+
async open(kind) {
|
|
67
|
+
const existing = this.instances.get(kind);
|
|
68
|
+
if (existing) {
|
|
69
|
+
this.retain(kind);
|
|
70
|
+
return this.describe(existing);
|
|
71
|
+
}
|
|
72
|
+
const pending = this.opening.get(kind);
|
|
73
|
+
if (pending) {
|
|
74
|
+
// Ride the in-flight create, but still count this viewer's attach.
|
|
75
|
+
const res = await pending;
|
|
76
|
+
this.retain(kind);
|
|
77
|
+
return res;
|
|
78
|
+
}
|
|
79
|
+
const def = this.registry.get(kind);
|
|
80
|
+
if (!def)
|
|
81
|
+
throw new Error(`No surface registered for kind: ${kind}`);
|
|
82
|
+
const promise = (async () => {
|
|
83
|
+
const instance = await def.open(this.ctx);
|
|
84
|
+
this.instances.set(kind, instance);
|
|
85
|
+
this.refs.set(kind, 1);
|
|
86
|
+
// Re-emit this instance's frames as multiplexed SurfaceDataMessages.
|
|
87
|
+
const unsub = instance.onData((payload) => this.emit({ surfaceId: instance.id, kind: instance.kind, payload }));
|
|
88
|
+
this.unsubs.set(instance.id, unsub);
|
|
89
|
+
return this.describe(instance);
|
|
90
|
+
})();
|
|
91
|
+
this.opening.set(kind, promise);
|
|
92
|
+
try {
|
|
93
|
+
return await promise;
|
|
94
|
+
}
|
|
95
|
+
finally {
|
|
96
|
+
this.opening.delete(kind);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
async input(surfaceId, msg) {
|
|
100
|
+
const instance = this.byId(surfaceId);
|
|
101
|
+
if (!instance)
|
|
102
|
+
return;
|
|
103
|
+
await instance.input(msg);
|
|
104
|
+
}
|
|
105
|
+
async resize(surfaceId, size) {
|
|
106
|
+
const instance = this.byId(surfaceId);
|
|
107
|
+
if (!instance?.resize)
|
|
108
|
+
return;
|
|
109
|
+
await instance.resize(size);
|
|
110
|
+
}
|
|
111
|
+
async close(surfaceId) {
|
|
112
|
+
const instance = this.byId(surfaceId);
|
|
113
|
+
if (!instance)
|
|
114
|
+
return;
|
|
115
|
+
const kind = instance.kind;
|
|
116
|
+
// Release this viewer; keep the shared instance alive while others hold it.
|
|
117
|
+
const remaining = (this.refs.get(kind) ?? 1) - 1;
|
|
118
|
+
if (remaining > 0) {
|
|
119
|
+
this.refs.set(kind, remaining);
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
this.refs.delete(kind);
|
|
123
|
+
this.unsubs.get(surfaceId)?.();
|
|
124
|
+
this.unsubs.delete(surfaceId);
|
|
125
|
+
this.instances.delete(kind);
|
|
126
|
+
try {
|
|
127
|
+
await instance.close();
|
|
128
|
+
}
|
|
129
|
+
catch (err) {
|
|
130
|
+
this.logger?.warn?.('SurfaceHost: close failed', {
|
|
131
|
+
surfaceId,
|
|
132
|
+
err: err instanceof Error ? err.message : String(err),
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
/** Bump the viewer attach count for an already-open kind. */
|
|
137
|
+
retain(kind) {
|
|
138
|
+
this.refs.set(kind, (this.refs.get(kind) ?? 0) + 1);
|
|
139
|
+
}
|
|
140
|
+
describe(instance) {
|
|
141
|
+
return {
|
|
142
|
+
surfaceId: instance.id,
|
|
143
|
+
kind: instance.kind,
|
|
144
|
+
...(instance.snapshot ? { snapshot: instance.snapshot() } : {}),
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
onData(cb) {
|
|
148
|
+
this.dataListeners.add(cb);
|
|
149
|
+
return () => this.dataListeners.delete(cb);
|
|
150
|
+
}
|
|
151
|
+
async closeAll() {
|
|
152
|
+
// Session shutdown: tear every instance down regardless of viewer refs.
|
|
153
|
+
for (const kind of [...this.instances.keys()])
|
|
154
|
+
this.refs.set(kind, 1);
|
|
155
|
+
const ids = [...this.unsubs.keys()];
|
|
156
|
+
for (const id of ids)
|
|
157
|
+
await this.close(id);
|
|
158
|
+
}
|
|
159
|
+
byId(surfaceId) {
|
|
160
|
+
for (const instance of this.instances.values()) {
|
|
161
|
+
if (instance.id === surfaceId)
|
|
162
|
+
return instance;
|
|
163
|
+
}
|
|
164
|
+
return undefined;
|
|
165
|
+
}
|
|
166
|
+
emit(msg) {
|
|
167
|
+
for (const fn of this.dataListeners) {
|
|
168
|
+
try {
|
|
169
|
+
fn(msg);
|
|
170
|
+
}
|
|
171
|
+
catch {
|
|
172
|
+
/* a bad listener must not break the stream */
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
//# sourceMappingURL=host.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"host.js","sourceRoot":"","sources":["../../src/surfaces/host.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The default tunnel provider: no tunnel at all, just the local URL. Used when
|
|
3
|
+
* the surface and the user share a machine (TUI), or when no real tunnel
|
|
4
|
+
* (cloudflared) is configured/installed.
|
|
5
|
+
*/
|
|
6
|
+
export declare const localhostTunnel: import("@moxxy/sdk").TunnelProviderDef;
|
|
7
|
+
//# sourceMappingURL=localhost.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"localhost.d.ts","sourceRoot":"","sources":["../../src/tunnel/localhost.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,eAAO,MAAM,eAAe,wCAa1B,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { defineTunnelProvider } from '@moxxy/sdk';
|
|
2
|
+
/**
|
|
3
|
+
* The default tunnel provider: no tunnel at all, just the local URL. Used when
|
|
4
|
+
* the surface and the user share a machine (TUI), or when no real tunnel
|
|
5
|
+
* (cloudflared) is configured/installed.
|
|
6
|
+
*/
|
|
7
|
+
export const localhostTunnel = defineTunnelProvider({
|
|
8
|
+
name: 'localhost',
|
|
9
|
+
open: (opts) => {
|
|
10
|
+
// Bracket an IPv6 literal host (e.g. `::1` → `[::1]`) so the `:port`
|
|
11
|
+
// delimiter is unambiguous and the result is a valid URL. A bare IPv6
|
|
12
|
+
// host (`http://::1:4040`) is rejected by most URL parsers.
|
|
13
|
+
const host = opts.host.includes(':') ? `[${opts.host}]` : opts.host;
|
|
14
|
+
return Promise.resolve({
|
|
15
|
+
url: `http://${host}:${opts.port}`,
|
|
16
|
+
close: () => Promise.resolve(),
|
|
17
|
+
});
|
|
18
|
+
},
|
|
19
|
+
isAvailable: () => Promise.resolve(true),
|
|
20
|
+
});
|
|
21
|
+
//# sourceMappingURL=localhost.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"localhost.js","sourceRoot":"","sources":["../../src/tunnel/localhost.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAElD;;;;GAIG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,oBAAoB,CAAC;IAClD,IAAI,EAAE,WAAW;IACjB,IAAI,EAAE,CAAC,IAAI,EAAE,EAAE;QACb,qEAAqE;QACrE,sEAAsE;QACtE,4DAA4D;QAC5D,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;QACpE,OAAO,OAAO,CAAC,OAAO,CAAC;YACrB,GAAG,EAAE,UAAU,IAAI,IAAI,IAAI,CAAC,IAAI,EAAE;YAClC,KAAK,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE;SAC/B,CAAC,CAAC;IACL,CAAC;IACD,WAAW,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC;CACzC,CAAC,CAAC"}
|