refactor(v2/providers): self-registration barrel + host container-config registry

Providers now mirror the channels pattern: each module calls
registerProvider() at top level, and providers/index.ts is a barrel of
side-effect imports. createProvider() becomes a thin registry lookup;
the closed ProviderName union is gone (now a string alias, since the
env var is a runtime string anyway).

Also adds a host-side provider-container-registry so providers can
declare their own mounts and env passthrough in src/providers/<name>.ts
instead of the container-runner having to know about each one. The
resolver runs once per spawn and threads provider + contribution
through buildMounts and buildContainerArgs so side effects (mkdir,
etc.) fire exactly once.

Both barrels are append-only — adding a new provider is a new file
+ one import line per barrel, no edits to existing files. The built-in
providers (claude, mock) don't need host-side config, so src/providers/
ships with an empty barrel; the container-side barrel imports both.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
gavrielc
2026-04-17 11:34:29 +03:00
parent a38c6a962f
commit 1f3b023a5a
9 changed files with 186 additions and 22 deletions

View File

@@ -8,7 +8,8 @@
* - SESSION_INBOUND_DB_PATH: path to host-owned inbound DB (default: /workspace/inbound.db)
* - SESSION_OUTBOUND_DB_PATH: path to container-owned outbound DB (default: /workspace/outbound.db)
* - SESSION_HEARTBEAT_PATH: heartbeat file path (default: /workspace/.heartbeat)
* - AGENT_PROVIDER: 'claude' | 'mock' (default: claude)
* - AGENT_PROVIDER: any registered provider name (default: claude). The
* set of registered providers is whatever `providers/index.ts` imports.
* - NANOCLAW_ASSISTANT_NAME: assistant name for transcript archiving
* - NANOCLAW_ADMIN_USER_IDS: comma-separated user IDs allowed to run admin commands
*
@@ -27,6 +28,9 @@ import path from 'path';
import { fileURLToPath } from 'url';
import { buildSystemPromptAddendum } from './destinations.js';
// Providers barrel — each enabled provider self-registers on import.
// Provider skills append imports to providers/index.ts.
import './providers/index.js';
import { createProvider, type ProviderName } from './providers/factory.js';
import { runPollLoop } from './poll-loop.js';