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:
@@ -1,16 +1,22 @@
|
||||
import type { AgentProvider, AgentQuery, ProviderEvent, QueryInput } from './types.js';
|
||||
import type { AgentProvider, AgentQuery, ProviderEvent, ProviderOptions, QueryInput } from './types.js';
|
||||
|
||||
/**
|
||||
* Mock provider for testing. Returns canned responses.
|
||||
* Supports push() — queued messages produce additional results.
|
||||
*/
|
||||
export class MockProvider implements AgentProvider {
|
||||
readonly supportsNativeSlashCommands = false;
|
||||
|
||||
private responseFactory: (prompt: string) => string;
|
||||
|
||||
constructor(responseFactory?: (prompt: string) => string) {
|
||||
constructor(_options: ProviderOptions = {}, responseFactory?: (prompt: string) => string) {
|
||||
this.responseFactory = responseFactory ?? ((prompt) => `Mock response to: ${prompt.slice(0, 100)}`);
|
||||
}
|
||||
|
||||
isSessionInvalid(_err: unknown): boolean {
|
||||
return false;
|
||||
}
|
||||
|
||||
query(input: QueryInput): AgentQuery {
|
||||
const pending: string[] = [];
|
||||
let waiting: (() => void) | null = null;
|
||||
@@ -21,7 +27,7 @@ export class MockProvider implements AgentProvider {
|
||||
const events: AsyncIterable<ProviderEvent> = {
|
||||
async *[Symbol.asyncIterator]() {
|
||||
yield { type: 'activity' };
|
||||
yield { type: 'init', sessionId: `mock-session-${Date.now()}` };
|
||||
yield { type: 'init', continuation: `mock-session-${Date.now()}` };
|
||||
|
||||
// Process initial prompt
|
||||
yield { type: 'activity' };
|
||||
|
||||
Reference in New Issue
Block a user