mirror of
https://github.com/garrytan/gbrain.git
synced 2026-07-28 14:59:47 +00:00
* feat(engine): listEnrichCandidates source-aware candidate selection (#1700) One SQL query per engine: thin-filter + per-page source-correct inbound-link count (to_page_id = p.id, mentions excluded) + enriched_at recency guard + whitelisted ORDER BY (ENRICH_ORDER_SQL) + LIMIT, returning a lightweight projection (no page bodies). EnrichCandidate/EnrichCandidatesOpts types. pg + pglite parity, pinned by engine-parity.test.ts. * feat(enrich): gbrain enrich --thin brain-internal grounded synthesis (#1700) Develops stub pages at scale by consolidating scattered brain knowledge (search + backlinks + facts + raw_data) into one grounded gateway.chat call per page. Resumable (op-checkpoint), budget-capped (best-effort under --workers), per-page advisory lock, put_page write-through. CLI + thin-client refuse + Minion handler. Includes codex-review fixes: sanitizeContext neutralizes the <context> envelope delimiters (P1 injection escape); background fan-out idempotency key carries the run fingerprint (P1); post-hoc budget-overage flag via new BudgetTracker.cap getter (P1); checkpoint flush on budget exhaustion (P2). Accepts the documented best-effort in-flight-cancel limitation (D5) with an explicit code note. * feat(cycle): enrich_thin opt-in autopilot phase (#1700) Default-OFF trickle around runEnrichCore: develops a few thin pages per source per tick so the brain compounds over time. Per-source cap enforced as min(per-source, brain-wide remaining) with brain-wide total + walltime caps (P2 fix: per-source max_cost_usd was parsed but never enforced). Wired into CyclePhase / ALL_PHASES / PHASE_SCOPE / NEEDS_LOCK + dispatch. * chore: bump version and changelog (v0.42.6.0) gbrain enrich --thin batch enrichment (#1700) + codex-review fixes. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
41 lines
1.7 KiB
TypeScript
41 lines
1.7 KiB
TypeScript
/**
|
|
* v0.41.39 (#1700) — P1#4 regression: the multi-source `--background` fan-out
|
|
* idempotency key must incorporate the full run config, so a re-run with
|
|
* different flags enqueues NEW work instead of returning the old job.
|
|
* Pure (no engine) — runs in the fast parallel loop.
|
|
*/
|
|
import { describe, test, expect } from 'bun:test';
|
|
import { backgroundIdempotencyKey } from '../../src/commands/enrich.ts';
|
|
|
|
describe('backgroundIdempotencyKey (P1#4)', () => {
|
|
test('namespaced by source id', () => {
|
|
expect(backgroundIdempotencyKey('dept-x', ['--thin'])).toMatch(/^enrich:dept-x:/);
|
|
});
|
|
|
|
test('same flags → same key (idempotent re-submit dedups)', () => {
|
|
const a = backgroundIdempotencyKey('default', ['--thin', '--model', 'anthropic:x']);
|
|
const b = backgroundIdempotencyKey('default', ['--thin', '--model', 'anthropic:x']);
|
|
expect(a).toBe(b);
|
|
});
|
|
|
|
test('different --model → different key (new job)', () => {
|
|
const a = backgroundIdempotencyKey('default', ['--thin', '--model', 'anthropic:x']);
|
|
const b = backgroundIdempotencyKey('default', ['--thin', '--model', 'anthropic:y']);
|
|
expect(a).not.toBe(b);
|
|
});
|
|
|
|
test('different --limit / --force / --dry-run → different key', () => {
|
|
const base = ['--thin'];
|
|
const k0 = backgroundIdempotencyKey('default', base);
|
|
expect(backgroundIdempotencyKey('default', [...base, '--limit', '50'])).not.toBe(k0);
|
|
expect(backgroundIdempotencyKey('default', [...base, '--force'])).not.toBe(k0);
|
|
expect(backgroundIdempotencyKey('default', [...base, '--dry-run'])).not.toBe(k0);
|
|
});
|
|
|
|
test('different source id → different key', () => {
|
|
expect(backgroundIdempotencyKey('a', ['--thin'])).not.toBe(
|
|
backgroundIdempotencyKey('b', ['--thin']),
|
|
);
|
|
});
|
|
});
|