@soleri/core 9.11.0 → 9.13.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/dist/adapters/types.d.ts +2 -0
- package/dist/adapters/types.d.ts.map +1 -1
- package/dist/brain/brain.d.ts +5 -1
- package/dist/brain/brain.d.ts.map +1 -1
- package/dist/brain/brain.js +97 -10
- package/dist/brain/brain.js.map +1 -1
- package/dist/dream/cron-manager.d.ts +10 -0
- package/dist/dream/cron-manager.d.ts.map +1 -0
- package/dist/dream/cron-manager.js +122 -0
- package/dist/dream/cron-manager.js.map +1 -0
- package/dist/dream/dream-engine.d.ts +34 -0
- package/dist/dream/dream-engine.d.ts.map +1 -0
- package/dist/dream/dream-engine.js +88 -0
- package/dist/dream/dream-engine.js.map +1 -0
- package/dist/dream/dream-ops.d.ts +8 -0
- package/dist/dream/dream-ops.d.ts.map +1 -0
- package/dist/dream/dream-ops.js +49 -0
- package/dist/dream/dream-ops.js.map +1 -0
- package/dist/dream/index.d.ts +7 -0
- package/dist/dream/index.d.ts.map +1 -0
- package/dist/dream/index.js +5 -0
- package/dist/dream/index.js.map +1 -0
- package/dist/dream/schema.d.ts +3 -0
- package/dist/dream/schema.d.ts.map +1 -0
- package/dist/dream/schema.js +16 -0
- package/dist/dream/schema.js.map +1 -0
- package/dist/embeddings/index.d.ts +5 -0
- package/dist/embeddings/index.d.ts.map +1 -0
- package/dist/embeddings/index.js +3 -0
- package/dist/embeddings/index.js.map +1 -0
- package/dist/embeddings/openai-provider.d.ts +31 -0
- package/dist/embeddings/openai-provider.d.ts.map +1 -0
- package/dist/embeddings/openai-provider.js +120 -0
- package/dist/embeddings/openai-provider.js.map +1 -0
- package/dist/embeddings/pipeline.d.ts +36 -0
- package/dist/embeddings/pipeline.d.ts.map +1 -0
- package/dist/embeddings/pipeline.js +78 -0
- package/dist/embeddings/pipeline.js.map +1 -0
- package/dist/embeddings/types.d.ts +62 -0
- package/dist/embeddings/types.d.ts.map +1 -0
- package/dist/embeddings/types.js +3 -0
- package/dist/embeddings/types.js.map +1 -0
- package/dist/engine/bin/soleri-engine.js +4 -1
- package/dist/engine/bin/soleri-engine.js.map +1 -1
- package/dist/engine/module-manifest.d.ts.map +1 -1
- package/dist/engine/module-manifest.js +20 -0
- package/dist/engine/module-manifest.js.map +1 -1
- package/dist/engine/register-engine.d.ts.map +1 -1
- package/dist/engine/register-engine.js +12 -0
- package/dist/engine/register-engine.js.map +1 -1
- package/dist/flows/chain-types.d.ts +8 -8
- package/dist/flows/dispatch-registry.d.ts +15 -1
- package/dist/flows/dispatch-registry.d.ts.map +1 -1
- package/dist/flows/dispatch-registry.js +28 -1
- package/dist/flows/dispatch-registry.js.map +1 -1
- package/dist/flows/executor.d.ts +20 -2
- package/dist/flows/executor.d.ts.map +1 -1
- package/dist/flows/executor.js +79 -1
- package/dist/flows/executor.js.map +1 -1
- package/dist/flows/index.d.ts +2 -1
- package/dist/flows/index.d.ts.map +1 -1
- package/dist/flows/index.js.map +1 -1
- package/dist/flows/types.d.ts +43 -21
- package/dist/flows/types.d.ts.map +1 -1
- package/dist/index.d.ts +6 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -1
- package/dist/index.js.map +1 -1
- package/dist/persona/defaults.d.ts +8 -0
- package/dist/persona/defaults.d.ts.map +1 -1
- package/dist/persona/defaults.js +49 -0
- package/dist/persona/defaults.js.map +1 -1
- package/dist/plugins/types.d.ts +31 -31
- package/dist/runtime/admin-ops.d.ts.map +1 -1
- package/dist/runtime/admin-ops.js +15 -0
- package/dist/runtime/admin-ops.js.map +1 -1
- package/dist/runtime/admin-setup-ops.js +2 -2
- package/dist/runtime/admin-setup-ops.js.map +1 -1
- package/dist/runtime/embedding-ops.d.ts +12 -0
- package/dist/runtime/embedding-ops.d.ts.map +1 -0
- package/dist/runtime/embedding-ops.js +96 -0
- package/dist/runtime/embedding-ops.js.map +1 -0
- package/dist/runtime/facades/embedding-facade.d.ts +7 -0
- package/dist/runtime/facades/embedding-facade.d.ts.map +1 -0
- package/dist/runtime/facades/embedding-facade.js +8 -0
- package/dist/runtime/facades/embedding-facade.js.map +1 -0
- package/dist/runtime/facades/index.d.ts.map +1 -1
- package/dist/runtime/facades/index.js +12 -0
- package/dist/runtime/facades/index.js.map +1 -1
- package/dist/runtime/facades/orchestrate-facade.d.ts.map +1 -1
- package/dist/runtime/facades/orchestrate-facade.js +120 -0
- package/dist/runtime/facades/orchestrate-facade.js.map +1 -1
- package/dist/runtime/feature-flags.d.ts.map +1 -1
- package/dist/runtime/feature-flags.js +4 -0
- package/dist/runtime/feature-flags.js.map +1 -1
- package/dist/runtime/orchestrate-ops.d.ts.map +1 -1
- package/dist/runtime/orchestrate-ops.js +140 -9
- package/dist/runtime/orchestrate-ops.js.map +1 -1
- package/dist/runtime/planning-extra-ops.d.ts.map +1 -1
- package/dist/runtime/planning-extra-ops.js +51 -0
- package/dist/runtime/planning-extra-ops.js.map +1 -1
- package/dist/runtime/preflight.d.ts +32 -0
- package/dist/runtime/preflight.d.ts.map +1 -0
- package/dist/runtime/preflight.js +29 -0
- package/dist/runtime/preflight.js.map +1 -0
- package/dist/runtime/runtime.d.ts.map +1 -1
- package/dist/runtime/runtime.js +33 -2
- package/dist/runtime/runtime.js.map +1 -1
- package/dist/runtime/types.d.ts +27 -0
- package/dist/runtime/types.d.ts.map +1 -1
- package/dist/skills/step-tracker.d.ts +39 -0
- package/dist/skills/step-tracker.d.ts.map +1 -0
- package/dist/skills/step-tracker.js +105 -0
- package/dist/skills/step-tracker.js.map +1 -0
- package/dist/skills/sync-skills.d.ts +3 -2
- package/dist/skills/sync-skills.d.ts.map +1 -1
- package/dist/skills/sync-skills.js +42 -8
- package/dist/skills/sync-skills.js.map +1 -1
- package/dist/subagent/dispatcher.d.ts +4 -3
- package/dist/subagent/dispatcher.d.ts.map +1 -1
- package/dist/subagent/dispatcher.js +57 -35
- package/dist/subagent/dispatcher.js.map +1 -1
- package/dist/subagent/index.d.ts +1 -0
- package/dist/subagent/index.d.ts.map +1 -1
- package/dist/subagent/index.js.map +1 -1
- package/dist/subagent/orphan-reaper.d.ts +51 -4
- package/dist/subagent/orphan-reaper.d.ts.map +1 -1
- package/dist/subagent/orphan-reaper.js +103 -3
- package/dist/subagent/orphan-reaper.js.map +1 -1
- package/dist/subagent/types.d.ts +7 -0
- package/dist/subagent/types.d.ts.map +1 -1
- package/dist/subagent/workspace-resolver.d.ts +2 -0
- package/dist/subagent/workspace-resolver.d.ts.map +1 -1
- package/dist/subagent/workspace-resolver.js +3 -1
- package/dist/subagent/workspace-resolver.js.map +1 -1
- package/dist/vault/vault-entries.d.ts +18 -0
- package/dist/vault/vault-entries.d.ts.map +1 -1
- package/dist/vault/vault-entries.js +73 -0
- package/dist/vault/vault-entries.js.map +1 -1
- package/dist/vault/vault-manager.d.ts.map +1 -1
- package/dist/vault/vault-manager.js +1 -0
- package/dist/vault/vault-manager.js.map +1 -1
- package/dist/vault/vault-schema.d.ts.map +1 -1
- package/dist/vault/vault-schema.js +14 -0
- package/dist/vault/vault-schema.js.map +1 -1
- package/dist/vault/vault.d.ts +1 -0
- package/dist/vault/vault.d.ts.map +1 -1
- package/dist/vault/vault.js.map +1 -1
- package/package.json +3 -5
- package/src/__tests__/cron-manager.test.ts +132 -0
- package/src/__tests__/deviation-detection.test.ts +234 -0
- package/src/__tests__/embeddings.test.ts +536 -0
- package/src/__tests__/preflight.test.ts +97 -0
- package/src/__tests__/step-persistence.test.ts +324 -0
- package/src/__tests__/step-tracker.test.ts +260 -0
- package/src/__tests__/subagent/dispatcher.test.ts +122 -4
- package/src/__tests__/subagent/orphan-reaper.test.ts +148 -12
- package/src/__tests__/subagent/process-lifecycle.test.ts +422 -0
- package/src/__tests__/subagent/workspace-resolver.test.ts +6 -1
- package/src/adapters/types.ts +2 -0
- package/src/brain/brain.ts +117 -9
- package/src/dream/cron-manager.ts +137 -0
- package/src/dream/dream-engine.ts +119 -0
- package/src/dream/dream-ops.ts +56 -0
- package/src/dream/dream.test.ts +182 -0
- package/src/dream/index.ts +6 -0
- package/src/dream/schema.ts +17 -0
- package/src/embeddings/openai-provider.ts +158 -0
- package/src/embeddings/pipeline.ts +126 -0
- package/src/embeddings/types.ts +67 -0
- package/src/engine/bin/soleri-engine.ts +4 -1
- package/src/engine/module-manifest.test.ts +4 -4
- package/src/engine/module-manifest.ts +20 -0
- package/src/engine/register-engine.ts +12 -0
- package/src/flows/dispatch-registry.ts +44 -1
- package/src/flows/executor.ts +93 -2
- package/src/flows/index.ts +2 -0
- package/src/flows/types.ts +39 -1
- package/src/index.ts +12 -0
- package/src/persona/defaults.test.ts +39 -1
- package/src/persona/defaults.ts +65 -0
- package/src/planning/goal-ancestry.test.ts +3 -5
- package/src/planning/planner.test.ts +2 -3
- package/src/runtime/admin-ops.test.ts +2 -2
- package/src/runtime/admin-ops.ts +17 -0
- package/src/runtime/admin-setup-ops.ts +2 -2
- package/src/runtime/embedding-ops.ts +116 -0
- package/src/runtime/facades/admin-facade.test.ts +31 -0
- package/src/runtime/facades/embedding-facade.ts +11 -0
- package/src/runtime/facades/index.ts +12 -0
- package/src/runtime/facades/orchestrate-facade.test.ts +16 -0
- package/src/runtime/facades/orchestrate-facade.ts +146 -0
- package/src/runtime/feature-flags.ts +4 -0
- package/src/runtime/orchestrate-ops.test.ts +131 -0
- package/src/runtime/orchestrate-ops.ts +158 -10
- package/src/runtime/planning-extra-ops.ts +77 -0
- package/src/runtime/preflight.ts +53 -0
- package/src/runtime/runtime.ts +41 -2
- package/src/runtime/types.ts +20 -0
- package/src/skills/__tests__/sync-skills.test.ts +132 -0
- package/src/skills/step-tracker.ts +162 -0
- package/src/skills/sync-skills.ts +54 -9
- package/src/subagent/dispatcher.ts +62 -39
- package/src/subagent/index.ts +1 -0
- package/src/subagent/orphan-reaper.test.ts +135 -0
- package/src/subagent/orphan-reaper.ts +130 -7
- package/src/subagent/types.ts +10 -0
- package/src/subagent/workspace-resolver.ts +3 -1
- package/src/vault/vault-entries.ts +112 -0
- package/src/vault/vault-manager.ts +1 -0
- package/src/vault/vault-scaling.test.ts +3 -2
- package/src/vault/vault-schema.ts +15 -0
- package/src/vault/vault.ts +1 -0
- package/vitest.config.ts +2 -1
- package/dist/brain/strength-scorer.d.ts +0 -31
- package/dist/brain/strength-scorer.d.ts.map +0 -1
- package/dist/brain/strength-scorer.js +0 -264
- package/dist/brain/strength-scorer.js.map +0 -1
- package/dist/engine/index.d.ts +0 -21
- package/dist/engine/index.d.ts.map +0 -1
- package/dist/engine/index.js +0 -18
- package/dist/engine/index.js.map +0 -1
- package/dist/hooks/index.d.ts +0 -2
- package/dist/hooks/index.d.ts.map +0 -1
- package/dist/hooks/index.js +0 -2
- package/dist/hooks/index.js.map +0 -1
- package/dist/persona/index.d.ts +0 -5
- package/dist/persona/index.d.ts.map +0 -1
- package/dist/persona/index.js +0 -4
- package/dist/persona/index.js.map +0 -1
- package/dist/vault/vault-interfaces.d.ts +0 -153
- package/dist/vault/vault-interfaces.d.ts.map +0 -1
- package/dist/vault/vault-interfaces.js +0 -2
- package/dist/vault/vault-interfaces.js.map +0 -1
package/src/persona/defaults.ts
CHANGED
|
@@ -80,9 +80,74 @@ export const ITALIAN_CRAFTSPERSON: Omit<PersonaConfig, 'name' | 'history'> = {
|
|
|
80
80
|
],
|
|
81
81
|
};
|
|
82
82
|
|
|
83
|
+
/**
|
|
84
|
+
* Neutral Custom — a rich, editable persona with no cultural flavor.
|
|
85
|
+
*
|
|
86
|
+
* Every field is populated so the user sees the full structure in agent.yaml
|
|
87
|
+
* and can customize it by hand or ask their agent to refine it.
|
|
88
|
+
* Intentionally generic — this is a starting point, not a character.
|
|
89
|
+
*/
|
|
90
|
+
export const NEUTRAL_PERSONA: Omit<PersonaConfig, 'name' | 'history'> = {
|
|
91
|
+
template: 'neutral-custom',
|
|
92
|
+
|
|
93
|
+
inspiration:
|
|
94
|
+
'A reliable professional — clear communication, strong opinions loosely held, focused on outcomes.',
|
|
95
|
+
|
|
96
|
+
culture: '',
|
|
97
|
+
|
|
98
|
+
metaphors: ['tools', 'building', 'systems', 'patterns', 'craft'],
|
|
99
|
+
|
|
100
|
+
voice:
|
|
101
|
+
'A helpful assistant — clear, direct, and adaptable to your style. Professional without being stiff, friendly without being casual.',
|
|
102
|
+
|
|
103
|
+
traits: [
|
|
104
|
+
'helpful — puts your goals first',
|
|
105
|
+
'precise — says what it means, no filler',
|
|
106
|
+
'patient — explains as many times as needed',
|
|
107
|
+
'pragmatic — favors working solutions over perfect ones',
|
|
108
|
+
'curious — asks clarifying questions instead of guessing',
|
|
109
|
+
'honest — flags uncertainty rather than bluffing',
|
|
110
|
+
],
|
|
111
|
+
|
|
112
|
+
quirks: [
|
|
113
|
+
'Summarizes next steps at the end of complex answers',
|
|
114
|
+
'Asks "does that match what you had in mind?" after proposing something non-obvious',
|
|
115
|
+
'Uses numbered lists for multi-step instructions',
|
|
116
|
+
'Calls out assumptions explicitly — "I\'m assuming X, correct me if not"',
|
|
117
|
+
],
|
|
118
|
+
|
|
119
|
+
opinions: [
|
|
120
|
+
'Working software beats perfect plans — ship, then iterate',
|
|
121
|
+
'Naming things well is half the battle',
|
|
122
|
+
'If you have to explain it twice, it needs a better abstraction',
|
|
123
|
+
'Tests are documentation that runs — write them first when it matters',
|
|
124
|
+
'Complexity is a cost, simplicity is a feature',
|
|
125
|
+
'Good defaults beat extensive configuration',
|
|
126
|
+
],
|
|
127
|
+
|
|
128
|
+
languageRule:
|
|
129
|
+
"Match the user's language and formality level. No slang unless the user uses it first. No jargon unless the context calls for it.",
|
|
130
|
+
|
|
131
|
+
nameRule:
|
|
132
|
+
'Adapt to name changes naturally. The personality stays the same regardless of what name is chosen.',
|
|
133
|
+
|
|
134
|
+
greetings: [
|
|
135
|
+
'Hello! What are we working on?',
|
|
136
|
+
"Ready when you are. What's the task?",
|
|
137
|
+
'Good to see you. What do you need?',
|
|
138
|
+
],
|
|
139
|
+
|
|
140
|
+
signoffs: [
|
|
141
|
+
'Let me know if anything else comes up.',
|
|
142
|
+
"Good progress. Pick it up whenever you're ready.",
|
|
143
|
+
'That should do it. See you next time.',
|
|
144
|
+
],
|
|
145
|
+
};
|
|
146
|
+
|
|
83
147
|
/** Template registry — extensible for future built-in personas */
|
|
84
148
|
export const PERSONA_TEMPLATES: Record<string, Omit<PersonaConfig, 'name' | 'history'>> = {
|
|
85
149
|
'italian-craftsperson': ITALIAN_CRAFTSPERSON,
|
|
150
|
+
'neutral-custom': NEUTRAL_PERSONA,
|
|
86
151
|
};
|
|
87
152
|
|
|
88
153
|
/**
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
|
2
|
-
import {
|
|
2
|
+
import { mkdtempSync, rmSync } from 'node:fs';
|
|
3
3
|
import { join } from 'node:path';
|
|
4
4
|
import { tmpdir } from 'node:os';
|
|
5
5
|
import { GoalAncestry, JsonGoalRepository, generateGoalId } from './goal-ancestry.js';
|
|
@@ -278,8 +278,7 @@ describe('JsonGoalRepository', () => {
|
|
|
278
278
|
let repo: JsonGoalRepository;
|
|
279
279
|
|
|
280
280
|
beforeEach(() => {
|
|
281
|
-
tempDir = join(tmpdir(),
|
|
282
|
-
mkdirSync(tempDir, { recursive: true });
|
|
281
|
+
tempDir = mkdtempSync(join(tmpdir(), 'goal-repo-test-'));
|
|
283
282
|
repo = new JsonGoalRepository(join(tempDir, 'goals.json'));
|
|
284
283
|
});
|
|
285
284
|
|
|
@@ -347,8 +346,7 @@ describe('Planner goalId integration', () => {
|
|
|
347
346
|
let planner: Planner;
|
|
348
347
|
|
|
349
348
|
beforeEach(() => {
|
|
350
|
-
tempDir = join(tmpdir(),
|
|
351
|
-
mkdirSync(tempDir, { recursive: true });
|
|
349
|
+
tempDir = mkdtempSync(join(tmpdir(), 'planner-goal-test-'));
|
|
352
350
|
planner = new Planner(join(tempDir, 'plans.json'));
|
|
353
351
|
});
|
|
354
352
|
|
|
@@ -3,7 +3,7 @@ import { Planner, PlanGradeRejectionError } from './planner.js';
|
|
|
3
3
|
import type { PlanGap } from './gap-types.js';
|
|
4
4
|
import type { PlanAlternative } from './planner.js';
|
|
5
5
|
import { generateGapId } from './gap-types.js';
|
|
6
|
-
import {
|
|
6
|
+
import { mkdtempSync, rmSync } from 'node:fs';
|
|
7
7
|
import { join } from 'node:path';
|
|
8
8
|
import { tmpdir } from 'node:os';
|
|
9
9
|
|
|
@@ -28,8 +28,7 @@ describe('Planner', () => {
|
|
|
28
28
|
let planner: Planner;
|
|
29
29
|
|
|
30
30
|
beforeEach(() => {
|
|
31
|
-
tempDir = join(tmpdir(),
|
|
32
|
-
mkdirSync(tempDir, { recursive: true });
|
|
31
|
+
tempDir = mkdtempSync(join(tmpdir(), 'planner-test-'));
|
|
33
32
|
planner = new Planner(join(tempDir, 'plans.json'));
|
|
34
33
|
});
|
|
35
34
|
|
|
@@ -70,8 +70,8 @@ describe('createAdminOps', () => {
|
|
|
70
70
|
ops = createAdminOps(rt);
|
|
71
71
|
});
|
|
72
72
|
|
|
73
|
-
it('returns
|
|
74
|
-
expect(ops.length).
|
|
73
|
+
it('returns ops array', () => {
|
|
74
|
+
expect(ops.length).toBeGreaterThan(0);
|
|
75
75
|
});
|
|
76
76
|
|
|
77
77
|
// ─── admin_health ─────────────────────────────────────────────
|
package/src/runtime/admin-ops.ts
CHANGED
|
@@ -277,6 +277,23 @@ export function createAdminOps(runtime: AgentRuntime): OpDefinition[] {
|
|
|
277
277
|
},
|
|
278
278
|
},
|
|
279
279
|
|
|
280
|
+
// ─── Subagent Orphan Reaping ────────────────────────────────────
|
|
281
|
+
{
|
|
282
|
+
name: 'admin_reap_orphans',
|
|
283
|
+
description:
|
|
284
|
+
'Detect and clean up orphaned subagent processes. Returns reaped PIDs and task IDs.',
|
|
285
|
+
auth: 'admin',
|
|
286
|
+
handler: async () => {
|
|
287
|
+
const dispatcher = runtime.subagentDispatcher;
|
|
288
|
+
const results = dispatcher.reapOrphans();
|
|
289
|
+
return {
|
|
290
|
+
reaped: results.reaped.length,
|
|
291
|
+
tasks: results.reaped,
|
|
292
|
+
alive: results.alive,
|
|
293
|
+
};
|
|
294
|
+
},
|
|
295
|
+
},
|
|
296
|
+
|
|
280
297
|
// ─── Diagnostics ─────────────────────────────────────────────────
|
|
281
298
|
{
|
|
282
299
|
name: 'admin_diagnostic',
|
|
@@ -352,7 +352,7 @@ export function createAdminSetupOps(runtime: AgentRuntime): OpDefinition[] {
|
|
|
352
352
|
{
|
|
353
353
|
name: 'admin_setup_global',
|
|
354
354
|
description:
|
|
355
|
-
'Install global agent configuration — hookify rules to ~/.claude/, skills to ~/.claude/
|
|
355
|
+
'Install global agent configuration — hookify rules to ~/.claude/, skills to ~/.claude/skills/, lifecycle hooks to settings.json. Dry-run by default.',
|
|
356
356
|
auth: 'admin',
|
|
357
357
|
schema: z.object({
|
|
358
358
|
install: z.boolean().describe('Set true to install, false for dry-run preview'),
|
|
@@ -370,7 +370,7 @@ export function createAdminSetupOps(runtime: AgentRuntime): OpDefinition[] {
|
|
|
370
370
|
.boolean()
|
|
371
371
|
.optional()
|
|
372
372
|
.default(false)
|
|
373
|
-
.describe('Only install skills to ~/.claude/
|
|
373
|
+
.describe('Only install skills to ~/.claude/skills/'),
|
|
374
374
|
}),
|
|
375
375
|
handler: async (params) => {
|
|
376
376
|
const install = params.install as boolean;
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Embedding Ops — embed_status, embed_rebuild, embed_entry.
|
|
3
|
+
*
|
|
4
|
+
* Covers:
|
|
5
|
+
* - Embedding statistics and health
|
|
6
|
+
* - Batch rebuild of missing vectors
|
|
7
|
+
* - Single-entry embedding
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { z } from 'zod';
|
|
11
|
+
import type { OpDefinition } from '../facades/types.js';
|
|
12
|
+
import type { AgentRuntime } from './types.js';
|
|
13
|
+
import { getEntriesWithoutVectors } from '../vault/vault-entries.js';
|
|
14
|
+
|
|
15
|
+
export function createEmbeddingOps(runtime: AgentRuntime): OpDefinition[] {
|
|
16
|
+
const { vault, flags, embeddingProvider, embeddingPipeline } = runtime;
|
|
17
|
+
|
|
18
|
+
return [
|
|
19
|
+
{
|
|
20
|
+
name: 'embed_status',
|
|
21
|
+
description:
|
|
22
|
+
'Get embedding subsystem status — provider info, vector counts, token usage. Returns { enabled: false } when embeddings are not configured.',
|
|
23
|
+
auth: 'read' as const,
|
|
24
|
+
handler: async () => {
|
|
25
|
+
if (!embeddingProvider || !flags.isEnabled('embedding-enabled')) {
|
|
26
|
+
return {
|
|
27
|
+
enabled: false,
|
|
28
|
+
reason: !flags.isEnabled('embedding-enabled')
|
|
29
|
+
? 'feature flag embedding-enabled is off'
|
|
30
|
+
: 'no embedding config',
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const persistence = vault.getProvider();
|
|
35
|
+
const model = embeddingProvider.model;
|
|
36
|
+
const missingIds = getEntriesWithoutVectors(persistence, model);
|
|
37
|
+
|
|
38
|
+
const embeddedRow = persistence.get<{ count: number }>(
|
|
39
|
+
'SELECT COUNT(*) as count FROM entry_vectors WHERE model = ?',
|
|
40
|
+
[model],
|
|
41
|
+
);
|
|
42
|
+
const totalEmbedded = embeddedRow?.count ?? 0;
|
|
43
|
+
|
|
44
|
+
const tokensRow = persistence.get<{ total: number }>(
|
|
45
|
+
`SELECT COALESCE(SUM(1), 0) as total FROM entry_vectors`,
|
|
46
|
+
[],
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
return {
|
|
50
|
+
enabled: true,
|
|
51
|
+
provider: embeddingProvider.providerName,
|
|
52
|
+
model: embeddingProvider.model,
|
|
53
|
+
dimensions: embeddingProvider.dimensions,
|
|
54
|
+
totalEmbedded,
|
|
55
|
+
totalMissing: missingIds.length,
|
|
56
|
+
// Token tracking is per-call in pipeline — we report what we can from the DB
|
|
57
|
+
totalTokensUsed: tokensRow?.total ?? 0,
|
|
58
|
+
};
|
|
59
|
+
},
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
name: 'embed_rebuild',
|
|
63
|
+
description:
|
|
64
|
+
'Trigger batch embedding of all vault entries missing vectors. Returns counts of embedded, skipped, failed entries and tokens used.',
|
|
65
|
+
auth: 'write' as const,
|
|
66
|
+
handler: async () => {
|
|
67
|
+
if (!embeddingPipeline || !flags.isEnabled('embedding-enabled')) {
|
|
68
|
+
return {
|
|
69
|
+
enabled: false,
|
|
70
|
+
reason: !flags.isEnabled('embedding-enabled')
|
|
71
|
+
? 'feature flag embedding-enabled is off'
|
|
72
|
+
: 'no embedding pipeline configured',
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const result = await embeddingPipeline.batchEmbed();
|
|
77
|
+
return {
|
|
78
|
+
enabled: true,
|
|
79
|
+
embedded: result.embedded,
|
|
80
|
+
skipped: result.skipped,
|
|
81
|
+
failed: result.failed,
|
|
82
|
+
tokensUsed: result.tokensUsed,
|
|
83
|
+
};
|
|
84
|
+
},
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
name: 'embed_entry',
|
|
88
|
+
description:
|
|
89
|
+
'Embed a single vault entry by ID. Returns { embedded: true } if a new vector was created, { embedded: false } if already up to date.',
|
|
90
|
+
auth: 'write' as const,
|
|
91
|
+
schema: z.object({
|
|
92
|
+
entryId: z.string().describe('Vault entry ID to embed'),
|
|
93
|
+
}),
|
|
94
|
+
handler: async (params) => {
|
|
95
|
+
if (!embeddingPipeline || !flags.isEnabled('embedding-enabled')) {
|
|
96
|
+
return {
|
|
97
|
+
enabled: false,
|
|
98
|
+
reason: !flags.isEnabled('embedding-enabled')
|
|
99
|
+
? 'feature flag embedding-enabled is off'
|
|
100
|
+
: 'no embedding pipeline configured',
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
const entryId = params.entryId as string;
|
|
105
|
+
const entry = vault.get(entryId);
|
|
106
|
+
if (!entry) {
|
|
107
|
+
return { embedded: false, error: `Entry "${entryId}" not found` };
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
const text = [entry.title, entry.description, entry.context].filter(Boolean).join('\n');
|
|
111
|
+
const embedded = await embeddingPipeline.embedEntry(entryId, text);
|
|
112
|
+
return { embedded };
|
|
113
|
+
},
|
|
114
|
+
},
|
|
115
|
+
];
|
|
116
|
+
}
|
|
@@ -85,6 +85,9 @@ function mockRuntime(): AgentRuntime {
|
|
|
85
85
|
get: vi.fn(),
|
|
86
86
|
},
|
|
87
87
|
packInstaller: { list: vi.fn(() => []) },
|
|
88
|
+
subagentDispatcher: {
|
|
89
|
+
reapOrphans: vi.fn().mockReturnValue({ reaped: [], alive: [] }),
|
|
90
|
+
},
|
|
88
91
|
createdAt: Date.now() - 60000,
|
|
89
92
|
persona: { name: 'TestAgent' },
|
|
90
93
|
} as unknown as AgentRuntime;
|
|
@@ -327,4 +330,32 @@ describe('createAdminFacadeOps', () => {
|
|
|
327
330
|
expect(result).toEqual({});
|
|
328
331
|
});
|
|
329
332
|
});
|
|
333
|
+
|
|
334
|
+
describe('admin_reap_orphans (from satellite)', () => {
|
|
335
|
+
it('returns empty when no orphans', async () => {
|
|
336
|
+
const result = (await findOp(ops, 'admin_reap_orphans').handler({})) as Record<
|
|
337
|
+
string,
|
|
338
|
+
unknown
|
|
339
|
+
>;
|
|
340
|
+
expect(result.reaped).toBe(0);
|
|
341
|
+
expect(result.tasks).toEqual([]);
|
|
342
|
+
expect(result.alive).toEqual([]);
|
|
343
|
+
});
|
|
344
|
+
|
|
345
|
+
it('returns reaped orphans', async () => {
|
|
346
|
+
vi.mocked(runtime.subagentDispatcher.reapOrphans).mockReturnValue({
|
|
347
|
+
reaped: ['task-1', 'task-2'],
|
|
348
|
+
alive: ['task-3'],
|
|
349
|
+
});
|
|
350
|
+
ops = createAdminFacadeOps(runtime);
|
|
351
|
+
|
|
352
|
+
const result = (await findOp(ops, 'admin_reap_orphans').handler({})) as Record<
|
|
353
|
+
string,
|
|
354
|
+
unknown
|
|
355
|
+
>;
|
|
356
|
+
expect(result.reaped).toBe(2);
|
|
357
|
+
expect(result.tasks).toEqual(['task-1', 'task-2']);
|
|
358
|
+
expect(result.alive).toEqual(['task-3']);
|
|
359
|
+
});
|
|
360
|
+
});
|
|
330
361
|
});
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Embedding facade — vector embedding management ops.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import type { OpDefinition } from '../../facades/types.js';
|
|
6
|
+
import type { AgentRuntime } from '../types.js';
|
|
7
|
+
import { createEmbeddingOps } from '../embedding-ops.js';
|
|
8
|
+
|
|
9
|
+
export function createEmbeddingFacadeOps(runtime: AgentRuntime): OpDefinition[] {
|
|
10
|
+
return [...createEmbeddingOps(runtime)];
|
|
11
|
+
}
|
|
@@ -27,6 +27,8 @@ import { createIntakeFacadeOps } from './intake-facade.js';
|
|
|
27
27
|
import { createLinksFacadeOps } from './links-facade.js';
|
|
28
28
|
import { createBranchingFacadeOps } from './branching-facade.js';
|
|
29
29
|
import { createTierFacadeOps } from './tier-facade.js';
|
|
30
|
+
import { createEmbeddingFacadeOps } from './embedding-facade.js';
|
|
31
|
+
import { createDreamOps } from '../../dream/dream-ops.js';
|
|
30
32
|
|
|
31
33
|
export function createSemanticFacades(runtime: AgentRuntime, agentId: string): FacadeConfig[] {
|
|
32
34
|
const facades: FacadeConfig[] = [
|
|
@@ -128,11 +130,21 @@ export function createSemanticFacades(runtime: AgentRuntime, agentId: string): F
|
|
|
128
130
|
description: 'Vault branching — create, list, merge, delete branches.',
|
|
129
131
|
ops: createBranchingFacadeOps(runtime),
|
|
130
132
|
},
|
|
133
|
+
{
|
|
134
|
+
name: `${agentId}_embedding`,
|
|
135
|
+
description: 'Embedding management — status, batch rebuild, single-entry embedding.',
|
|
136
|
+
ops: createEmbeddingFacadeOps(runtime),
|
|
137
|
+
},
|
|
131
138
|
{
|
|
132
139
|
name: `${agentId}_tier`,
|
|
133
140
|
description: 'Multi-vault tiers — connect, disconnect, search across sources.',
|
|
134
141
|
ops: createTierFacadeOps(runtime),
|
|
135
142
|
},
|
|
143
|
+
{
|
|
144
|
+
name: `${agentId}_dream`,
|
|
145
|
+
description: 'Dream — automatic memory consolidation, vault cleanup, and maintenance.',
|
|
146
|
+
ops: createDreamOps(runtime),
|
|
147
|
+
},
|
|
136
148
|
];
|
|
137
149
|
|
|
138
150
|
return facades;
|
|
@@ -95,6 +95,22 @@ describe('orchestrate-facade', () => {
|
|
|
95
95
|
expect(data.governance).toBeDefined();
|
|
96
96
|
});
|
|
97
97
|
|
|
98
|
+
it('session_start includes preflight manifest', async () => {
|
|
99
|
+
const result = await executeOp(ops, 'session_start', { projectPath: '/test/proj' });
|
|
100
|
+
expect(result.success).toBe(true);
|
|
101
|
+
const data = result.data as Record<string, unknown>;
|
|
102
|
+
const preflight = data.preflight as Record<string, unknown>;
|
|
103
|
+
expect(preflight).toBeDefined();
|
|
104
|
+
expect(Array.isArray(preflight.tools)).toBe(true);
|
|
105
|
+
expect(Array.isArray(preflight.skills)).toBe(true);
|
|
106
|
+
expect(Array.isArray(preflight.activePlans)).toBe(true);
|
|
107
|
+
expect(preflight.vaultSummary).toBeDefined();
|
|
108
|
+
const vaultSummary = preflight.vaultSummary as Record<string, unknown>;
|
|
109
|
+
expect(typeof vaultSummary.entryCount).toBe('number');
|
|
110
|
+
expect(typeof vaultSummary.connected).toBe('boolean');
|
|
111
|
+
expect(Array.isArray(vaultSummary.domains)).toBe(true);
|
|
112
|
+
});
|
|
113
|
+
|
|
98
114
|
it('session_start increments session count on second call', async () => {
|
|
99
115
|
await executeOp(ops, 'session_start', { projectPath: '/test/proj' });
|
|
100
116
|
const result = await executeOp(ops, 'session_start', { projectPath: '/test/proj' });
|
|
@@ -10,6 +10,18 @@ import { createOrchestrateOps } from '../orchestrate-ops.js';
|
|
|
10
10
|
import { createProjectOps } from '../project-ops.js';
|
|
11
11
|
import { createPlaybookOps } from '../playbook-ops.js';
|
|
12
12
|
import { checkForUpdate } from '../../update-check.js';
|
|
13
|
+
import { buildPreflightManifest } from '../preflight.js';
|
|
14
|
+
import { ENGINE_MODULE_MANIFEST } from '../../engine/module-manifest.js';
|
|
15
|
+
import {
|
|
16
|
+
createTracker,
|
|
17
|
+
advanceStep,
|
|
18
|
+
recordEvidence,
|
|
19
|
+
generateCheckpoint,
|
|
20
|
+
validateCompletion,
|
|
21
|
+
persistTracker,
|
|
22
|
+
loadTracker,
|
|
23
|
+
} from '../../skills/step-tracker.js';
|
|
24
|
+
import type { SkillStep, EvidenceType } from '../../skills/step-tracker.js';
|
|
13
25
|
|
|
14
26
|
export function createOrchestrateFacadeOps(runtime: AgentRuntime): OpDefinition[] {
|
|
15
27
|
const { vault, governance, projectRegistry } = runtime;
|
|
@@ -85,6 +97,59 @@ export function createOrchestrateFacadeOps(runtime: AgentRuntime): OpDefinition[
|
|
|
85
97
|
// package.json not readable — skip update check silently
|
|
86
98
|
}
|
|
87
99
|
|
|
100
|
+
// Auto-dream: increment session counter and check gate
|
|
101
|
+
let dreamInfo: { status: unknown; gate: { eligible: boolean; reason: string } } | null =
|
|
102
|
+
null;
|
|
103
|
+
try {
|
|
104
|
+
const { ensureDreamSchema } = await import('../../dream/schema.js');
|
|
105
|
+
const { DreamEngine } = await import('../../dream/dream-engine.js');
|
|
106
|
+
ensureDreamSchema(runtime.vault.getProvider());
|
|
107
|
+
const dreamEngine = new DreamEngine(runtime.vault, runtime.curator);
|
|
108
|
+
dreamEngine.incrementSessionCount();
|
|
109
|
+
const gate = dreamEngine.checkGate();
|
|
110
|
+
dreamInfo = { status: dreamEngine.getStatus(), gate };
|
|
111
|
+
if (gate.eligible) {
|
|
112
|
+
// Fire-and-forget: don't block session_start
|
|
113
|
+
Promise.resolve()
|
|
114
|
+
.then(() => dreamEngine.run())
|
|
115
|
+
.catch(() => {
|
|
116
|
+
/* best-effort */
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
} catch {
|
|
120
|
+
/* dream module not available — skip silently */
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// ─── Pre-flight manifest ───────────────────────────────
|
|
124
|
+
let skills: string[] = [];
|
|
125
|
+
try {
|
|
126
|
+
const { discoverSkills } = await import('../../skills/sync-skills.js');
|
|
127
|
+
const agentDir = runtime.config.agentDir;
|
|
128
|
+
const skillsDirs = agentDir ? [join(agentDir, 'skills')] : [];
|
|
129
|
+
skills = discoverSkills(skillsDirs).map((s) => s.name);
|
|
130
|
+
} catch {
|
|
131
|
+
// Skills discovery is best-effort
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
const agentId = runtime.config.agentId;
|
|
135
|
+
const facades = ENGINE_MODULE_MANIFEST.map((m) => ({
|
|
136
|
+
name: `${agentId}_${m.suffix}`,
|
|
137
|
+
ops: m.keyOps.map((op) => ({ name: op, description: m.description })),
|
|
138
|
+
}));
|
|
139
|
+
|
|
140
|
+
const executingPlans = runtime.planner.getExecuting().map((p) => ({
|
|
141
|
+
id: p.id,
|
|
142
|
+
objective: p.objective,
|
|
143
|
+
status: p.status,
|
|
144
|
+
}));
|
|
145
|
+
|
|
146
|
+
const preflight = buildPreflightManifest({
|
|
147
|
+
facades,
|
|
148
|
+
skills,
|
|
149
|
+
executingPlans,
|
|
150
|
+
vaultStats: stats,
|
|
151
|
+
});
|
|
152
|
+
|
|
88
153
|
return {
|
|
89
154
|
project,
|
|
90
155
|
is_new: isNew,
|
|
@@ -101,11 +166,92 @@ export function createOrchestrateFacadeOps(runtime: AgentRuntime): OpDefinition[
|
|
|
101
166
|
isQuotaWarning: quotaStatus.isWarning,
|
|
102
167
|
expiredThisSession: expired,
|
|
103
168
|
},
|
|
169
|
+
preflight,
|
|
104
170
|
...(stagingWarning ? { stagingWarning } : {}),
|
|
171
|
+
...(dreamInfo ? { dream: dreamInfo } : {}),
|
|
105
172
|
};
|
|
106
173
|
},
|
|
107
174
|
},
|
|
108
175
|
|
|
176
|
+
// ─── Skill Step Tracking ──────────────────────────────────────
|
|
177
|
+
{
|
|
178
|
+
name: 'skill_step_start',
|
|
179
|
+
description:
|
|
180
|
+
'Create a skill step tracker. Persists initial state to disk and returns the tracker with checkpoint summary.',
|
|
181
|
+
auth: 'write',
|
|
182
|
+
schema: z.object({
|
|
183
|
+
skillName: z.string().describe('Name of the skill being tracked'),
|
|
184
|
+
steps: z
|
|
185
|
+
.array(
|
|
186
|
+
z.object({
|
|
187
|
+
id: z.string(),
|
|
188
|
+
description: z.string(),
|
|
189
|
+
evidence: z.enum(['tool_called', 'file_exists']),
|
|
190
|
+
}),
|
|
191
|
+
)
|
|
192
|
+
.describe('Ordered steps with evidence requirements'),
|
|
193
|
+
}),
|
|
194
|
+
handler: async (params) => {
|
|
195
|
+
const steps = (
|
|
196
|
+
params.steps as Array<{ id: string; description: string; evidence: EvidenceType }>
|
|
197
|
+
).map((s): SkillStep => ({ id: s.id, description: s.description, evidence: s.evidence }));
|
|
198
|
+
const tracker = createTracker(params.skillName as string, steps);
|
|
199
|
+
const filePath = persistTracker(tracker);
|
|
200
|
+
const checkpoint = generateCheckpoint(tracker);
|
|
201
|
+
return { tracker, filePath, checkpoint };
|
|
202
|
+
},
|
|
203
|
+
},
|
|
204
|
+
{
|
|
205
|
+
name: 'skill_step_advance',
|
|
206
|
+
description:
|
|
207
|
+
'Record evidence for the current step, advance to the next step, persist state, and return checkpoint summary.',
|
|
208
|
+
auth: 'write',
|
|
209
|
+
schema: z.object({
|
|
210
|
+
runId: z.string().describe('Run ID returned by skill_step_start'),
|
|
211
|
+
stepId: z.string().describe('Step ID to record evidence for'),
|
|
212
|
+
evidence: z.string().describe('Evidence value (tool name or file path)'),
|
|
213
|
+
verified: z.boolean().optional().default(true).describe('Whether evidence is verified'),
|
|
214
|
+
}),
|
|
215
|
+
handler: async (params) => {
|
|
216
|
+
let tracker = loadTracker(params.runId as string);
|
|
217
|
+
if (!tracker) {
|
|
218
|
+
return { error: `No tracker found for runId: ${params.runId}` };
|
|
219
|
+
}
|
|
220
|
+
tracker = recordEvidence(
|
|
221
|
+
tracker,
|
|
222
|
+
params.stepId as string,
|
|
223
|
+
params.evidence as string,
|
|
224
|
+
(params.verified as boolean) ?? true,
|
|
225
|
+
);
|
|
226
|
+
tracker = advanceStep(tracker);
|
|
227
|
+
const filePath = persistTracker(tracker);
|
|
228
|
+
const checkpoint = generateCheckpoint(tracker);
|
|
229
|
+
return { tracker, filePath, checkpoint };
|
|
230
|
+
},
|
|
231
|
+
},
|
|
232
|
+
{
|
|
233
|
+
name: 'skill_step_complete',
|
|
234
|
+
description:
|
|
235
|
+
'Validate skill completion, persist final state, and return a completion result with any skipped steps.',
|
|
236
|
+
auth: 'write',
|
|
237
|
+
schema: z.object({
|
|
238
|
+
runId: z.string().describe('Run ID returned by skill_step_start'),
|
|
239
|
+
}),
|
|
240
|
+
handler: async (params) => {
|
|
241
|
+
const tracker = loadTracker(params.runId as string);
|
|
242
|
+
if (!tracker) {
|
|
243
|
+
return { error: `No tracker found for runId: ${params.runId}` };
|
|
244
|
+
}
|
|
245
|
+
const result = validateCompletion(tracker);
|
|
246
|
+
// Mark completed if all steps have evidence
|
|
247
|
+
const finalTracker = result.complete
|
|
248
|
+
? { ...tracker, completedAt: tracker.completedAt ?? new Date().toISOString() }
|
|
249
|
+
: tracker;
|
|
250
|
+
const filePath = persistTracker(finalTracker);
|
|
251
|
+
return { result, tracker: finalTracker, filePath };
|
|
252
|
+
},
|
|
253
|
+
},
|
|
254
|
+
|
|
109
255
|
// ─── Satellite ops ───────────────────────────────────────────
|
|
110
256
|
...createOrchestrateOps(runtime),
|
|
111
257
|
...createProjectOps(runtime),
|
|
@@ -23,6 +23,10 @@ const BUILT_IN_FLAGS: Record<string, FlagDefinition> = {
|
|
|
23
23
|
description: 'Sync vault entries to Cognee knowledge graph',
|
|
24
24
|
defaultValue: true,
|
|
25
25
|
},
|
|
26
|
+
'embedding-enabled': {
|
|
27
|
+
description: 'Enable vector embedding provider for hybrid search',
|
|
28
|
+
defaultValue: false,
|
|
29
|
+
},
|
|
26
30
|
};
|
|
27
31
|
|
|
28
32
|
export class FeatureFlags {
|