Skip to content

Commit c1cfb19

Browse files
committed
refactor: support extending local executor without creating genkit
Currently `extends LocalExecutor` always means instantiating a Genkit instance. This makes it hard to come up with a custom prescrape LLM output executor that doesn't involve any LLM.
1 parent 2e78ec3 commit c1cfb19

File tree

3 files changed

+43
-1
lines changed

3 files changed

+43
-1
lines changed
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import {
2+
LlmRunner,
3+
LocalLlmConstrainedOutputGenerateResponse,
4+
LocalLlmGenerateFilesResponse,
5+
LocalLlmGenerateTextResponse,
6+
} from './llm-runner.js';
7+
8+
/**
9+
* Noop runner that is useful for creating a `LocalExecutor`
10+
* that doesn't leverage a runner specified to WCS.
11+
*
12+
* E.g. a custom executor that uses pre-scraped LLM output will override
13+
* corresponding generation methods in the `Executor` but doesn't want
14+
* the Genkit LLM runner to be instantiated just to expect a `GEMINI_API_KEY`.
15+
*/
16+
export class NoopUnimplementedRunner implements LlmRunner {
17+
displayName = 'noop-unimplemented';
18+
id = 'noop-unimplemented';
19+
hasBuiltInRepairLoop = true;
20+
21+
generateFiles(): Promise<LocalLlmGenerateFilesResponse> {
22+
throw new Error('Method not implemented.');
23+
}
24+
generateText(): Promise<LocalLlmGenerateTextResponse> {
25+
throw new Error('Method not implemented.');
26+
}
27+
generateConstrained(): Promise<LocalLlmConstrainedOutputGenerateResponse<any>> {
28+
throw new Error('Method not implemented.');
29+
}
30+
getSupportedModels(): string[] {
31+
throw new Error('Method not implemented.');
32+
}
33+
async dispose(): Promise<void> {
34+
throw new Error('Method not implemented.');
35+
}
36+
}

runner/codegen/runner-creation.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,14 @@ import type {GeminiCliRunner} from './gemini-cli-runner.js';
33
import type {ClaudeCodeRunner} from './claude-code-runner.js';
44
import type {GenkitRunner} from './genkit/genkit-runner.js';
55
import type {CodexRunner} from './codex-runner.js';
6+
import type {NoopUnimplementedRunner} from './noop-unimplemented-runner.js';
67

78
interface AvailableRunners {
89
genkit: GenkitRunner;
910
'gemini-cli': GeminiCliRunner;
1011
'claude-code': ClaudeCodeRunner;
1112
'codex': CodexRunner;
13+
'noop-unimplemented': NoopUnimplementedRunner;
1214
}
1315

1416
/** Names of supported runners. */
@@ -35,6 +37,10 @@ export async function getRunnerByName<T extends RunnerName>(name: T): Promise<Av
3537
);
3638
case 'codex':
3739
return import('./codex-runner.js').then(m => new m.CodexRunner() as AvailableRunners[T]);
40+
case 'noop-unimplemented':
41+
return import('./noop-unimplemented-runner.js').then(
42+
m => new m.NoopUnimplementedRunner() as AvailableRunners[T],
43+
);
3844
default:
3945
throw new UserFacingError(`Unsupported runner ${name}`);
4046
}

runner/orchestration/executors/local-executor.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ export class LocalExecutor implements Executor {
3636

3737
constructor(
3838
public config: LocalExecutorConfig,
39-
runnerName: RunnerName = 'genkit',
39+
runnerName: RunnerName = 'noop-unimplemented',
4040
) {
4141
this.llm = getRunnerByName(runnerName);
4242
}

0 commit comments

Comments
 (0)