singularity-forge/src
Mikael Hugo 385e0b4480
Some checks are pending
CI / detect-changes (push) Waiting to run
CI / docs-check (push) Blocked by required conditions
CI / lint (push) Blocked by required conditions
CI / build (push) Blocked by required conditions
CI / integration-tests (push) Blocked by required conditions
CI / windows-portability (push) Blocked by required conditions
CI / rtk-portability (linux, blacksmith-4vcpu-ubuntu-2404) (push) Blocked by required conditions
CI / rtk-portability (macos, macos-15) (push) Blocked by required conditions
CI / rtk-portability (windows, blacksmith-4vcpu-windows-2025) (push) Blocked by required conditions
feat(model-learner): canonicalIdFor consults discovery cache as fallback
After commit 089bf0cbe added 23 hand-written aliases for production
route keys, the right structural fix is to also consult the dynamic
model-discovery cache (~/.sf/agent/discovery-cache.json). Otherwise
every new model variant from a discovered provider (ollama-cloud +39
models, openrouter +24, etc.) requires another round of hand-editing.

canonicalIdFor now resolves in this order:
  1. CANONICAL_BY_ROUTE (static fast path, retains real aliases like
     kimi-coding/kimi-for-coding → kimi-k2.6 where canonical differs)
  2. _ENTRY_BY_ROUTE (existing static path)
  3. canonicalIdFromDiscovery — reads ~/.sf/agent/discovery-cache.json,
     finds (provider, modelId) pair, returns bare modelId

In-memory cache with 60s TTL (DISCOVERY_CACHE_TTL_MS) so the readFileSync
on the hot path becomes one disk read per minute at most. canonicalIdFor
is per-dispatch, not per-token, so the overhead is negligible.

Test hook __setDiscoveryCacheForTest lets vitest inject a cache without
touching the fs.

Tests: 6 new in canonical-id-dynamic.test.mjs (dynamic hit, static-alias
wins over dynamic, cache miss → null, null cache graceful, missing-models
graceful, multiple models per provider). Combined with existing
canonical-id-mapping: 22/22 pass. Full suite 1912 pass, no regressions.

Sanity verified: canonicalIdFor("ollama-cloud/glm-5.1") → "glm-5.1"
(dynamic-only, not in static table); canonicalIdFor("unknown/never")
→ null.

Follow-up (in flight, separate agent): prune the static identity-strip
aliases from CANONICAL_BY_ROUTE for providers in the discovery cache
since they're now redundant with the dynamic resolver.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 14:14:04 +02:00
..
resources feat(model-learner): canonicalIdFor consults discovery cache as fallback 2026-05-15 14:14:04 +02:00
tests fix(triage): --run routes through runTriageApply{dryRun:true} via SF router 2026-05-15 09:20:43 +02:00
web feat(notifications): tag remaining auto/loop/register-hooks notices + trace-writer 2026-05-10 20:14:22 +02:00
app-paths.ts sf snapshot: uncommitted changes after 93m inactivity 2026-05-06 11:37:27 +02:00
bundled-extension-paths.ts feat: introduce repo-vcs skill and add JSDoc annotations across core modules 2026-05-01 21:36:32 +02:00
bundled-resource-path.ts batch: snapshot of in-flight v2 work 2026-04-29 12:42:31 +02:00
claude-cli-check.ts batch: snapshot of in-flight v2 work 2026-04-29 12:42:31 +02:00
cli-logs.ts sf snapshot: uncommitted changes after 93m inactivity 2026-05-06 11:37:27 +02:00
cli-stats.ts style: format repository with biome 2026-05-05 14:31:16 +02:00
cli-status.ts feat(notifications): NOTICE_KIND enum, schema v2 dedup, sf-db cleanup 2026-05-10 20:13:58 +02:00
cli-web-branch.ts fix: make autonomous mode canonical 2026-05-05 15:42:10 +02:00
cli.ts fix: bound sf print mode and chat routing 2026-05-14 20:55:00 +02:00
env.ts fix(env): align SF_PERMISSION_LEVEL enum with permission-profile values 2026-05-14 21:11:36 +02:00
errors.ts feat: introduce repo-vcs skill and add JSDoc annotations across core modules 2026-05-01 21:36:32 +02:00
extension-discovery.ts fix: consolidate extensions into sf, migrate kernel.ts, fix test suite 2026-05-11 02:40:52 +02:00
extension-registry.ts feat: introduce repo-vcs skill and add JSDoc annotations across core modules 2026-05-01 21:36:32 +02:00
headless-answers.ts refactor: rename pi-* packages to forge-native names (Phase 1) 2026-05-10 11:28:01 +02:00
headless-context.ts refactor: align agent resource overlays 2026-05-14 19:32:41 +02:00
headless-events.ts fix(headless): do not restart graceful child exits 2026-05-15 07:25:06 +02:00
headless-import-backlog.ts sf snapshot: uncommitted changes after 49m inactivity 2026-05-12 16:45:04 +02:00
headless-query.ts fix: repair headless runtime self-healing 2026-05-15 03:33:29 +02:00
headless-reflect.ts refactor(reflect): route reflection-pass through loadPrompt in extension 2026-05-14 06:20:38 +02:00
headless-triage.ts fix(triage): --run routes through runTriageApply{dryRun:true} via SF router 2026-05-15 09:20:43 +02:00
headless-types.ts feat(notifications): NOTICE_KIND enum, schema v2 dedup, sf-db cleanup 2026-05-10 20:13:58 +02:00
headless-ui.ts refactor: rename pi-* packages to forge-native names (Phase 1) 2026-05-10 11:28:01 +02:00
headless-uok-status.ts fix(uok-status): surface manualAttention bucket in status uok output 2026-05-14 18:46:28 +02:00
headless-usage.ts feat(headless,gemini-cli): add sf headless usage + unify gemini quota path 2026-05-14 03:42:53 +02:00
headless.ts fix(headless): do not restart graceful child exits 2026-05-15 07:25:06 +02:00
help-text.ts refactor: rename review gate agent 2026-05-14 19:43:01 +02:00
interactive-session-lock.ts fix: enforce one interactive sf per repo 2026-05-05 20:55:53 +02:00
loader.ts fix(lint): reformat 6 files touched during web dep upgrade 2026-05-10 12:10:10 +02:00
logger.ts refactor: rename pi-* packages to forge-native names (Phase 1) 2026-05-10 11:28:01 +02:00
logo.ts batch: snapshot of in-flight v2 work 2026-04-29 12:42:31 +02:00
models-resolver.ts batch: snapshot of in-flight v2 work 2026-04-29 12:42:31 +02:00
onboarding.ts refactor: rename pi-* packages to forge-native names (Phase 1) 2026-05-10 11:28:01 +02:00
pi-migration.ts refactor: rename pi-* packages to forge-native names (Phase 1) 2026-05-10 11:28:01 +02:00
project-sessions.ts batch: snapshot of in-flight v2 work 2026-04-29 12:42:31 +02:00
provider-migrations.ts refactor: rename pi-* packages to forge-native names (Phase 1) 2026-05-10 11:28:01 +02:00
remote-questions-config.ts batch: snapshot of in-flight v2 work 2026-04-29 12:42:31 +02:00
resource-loader.ts fix: repair headless runtime self-healing 2026-05-15 03:33:29 +02:00
rtk.ts batch: snapshot of in-flight v2 work 2026-04-29 12:42:31 +02:00
security-overrides.ts refactor: rename pi-* packages to forge-native names (Phase 1) 2026-05-10 11:28:01 +02:00
startup-model-validation.ts chore: commit current workspace state 2026-05-05 14:46:18 +02:00
startup-timings.ts batch: snapshot of in-flight v2 work 2026-04-29 12:42:31 +02:00
tool-bootstrap.ts batch: snapshot of in-flight v2 work 2026-04-29 12:42:31 +02:00
traces.ts sf snapshot: uncommitted changes after 49m inactivity 2026-05-08 01:07:24 +02:00
update-check.ts fix: clean provider surfaces and core build 2026-05-05 16:31:53 +02:00
update-cmd.ts fix: clean provider surfaces and core build 2026-05-05 16:31:53 +02:00
web-mode.ts fix(sf): recover model routes and self-feedback 2026-05-02 22:07:10 +02:00
welcome-screen.ts fix: update test snapshots for queryInstruction and complete /sf prefix Phase 2 deprecation 2026-05-09 00:17:47 +02:00
wizard.ts refactor: rename pi-* packages to forge-native names (Phase 1) 2026-05-10 11:28:01 +02:00
worktree-cli.ts sf snapshot: uncommitted changes after 43m inactivity 2026-05-05 21:39:56 +02:00
worktree-name-gen.ts batch: snapshot of in-flight v2 work 2026-04-29 12:42:31 +02:00