Phase 28-36 body of work
Accumulated since a6f12e2 (Phase 21 Rust port + Phase 27 versioning):
- Phase 36: embed_semaphore on VectorState (permits=1) serializes
seed embed calls — prevents sidecar socket collisions under
concurrent /seed stress load
- Phase 31+: run_stress.ts 6-task diverse stress scaffolding;
run_e2e_rated.ts + orchestrator.ts tightening
- Catalog dedupe cleanup: 16 duplicate manifests removed; canonical
candidates.parquet (10.5MB -> 76KB) + placements.parquet (1.2MB ->
11KB) regenerated post-dedupe; fresh manifests for active datasets
- vectord: harness EvalSet refinements (+181), agent portfolio
rotation + ingest triggers (+158), autotune + rag adjustments
- catalogd/storaged/ingestd/mcp-server: misc tightening
- docs: Phase 28-36 PRD entries + DECISIONS ADR additions;
control-plane pivot banner added to top of docs/PRD.md (pointing
at docs/CONTROL_PLANE_PRD.md which lands in next commit)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.7
parent
a6f12e2609
commit
5b1fcf6d27
@@ -75,7 +75,7 @@ async function runOrchestrator(task: TaskSpec, prefix: string): Promise<RunResul
|
||||
turn += 1;
|
||||
|
||||
// Executor
|
||||
const execRaw = await generate(EXECUTOR_MODEL, executorPrompt(task, log), { temperature: 0.2, max_tokens: 1200 });
|
||||
const execRaw = await generate(EXECUTOR_MODEL, executorPrompt(task, log), { temperature: 0.2, max_tokens: 1200, think: false });
|
||||
const execAction = parseAction(execRaw, "executor");
|
||||
append({ turn, role: "executor", model: EXECUTOR_MODEL, kind: execAction.kind as any, content: execAction });
|
||||
|
||||
@@ -95,7 +95,7 @@ async function runOrchestrator(task: TaskSpec, prefix: string): Promise<RunResul
|
||||
}
|
||||
|
||||
// Reviewer
|
||||
const revRaw = await generate(REVIEWER_MODEL, reviewerPrompt(task, log), { temperature: 0.1, max_tokens: 1000 });
|
||||
const revRaw = await generate(REVIEWER_MODEL, reviewerPrompt(task, log), { temperature: 0.1, max_tokens: 1000, think: false });
|
||||
const revAction = parseAction(revRaw, "reviewer");
|
||||
append({ turn, role: "reviewer", model: REVIEWER_MODEL, kind: "critique", content: revAction });
|
||||
|
||||
@@ -116,31 +116,6 @@ async function runOrchestrator(task: TaskSpec, prefix: string): Promise<RunResul
|
||||
|
||||
if (!sealed) throw new Error(`no consensus after ${MAX_TURNS} turns`);
|
||||
|
||||
// Phase 19 write-through: seed playbook_memory so the next semantically
|
||||
// similar query benefits from this fill. Mirrors orchestrator.ts. Names
|
||||
// are the consensus fills' display names — that's what the boost-key
|
||||
// matcher (city, state, name) will look up against worker chunks.
|
||||
try {
|
||||
const seedRes = await fetch(`${GATEWAY}/vectors/playbook_memory/seed`, {
|
||||
method: "POST", headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({
|
||||
operation: task.operation,
|
||||
approach: sealed.approach || "multi-agent → hybrid search",
|
||||
context: task.approach_hint ?? `${task.target_role} fill in ${task.target_city}, ${task.target_state}`,
|
||||
endorsed_names: sealed.fills.map(f => f.name),
|
||||
append: true,
|
||||
}),
|
||||
});
|
||||
if (!seedRes.ok) {
|
||||
console.warn(`[${prefix}] seed warning: ${seedRes.status} ${await seedRes.text()}`);
|
||||
} else {
|
||||
const j = await seedRes.json() as any;
|
||||
console.log(`[${prefix}] ↳ seeded playbook_memory: id=${j.playbook_id} entries=${j.entries_after}`);
|
||||
}
|
||||
} catch (e) {
|
||||
console.warn(`[${prefix}] seed errored: ${(e as Error).message}`);
|
||||
}
|
||||
|
||||
return {
|
||||
task, ok: true, turns: turn, fills: sealed.fills, approach: sealed.approach,
|
||||
duration_secs: Math.round((Date.now() - start) / 1000), log,
|
||||
@@ -344,6 +319,39 @@ async function main() {
|
||||
throw new Error(`both orchestrators failed — substrate or models in bad state`);
|
||||
}
|
||||
|
||||
// Sequential seed after parallel runs — avoids concurrent embed socket collision
|
||||
async function seedTask(res: RunResult, prefix: string) {
|
||||
if (!res.ok || res.fills.length === 0) return;
|
||||
for (let attempt = 0; attempt < 3; attempt++) {
|
||||
try {
|
||||
const r = await fetch(`${GATEWAY}/vectors/playbook_memory/seed`, {
|
||||
method: "POST", headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({
|
||||
operation: res.task.operation,
|
||||
approach: res.approach || "multi-agent → hybrid search",
|
||||
context: res.task.approach_hint ?? `${res.task.target_role} fill in ${res.task.target_city}, ${res.task.target_state}`,
|
||||
endorsed_names: res.fills.map(f => f.name),
|
||||
append: true,
|
||||
}),
|
||||
});
|
||||
if (r.ok) {
|
||||
const j = await r.json() as any;
|
||||
console.log(`[${prefix}] ↳ seeded playbook_memory: id=${j.outcome?.playbook_id ?? j.playbook_id} entries=${j.entries_after}`);
|
||||
} else {
|
||||
console.warn(`[${prefix}] seed warning: ${r.status} ${await r.text()}`);
|
||||
}
|
||||
return;
|
||||
} catch (e) {
|
||||
if (attempt === 2) { console.warn(`[${prefix}] seed errored: ${(e as Error).message}`); return; }
|
||||
await Bun.sleep(1000 * (attempt + 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
await seedTask(resA, "A");
|
||||
await Bun.sleep(5000);
|
||||
await seedTask(resB, "B");
|
||||
|
||||
const statsMid = await fetchMemoryStats();
|
||||
console.log(`\n▶ playbook_memory after both runs: ${statsMid.entries} entries (+${statsMid.entries - statsBefore.entries})\n`);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user