@voybio/ace-swarm 2.4.8 → 2.4.10
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/CHANGELOG.md +52 -14
- package/README.md +14 -10
- package/assets/.agents/ACE/ACE_coders/AGENTS.md +23 -30
- package/assets/.agents/ACE/ACE_coders/INSTRUCTIONS.md +21 -30
- package/assets/.agents/skills/landing-review-watcher/SKILL.md +1 -1
- package/assets/.agents/skills/learn-from-work/SKILL.md +41 -0
- package/assets/agent-state/ACE_WORKFLOW.md +25 -2
- package/assets/agent-state/MODULES/schemas/ACE_RUNTIME_PROFILE.schema.json +143 -2
- package/assets/agent-state/MODULES/schemas/RUNTIME_EXECUTOR_SESSION_REGISTRY.schema.json +2 -2
- package/assets/agent-state/MODULES/schemas/SWARM_HANDOFF.schema.json +10 -0
- package/assets/eval-battery/battery.json +1 -1
- package/assets/instructions/ACE_Coder.instructions.md +9 -13
- package/assets/scripts/ace-hook-dispatch.mjs +16 -411
- package/assets/tasks/SWARM_HANDOFF.example_ui_to_coders.json +1 -2
- package/assets/vendor/README.md +9 -0
- package/assets/vendor/vericify-reader.mjs +272 -0
- package/assets/vendor/vericify-reader.provenance.json +10 -0
- package/dist/ace-autonomy.d.ts +58 -0
- package/dist/ace-autonomy.js +211 -6
- package/dist/ace-internal-tools.d.ts +1 -0
- package/dist/ace-internal-tools.js +3 -3
- package/dist/ace-server-instructions.d.ts +3 -3
- package/dist/ace-server-instructions.js +46 -192
- package/dist/cli.js +44 -6
- package/dist/experience-reflector.d.ts +7 -0
- package/dist/experience-reflector.js +39 -0
- package/dist/goal-engine.d.ts +64 -7
- package/dist/goal-engine.js +197 -41
- package/dist/handoff-registry.d.ts +10 -0
- package/dist/handoff-registry.js +59 -0
- package/dist/helpers/artifacts.d.ts +6 -2
- package/dist/helpers/artifacts.js +8 -6
- package/dist/helpers/bootstrap.js +13 -20
- package/dist/helpers/path-utils.js +2 -0
- package/dist/helpers/store-resolution.js +18 -3
- package/dist/helpers/workspace-root.d.ts +2 -0
- package/dist/helpers/workspace-root.js +9 -0
- package/dist/helpers.d.ts +1 -0
- package/dist/helpers.js +1 -0
- package/dist/hermes/bridge-protocol.d.ts +1 -1
- package/dist/hermes/session-manager.d.ts +17 -0
- package/dist/hermes/session-manager.js +67 -14
- package/dist/host-goal-engine.d.ts +138 -0
- package/dist/host-goal-engine.js +793 -0
- package/dist/host-goal-status.d.ts +113 -0
- package/dist/host-goal-status.js +175 -0
- package/dist/host-learning.d.ts +68 -0
- package/dist/host-learning.js +115 -0
- package/dist/host-observation.d.ts +12 -0
- package/dist/host-observation.js +91 -0
- package/dist/host-plan-revision.d.ts +14 -0
- package/dist/host-plan-revision.js +101 -0
- package/dist/host-verification-job.d.ts +12 -0
- package/dist/host-verification-job.js +183 -0
- package/dist/host-work-context.d.ts +12 -0
- package/dist/host-work-context.js +8 -0
- package/dist/job-scheduler.d.ts +58 -13
- package/dist/job-scheduler.js +298 -48
- package/dist/job-worker.d.ts +3 -1
- package/dist/job-worker.js +10 -3
- package/dist/kanban.d.ts +4 -1
- package/dist/kanban.js +44 -16
- package/dist/learned-artifacts.d.ts +64 -0
- package/dist/learned-artifacts.js +321 -0
- package/dist/learning-controls.d.ts +142 -0
- package/dist/learning-controls.js +135 -0
- package/dist/learning-input-context.d.ts +9 -0
- package/dist/learning-input-context.js +62 -0
- package/dist/learning-lifecycle.d.ts +10 -0
- package/dist/learning-lifecycle.js +11 -0
- package/dist/learning-overlays.d.ts +3 -0
- package/dist/learning-overlays.js +17 -0
- package/dist/learning-policy.d.ts +40 -0
- package/dist/learning-policy.js +38 -0
- package/dist/learning-records.d.ts +35 -0
- package/dist/learning-records.js +17 -0
- package/dist/learning-scorecard.d.ts +82 -0
- package/dist/learning-scorecard.js +86 -0
- package/dist/learning-serving.d.ts +29 -0
- package/dist/learning-serving.js +134 -0
- package/dist/linked-work.d.ts +9 -0
- package/dist/linked-work.js +28 -0
- package/dist/local-model-runtime.js +1 -1
- package/dist/mcp-command-progress.d.ts +16 -0
- package/dist/mcp-command-progress.js +70 -0
- package/dist/model-bridge.d.ts +14 -13
- package/dist/model-bridge.js +73 -41
- package/dist/orchestrator-supervisor.d.ts +111 -6
- package/dist/orchestrator-supervisor.js +67 -43
- package/dist/plan-proposal.js +3 -3
- package/dist/playbook-curator.d.ts +1 -0
- package/dist/playbook-curator.js +11 -9
- package/dist/process-identity.d.ts +8 -0
- package/dist/process-identity.js +38 -0
- package/dist/progress-command.d.ts +34 -0
- package/dist/progress-command.js +153 -0
- package/dist/prompts.js +15 -15
- package/dist/resources.js +2 -2
- package/dist/runtime-command.d.ts +8 -1
- package/dist/runtime-command.js +48 -7
- package/dist/runtime-executor.js +33 -11
- package/dist/runtime-profile-syntax.d.ts +6 -0
- package/dist/runtime-profile-syntax.js +121 -0
- package/dist/runtime-profile.d.ts +37 -5
- package/dist/runtime-profile.js +36 -129
- package/dist/runtime-tool-specs.js +1 -1
- package/dist/safe-edit.d.ts +7 -3
- package/dist/safe-edit.js +40 -47
- package/dist/schemas.js +4 -2
- package/dist/server.d.ts +2 -16
- package/dist/server.js +14 -20
- package/dist/shared.d.ts +2 -0
- package/dist/shared.js +2 -0
- package/dist/skill-auditor.d.ts +19 -0
- package/dist/skill-auditor.js +32 -2
- package/dist/skill-catalog.d.ts +4 -1
- package/dist/skill-catalog.js +6 -5
- package/dist/store/ace-packed-store.d.ts +5 -1
- package/dist/store/ace-packed-store.js +33 -1
- package/dist/store/bootstrap-store.js +19 -12
- package/dist/store/cache-workspace.d.ts +8 -0
- package/dist/store/cache-workspace.js +94 -27
- package/dist/store/importer.js +11 -20
- package/dist/store/knowledge-bake.d.ts +3 -1
- package/dist/store/knowledge-bake.js +10 -1
- package/dist/store/legacy-vericify-posts.d.ts +8 -0
- package/dist/store/legacy-vericify-posts.js +76 -0
- package/dist/store/materializers/hook-context-materializer.d.ts +2 -1
- package/dist/store/materializers/hook-context-materializer.js +6 -2
- package/dist/store/materializers/host-file-materializer.js +2 -2
- package/dist/store/materializers/projection-manager.d.ts +4 -1
- package/dist/store/materializers/projection-manager.js +10 -3
- package/dist/store/materializers/todo-syncer.d.ts +39 -20
- package/dist/store/materializers/todo-syncer.js +208 -110
- package/dist/store/materializers/vericify-projector.js +15 -26
- package/dist/store/repositories/goal-repository.d.ts +51 -2
- package/dist/store/repositories/goal-repository.js +114 -48
- package/dist/store/repositories/playbook-repository.d.ts +41 -3
- package/dist/store/repositories/playbook-repository.js +61 -5
- package/dist/store/repositories/todo-repository.d.ts +8 -2
- package/dist/store/repositories/todo-repository.js +1 -1
- package/dist/store/repositories/vericify-repository.d.ts +4 -0
- package/dist/store/repositories/vericify-repository.js +46 -0
- package/dist/store/skills-install.d.ts +1 -0
- package/dist/store/skills-install.js +20 -16
- package/dist/store/source-preservation.d.ts +24 -0
- package/dist/store/source-preservation.js +79 -0
- package/dist/store/store-artifacts.js +8 -1
- package/dist/store/test-write-boundary.d.ts +16 -0
- package/dist/store/test-write-boundary.js +175 -0
- package/dist/store/types.d.ts +5 -1
- package/dist/store/write-coordinator.js +16 -0
- package/dist/task-plan-context.d.ts +11 -0
- package/dist/task-plan-context.js +59 -0
- package/dist/todo-state.d.ts +19 -9
- package/dist/todo-state.js +204 -321
- package/dist/tools-agent.d.ts +1 -1
- package/dist/tools-agent.js +38 -62
- package/dist/tools-files.d.ts +0 -3
- package/dist/tools-files.js +21 -11
- package/dist/tools-framework.js +16 -25
- package/dist/tools-goal.d.ts +2 -4
- package/dist/tools-goal.js +119 -16
- package/dist/tools-handoff.d.ts +3 -2
- package/dist/tools-handoff.js +53 -23
- package/dist/tools-lifecycle.js +1 -1
- package/dist/tools-memory.d.ts +0 -3
- package/dist/tools-memory.js +51 -6
- package/dist/tools-scheduler.js +20 -17
- package/dist/tools-todo.js +160 -148
- package/dist/vericify-bridge.d.ts +8 -0
- package/dist/vericify-bridge.js +18 -0
- package/dist/vericify-context.d.ts +4 -0
- package/dist/vericify-context.js +26 -5
- package/dist/vericify-native.d.ts +101 -0
- package/dist/vericify-native.js +221 -0
- package/dist/verification-worker.d.ts +2 -0
- package/dist/verification-worker.js +31 -0
- package/docs/mcp-tool-reference.md +50 -10
- package/docs/troubleshooting.md +29 -0
- package/package.json +19 -6
- package/scripts/dev/run-tests-isolated.mjs +165 -0
- package/scripts/dev/run_hermes_crispr_live.mjs +1 -0
- package/scripts/dev/test-isolation-guard.mjs +20 -0
- package/scripts/dev/test-preload.mjs +153 -0
- package/scripts/dev/test-source-inventory.mjs +31 -0
- package/docs/development.md +0 -46
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import { type LearnedArtifact } from './learned-artifacts.js';
|
|
2
|
+
export declare function listLearning(root: string): {
|
|
3
|
+
lessons: import("./store/repositories/playbook-repository.js").PlaybookBullet[];
|
|
4
|
+
artifacts: LearnedArtifact[];
|
|
5
|
+
};
|
|
6
|
+
export declare function showLearning(root: string, id: string): import("./store/repositories/playbook-repository.js").PlaybookBullet | LearnedArtifact | undefined;
|
|
7
|
+
export declare function approveLearning(root: string, id: string): Promise<void>;
|
|
8
|
+
export declare function retireLearning(root: string, id: string, reason: string): Promise<void>;
|
|
9
|
+
export { approvedInstructionText, approvedDistillerText } from './learning-overlays.js';
|
|
10
|
+
export declare function learningReport(root: string): {
|
|
11
|
+
scorecard: {
|
|
12
|
+
active_learned_artifacts: {
|
|
13
|
+
lessons: number;
|
|
14
|
+
skills: number;
|
|
15
|
+
approved_instructions: number;
|
|
16
|
+
};
|
|
17
|
+
repeat_failure_rate: {
|
|
18
|
+
signatures_served: number;
|
|
19
|
+
signatures_recurred: number;
|
|
20
|
+
rate: number | null;
|
|
21
|
+
missing_context_attempts: number;
|
|
22
|
+
interpretation: string;
|
|
23
|
+
};
|
|
24
|
+
first_attempt_success_by_scope: {
|
|
25
|
+
scope: string;
|
|
26
|
+
before: ReturnType<() => {
|
|
27
|
+
done: number;
|
|
28
|
+
steps: number;
|
|
29
|
+
rate: number | null;
|
|
30
|
+
}>;
|
|
31
|
+
after: ReturnType<() => {
|
|
32
|
+
done: number;
|
|
33
|
+
steps: number;
|
|
34
|
+
rate: number | null;
|
|
35
|
+
}>;
|
|
36
|
+
unclassified: ReturnType<() => {
|
|
37
|
+
done: number;
|
|
38
|
+
steps: number;
|
|
39
|
+
rate: number | null;
|
|
40
|
+
}>;
|
|
41
|
+
unexposed: ReturnType<() => {
|
|
42
|
+
done: number;
|
|
43
|
+
steps: number;
|
|
44
|
+
rate: number | null;
|
|
45
|
+
}>;
|
|
46
|
+
}[];
|
|
47
|
+
first_attempt_coverage: {
|
|
48
|
+
missing_first_attempts: number;
|
|
49
|
+
reconstructed_scopes: number;
|
|
50
|
+
interpretation: string;
|
|
51
|
+
};
|
|
52
|
+
served_helpfulness: {
|
|
53
|
+
helpful: number;
|
|
54
|
+
harmful: number;
|
|
55
|
+
ratio: number | null;
|
|
56
|
+
counter_scope: string;
|
|
57
|
+
};
|
|
58
|
+
distill_acceptance: {
|
|
59
|
+
checked: number;
|
|
60
|
+
submitted: number;
|
|
61
|
+
rate: number | null;
|
|
62
|
+
demonstrated_current_artifacts: number;
|
|
63
|
+
};
|
|
64
|
+
learning_overhead: {
|
|
65
|
+
learning_steps: number;
|
|
66
|
+
all_steps: number;
|
|
67
|
+
ratio: number | null;
|
|
68
|
+
opportunistic_payload_steps: number;
|
|
69
|
+
assignments: {
|
|
70
|
+
episode_id: string;
|
|
71
|
+
utf8_bytes: number;
|
|
72
|
+
token_upper_bound: number;
|
|
73
|
+
}[];
|
|
74
|
+
max_served_token_upper_bound: number | null;
|
|
75
|
+
token_method: string;
|
|
76
|
+
};
|
|
77
|
+
retirement_health: {
|
|
78
|
+
window_days: number;
|
|
79
|
+
retired: number;
|
|
80
|
+
ever_active: number;
|
|
81
|
+
ratio: number | null;
|
|
82
|
+
unknown_history: number;
|
|
83
|
+
};
|
|
84
|
+
distillation_steps: {
|
|
85
|
+
goal_id: string;
|
|
86
|
+
step_id: string;
|
|
87
|
+
checked: boolean;
|
|
88
|
+
items_after_20_serves: number;
|
|
89
|
+
mean_strong_helpfulness: number | null;
|
|
90
|
+
}[];
|
|
91
|
+
coverage: string;
|
|
92
|
+
};
|
|
93
|
+
enabled: boolean;
|
|
94
|
+
policy_issue: string | null;
|
|
95
|
+
observation: string;
|
|
96
|
+
episodes: number;
|
|
97
|
+
attempts: number;
|
|
98
|
+
first_attempts_done: number;
|
|
99
|
+
steps_with_outcomes: number;
|
|
100
|
+
artifacts: {
|
|
101
|
+
lessons: number;
|
|
102
|
+
skills: number;
|
|
103
|
+
quarantined: number;
|
|
104
|
+
};
|
|
105
|
+
instructions: {
|
|
106
|
+
active: number;
|
|
107
|
+
proposed: number;
|
|
108
|
+
};
|
|
109
|
+
served: number;
|
|
110
|
+
used: number;
|
|
111
|
+
helpful: number;
|
|
112
|
+
harmful: number;
|
|
113
|
+
weak_outcomes: {
|
|
114
|
+
done_first_attempt: number;
|
|
115
|
+
failed_same_signature: number;
|
|
116
|
+
other: number;
|
|
117
|
+
};
|
|
118
|
+
repeat_signatures: {
|
|
119
|
+
signature: string;
|
|
120
|
+
count: number;
|
|
121
|
+
}[];
|
|
122
|
+
distillation: {
|
|
123
|
+
submitted: number;
|
|
124
|
+
checked: number;
|
|
125
|
+
acceptance_rate: number | null;
|
|
126
|
+
demonstrated: number;
|
|
127
|
+
helpfulness_after_20_serves: {
|
|
128
|
+
id: unknown;
|
|
129
|
+
helpful: number;
|
|
130
|
+
harmful: number;
|
|
131
|
+
used: number;
|
|
132
|
+
}[];
|
|
133
|
+
};
|
|
134
|
+
limitations: string[];
|
|
135
|
+
};
|
|
136
|
+
export declare function exportLearning(root: string, to: string): Promise<{
|
|
137
|
+
files: string[];
|
|
138
|
+
unexported: string[];
|
|
139
|
+
}>;
|
|
140
|
+
/** Open the next useful proposal, never a coordinator or automatic approval. */
|
|
141
|
+
export declare function advanceLearning(root: string): Promise<void>;
|
|
142
|
+
//# sourceMappingURL=learning-controls.d.ts.map
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import { buildLearningScorecard } from './learning-scorecard.js';
|
|
2
|
+
/** Explicit operator controls and reports over existing learning records. */
|
|
3
|
+
import { mkdirSync, writeFileSync } from 'node:fs';
|
|
4
|
+
import { join, dirname, resolve } from 'node:path';
|
|
5
|
+
import { createHash } from 'node:crypto';
|
|
6
|
+
import { GoalRepository, defaultGoalBudgets } from './store/repositories/goal-repository.js';
|
|
7
|
+
import { amendTaskPlan, createTaskPlan } from './orchestrator-supervisor.js';
|
|
8
|
+
import { PlaybookRepository, withPlaybookTransaction } from './store/repositories/playbook-repository.js';
|
|
9
|
+
import { listLearnedArtifacts, saveLearnedArtifact, regenerateLearnedProjection, withLearnedStore } from './learned-artifacts.js';
|
|
10
|
+
import { withStoreWriteCoordinator } from './store/write-coordinator.js';
|
|
11
|
+
import { readLearningPolicy } from './learning-policy.js';
|
|
12
|
+
import { ContentSource } from './store/types.js';
|
|
13
|
+
import { listEpisodes } from './host-learning.js';
|
|
14
|
+
export function listLearning(root) { return { lessons: new PlaybookRepository(root).listBulletsReadOnly(), artifacts: listLearnedArtifacts(root) }; }
|
|
15
|
+
export function showLearning(root, id) { const all = listLearning(root); return all.lessons.find(b => b.bullet_id === id) ?? all.artifacts.find(a => a.id === id); }
|
|
16
|
+
export async function approveLearning(root, id) {
|
|
17
|
+
const a = listLearnedArtifacts(root).find(a => a.id === id);
|
|
18
|
+
if (!a || a.status !== 'proposed' || !['instruction', 'distiller'].includes(a.kind))
|
|
19
|
+
throw Error('Choose an existing proposed instruction or distiller overlay. Lessons and skills do not need operator approval.');
|
|
20
|
+
const sourceKey = a.key, canonical = a.kind === 'instruction' ? `knowledge/agents/${a.scope.role}/LEARNED.md` : 'knowledge/skills/learn-from-work/LEARNED.md';
|
|
21
|
+
await withLearnedStore(root, async (store) => {
|
|
22
|
+
const prior = await store.getBlob(canonical);
|
|
23
|
+
if (prior) {
|
|
24
|
+
const name = `references/history/${new Date().toISOString().replace(/[^0-9]/g, '')}.md`;
|
|
25
|
+
if (a.kind === 'instruction')
|
|
26
|
+
await store.setAgentInstruction(a.scope.role, name, prior, ContentSource.User);
|
|
27
|
+
else
|
|
28
|
+
await store.setSkillContent('learn-from-work', name, prior, ContentSource.User);
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
if (sourceKey !== canonical)
|
|
32
|
+
await saveLearnedArtifact(root, { ...a, id: a.id + ':proposal-record', status: 'retired', retired_reason: 'Approved into ' + canonical });
|
|
33
|
+
a.status = 'active';
|
|
34
|
+
a.approved_at = new Date().toISOString();
|
|
35
|
+
a.approval = 'explicit ace learn approve';
|
|
36
|
+
a.key = canonical;
|
|
37
|
+
await saveLearnedArtifact(root, a);
|
|
38
|
+
await regenerateLearnedProjection(root);
|
|
39
|
+
}
|
|
40
|
+
export async function retireLearning(root, id, reason) {
|
|
41
|
+
if (!reason.trim())
|
|
42
|
+
throw Error('Retirement needs a reason.');
|
|
43
|
+
const a = listLearnedArtifacts(root).find(a => a.id === id);
|
|
44
|
+
if (a) {
|
|
45
|
+
await saveLearnedArtifact(root, { ...a, status: 'retired', retired_reason: reason });
|
|
46
|
+
}
|
|
47
|
+
else
|
|
48
|
+
await withPlaybookTransaction(root, repo => {
|
|
49
|
+
const b = repo.getBullet(id);
|
|
50
|
+
if (!b)
|
|
51
|
+
throw Error('Learning item not found: ' + id);
|
|
52
|
+
repo.saveBullet({ ...b, status: 'retired', retired_reason: reason });
|
|
53
|
+
});
|
|
54
|
+
await regenerateLearnedProjection(root);
|
|
55
|
+
}
|
|
56
|
+
export { approvedInstructionText, approvedDistillerText } from './learning-overlays.js';
|
|
57
|
+
export function learningReport(root) {
|
|
58
|
+
const all = listLearning(root), repo = new GoalRepository(root), steps = repo.listGoals().flatMap(g => (repo.getPlan(g.goal_id)?.steps ?? []).map(s => ({ goal: g.goal_id, step: s }))), episodes = listEpisodes(root);
|
|
59
|
+
const logs = steps.flatMap(({ goal, step }) => (step.attempts_log ?? []).map(a => ({ ...a, goal, step_id: step.step_id })));
|
|
60
|
+
const distill = steps.filter(({ step }) => step.learning_payload && step.learning_result), skills = all.artifacts.filter(a => a.kind === 'skill'), instructions = all.artifacts.filter(a => a.kind === 'instruction'), served = [...all.lessons, ...skills];
|
|
61
|
+
const signatureCounts = new Map();
|
|
62
|
+
for (const ep of episodes)
|
|
63
|
+
if (ep.failure_signature)
|
|
64
|
+
signatureCounts.set(ep.failure_signature, (signatureCounts.get(ep.failure_signature) ?? 0) + 1);
|
|
65
|
+
return { scorecard: buildLearningScorecard(steps, episodes, all.lessons, all.artifacts), enabled: readLearningPolicy(root).enabled, policy_issue: readLearningPolicy(root).issue ?? null, observation: 'unavailable unless a qualified Vericify adapter supplied Linked records', episodes: episodes.length, attempts: logs.length, first_attempts_done: logs.filter(a => a.attempt === 1 && a.status === 'done').length, steps_with_outcomes: new Set(logs.map(a => `${a.goal}:${a.step_id}`)).size, artifacts: { lessons: all.lessons.filter(b => b.status === 'active').length, skills: skills.filter(a => a.status === 'active').length, quarantined: all.lessons.filter(b => b.status === 'quarantined').length + all.artifacts.filter(a => a.status === 'quarantined').length }, instructions: { active: instructions.filter(a => a.status === 'active').length, proposed: instructions.filter(a => a.status === 'proposed').length }, served: served.reduce((sum, b) => sum + (b.served_count ?? 0), 0), used: served.reduce((sum, b) => sum + (b.used_count ?? 0), 0), helpful: served.reduce((sum, b) => sum + b.helpful_count, 0), harmful: served.reduce((sum, b) => sum + b.harmful_count, 0), weak_outcomes: served.reduce((sum, b) => ({ done_first_attempt: sum.done_first_attempt + (b.served_outcomes?.done_first_attempt ?? 0), failed_same_signature: sum.failed_same_signature + (b.served_outcomes?.failed_same_signature ?? 0), other: sum.other + (b.served_outcomes?.other ?? 0) }), { done_first_attempt: 0, failed_same_signature: 0, other: 0 }), repeat_signatures: [...signatureCounts.entries()].filter(([, count]) => count > 1).map(([signature, count]) => ({ signature, count })), distillation: { submitted: distill.length, checked: distill.filter(({ step }) => step.learning_result?.ok).length, acceptance_rate: distill.length ? distill.filter(({ step }) => step.learning_result?.ok).length / distill.length : null, demonstrated: all.artifacts.filter(a => a.label === 'demonstrated').length + all.lessons.filter(b => b.label === 'demonstrated').length, helpfulness_after_20_serves: served.filter(a => (a.served_count ?? 0) >= 20).map(a => ({ id: 'bullet_id' in a ? a.bullet_id : a.id, helpful: a.helpful_count, harmful: a.harmful_count, used: a.used_count ?? 0 })) }, limitations: ['Attempt context retains five entries; pinned citations preserve cited earlier episodes.', 'No provider quality, causal benefit or unavailable external observation is inferred from these counters.'] };
|
|
66
|
+
}
|
|
67
|
+
export async function exportLearning(root, to) {
|
|
68
|
+
const all = listLearning(root), files = [], unexported = [];
|
|
69
|
+
const target = resolve(root, to);
|
|
70
|
+
const emit = (path, text) => { const file = join(target, path); mkdirSync(dirname(file), { recursive: true }); const marker = '<!-- Generated by ace learn export; review changes before committing. -->\n'; const output = text.startsWith('---\n') ? text.replace(/\n---\n/, '\n---\n' + marker) : marker + text; writeFileSync(file, output.endsWith('\n') ? output : output + '\n'); files.push(file); };
|
|
71
|
+
const grouped = new Map();
|
|
72
|
+
for (const b of all.lessons.filter(b => b.status === 'active')) {
|
|
73
|
+
if (!b.evidence_snapshots?.length) {
|
|
74
|
+
unexported.push(`${b.bullet_id}: no ACE episode citation`);
|
|
75
|
+
continue;
|
|
76
|
+
}
|
|
77
|
+
const key = createHash('sha256').update(JSON.stringify(b.scope)).digest('hex').slice(0, 8);
|
|
78
|
+
grouped.set(key, [...(grouped.get(key) ?? []), b]);
|
|
79
|
+
}
|
|
80
|
+
for (const [key, items] of grouped)
|
|
81
|
+
emit(`lessons/${key}.md`, '# Learned lessons\n\n' + items.map(b => `## ${b.bullet_id} (${b.label ?? 'checked'})\n\n${b.content}\n\nEpisodes: ${b.evidence_snapshots.map(e => e.id).join(', ')}\n\nScope: ${JSON.stringify(b.scope)}`).join('\n\n'));
|
|
82
|
+
for (const a of all.artifacts.filter(a => a.status === 'active')) {
|
|
83
|
+
if (!a.episodes.length) {
|
|
84
|
+
unexported.push(`${a.id}: no episode citation`);
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
const name = a.kind === 'skill' ? `skills/${a.id.replace(/^learned\//, '')}/SKILL.md` : a.kind === 'instruction' ? `agents/${a.scope.role}/LEARNED.md` : 'skills/learn-from-work/LEARNED.md';
|
|
88
|
+
const front = a.kind === 'skill' ? `---\nname: ${JSON.stringify(a.id.replace(/^learned\//, ''))}\ndescription: ${JSON.stringify(a.description ?? 'Use for ' + JSON.stringify(a.scope))}\nscope: ${JSON.stringify(a.scope)}\norigin: learned\nlabel: ${a.label}\nepisodes: ${JSON.stringify(a.episodes)}\n---\n` : '';
|
|
89
|
+
emit(name, front + (a.kind === 'skill' ? a.body : `# ${a.id}\n\nLabel: ${a.label}\n\nEpisodes: ${a.episodes.join(', ')}\n\n${a.body}`));
|
|
90
|
+
for (const [name, body] of Object.entries(a.references ?? {}))
|
|
91
|
+
emit(`skills/${a.id.replace(/^learned\//, '')}/references/${name}`, `Episodes: ${a.episodes.join(', ')}\n\n${body}`);
|
|
92
|
+
if (a.kind === 'skill')
|
|
93
|
+
emit(`skills/${a.id.replace(/^learned\//, '')}/references/episodes.md`, a.evidence_snapshots.map(e => { const current = listEpisodes(root).find(item => item.id === e.id) ?? e; return `## ${e.id}\n\n${JSON.stringify(current, null, 2)}`; }).join('\n\n'));
|
|
94
|
+
}
|
|
95
|
+
return { files, unexported };
|
|
96
|
+
}
|
|
97
|
+
/** Open the next useful proposal, never a coordinator or automatic approval. */
|
|
98
|
+
export async function advanceLearning(root) {
|
|
99
|
+
const policy = readLearningPolicy(root);
|
|
100
|
+
if (!policy.enabled)
|
|
101
|
+
return;
|
|
102
|
+
const repo = new GoalRepository(root), catalog = listLearnedArtifacts(root), eligible = catalog.filter(a => a.kind === 'skill' && a.status === 'active' && a.label === 'demonstrated' && a.helpful_count >= 10 && a.harmful_count === 0 && (a.used_goals?.length ?? 0) >= 3);
|
|
103
|
+
const prior = repo.getPlan('G-learning');
|
|
104
|
+
if (prior?.steps.some(s => ['planned', 'running', 'blocked'].includes(s.status)))
|
|
105
|
+
return;
|
|
106
|
+
const priorBase = (prior?.steps ?? []).filter(s => s.learning_payload && s.learning_result && s.learning_kind !== 'meta').slice(-10);
|
|
107
|
+
if (!eligible.length && !(priorBase.length === 10 && priorBase.filter(s => s.learning_result.ok).length < 5))
|
|
108
|
+
return;
|
|
109
|
+
await withStoreWriteCoordinator(repo.planPath('G-learning'), async () => {
|
|
110
|
+
let g = repo.getGoal('G-learning'), p = repo.getPlan('G-learning');
|
|
111
|
+
if (p?.steps.some(s => ['planned', 'running', 'blocked'].includes(s.status)))
|
|
112
|
+
return;
|
|
113
|
+
const base = (p?.steps ?? []).filter(s => s.learning_payload && s.learning_result && s.learning_kind !== 'meta').slice(-10), trigger = base.map(s => s.step_id).join(',');
|
|
114
|
+
const coolingMeta = (p?.steps ?? []).some(s => s.learning_kind === 'meta' && Date.now() - Date.parse(s.learning_opened_at ?? new Date().toISOString()) < policy.distill_cooldown_days * 86400000);
|
|
115
|
+
const meta = !coolingMeta && base.length === 10 && base.filter(s => s.learning_result.ok).length < 5 && !(p?.steps ?? []).some(s => s.learning_kind === 'meta' && s.learning_trigger === trigger);
|
|
116
|
+
const candidate = eligible.find(a => !p?.steps.some(s => s.learning_kind === 'graduation' && s.learning_source === a.id));
|
|
117
|
+
const graduate = !!candidate;
|
|
118
|
+
if (!meta && !graduate)
|
|
119
|
+
return;
|
|
120
|
+
const now = new Date().toISOString();
|
|
121
|
+
const body = meta ? 'Propose one depth-one revision to the learn-from-work distillation skill. Use outcome.learned.skill with slug learn-from-work. Keep it proposed for operator approval. Never propose a revision about this overlay itself. Inspect the referenced rejected base payloads and acceptance errors.' : 'Propose the role-level rule this demonstrated skill implies, if any. Submit outcome.learned.instruction; it remains proposed until an operator approves it. Inspect the referenced demonstrated skill.';
|
|
122
|
+
const learning_inputs = meta ? { rejected_steps: base.map(s => s.step_id) } : { artifacts: [candidate.id] };
|
|
123
|
+
if (!p) {
|
|
124
|
+
p = createTaskPlan({ task: 'Keep this workspace\'s learned artifacts current', steps: [] });
|
|
125
|
+
g = { goal_id: 'G-learning', objective: p.task, status: 'executing', executor: 'host', plan_id: p.plan_id, success_contract: { expected_artifacts: [], required_evidence_refs: [], verification_commands: [], gate_ids: [], uncompilable_criteria: [] }, budgets: defaultGoalBudgets(), created_at: now, updated_at: now, tick_count: 0, replan_count: 0, stop_requested: false, escalations: [] };
|
|
126
|
+
}
|
|
127
|
+
p = amendTaskPlan(p, { append_steps: [{ role: 'coders', task: body, learning_inputs, learning_scope: meta ? 'distiller-depth-1' : `graduate:${candidate.id}`, learning_kind: meta ? 'meta' : 'graduation', learning_source: meta ? undefined : candidate.id, learning_trigger: meta ? trigger : undefined, learning_opened_at: now }] });
|
|
128
|
+
if (g.status === 'done' || !g.started_at)
|
|
129
|
+
g.started_at = now;
|
|
130
|
+
g.status = 'executing';
|
|
131
|
+
repo.savePlan('G-learning', p);
|
|
132
|
+
repo.saveGoal(g);
|
|
133
|
+
}, { operation_label: 'learning_proposal' });
|
|
134
|
+
}
|
|
135
|
+
//# sourceMappingURL=learning-controls.js.map
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/** Bounded derived context. The existing plans/knowledge retain every full input. */
|
|
2
|
+
import type { TaskStep } from './orchestrator-supervisor.js';
|
|
3
|
+
export interface LearningInputRefs {
|
|
4
|
+
episodes?: string[];
|
|
5
|
+
artifacts?: string[];
|
|
6
|
+
rejected_steps?: string[];
|
|
7
|
+
}
|
|
8
|
+
export declare function renderLearningTask(root: string, goalId: string, step: TaskStep): string;
|
|
9
|
+
//# sourceMappingURL=learning-input-context.d.ts.map
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { GoalRepository } from './store/repositories/goal-repository.js';
|
|
2
|
+
import { PlaybookRepository } from './store/repositories/playbook-repository.js';
|
|
3
|
+
import { listEpisodes } from './host-learning.js';
|
|
4
|
+
import { listLearnedArtifacts } from './learned-artifacts.js';
|
|
5
|
+
import { utf8Prefix } from './task-plan-context.js';
|
|
6
|
+
const MAX_CONTEXT_BYTES = 8000;
|
|
7
|
+
export function renderLearningTask(root, goalId, step) {
|
|
8
|
+
if (!step.learning_scope)
|
|
9
|
+
return step.task;
|
|
10
|
+
const source = `agent-state/goals/${goalId}.plan.json#${step.step_id}`;
|
|
11
|
+
const refs = step.learning_inputs;
|
|
12
|
+
if (!refs) {
|
|
13
|
+
if (Buffer.byteLength(step.task) <= MAX_CONTEXT_BYTES)
|
|
14
|
+
return step.task;
|
|
15
|
+
return `${utf8Prefix(step.task, 7400)}\n[Legacy learning input preview; full retained text is at the source below.]\nFull learning inputs: ${source}.task`;
|
|
16
|
+
}
|
|
17
|
+
const rows = [];
|
|
18
|
+
const episodes = new Map(listEpisodes(root).map(e => [e.id, e]));
|
|
19
|
+
const groups = new Map();
|
|
20
|
+
for (const id of refs.episodes ?? []) {
|
|
21
|
+
const group = episodes.get(id)?.goal_id ?? 'unavailable';
|
|
22
|
+
groups.set(group, [...(groups.get(group) ?? []), id]);
|
|
23
|
+
}
|
|
24
|
+
const selected = [];
|
|
25
|
+
while (selected.length < 8 && [...groups.values()].some(ids => ids.length)) {
|
|
26
|
+
for (const ids of groups.values()) {
|
|
27
|
+
if (ids.length && selected.length < 8)
|
|
28
|
+
selected.push(ids.shift());
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
for (const id of selected) {
|
|
32
|
+
const e = episodes.get(id);
|
|
33
|
+
rows.push({ id, text: e ? `${e.status}: ${utf8Prefix(e.failure_excerpt ?? '', 220)}\nSummary: ${utf8Prefix(e.summary, 300)}\nEvidence: ${e.evidence_refs.slice(0, 2).join(', ')}` : 'Source unavailable; retain this identity and inspect the referenced plan or pinned knowledge.' });
|
|
34
|
+
}
|
|
35
|
+
const artifacts = new Map([
|
|
36
|
+
...new PlaybookRepository(root).listBulletsReadOnly().map(b => [b.bullet_id, b]),
|
|
37
|
+
...listLearnedArtifacts(root).map(a => [a.id, a]),
|
|
38
|
+
]);
|
|
39
|
+
for (const id of (refs.artifacts ?? []).slice(0, 4)) {
|
|
40
|
+
const a = artifacts.get(id);
|
|
41
|
+
rows.push({ id, text: a ? `${a.status}: ${a.content ?? a.body ?? ''}` : 'Artifact unavailable; preserve its reference.' });
|
|
42
|
+
}
|
|
43
|
+
const plan = new GoalRepository(root).getPlan(goalId);
|
|
44
|
+
for (const id of (refs.rejected_steps ?? []).slice(-10)) {
|
|
45
|
+
const s = plan?.steps.find(s => s.step_id === id);
|
|
46
|
+
rows.push({ id: `${goalId}/${id}`, text: s ? `Acceptance errors: ${(s.learning_result?.errors ?? []).join('; ')}\nPayload preview: ${JSON.stringify(s.learning_payload)}` : 'Rejected work record unavailable; inspect its retained source.' });
|
|
47
|
+
}
|
|
48
|
+
const count = (refs.episodes?.length ?? 0) + (refs.artifacts?.length ?? 0) + (refs.rejected_steps?.length ?? 0);
|
|
49
|
+
const footer = `\nInput selection: ${rows.length} of ${count} records previewed. Summaries are excerpts; no source record is deleted.\nFull learning inputs: ${source}.learning_inputs\nRead the referenced goal plans, pinned episodes and knowledge with the host's tools or existing ACE read tools when more detail is needed.`;
|
|
50
|
+
const prefix = `${step.task}\n\nRetained input previews:\n`;
|
|
51
|
+
let remaining = MAX_CONTEXT_BYTES - Buffer.byteLength(prefix + footer);
|
|
52
|
+
const blocks = rows.map((row, index) => {
|
|
53
|
+
const budget = Math.max(0, Math.floor(remaining / (rows.length - index)));
|
|
54
|
+
const header = `[${row.id}]\n`;
|
|
55
|
+
const text = utf8Prefix(row.text, Math.max(0, budget - Buffer.byteLength(header) - 45));
|
|
56
|
+
const block = `${header}${text}${text.length < row.text.length ? '\n[excerpt; full source referenced below]' : ''}\n`;
|
|
57
|
+
remaining -= Buffer.byteLength(block);
|
|
58
|
+
return block;
|
|
59
|
+
});
|
|
60
|
+
return prefix + blocks.join('\n') + footer;
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=learning-input-context.js.map
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/** State transition dates on the artifact itself; no separate activity log. */
|
|
2
|
+
export interface LearningLifecycle {
|
|
3
|
+
status: string;
|
|
4
|
+
ever_active?: boolean;
|
|
5
|
+
activated_at?: string;
|
|
6
|
+
last_active_at?: string;
|
|
7
|
+
retired_at?: string;
|
|
8
|
+
}
|
|
9
|
+
export declare function learningLifecycle(next: LearningLifecycle, previous: LearningLifecycle | undefined, at: string): Omit<LearningLifecycle, 'status'>;
|
|
10
|
+
//# sourceMappingURL=learning-lifecycle.d.ts.map
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export function learningLifecycle(next, previous, at) {
|
|
2
|
+
const active = next.status === 'active';
|
|
3
|
+
const ever = active || previous?.status === 'active' ? true : next.ever_active ?? previous?.ever_active ?? (previous ? undefined : false);
|
|
4
|
+
return {
|
|
5
|
+
ever_active: ever,
|
|
6
|
+
activated_at: next.activated_at ?? previous?.activated_at ?? (active && previous?.status !== 'active' ? at : undefined),
|
|
7
|
+
last_active_at: active || previous?.status === 'active' ? at : next.last_active_at ?? previous?.last_active_at,
|
|
8
|
+
retired_at: next.status === 'retired' ? next.retired_at ?? (previous?.status !== 'retired' ? at : previous?.retired_at) : undefined,
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=learning-lifecycle.js.map
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/** Read approved canonical overlays without importing execution/runtime owners. */
|
|
2
|
+
import { readLearningPolicy } from './learning-policy.js';
|
|
3
|
+
import { readStoreBlobSync } from './store/store-snapshot.js';
|
|
4
|
+
import { decodeLearned } from './learning-records.js';
|
|
5
|
+
export function approvedInstructionText(root, role) {
|
|
6
|
+
if (!readLearningPolicy(root).enabled)
|
|
7
|
+
return '';
|
|
8
|
+
const key = `knowledge/agents/${role}/LEARNED.md`, a = decodeLearned(readStoreBlobSync(root, key) ?? '', key);
|
|
9
|
+
return a?.kind === 'instruction' && a.status === 'active' && a.scope.role === role ? `\n\n## Learned in this workspace\n[${a.id}] ${a.body}\nEpisodes: ${a.episodes.join(', ')}` : '';
|
|
10
|
+
}
|
|
11
|
+
export function approvedDistillerText(root) {
|
|
12
|
+
if (!readLearningPolicy(root).enabled)
|
|
13
|
+
return '';
|
|
14
|
+
const key = 'knowledge/skills/learn-from-work/LEARNED.md', a = decodeLearned(readStoreBlobSync(root, key) ?? '', key);
|
|
15
|
+
return a?.kind === 'distiller' && a.status === 'active' ? `\n\n## Approved workspace distillation guidance\n[${a.id}] ${a.body}\nEpisodes: ${a.episodes.join(', ')}` : '';
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=learning-overlays.js.map
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/** The learning block of the existing ACE_WORKFLOW profile. No load events on reads. */
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
export declare const DEFAULT_LEARNING_POLICY: {
|
|
4
|
+
enabled: boolean;
|
|
5
|
+
distill_min_items: number;
|
|
6
|
+
distill_min_goals: number;
|
|
7
|
+
max_open_learning_steps: 1;
|
|
8
|
+
distill_cooldown_days: number;
|
|
9
|
+
max_learned_skills: number;
|
|
10
|
+
serve_max_lessons: number;
|
|
11
|
+
serve_max_skills: number;
|
|
12
|
+
serve_max_tokens: number;
|
|
13
|
+
retire_unhelpful_after_serves: number;
|
|
14
|
+
instructions_require_approval: true;
|
|
15
|
+
};
|
|
16
|
+
export declare const learningPolicySchema: z.ZodObject<{
|
|
17
|
+
enabled: z.ZodDefault<z.ZodBoolean>;
|
|
18
|
+
distill_min_items: z.ZodDefault<z.ZodNumber>;
|
|
19
|
+
distill_min_goals: z.ZodDefault<z.ZodNumber>;
|
|
20
|
+
max_open_learning_steps: z.ZodDefault<z.ZodLiteral<1>>;
|
|
21
|
+
distill_cooldown_days: z.ZodDefault<z.ZodNumber>;
|
|
22
|
+
max_learned_skills: z.ZodDefault<z.ZodNumber>;
|
|
23
|
+
serve_max_lessons: z.ZodDefault<z.ZodNumber>;
|
|
24
|
+
serve_max_skills: z.ZodDefault<z.ZodNumber>;
|
|
25
|
+
serve_max_tokens: z.ZodDefault<z.ZodNumber>;
|
|
26
|
+
retire_unhelpful_after_serves: z.ZodDefault<z.ZodNumber>;
|
|
27
|
+
instructions_require_approval: z.ZodDefault<z.ZodLiteral<true>>;
|
|
28
|
+
}, z.core.$strict>;
|
|
29
|
+
export type LearningPolicy = z.infer<typeof learningPolicySchema> & {
|
|
30
|
+
issue?: string;
|
|
31
|
+
};
|
|
32
|
+
export declare function readLearningPolicy(root: string): LearningPolicy;
|
|
33
|
+
/** One identity for threshold and re-distillation cooldown decisions. */
|
|
34
|
+
export declare function learningScopeKey(scope: {
|
|
35
|
+
role?: string;
|
|
36
|
+
paths?: string[];
|
|
37
|
+
task_tags?: string[];
|
|
38
|
+
}): string;
|
|
39
|
+
export declare function canonicalLearningScopeKey(value: string): string;
|
|
40
|
+
//# sourceMappingURL=learning-policy.d.ts.map
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/** The learning block of the existing ACE_WORKFLOW profile. No load events on reads. */
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
4
|
+
import { join } from 'node:path';
|
|
5
|
+
import { readStoreBlobSync } from './store/store-snapshot.js';
|
|
6
|
+
import { extractFrontMatter, parseYamlFrontMatter } from './runtime-profile-syntax.js';
|
|
7
|
+
export const DEFAULT_LEARNING_POLICY = { enabled: true, distill_min_items: 3, distill_min_goals: 2, max_open_learning_steps: 1, distill_cooldown_days: 7, max_learned_skills: 30, serve_max_lessons: 3, serve_max_skills: 2, serve_max_tokens: 600, retire_unhelpful_after_serves: 40, instructions_require_approval: true };
|
|
8
|
+
export const learningPolicySchema = z.object({ enabled: z.boolean().default(true), distill_min_items: z.number().int().positive().default(3), distill_min_goals: z.number().int().min(2).default(2), max_open_learning_steps: z.literal(1).default(1), distill_cooldown_days: z.number().positive().default(7), max_learned_skills: z.number().int().min(1).max(30).default(30), serve_max_lessons: z.number().int().min(0).max(3).default(3), serve_max_skills: z.number().int().min(0).max(2).default(2), serve_max_tokens: z.number().int().min(1).max(600).default(600), retire_unhelpful_after_serves: z.number().int().positive().default(40), instructions_require_approval: z.literal(true).default(true) }).strict();
|
|
9
|
+
export function readLearningPolicy(root) {
|
|
10
|
+
let result = { ...DEFAULT_LEARNING_POLICY };
|
|
11
|
+
const file = join(root, 'agent-state/ACE_WORKFLOW.md');
|
|
12
|
+
const raw = readStoreBlobSync(root, 'knowledge/runtime/ACE_WORKFLOW.md') ?? readStoreBlobSync(root, 'state/artifacts/agent-state/ACE_WORKFLOW.md') ?? (existsSync(file) ? readFileSync(file, 'utf8') : undefined);
|
|
13
|
+
if (raw)
|
|
14
|
+
try {
|
|
15
|
+
const front = parseYamlFrontMatter(extractFrontMatter(raw).front_matter);
|
|
16
|
+
result = learningPolicySchema.parse(front.learning ?? {});
|
|
17
|
+
}
|
|
18
|
+
catch (error) {
|
|
19
|
+
result = { ...result, enabled: false, issue: `Learning profile invalid: ${String(error)}` };
|
|
20
|
+
}
|
|
21
|
+
if (process.env.ACE_LEARN === '0')
|
|
22
|
+
result.enabled = false;
|
|
23
|
+
return result;
|
|
24
|
+
}
|
|
25
|
+
/** One identity for threshold and re-distillation cooldown decisions. */
|
|
26
|
+
export function learningScopeKey(scope) {
|
|
27
|
+
const path = (scope.paths?.[0] ?? '').replace(/\\/g, '/').replace(/^\.\//, '').split('/').slice(0, 2).join('/');
|
|
28
|
+
return `${scope.role ?? ''}|${path}|${scope.task_tags?.[0] ?? ''}`;
|
|
29
|
+
}
|
|
30
|
+
export function canonicalLearningScopeKey(value) {
|
|
31
|
+
try {
|
|
32
|
+
if (value.startsWith('{'))
|
|
33
|
+
return learningScopeKey(JSON.parse(value));
|
|
34
|
+
}
|
|
35
|
+
catch { }
|
|
36
|
+
return value;
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=learning-policy.js.map
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { Episode } from './host-learning.js';
|
|
2
|
+
import type { PlaybookScope } from './store/repositories/playbook-repository.js';
|
|
3
|
+
export interface LearnedArtifact {
|
|
4
|
+
id: string;
|
|
5
|
+
key: string;
|
|
6
|
+
kind: 'skill' | 'instruction' | 'distiller';
|
|
7
|
+
status: 'active' | 'quarantined' | 'proposed' | 'retired';
|
|
8
|
+
label: 'checked' | 'demonstrated';
|
|
9
|
+
episodes: string[];
|
|
10
|
+
evidence_snapshots: Episode[];
|
|
11
|
+
scope: PlaybookScope;
|
|
12
|
+
body: string;
|
|
13
|
+
acceptance_errors: string[];
|
|
14
|
+
checked_at: string;
|
|
15
|
+
proposal_id: string;
|
|
16
|
+
helpful_count: number;
|
|
17
|
+
harmful_count: number;
|
|
18
|
+
references?: Record<string, string>;
|
|
19
|
+
retired_reason?: string;
|
|
20
|
+
ever_active?: boolean;
|
|
21
|
+
activated_at?: string;
|
|
22
|
+
last_active_at?: string;
|
|
23
|
+
retired_at?: string;
|
|
24
|
+
used_goals?: string[];
|
|
25
|
+
served_count?: number;
|
|
26
|
+
used_count?: number;
|
|
27
|
+
served_outcomes?: {
|
|
28
|
+
done_first_attempt: number;
|
|
29
|
+
failed_same_signature: number;
|
|
30
|
+
other: number;
|
|
31
|
+
};
|
|
32
|
+
[key: string]: unknown;
|
|
33
|
+
}
|
|
34
|
+
export declare function decodeLearned(text: string, key: string): LearnedArtifact | undefined;
|
|
35
|
+
//# sourceMappingURL=learning-records.d.ts.map
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/** Shared learned-knowledge metadata codec; no runtime, helper or goal imports. */
|
|
2
|
+
import { parse } from 'yaml';
|
|
3
|
+
export function decodeLearned(text, key) {
|
|
4
|
+
try {
|
|
5
|
+
const m = text.match(/^---\n([\s\S]*?)\n---\n/);
|
|
6
|
+
if (!m)
|
|
7
|
+
return;
|
|
8
|
+
const front = parse(m[1]);
|
|
9
|
+
if (!front.ace_learning)
|
|
10
|
+
return;
|
|
11
|
+
return { ...front.ace_learning, key, body: text.slice(m[0].length), description: front.description };
|
|
12
|
+
}
|
|
13
|
+
catch {
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=learning-records.js.map
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/** The declared scorecard, derived from retained work and artifact state. */
|
|
2
|
+
import type { TaskStep } from './orchestrator-supervisor.js';
|
|
3
|
+
import type { Episode } from './host-learning.js';
|
|
4
|
+
import type { PlaybookBullet } from './store/repositories/playbook-repository.js';
|
|
5
|
+
import type { LearnedArtifact } from './learning-records.js';
|
|
6
|
+
type Work = {
|
|
7
|
+
goal: string;
|
|
8
|
+
step: TaskStep;
|
|
9
|
+
};
|
|
10
|
+
declare const phase: () => {
|
|
11
|
+
done: number;
|
|
12
|
+
steps: number;
|
|
13
|
+
rate: number | null;
|
|
14
|
+
};
|
|
15
|
+
export declare function buildLearningScorecard(steps: Work[], episodes: Episode[], lessons: PlaybookBullet[], artifacts: LearnedArtifact[], now?: number): {
|
|
16
|
+
active_learned_artifacts: {
|
|
17
|
+
lessons: number;
|
|
18
|
+
skills: number;
|
|
19
|
+
approved_instructions: number;
|
|
20
|
+
};
|
|
21
|
+
repeat_failure_rate: {
|
|
22
|
+
signatures_served: number;
|
|
23
|
+
signatures_recurred: number;
|
|
24
|
+
rate: number | null;
|
|
25
|
+
missing_context_attempts: number;
|
|
26
|
+
interpretation: string;
|
|
27
|
+
};
|
|
28
|
+
first_attempt_success_by_scope: {
|
|
29
|
+
scope: string;
|
|
30
|
+
before: ReturnType<typeof phase>;
|
|
31
|
+
after: ReturnType<typeof phase>;
|
|
32
|
+
unclassified: ReturnType<typeof phase>;
|
|
33
|
+
unexposed: ReturnType<typeof phase>;
|
|
34
|
+
}[];
|
|
35
|
+
first_attempt_coverage: {
|
|
36
|
+
missing_first_attempts: number;
|
|
37
|
+
reconstructed_scopes: number;
|
|
38
|
+
interpretation: string;
|
|
39
|
+
};
|
|
40
|
+
served_helpfulness: {
|
|
41
|
+
helpful: number;
|
|
42
|
+
harmful: number;
|
|
43
|
+
ratio: number | null;
|
|
44
|
+
counter_scope: string;
|
|
45
|
+
};
|
|
46
|
+
distill_acceptance: {
|
|
47
|
+
checked: number;
|
|
48
|
+
submitted: number;
|
|
49
|
+
rate: number | null;
|
|
50
|
+
demonstrated_current_artifacts: number;
|
|
51
|
+
};
|
|
52
|
+
learning_overhead: {
|
|
53
|
+
learning_steps: number;
|
|
54
|
+
all_steps: number;
|
|
55
|
+
ratio: number | null;
|
|
56
|
+
opportunistic_payload_steps: number;
|
|
57
|
+
assignments: {
|
|
58
|
+
episode_id: string;
|
|
59
|
+
utf8_bytes: number;
|
|
60
|
+
token_upper_bound: number;
|
|
61
|
+
}[];
|
|
62
|
+
max_served_token_upper_bound: number | null;
|
|
63
|
+
token_method: string;
|
|
64
|
+
};
|
|
65
|
+
retirement_health: {
|
|
66
|
+
window_days: number;
|
|
67
|
+
retired: number;
|
|
68
|
+
ever_active: number;
|
|
69
|
+
ratio: number | null;
|
|
70
|
+
unknown_history: number;
|
|
71
|
+
};
|
|
72
|
+
distillation_steps: {
|
|
73
|
+
goal_id: string;
|
|
74
|
+
step_id: string;
|
|
75
|
+
checked: boolean;
|
|
76
|
+
items_after_20_serves: number;
|
|
77
|
+
mean_strong_helpfulness: number | null;
|
|
78
|
+
}[];
|
|
79
|
+
coverage: string;
|
|
80
|
+
};
|
|
81
|
+
export {};
|
|
82
|
+
//# sourceMappingURL=learning-scorecard.d.ts.map
|