refactor(x): shared lazyResolve for the no-static-DI-edge pattern

Four modules hand-rolled the same lazy container-import-and-resolve
dance (agent registry, spawn-agent, background-task runner, notifier),
each restating the rationale. di/lazy-resolve.ts holds the pattern and
the reasoning once; all four sites migrate.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Ramnique Singh 2026-07-10 08:50:39 +05:30
parent 8dd5a2b49f
commit ca077faa95
4 changed files with 10 additions and 11 deletions

View file

@ -10,6 +10,7 @@ import { getRaw as getLabelingAgentRaw } from "../knowledge/labeling_agent.js";
import { getRaw as getNoteTaggingAgentRaw } from "../knowledge/note_tagging_agent.js"; import { getRaw as getNoteTaggingAgentRaw } from "../knowledge/note_tagging_agent.js";
import { getRaw as getInlineTaskAgentRaw } from "../knowledge/inline_task_agent.js"; import { getRaw as getInlineTaskAgentRaw } from "../knowledge/inline_task_agent.js";
import { getRaw as getAgentNotesAgentRaw } from "../knowledge/agent_notes_agent.js"; import { getRaw as getAgentNotesAgentRaw } from "../knowledge/agent_notes_agent.js";
import { lazyResolve } from "../di/lazy-resolve.js";
import type { IAgentsRepo } from "./repo.js"; import type { IAgentsRepo } from "./repo.js";
// The registry of built-in agents: one table instead of the historical // The registry of built-in agents: one table instead of the historical
@ -89,9 +90,7 @@ export async function loadAgent(id: string): Promise<z.infer<typeof Agent>> {
if (builtin) { if (builtin) {
return builtin.build(); return builtin.build();
} }
// User-defined agents. The container is imported lazily so this module // User-defined agents (lazyResolve: no static DI edge from this module).
// adds no static edge into the DI graph (mirrors spawn-agent). const repo = await lazyResolve<IAgentsRepo>("agentsRepo");
const { default: container } = await import("../di/container.js");
const repo = container.resolve<IAgentsRepo>("agentsRepo");
return repo.fetch(id); return repo.fetch(id);
} }

View file

@ -219,13 +219,13 @@ export async function runSpawnedAgent(
async function resolveServices(): Promise< async function resolveServices(): Promise<
NonNullable<SpawnedAgentCallbacks["services"]> NonNullable<SpawnedAgentCallbacks["services"]>
> { > {
const { default: container } = await import("../di/container.js"); const { lazyResolve } = await import("../di/lazy-resolve.js");
return { return {
turnRuntime: turnRuntime:
container.resolve<import("../turns/api.js").ITurnRuntime>( await lazyResolve<import("../turns/api.js").ITurnRuntime>(
"turnRuntime", "turnRuntime",
), ),
headlessRunner: container.resolve< headlessRunner: await lazyResolve<
import("./headless.js").IHeadlessAgentRunner import("./headless.js").IHeadlessAgentRunner
>("headlessAgentRunner"), >("headlessAgentRunner"),
}; };

View file

@ -19,8 +19,8 @@ export async function notifyIfEnabled(
): Promise<void> { ): Promise<void> {
try { try {
if (!isNotificationCategoryEnabled(category)) return; if (!isNotificationCategoryEnabled(category)) return;
const { default: container } = await import('../../di/container.js'); const { lazyResolve } = await import('../../di/lazy-resolve.js');
const service = container.resolve<INotificationService>('notificationService'); const service = await lazyResolve<INotificationService>('notificationService');
if (!service.isSupported()) return; if (!service.isSupported()) return;
service.notify(input); service.notify(input);
} catch (err) { } catch (err) {

View file

@ -128,8 +128,8 @@ export async function runBackgroundTask(
let codeProject: { id: string; path: string; name: string } | undefined; let codeProject: { id: string; path: string; name: string } | undefined;
if (task.projectId) { if (task.projectId) {
try { try {
const { default: container } = await import('../di/container.js'); const { lazyResolve } = await import('../di/lazy-resolve.js');
const projectsRepo = container.resolve<import('../code-mode/projects/repo.js').ICodeProjectsRepo>('codeProjectsRepo'); const projectsRepo = await lazyResolve<import('../code-mode/projects/repo.js').ICodeProjectsRepo>('codeProjectsRepo');
const project = await projectsRepo.get(task.projectId); const project = await projectsRepo.get(task.projectId);
if (project) codeProject = { id: project.id, path: project.path, name: project.name }; if (project) codeProject = { id: project.id, path: project.path, name: project.name };
} catch (err) { } catch (err) {