@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,241 @@
|
|
|
1
|
+
import { promises as fs } from 'node:fs';
|
|
2
|
+
import * as path from 'node:path';
|
|
3
|
+
import { asSkillId, definePlugin, defineTool, skillFrontmatterSchema, } from '@moxxy/sdk';
|
|
4
|
+
import { z } from 'zod';
|
|
5
|
+
import { defaultProjectSkillsDir, defaultUserSkillsDir } from './loader.js';
|
|
6
|
+
import { draftSkill } from './synthesize-draft.js';
|
|
7
|
+
export async function synthesizeSkill(session, intent, scope, opts = {},
|
|
8
|
+
/**
|
|
9
|
+
* The active turn's id, threaded from the tool's `ctx.turnId`. The
|
|
10
|
+
* `skill_created` event MUST carry it so run-turn's per-turn subscriber
|
|
11
|
+
* (`event.turnId !== turnId → drop`) doesn't filter the event out of the
|
|
12
|
+
* running turn's stream. Falls back to a fresh turn only for legacy callers
|
|
13
|
+
* that invoke this outside a turn.
|
|
14
|
+
*/
|
|
15
|
+
turnId) {
|
|
16
|
+
const provider = session.providers.getActive();
|
|
17
|
+
// Prefer the model the conversation last ran on over the provider's first
|
|
18
|
+
// descriptor; 'default' matches run-turn's terminal fallback (never a
|
|
19
|
+
// hardcoded vendor id that goes stale).
|
|
20
|
+
const model = opts.model ?? session.lastResolvedModel ?? provider.models[0]?.id ?? 'default';
|
|
21
|
+
const draft = await draftSkill(provider, model, intent, session.signal);
|
|
22
|
+
const baseDir = scope === 'project'
|
|
23
|
+
? opts.projectDir ?? defaultProjectSkillsDir(session.cwd)
|
|
24
|
+
: opts.userDir ?? defaultUserSkillsDir();
|
|
25
|
+
await fs.mkdir(baseDir, { recursive: true });
|
|
26
|
+
// Validate the LLM-drafted frontmatter against the published schema BEFORE
|
|
27
|
+
// we write it to disk or register it. A model that returns sloppy YAML
|
|
28
|
+
// (missing description, illegal slug, etc.) should fail with a single
|
|
29
|
+
// readable line — the raw zod issue array was dumping ~30 lines of
|
|
30
|
+
// angry red JSON into the chat, which is a worse signal than just
|
|
31
|
+
// saying "the model didn't produce valid frontmatter."
|
|
32
|
+
const parsed = skillFrontmatterSchema.safeParse(draft.frontmatter);
|
|
33
|
+
if (!parsed.success) {
|
|
34
|
+
const missing = parsed.error.issues
|
|
35
|
+
.map((iss) => iss.path.join('.') || '(root)')
|
|
36
|
+
.join(', ');
|
|
37
|
+
throw new Error(`synthesize_skill: the model didn't produce valid skill frontmatter ` +
|
|
38
|
+
`(missing or invalid: ${missing}). This usually means the model returned ` +
|
|
39
|
+
`prose or a code block without proper YAML frontmatter. Try a more specific intent.`);
|
|
40
|
+
}
|
|
41
|
+
const frontmatter = parsed.data;
|
|
42
|
+
const finalPath = await uniqueFilename(baseDir, slugify(frontmatter.name));
|
|
43
|
+
await fs.writeFile(finalPath, draft.raw, 'utf8');
|
|
44
|
+
// Derive the skill id from the on-disk filename, not from the LLM-supplied
|
|
45
|
+
// frontmatter name — otherwise synthesizing the same name twice collides
|
|
46
|
+
// even when uniqueFilename has just bumped the filename to `<slug>-2.md`.
|
|
47
|
+
const basename = path.basename(finalPath, '.md');
|
|
48
|
+
const skill = {
|
|
49
|
+
id: asSkillId(`${scope}/${basename}`),
|
|
50
|
+
path: finalPath,
|
|
51
|
+
scope,
|
|
52
|
+
frontmatter,
|
|
53
|
+
body: draft.body.trimEnd(),
|
|
54
|
+
};
|
|
55
|
+
session.skills.register(skill);
|
|
56
|
+
await session.log.append({
|
|
57
|
+
type: 'skill_created',
|
|
58
|
+
sessionId: session.id,
|
|
59
|
+
turnId: turnId ?? session.startTurn().turnId,
|
|
60
|
+
source: 'system',
|
|
61
|
+
skillId: skill.id,
|
|
62
|
+
name: skill.frontmatter.name,
|
|
63
|
+
path: finalPath,
|
|
64
|
+
scope,
|
|
65
|
+
originatingPrompt: intent,
|
|
66
|
+
});
|
|
67
|
+
const auditPath = opts.auditPath ?? path.join(defaultUserSkillsDir(), '.meta', 'created.jsonl');
|
|
68
|
+
await appendAudit(auditPath, {
|
|
69
|
+
slug: path.basename(finalPath, '.md'),
|
|
70
|
+
ts: new Date().toISOString(),
|
|
71
|
+
sessionId: String(session.id),
|
|
72
|
+
originatingPrompt: intent,
|
|
73
|
+
scope,
|
|
74
|
+
});
|
|
75
|
+
return { skill, path: finalPath, scope };
|
|
76
|
+
}
|
|
77
|
+
function slugify(name) {
|
|
78
|
+
return name
|
|
79
|
+
.toLowerCase()
|
|
80
|
+
.replace(/[^a-z0-9-]+/g, '-')
|
|
81
|
+
.replace(/^-+|-+$/g, '')
|
|
82
|
+
.slice(0, 60);
|
|
83
|
+
}
|
|
84
|
+
async function uniqueFilename(dir, base) {
|
|
85
|
+
let candidate = path.join(dir, `${base}.md`);
|
|
86
|
+
let n = 2;
|
|
87
|
+
while (await exists(candidate)) {
|
|
88
|
+
candidate = path.join(dir, `${base}-${n}.md`);
|
|
89
|
+
n += 1;
|
|
90
|
+
}
|
|
91
|
+
return candidate;
|
|
92
|
+
}
|
|
93
|
+
async function exists(p) {
|
|
94
|
+
try {
|
|
95
|
+
await fs.access(p);
|
|
96
|
+
return true;
|
|
97
|
+
}
|
|
98
|
+
catch {
|
|
99
|
+
return false;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
async function appendAudit(filePath, entry) {
|
|
103
|
+
await fs.mkdir(path.dirname(filePath), { recursive: true });
|
|
104
|
+
await fs.appendFile(filePath, JSON.stringify(entry) + '\n', 'utf8');
|
|
105
|
+
}
|
|
106
|
+
export function buildSynthesizeSkillPlugin(session, opts = {}) {
|
|
107
|
+
return definePlugin({
|
|
108
|
+
name: '@moxxy/synthesize-skill',
|
|
109
|
+
version: '0.0.0',
|
|
110
|
+
tools: [
|
|
111
|
+
defineTool({
|
|
112
|
+
name: 'synthesize_skill',
|
|
113
|
+
description: 'Draft and persist a new Markdown skill for the given user intent. ' +
|
|
114
|
+
'Uses the active provider to generate the skill body. Returns the path of the created skill. ' +
|
|
115
|
+
'ALWAYS pass scope="user" (the default) unless the user has EXPLICITLY asked to scope ' +
|
|
116
|
+
'the skill to this project — "user" writes to ~/.moxxy/skills/ and the skill is ' +
|
|
117
|
+
'available across every project; "project" writes to <cwd>/.moxxy/skills/ and only ' +
|
|
118
|
+
'applies in this directory. Most skills are general-purpose; pick "project" only when ' +
|
|
119
|
+
'the user said something like "for this repo only" or "project-specific".',
|
|
120
|
+
inputSchema: z.object({
|
|
121
|
+
intent: z.string().min(1).describe('What the user is trying to do. One sentence is enough.'),
|
|
122
|
+
scope: z
|
|
123
|
+
.enum(['user', 'project'])
|
|
124
|
+
.optional()
|
|
125
|
+
.default('user')
|
|
126
|
+
.describe('Where to write the skill. "user" → ~/.moxxy/skills/ (default, recommended). ' +
|
|
127
|
+
'"project" → <cwd>/.moxxy/skills/ — ONLY when the user explicitly asks for a project-scoped skill.'),
|
|
128
|
+
}),
|
|
129
|
+
permission: { action: 'prompt' },
|
|
130
|
+
handler: async ({ intent, scope }, ctx) => {
|
|
131
|
+
const result = await synthesizeSkill(session, intent, scope, opts, ctx.turnId);
|
|
132
|
+
return {
|
|
133
|
+
path: result.path,
|
|
134
|
+
scope: result.scope,
|
|
135
|
+
name: result.skill.frontmatter.name,
|
|
136
|
+
};
|
|
137
|
+
},
|
|
138
|
+
}),
|
|
139
|
+
defineTool({
|
|
140
|
+
name: 'load_skill',
|
|
141
|
+
description: 'Fetch the full body (instructions) of a pre-authored skill by name. ' +
|
|
142
|
+
'The system prompt lists each skill\'s name, description, and triggers; ' +
|
|
143
|
+
'call this tool to retrieve the actual workflow when the user\'s intent ' +
|
|
144
|
+
'matches one of those skills. Returns the markdown body verbatim plus the ' +
|
|
145
|
+
'frontmatter metadata (allowed-tools, scope, etc.).',
|
|
146
|
+
inputSchema: z.object({
|
|
147
|
+
name: z
|
|
148
|
+
.string()
|
|
149
|
+
.min(1)
|
|
150
|
+
.describe('The exact skill name from the "Available skills" list in the system prompt.'),
|
|
151
|
+
}),
|
|
152
|
+
handler: async ({ name }, ctx) => {
|
|
153
|
+
const skill = session.skills.byName(name);
|
|
154
|
+
if (!skill) {
|
|
155
|
+
const known = session.skills
|
|
156
|
+
.list()
|
|
157
|
+
.map((s) => s.frontmatter.name)
|
|
158
|
+
.join(', ');
|
|
159
|
+
throw new Error(`load_skill: no skill named "${name}". ` +
|
|
160
|
+
`Known skills: ${known || '(none registered)'}.`);
|
|
161
|
+
}
|
|
162
|
+
// Emit a skill_invoked event so the audit log captures which
|
|
163
|
+
// skills were actually exercised in this turn — useful for
|
|
164
|
+
// routing analytics and for the self-improver agent later. Use the
|
|
165
|
+
// active turn's id (ctx.turnId) so run-turn's per-turn subscriber
|
|
166
|
+
// filter doesn't drop it (a fresh startTurn() id wouldn't match).
|
|
167
|
+
await session.log.append({
|
|
168
|
+
type: 'skill_invoked',
|
|
169
|
+
sessionId: session.id,
|
|
170
|
+
turnId: ctx.turnId,
|
|
171
|
+
source: 'model',
|
|
172
|
+
skillId: skill.id,
|
|
173
|
+
name: skill.frontmatter.name,
|
|
174
|
+
reason: 'load_skill_tool',
|
|
175
|
+
});
|
|
176
|
+
return {
|
|
177
|
+
name: skill.frontmatter.name,
|
|
178
|
+
description: skill.frontmatter.description,
|
|
179
|
+
scope: skill.scope,
|
|
180
|
+
allowedTools: skill.frontmatter['allowed-tools'] ?? null,
|
|
181
|
+
body: skill.body,
|
|
182
|
+
};
|
|
183
|
+
},
|
|
184
|
+
}),
|
|
185
|
+
defineTool({
|
|
186
|
+
name: 'reload_skills',
|
|
187
|
+
description: 'Rescan all skill sources (builtin + plugin + ~/.moxxy/skills + ./.moxxy/skills), ' +
|
|
188
|
+
'registering any new or changed skills.',
|
|
189
|
+
inputSchema: z.object({}),
|
|
190
|
+
// Safe, idempotent, local-only rescan — never prompt. Without this the
|
|
191
|
+
// tool inherits the channel resolver's default, which denies in
|
|
192
|
+
// headless runs (the skill-author flow couldn't activate a new skill).
|
|
193
|
+
permission: { action: 'allow' },
|
|
194
|
+
handler: async () => {
|
|
195
|
+
const { discoverSkills } = await import('./loader.js');
|
|
196
|
+
// Discover first, swap second: never empty the registry while
|
|
197
|
+
// the fs scan is in flight, because concurrent skill lookups
|
|
198
|
+
// would observe an empty registry mid-reload. Pass the SAME
|
|
199
|
+
// source set the boot loader used (builtin + pluginDirs +
|
|
200
|
+
// user + project); a previous version of this handler omitted
|
|
201
|
+
// builtinDir/pluginDirs and reload silently nuked the builtin
|
|
202
|
+
// skill set.
|
|
203
|
+
const discovered = await discoverSkills({
|
|
204
|
+
projectDir: opts.projectDir ?? defaultProjectSkillsDir(session.cwd),
|
|
205
|
+
userDir: opts.userDir ?? defaultUserSkillsDir(),
|
|
206
|
+
...(opts.builtinDir ? { builtinDir: opts.builtinDir } : {}),
|
|
207
|
+
...(opts.pluginDirs ? { pluginDirs: opts.pluginDirs } : {}),
|
|
208
|
+
});
|
|
209
|
+
session.skills.replaceAll(discovered);
|
|
210
|
+
return `loaded ${discovered.length} skill${discovered.length === 1 ? '' : 's'}`;
|
|
211
|
+
},
|
|
212
|
+
}),
|
|
213
|
+
defineTool({
|
|
214
|
+
name: 'load_tool',
|
|
215
|
+
description: 'Load a tool whose full schema was indexed but not sent (see "Loadable tools" ' +
|
|
216
|
+
'in the system prompt). Call this with the tool name; the tool becomes callable ' +
|
|
217
|
+
'on the next turn. Only needed when lazy tool loading is enabled — core tools ' +
|
|
218
|
+
'(Read/Write/Edit/Bash/Grep/Glob) are always available.',
|
|
219
|
+
inputSchema: z.object({
|
|
220
|
+
name: z.string().min(1).describe('Exact tool name from the "Loadable tools" index.'),
|
|
221
|
+
}),
|
|
222
|
+
permission: { action: 'allow' },
|
|
223
|
+
handler: ({ name }) => {
|
|
224
|
+
// The call itself is recorded in the log; `applyLazyTools` reads that
|
|
225
|
+
// to include the tool's schema on subsequent requests. Here we just
|
|
226
|
+
// validate the name and echo the description so the model can proceed.
|
|
227
|
+
const tool = session.tools.get(name);
|
|
228
|
+
if (!tool) {
|
|
229
|
+
const known = session.tools
|
|
230
|
+
.list()
|
|
231
|
+
.map((t) => t.name)
|
|
232
|
+
.join(', ');
|
|
233
|
+
throw new Error(`load_tool: no tool named "${name}". Known tools: ${known}.`);
|
|
234
|
+
}
|
|
235
|
+
return { name: tool.name, description: tool.description, loaded: true };
|
|
236
|
+
},
|
|
237
|
+
}),
|
|
238
|
+
],
|
|
239
|
+
});
|
|
240
|
+
}
|
|
241
|
+
//# sourceMappingURL=synthesize.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"synthesize.js","sourceRoot":"","sources":["../../src/skills/synthesize.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Subagent <-> parent log bridge. Wraps child `MoxxyEvent`s into
|
|
3
|
+
* `plugin_event` envelopes on the parent log so the TUI / exporters can
|
|
4
|
+
* render live progress, and emits the start/completed bookend envelopes.
|
|
5
|
+
*/
|
|
6
|
+
import type { MoxxyEvent, SessionId, StopReason, SubagentSpec, TurnId } from '@moxxy/sdk';
|
|
7
|
+
import type { SessionRuntime } from '../session-runtime.js';
|
|
8
|
+
export declare const SUBAGENT_PLUGIN_ID: import("@moxxy/sdk").PluginId;
|
|
9
|
+
export declare function emitSubagentStart(parentSession: SessionRuntime, parentTurnId: TurnId, label: string, childSessionId: SessionId, spec: SubagentSpec, mode: string): Promise<void>;
|
|
10
|
+
export declare function emitSubagentCompleted(parentSession: SessionRuntime, parentTurnId: TurnId, label: string, childSessionId: SessionId, text: string, stopReason: StopReason, errorMessage: string | null, agentType: string, tokensUsed: number): Promise<void>;
|
|
11
|
+
export declare function emitSubagentWarning(parentSession: SessionRuntime, parentTurnId: TurnId, label: string, childSessionId: SessionId, message: string): Promise<void>;
|
|
12
|
+
/**
|
|
13
|
+
* Map each interesting child event to a parent `plugin_event` so the TUI
|
|
14
|
+
* can render the subagent's progress in real time. Noisy / book-keeping
|
|
15
|
+
* events (mode_iteration, provider_request, provider_response,
|
|
16
|
+
* assistant_message — covered by the explicit `subagent_completed`) are
|
|
17
|
+
* filtered out to keep the parent log lean.
|
|
18
|
+
*/
|
|
19
|
+
export declare function streamChildEventToParent(parentSession: SessionRuntime, parentTurnId: TurnId, label: string, childSessionId: SessionId, childEvt: MoxxyEvent): Promise<void>;
|
|
20
|
+
//# sourceMappingURL=events.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../src/subagents/events.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EACV,UAAU,EACV,SAAS,EACT,UAAU,EACV,YAAY,EACZ,MAAM,EACP,MAAM,YAAY,CAAC;AAEpB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAE5D,eAAO,MAAM,kBAAkB,+BAAiC,CAAC;AAEjE,wBAAsB,iBAAiB,CACrC,aAAa,EAAE,cAAc,EAC7B,YAAY,EAAE,MAAM,EACpB,KAAK,EAAE,MAAM,EACb,cAAc,EAAE,SAAS,EACzB,IAAI,EAAE,YAAY,EAClB,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,IAAI,CAAC,CAiBf;AAED,wBAAsB,qBAAqB,CACzC,aAAa,EAAE,cAAc,EAC7B,YAAY,EAAE,MAAM,EACpB,KAAK,EAAE,MAAM,EACb,cAAc,EAAE,SAAS,EACzB,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,UAAU,EACtB,YAAY,EAAE,MAAM,GAAG,IAAI,EAC3B,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,IAAI,CAAC,CAkBf;AAED,wBAAsB,mBAAmB,CACvC,aAAa,EAAE,cAAc,EAC7B,YAAY,EAAE,MAAM,EACpB,KAAK,EAAE,MAAM,EACb,cAAc,EAAE,SAAS,EACzB,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,IAAI,CAAC,CAcf;AAED;;;;;;GAMG;AACH,wBAAsB,wBAAwB,CAC5C,aAAa,EAAE,cAAc,EAC7B,YAAY,EAAE,MAAM,EACpB,KAAK,EAAE,MAAM,EACb,cAAc,EAAE,SAAS,EACzB,QAAQ,EAAE,UAAU,GACnB,OAAO,CAAC,IAAI,CAAC,CAwBf"}
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Subagent <-> parent log bridge. Wraps child `MoxxyEvent`s into
|
|
3
|
+
* `plugin_event` envelopes on the parent log so the TUI / exporters can
|
|
4
|
+
* render live progress, and emits the start/completed bookend envelopes.
|
|
5
|
+
*/
|
|
6
|
+
import { asPluginId } from '@moxxy/sdk';
|
|
7
|
+
export const SUBAGENT_PLUGIN_ID = asPluginId('@moxxy/subagents');
|
|
8
|
+
export async function emitSubagentStart(parentSession, parentTurnId, label, childSessionId, spec, mode) {
|
|
9
|
+
await parentSession.log.append({
|
|
10
|
+
type: 'plugin_event',
|
|
11
|
+
sessionId: parentSession.id,
|
|
12
|
+
turnId: parentTurnId,
|
|
13
|
+
source: 'plugin',
|
|
14
|
+
pluginId: SUBAGENT_PLUGIN_ID,
|
|
15
|
+
subtype: 'subagent_started',
|
|
16
|
+
payload: {
|
|
17
|
+
label,
|
|
18
|
+
childSessionId: String(childSessionId),
|
|
19
|
+
prompt: spec.prompt,
|
|
20
|
+
mode,
|
|
21
|
+
agentType: spec.agentType ?? 'default',
|
|
22
|
+
...(spec.model ? { model: spec.model } : {}),
|
|
23
|
+
},
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
export async function emitSubagentCompleted(parentSession, parentTurnId, label, childSessionId, text, stopReason, errorMessage, agentType, tokensUsed) {
|
|
27
|
+
await parentSession.log.append({
|
|
28
|
+
type: 'plugin_event',
|
|
29
|
+
sessionId: parentSession.id,
|
|
30
|
+
turnId: parentTurnId,
|
|
31
|
+
source: 'plugin',
|
|
32
|
+
pluginId: SUBAGENT_PLUGIN_ID,
|
|
33
|
+
subtype: 'subagent_completed',
|
|
34
|
+
payload: {
|
|
35
|
+
label,
|
|
36
|
+
childSessionId: String(childSessionId),
|
|
37
|
+
text,
|
|
38
|
+
stopReason,
|
|
39
|
+
agentType,
|
|
40
|
+
tokensUsed,
|
|
41
|
+
...(errorMessage ? { error: errorMessage } : {}),
|
|
42
|
+
},
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
export async function emitSubagentWarning(parentSession, parentTurnId, label, childSessionId, message) {
|
|
46
|
+
await parentSession.log.append({
|
|
47
|
+
type: 'plugin_event',
|
|
48
|
+
sessionId: parentSession.id,
|
|
49
|
+
turnId: parentTurnId,
|
|
50
|
+
source: 'plugin',
|
|
51
|
+
pluginId: SUBAGENT_PLUGIN_ID,
|
|
52
|
+
subtype: 'subagent_warning',
|
|
53
|
+
payload: {
|
|
54
|
+
label,
|
|
55
|
+
childSessionId: String(childSessionId),
|
|
56
|
+
message,
|
|
57
|
+
},
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Map each interesting child event to a parent `plugin_event` so the TUI
|
|
62
|
+
* can render the subagent's progress in real time. Noisy / book-keeping
|
|
63
|
+
* events (mode_iteration, provider_request, provider_response,
|
|
64
|
+
* assistant_message — covered by the explicit `subagent_completed`) are
|
|
65
|
+
* filtered out to keep the parent log lean.
|
|
66
|
+
*/
|
|
67
|
+
export async function streamChildEventToParent(parentSession, parentTurnId, label, childSessionId, childEvt) {
|
|
68
|
+
const mapped = mapChildEvent(label, childSessionId, childEvt);
|
|
69
|
+
if (!mapped)
|
|
70
|
+
return;
|
|
71
|
+
try {
|
|
72
|
+
await parentSession.log.append({
|
|
73
|
+
type: 'plugin_event',
|
|
74
|
+
sessionId: parentSession.id,
|
|
75
|
+
turnId: parentTurnId,
|
|
76
|
+
source: 'plugin',
|
|
77
|
+
pluginId: SUBAGENT_PLUGIN_ID,
|
|
78
|
+
subtype: mapped.subtype,
|
|
79
|
+
payload: mapped.payload,
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
catch (err) {
|
|
83
|
+
// Forwarding a child progress event is best-effort: a parent-log append
|
|
84
|
+
// failure must not abort the subagent run. EventLog.append already swallows
|
|
85
|
+
// listener errors, so this rejection would otherwise vanish with zero
|
|
86
|
+
// trace (the surface just stops updating); surface it so a chronic
|
|
87
|
+
// forwarding failure during a long subagent run is at least diagnosable.
|
|
88
|
+
process.stderr.write(`moxxy: dropped subagent progress event (${mapped.subtype}) — parent log append failed: ` +
|
|
89
|
+
`${err instanceof Error ? err.message : String(err)}\n`);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
function mapChildEvent(label, childSessionId, childEvt) {
|
|
93
|
+
const payload = {
|
|
94
|
+
label,
|
|
95
|
+
childSessionId: String(childSessionId),
|
|
96
|
+
};
|
|
97
|
+
switch (childEvt.type) {
|
|
98
|
+
case 'assistant_chunk':
|
|
99
|
+
payload.delta = childEvt.delta;
|
|
100
|
+
return { subtype: 'subagent_chunk', payload };
|
|
101
|
+
case 'tool_call_requested':
|
|
102
|
+
payload.name = childEvt.name;
|
|
103
|
+
payload.input = childEvt.input;
|
|
104
|
+
payload.callId = String(childEvt.callId);
|
|
105
|
+
return { subtype: 'subagent_tool_call', payload };
|
|
106
|
+
case 'tool_result':
|
|
107
|
+
payload.callId = String(childEvt.callId);
|
|
108
|
+
payload.ok = childEvt.ok;
|
|
109
|
+
if (childEvt.ok)
|
|
110
|
+
payload.output = childEvt.output;
|
|
111
|
+
else
|
|
112
|
+
payload.error = childEvt.error;
|
|
113
|
+
return { subtype: 'subagent_tool_result', payload };
|
|
114
|
+
case 'error':
|
|
115
|
+
payload.kind = childEvt.kind;
|
|
116
|
+
payload.message = childEvt.message;
|
|
117
|
+
return { subtype: 'subagent_error', payload };
|
|
118
|
+
case 'abort':
|
|
119
|
+
payload.reason = childEvt.reason;
|
|
120
|
+
return { subtype: 'subagent_abort', payload };
|
|
121
|
+
case 'plugin_event':
|
|
122
|
+
return mapNestedPluginEvent(label, payload, childEvt);
|
|
123
|
+
default:
|
|
124
|
+
return null;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
function mapNestedPluginEvent(label, payload, childEvt) {
|
|
128
|
+
// Bubble nested subagent events too, so a grand-child's progress
|
|
129
|
+
// surfaces all the way up. We strip the nested label-prefix to
|
|
130
|
+
// keep things compact; payload retains the chain via the embedded
|
|
131
|
+
// childSessionId.
|
|
132
|
+
const nestedSubtype = childEvt.subtype;
|
|
133
|
+
if (typeof nestedSubtype !== 'string' || !nestedSubtype.startsWith('subagent_'))
|
|
134
|
+
return null;
|
|
135
|
+
const nestedPayload = childEvt.payload;
|
|
136
|
+
if (nestedPayload && typeof nestedPayload === 'object') {
|
|
137
|
+
for (const [k, v] of Object.entries(nestedPayload)) {
|
|
138
|
+
if (k !== 'label' && k !== 'childSessionId')
|
|
139
|
+
payload[k] = v;
|
|
140
|
+
}
|
|
141
|
+
// Preserve the chain via a `via` field naming the immediate parent label.
|
|
142
|
+
payload.via = label;
|
|
143
|
+
}
|
|
144
|
+
return { subtype: nestedSubtype, payload };
|
|
145
|
+
}
|
|
146
|
+
//# sourceMappingURL=events.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"events.js","sourceRoot":"","sources":["../../src/subagents/events.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AASH,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAGxC,MAAM,CAAC,MAAM,kBAAkB,GAAG,UAAU,CAAC,kBAAkB,CAAC,CAAC;AAEjE,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,aAA6B,EAC7B,YAAoB,EACpB,KAAa,EACb,cAAyB,EACzB,IAAkB,EAClB,IAAY;IAEZ,MAAM,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC;QAC7B,IAAI,EAAE,cAAc;QACpB,SAAS,EAAE,aAAa,CAAC,EAAE;QAC3B,MAAM,EAAE,YAAY;QACpB,MAAM,EAAE,QAAQ;QAChB,QAAQ,EAAE,kBAAkB;QAC5B,OAAO,EAAE,kBAAkB;QAC3B,OAAO,EAAE;YACP,KAAK;YACL,cAAc,EAAE,MAAM,CAAC,cAAc,CAAC;YACtC,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,IAAI;YACJ,SAAS,EAAE,IAAI,CAAC,SAAS,IAAI,SAAS;YACtC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAC7C;KACF,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,aAA6B,EAC7B,YAAoB,EACpB,KAAa,EACb,cAAyB,EACzB,IAAY,EACZ,UAAsB,EACtB,YAA2B,EAC3B,SAAiB,EACjB,UAAkB;IAElB,MAAM,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC;QAC7B,IAAI,EAAE,cAAc;QACpB,SAAS,EAAE,aAAa,CAAC,EAAE;QAC3B,MAAM,EAAE,YAAY;QACpB,MAAM,EAAE,QAAQ;QAChB,QAAQ,EAAE,kBAAkB;QAC5B,OAAO,EAAE,oBAAoB;QAC7B,OAAO,EAAE;YACP,KAAK;YACL,cAAc,EAAE,MAAM,CAAC,cAAc,CAAC;YACtC,IAAI;YACJ,UAAU;YACV,SAAS;YACT,UAAU;YACV,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACjD;KACF,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,aAA6B,EAC7B,YAAoB,EACpB,KAAa,EACb,cAAyB,EACzB,OAAe;IAEf,MAAM,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC;QAC7B,IAAI,EAAE,cAAc;QACpB,SAAS,EAAE,aAAa,CAAC,EAAE;QAC3B,MAAM,EAAE,YAAY;QACpB,MAAM,EAAE,QAAQ;QAChB,QAAQ,EAAE,kBAAkB;QAC5B,OAAO,EAAE,kBAAkB;QAC3B,OAAO,EAAE;YACP,KAAK;YACL,cAAc,EAAE,MAAM,CAAC,cAAc,CAAC;YACtC,OAAO;SACR;KACF,CAAC,CAAC;AACL,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAC5C,aAA6B,EAC7B,YAAoB,EACpB,KAAa,EACb,cAAyB,EACzB,QAAoB;IAEpB,MAAM,MAAM,GAAG,aAAa,CAAC,KAAK,EAAE,cAAc,EAAE,QAAQ,CAAC,CAAC;IAC9D,IAAI,CAAC,MAAM;QAAE,OAAO;IACpB,IAAI,CAAC;QACH,MAAM,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC;YAC7B,IAAI,EAAE,cAAc;YACpB,SAAS,EAAE,aAAa,CAAC,EAAE;YAC3B,MAAM,EAAE,YAAY;YACpB,MAAM,EAAE,QAAQ;YAChB,QAAQ,EAAE,kBAAkB;YAC5B,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,OAAO,EAAE,MAAM,CAAC,OAAO;SACxB,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,wEAAwE;QACxE,4EAA4E;QAC5E,sEAAsE;QACtE,mEAAmE;QACnE,yEAAyE;QACzE,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,2CAA2C,MAAM,CAAC,OAAO,gCAAgC;YACvF,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAC1D,CAAC;IACJ,CAAC;AACH,CAAC;AAED,SAAS,aAAa,CACpB,KAAa,EACb,cAAyB,EACzB,QAAoB;IAEpB,MAAM,OAAO,GAA4B;QACvC,KAAK;QACL,cAAc,EAAE,MAAM,CAAC,cAAc,CAAC;KACvC,CAAC;IACF,QAAQ,QAAQ,CAAC,IAAI,EAAE,CAAC;QACtB,KAAK,iBAAiB;YACpB,OAAO,CAAC,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC;YAC/B,OAAO,EAAE,OAAO,EAAE,gBAAgB,EAAE,OAAO,EAAE,CAAC;QAChD,KAAK,qBAAqB;YACxB,OAAO,CAAC,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC;YAC7B,OAAO,CAAC,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC;YAC/B,OAAO,CAAC,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;YACzC,OAAO,EAAE,OAAO,EAAE,oBAAoB,EAAE,OAAO,EAAE,CAAC;QACpD,KAAK,aAAa;YAChB,OAAO,CAAC,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;YACzC,OAAO,CAAC,EAAE,GAAG,QAAQ,CAAC,EAAE,CAAC;YACzB,IAAI,QAAQ,CAAC,EAAE;gBAAE,OAAO,CAAC,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC;;gBAC7C,OAAO,CAAC,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC;YACpC,OAAO,EAAE,OAAO,EAAE,sBAAsB,EAAE,OAAO,EAAE,CAAC;QACtD,KAAK,OAAO;YACV,OAAO,CAAC,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC;YAC7B,OAAO,CAAC,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC;YACnC,OAAO,EAAE,OAAO,EAAE,gBAAgB,EAAE,OAAO,EAAE,CAAC;QAChD,KAAK,OAAO;YACV,OAAO,CAAC,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC;YACjC,OAAO,EAAE,OAAO,EAAE,gBAAgB,EAAE,OAAO,EAAE,CAAC;QAChD,KAAK,cAAc;YACjB,OAAO,oBAAoB,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;QACxD;YACE,OAAO,IAAI,CAAC;IAChB,CAAC;AACH,CAAC;AAED,SAAS,oBAAoB,CAC3B,KAAa,EACb,OAAgC,EAChC,QAAuD;IAEvD,iEAAiE;IACjE,+DAA+D;IAC/D,kEAAkE;IAClE,kBAAkB;IAClB,MAAM,aAAa,GAAG,QAAQ,CAAC,OAAO,CAAC;IACvC,IAAI,OAAO,aAAa,KAAK,QAAQ,IAAI,CAAC,aAAa,CAAC,UAAU,CAAC,WAAW,CAAC;QAAE,OAAO,IAAI,CAAC;IAC7F,MAAM,aAAa,GAAG,QAAQ,CAAC,OAAO,CAAC;IACvC,IAAI,aAAa,IAAI,OAAO,aAAa,KAAK,QAAQ,EAAE,CAAC;QACvD,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,aAAwC,CAAC,EAAE,CAAC;YAC9E,IAAI,CAAC,KAAK,OAAO,IAAI,CAAC,KAAK,gBAAgB;gBAAE,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;QAC9D,CAAC;QACD,0EAA0E;QAC1E,OAAO,CAAC,GAAG,GAAG,KAAK,CAAC;IACtB,CAAC;IACD,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,OAAO,EAAE,CAAC;AAC7C,CAAC"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Retained-child session registry — backs the `awaitInput` pause/resume flow.
|
|
3
|
+
*
|
|
4
|
+
* A subagent spawned with `retainSession: true` keeps its `EventLog` and
|
|
5
|
+
* `ModeContext` alive after its first turn so a later `continue()` can append
|
|
6
|
+
* an operator reply and run it again. The registry is a process-local map
|
|
7
|
+
* keyed by child session id; entries are dropped on `continue` or `release`.
|
|
8
|
+
*
|
|
9
|
+
* Each entry records its `parentSession`, so {@link clearRetainedChildren}
|
|
10
|
+
* drops only the children belonging to the session that is closing. The map is
|
|
11
|
+
* process-wide (one per module), but a `Session.close()` must NOT wipe another
|
|
12
|
+
* live session's paused children — that would break their `continue()` in any
|
|
13
|
+
* host that runs >1 Session per process (the desktop in-process path, tests).
|
|
14
|
+
*/
|
|
15
|
+
import type { ModeContext, SessionId, SubagentSpec, TurnId } from '@moxxy/sdk';
|
|
16
|
+
import type { EventLog } from '../events/log.js';
|
|
17
|
+
import type { SessionRuntime } from '../session-runtime.js';
|
|
18
|
+
export interface RetainedChildSession {
|
|
19
|
+
readonly label: string;
|
|
20
|
+
readonly childSessionId: SessionId;
|
|
21
|
+
readonly childTurnId: TurnId;
|
|
22
|
+
readonly childLog: EventLog;
|
|
23
|
+
readonly childCtx: ModeContext;
|
|
24
|
+
readonly spec: SubagentSpec;
|
|
25
|
+
readonly strategy: ReturnType<SessionRuntime['modes']['list']>[number];
|
|
26
|
+
readonly strategyName: string;
|
|
27
|
+
readonly parentSession: SessionRuntime;
|
|
28
|
+
readonly parentTurnId: TurnId;
|
|
29
|
+
}
|
|
30
|
+
export declare function registerRetainedChild(session: RetainedChildSession): void;
|
|
31
|
+
export declare function getRetainedChild(childSessionId: SessionId): RetainedChildSession | undefined;
|
|
32
|
+
export declare function releaseRetainedChild(childSessionId: SessionId): void;
|
|
33
|
+
/**
|
|
34
|
+
* Drop retained children. With a `parentSessionId`, drop ONLY the children
|
|
35
|
+
* whose `parentSession` is that session — so one session's `close()` can't wipe
|
|
36
|
+
* another live session's paused `awaitInput` children. Without an id (legacy /
|
|
37
|
+
* test-teardown callers), clear everything.
|
|
38
|
+
*/
|
|
39
|
+
export declare function clearRetainedChildren(parentSessionId?: SessionId): void;
|
|
40
|
+
//# sourceMappingURL=registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/subagents/registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAC/E,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAE5D,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,cAAc,EAAE,SAAS,CAAC;IACnC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC5B,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC;IAC/B,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC;IAC5B,QAAQ,CAAC,QAAQ,EAAE,UAAU,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;IACvE,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,aAAa,EAAE,cAAc,CAAC;IACvC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;CAC/B;AAID,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,oBAAoB,GAAG,IAAI,CAEzE;AAED,wBAAgB,gBAAgB,CAAC,cAAc,EAAE,SAAS,GAAG,oBAAoB,GAAG,SAAS,CAE5F;AAED,wBAAgB,oBAAoB,CAAC,cAAc,EAAE,SAAS,GAAG,IAAI,CAEpE;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,eAAe,CAAC,EAAE,SAAS,GAAG,IAAI,CASvE"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Retained-child session registry — backs the `awaitInput` pause/resume flow.
|
|
3
|
+
*
|
|
4
|
+
* A subagent spawned with `retainSession: true` keeps its `EventLog` and
|
|
5
|
+
* `ModeContext` alive after its first turn so a later `continue()` can append
|
|
6
|
+
* an operator reply and run it again. The registry is a process-local map
|
|
7
|
+
* keyed by child session id; entries are dropped on `continue` or `release`.
|
|
8
|
+
*
|
|
9
|
+
* Each entry records its `parentSession`, so {@link clearRetainedChildren}
|
|
10
|
+
* drops only the children belonging to the session that is closing. The map is
|
|
11
|
+
* process-wide (one per module), but a `Session.close()` must NOT wipe another
|
|
12
|
+
* live session's paused children — that would break their `continue()` in any
|
|
13
|
+
* host that runs >1 Session per process (the desktop in-process path, tests).
|
|
14
|
+
*/
|
|
15
|
+
const retained = new Map();
|
|
16
|
+
export function registerRetainedChild(session) {
|
|
17
|
+
retained.set(String(session.childSessionId), session);
|
|
18
|
+
}
|
|
19
|
+
export function getRetainedChild(childSessionId) {
|
|
20
|
+
return retained.get(String(childSessionId));
|
|
21
|
+
}
|
|
22
|
+
export function releaseRetainedChild(childSessionId) {
|
|
23
|
+
retained.delete(String(childSessionId));
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Drop retained children. With a `parentSessionId`, drop ONLY the children
|
|
27
|
+
* whose `parentSession` is that session — so one session's `close()` can't wipe
|
|
28
|
+
* another live session's paused `awaitInput` children. Without an id (legacy /
|
|
29
|
+
* test-teardown callers), clear everything.
|
|
30
|
+
*/
|
|
31
|
+
export function clearRetainedChildren(parentSessionId) {
|
|
32
|
+
if (parentSessionId === undefined) {
|
|
33
|
+
retained.clear();
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
const target = String(parentSessionId);
|
|
37
|
+
for (const [childId, entry] of retained) {
|
|
38
|
+
if (String(entry.parentSession.id) === target)
|
|
39
|
+
retained.delete(childId);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/subagents/registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAmBH,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAgC,CAAC;AAEzD,MAAM,UAAU,qBAAqB,CAAC,OAA6B;IACjE,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,EAAE,OAAO,CAAC,CAAC;AACxD,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,cAAyB;IACxD,OAAO,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,CAAC;AAC9C,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,cAAyB;IAC5D,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,CAAC;AAC1C,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,qBAAqB,CAAC,eAA2B;IAC/D,IAAI,eAAe,KAAK,SAAS,EAAE,CAAC;QAClC,QAAQ,CAAC,KAAK,EAAE,CAAC;QACjB,OAAO;IACT,CAAC;IACD,MAAM,MAAM,GAAG,MAAM,CAAC,eAAe,CAAC,CAAC;IACvC,KAAK,MAAM,CAAC,OAAO,EAAE,KAAK,CAAC,IAAI,QAAQ,EAAE,CAAC;QACxC,IAAI,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC,EAAE,CAAC,KAAK,MAAM;YAAE,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAC1E,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,43 @@
|
|
|
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 type { SessionId, SubagentResult, SubagentSpawner, SubagentSpec, TurnId } from '@moxxy/sdk';
|
|
25
|
+
import type { SessionRuntime } from '../session-runtime.js';
|
|
26
|
+
export interface SubagentRuntime {
|
|
27
|
+
readonly parentSession: SessionRuntime;
|
|
28
|
+
readonly parentTurnId: TurnId;
|
|
29
|
+
readonly parentSignal: AbortSignal;
|
|
30
|
+
readonly parentModel: string;
|
|
31
|
+
}
|
|
32
|
+
export declare function runChildTurn(args: {
|
|
33
|
+
rt: SubagentRuntime;
|
|
34
|
+
spec: SubagentSpec;
|
|
35
|
+
retainSession: boolean;
|
|
36
|
+
}): Promise<SubagentResult>;
|
|
37
|
+
export declare function continueChildTurn(args: {
|
|
38
|
+
childSessionId: SessionId;
|
|
39
|
+
prompt: string;
|
|
40
|
+
label?: string;
|
|
41
|
+
}): Promise<SubagentResult>;
|
|
42
|
+
export declare function createSubagentSpawner(rt: SubagentRuntime): SubagentSpawner;
|
|
43
|
+
//# sourceMappingURL=run-child.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run-child.d.ts","sourceRoot":"","sources":["../../src/subagents/run-child.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,KAAK,EAIV,SAAS,EAGT,cAAc,EACd,eAAe,EACf,YAAY,EAEZ,MAAM,EACP,MAAM,YAAY,CAAC;AAGpB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAe5D,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,aAAa,EAAE,cAAc,CAAC;IACvC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,YAAY,EAAE,WAAW,CAAC;IACnC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC9B;AAMD,wBAAsB,YAAY,CAAC,IAAI,EAAE;IACvC,EAAE,EAAE,eAAe,CAAC;IACpB,IAAI,EAAE,YAAY,CAAC;IACnB,aAAa,EAAE,OAAO,CAAC;CACxB,GAAG,OAAO,CAAC,cAAc,CAAC,CAsE1B;AAED,wBAAsB,iBAAiB,CAAC,IAAI,EAAE;IAC5C,cAAc,EAAE,SAAS,CAAC;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,GAAG,OAAO,CAAC,cAAc,CAAC,CAqC1B;AAiOD,wBAAgB,qBAAqB,CAAC,EAAE,EAAE,eAAe,GAAG,eAAe,CAiB1E"}
|