refactor(agent-runner): decouple provider interface from Claude specifics
Reshape AgentProvider so provider-specific assumptions stop leaking into the generic layer. No change to what reaches sdkQuery() — same values, different plumbing. - QueryInput: opaque `continuation` replaces `sessionId` + `resumeAt`; `systemContext.instructions` replaces ambiguous `systemPrompt`; `mcpServers`, `env`, `additionalDirectories` move to `ProviderOptions` at construction time. - AgentProvider gains `isSessionInvalid(err)` and `supportsNativeSlashCommands` so the poll-loop stops regex-matching Claude error strings and gates passthrough slash commands per provider. - ClaudeProvider owns `CLAUDE_CODE_AUTO_COMPACT_WINDOW` and the stale-session regex internally. - ProviderEvent.activity kept and documented as the liveness signal (fires on every SDK message so the idle timer stays honest during long tool runs); init carries `continuation` instead of `sessionId`. - poll-loop drops mcpServers/env/systemPrompt from its config; admin user id now passed explicitly. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -40,19 +40,18 @@ const GLOBAL_CLAUDE_MD = '/workspace/global/CLAUDE.md';
|
||||
async function main(): Promise<void> {
|
||||
const providerName = (process.env.AGENT_PROVIDER || 'claude') as ProviderName;
|
||||
const assistantName = process.env.NANOCLAW_ASSISTANT_NAME;
|
||||
const adminUserId = process.env.NANOCLAW_ADMIN_USER_ID;
|
||||
|
||||
log(`Starting v2 agent-runner (provider: ${providerName})`);
|
||||
|
||||
const provider = createProvider(providerName, { assistantName });
|
||||
|
||||
// Load global CLAUDE.md as additional system context, then append destinations addendum
|
||||
let systemPrompt: string | undefined;
|
||||
let instructions: string | undefined;
|
||||
if (fs.existsSync(GLOBAL_CLAUDE_MD)) {
|
||||
systemPrompt = fs.readFileSync(GLOBAL_CLAUDE_MD, 'utf-8');
|
||||
instructions = fs.readFileSync(GLOBAL_CLAUDE_MD, 'utf-8');
|
||||
log('Loaded global CLAUDE.md');
|
||||
}
|
||||
const addendum = buildSystemPromptAddendum();
|
||||
systemPrompt = systemPrompt ? `${systemPrompt}\n\n${addendum}` : addendum;
|
||||
instructions = instructions ? `${instructions}\n\n${addendum}` : addendum;
|
||||
|
||||
// Discover additional directories mounted at /workspace/extra/*
|
||||
const additionalDirectories: string[] = [];
|
||||
@@ -73,12 +72,6 @@ async function main(): Promise<void> {
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||
const mcpServerPath = path.join(__dirname, 'mcp-tools', 'index.js');
|
||||
|
||||
// SDK env
|
||||
const env: Record<string, string | undefined> = {
|
||||
...process.env,
|
||||
CLAUDE_CODE_AUTO_COMPACT_WINDOW: '165000',
|
||||
};
|
||||
|
||||
// Build MCP servers config: nanoclaw built-in + any additional from host
|
||||
const mcpServers: Record<string, { command: string; args: string[]; env: Record<string, string> }> = {
|
||||
nanoclaw: {
|
||||
@@ -105,13 +98,18 @@ async function main(): Promise<void> {
|
||||
}
|
||||
}
|
||||
|
||||
const provider = createProvider(providerName, {
|
||||
assistantName,
|
||||
mcpServers,
|
||||
env: { ...process.env },
|
||||
additionalDirectories: additionalDirectories.length > 0 ? additionalDirectories : undefined,
|
||||
});
|
||||
|
||||
await runPollLoop({
|
||||
provider,
|
||||
cwd: CWD,
|
||||
mcpServers,
|
||||
systemPrompt,
|
||||
env,
|
||||
additionalDirectories: additionalDirectories.length > 0 ? additionalDirectories : undefined,
|
||||
systemContext: { instructions },
|
||||
adminUserId,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user