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:
@@ -34,7 +34,7 @@ describe('poll loop integration', () => {
|
||||
it('should pick up a message, process it, and write a response', async () => {
|
||||
insertMessage('m1', { sender: 'Alice', text: 'What is the meaning of life?' }, { platformId: 'chan-1', channelType: 'discord', threadId: 'thread-1' });
|
||||
|
||||
const provider = new MockProvider(() => '<message to="discord-test">42</message>');
|
||||
const provider = new MockProvider({}, () => '<message to="discord-test">42</message>');
|
||||
|
||||
const controller = new AbortController();
|
||||
const loopPromise = runPollLoopWithTimeout(provider, controller.signal, 2000);
|
||||
@@ -60,7 +60,7 @@ describe('poll loop integration', () => {
|
||||
insertMessage('m1', { sender: 'Alice', text: 'Hello' });
|
||||
insertMessage('m2', { sender: 'Bob', text: 'World' });
|
||||
|
||||
const provider = new MockProvider(() => '<message to="discord-test">Got both messages</message>');
|
||||
const provider = new MockProvider({}, () => '<message to="discord-test">Got both messages</message>');
|
||||
const controller = new AbortController();
|
||||
const loopPromise = runPollLoopWithTimeout(provider, controller.signal, 2000);
|
||||
|
||||
@@ -75,7 +75,7 @@ describe('poll loop integration', () => {
|
||||
});
|
||||
|
||||
it('should process messages arriving after loop starts', async () => {
|
||||
const provider = new MockProvider(() => '<message to="discord-test">Processed</message>');
|
||||
const provider = new MockProvider({}, () => '<message to="discord-test">Processed</message>');
|
||||
const controller = new AbortController();
|
||||
const loopPromise = runPollLoopWithTimeout(provider, controller.signal, 3000);
|
||||
|
||||
@@ -99,8 +99,6 @@ async function runPollLoopWithTimeout(provider: MockProvider, signal: AbortSigna
|
||||
runPollLoop({
|
||||
provider,
|
||||
cwd: '/tmp',
|
||||
mcpServers: {},
|
||||
env: {},
|
||||
}),
|
||||
new Promise<void>((_, reject) => {
|
||||
signal.addEventListener('abort', () => reject(new Error('aborted')));
|
||||
|
||||
Reference in New Issue
Block a user