mcp-codex-worker 0.1.11 → 0.1.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/src/execution/base-adapter.d.ts +63 -0
- package/dist/src/execution/base-adapter.js +74 -0
- package/dist/src/execution/base-adapter.js.map +1 -0
- package/dist/src/execution/claude-adapter.d.ts +12 -0
- package/dist/src/execution/claude-adapter.js +23 -0
- package/dist/src/execution/claude-adapter.js.map +1 -0
- package/dist/src/execution/codex-adapter.d.ts +21 -0
- package/dist/src/execution/codex-adapter.js +35 -0
- package/dist/src/execution/codex-adapter.js.map +1 -0
- package/dist/src/execution/codex-pause-flow.d.ts +23 -0
- package/dist/src/execution/codex-pause-flow.js +185 -0
- package/dist/src/execution/codex-pause-flow.js.map +1 -0
- package/dist/src/execution/copilot-adapter.d.ts +12 -0
- package/dist/src/execution/copilot-adapter.js +23 -0
- package/dist/src/execution/copilot-adapter.js.map +1 -0
- package/dist/src/execution/provider-capabilities.d.ts +35 -0
- package/dist/src/execution/provider-capabilities.js +58 -0
- package/dist/src/execution/provider-capabilities.js.map +1 -0
- package/dist/src/execution/provider-registry.d.ts +37 -0
- package/dist/src/execution/provider-registry.js +69 -0
- package/dist/src/execution/provider-registry.js.map +1 -0
- package/dist/src/mcp/resource-renderers.d.ts +25 -0
- package/dist/src/mcp/resource-renderers.js +190 -0
- package/dist/src/mcp/resource-renderers.js.map +1 -0
- package/dist/src/mcp/sep1686-handlers.d.ts +56 -0
- package/dist/src/mcp/sep1686-handlers.js +98 -0
- package/dist/src/mcp/sep1686-handlers.js.map +1 -0
- package/dist/src/mcp/tool-definitions.d.ts +157 -0
- package/dist/src/mcp/tool-definitions.js +242 -0
- package/dist/src/mcp/tool-definitions.js.map +1 -1
- package/dist/src/task/fsm-transitions.d.ts +17 -0
- package/dist/src/task/fsm-transitions.js +66 -0
- package/dist/src/task/fsm-transitions.js.map +1 -0
- package/dist/src/task/task-handle-impl.d.ts +10 -0
- package/dist/src/task/task-handle-impl.js +139 -0
- package/dist/src/task/task-handle-impl.js.map +1 -0
- package/dist/src/task/task-handle.d.ts +88 -0
- package/dist/src/task/task-handle.js +2 -0
- package/dist/src/task/task-handle.js.map +1 -0
- package/dist/src/task/task-manager.d.ts +99 -0
- package/dist/src/task/task-manager.js +246 -0
- package/dist/src/task/task-manager.js.map +1 -0
- package/dist/src/task/task-persistence.d.ts +18 -0
- package/dist/src/task/task-persistence.js +61 -0
- package/dist/src/task/task-persistence.js.map +1 -0
- package/dist/src/task/task-state.d.ts +79 -0
- package/dist/src/task/task-state.js +24 -0
- package/dist/src/task/task-state.js.map +1 -0
- package/dist/src/task/task-store.d.ts +46 -0
- package/dist/src/task/task-store.js +104 -0
- package/dist/src/task/task-store.js.map +1 -0
- package/dist/src/task/wire-state-mapper.d.ts +21 -0
- package/dist/src/task/wire-state-mapper.js +63 -0
- package/dist/src/task/wire-state-mapper.js.map +1 -0
- package/package.json +2 -1
- package/src/execution/base-adapter.ts +133 -0
- package/src/execution/claude-adapter.ts +40 -0
- package/src/execution/codex-adapter.ts +67 -0
- package/src/execution/codex-pause-flow.ts +225 -0
- package/src/execution/copilot-adapter.ts +40 -0
- package/src/execution/provider-capabilities.ts +100 -0
- package/src/execution/provider-registry.ts +81 -0
- package/src/mcp/resource-renderers.ts +224 -0
- package/src/mcp/sep1686-handlers.ts +149 -0
- package/src/mcp/tool-definitions.ts +255 -0
- package/src/task/fsm-transitions.ts +72 -0
- package/src/task/task-handle-impl.ts +170 -0
- package/src/task/task-handle.ts +135 -0
- package/src/task/task-manager.ts +328 -0
- package/src/task/task-persistence.ts +95 -0
- package/src/task/task-state.ts +121 -0
- package/src/task/task-store.ts +121 -0
- package/src/task/wire-state-mapper.ts +77 -0
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import type { TaskHandle } from '../task/task-handle.js';
|
|
2
|
+
import type { Provider } from '../task/task-state.js';
|
|
3
|
+
import type { ProviderCapabilities } from './provider-capabilities.js';
|
|
4
|
+
/**
|
|
5
|
+
* Options passed to `BaseProviderAdapter.spawn()` to start a provider session.
|
|
6
|
+
*/
|
|
7
|
+
export interface ProviderSpawnOptions {
|
|
8
|
+
taskId: string;
|
|
9
|
+
prompt: string;
|
|
10
|
+
cwd: string;
|
|
11
|
+
timeout: number;
|
|
12
|
+
model?: string;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Result of an availability check on a provider adapter.
|
|
16
|
+
*/
|
|
17
|
+
export type AvailabilityResult = {
|
|
18
|
+
available: true;
|
|
19
|
+
} | {
|
|
20
|
+
available: false;
|
|
21
|
+
reason: string;
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* Base class for all provider adapters.
|
|
25
|
+
*
|
|
26
|
+
* Implements the Template Method pattern: `spawn()` provides the common
|
|
27
|
+
* lifecycle skeleton (abort controller, timeout, error handling) and
|
|
28
|
+
* delegates the actual provider interaction to `executeSession()`.
|
|
29
|
+
*/
|
|
30
|
+
export declare abstract class BaseProviderAdapter {
|
|
31
|
+
/** Unique provider identifier. */
|
|
32
|
+
abstract readonly id: Provider;
|
|
33
|
+
/** Human-readable display name. */
|
|
34
|
+
abstract readonly displayName: string;
|
|
35
|
+
/** Check whether the provider is currently available. */
|
|
36
|
+
abstract checkAvailability(): AvailabilityResult;
|
|
37
|
+
/** Return the capability matrix for this provider. */
|
|
38
|
+
abstract getCapabilities(): ProviderCapabilities;
|
|
39
|
+
/** Return runtime statistics for observability. */
|
|
40
|
+
abstract getStats(): Record<string, unknown>;
|
|
41
|
+
/**
|
|
42
|
+
* Template Method hook — the actual provider session logic.
|
|
43
|
+
* Subclasses implement this to drive the provider (spawn process, call API, etc.).
|
|
44
|
+
*/
|
|
45
|
+
protected abstract executeSession(handle: TaskHandle, prompt: string, signal: AbortSignal, options: ProviderSpawnOptions): Promise<void>;
|
|
46
|
+
/**
|
|
47
|
+
* Spawn a provider session for the given task.
|
|
48
|
+
*
|
|
49
|
+
* Template method: checks terminal state, sets up AbortController + timeout,
|
|
50
|
+
* calls `executeSession`, and handles errors.
|
|
51
|
+
*/
|
|
52
|
+
spawn(options: ProviderSpawnOptions, handle: TaskHandle): Promise<void>;
|
|
53
|
+
/**
|
|
54
|
+
* Attempt to abort a running task by ID.
|
|
55
|
+
* Default implementation returns false (not supported).
|
|
56
|
+
*/
|
|
57
|
+
abort(_taskId: string): Promise<boolean>;
|
|
58
|
+
/**
|
|
59
|
+
* Graceful shutdown hook. Called when the server is stopping.
|
|
60
|
+
* Default implementation is a no-op.
|
|
61
|
+
*/
|
|
62
|
+
shutdown(): Promise<void>;
|
|
63
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// BaseProviderAdapter — Template Method pattern for provider lifecycle
|
|
3
|
+
// Spec reference: §3.4
|
|
4
|
+
// ---------------------------------------------------------------------------
|
|
5
|
+
// ---------------------------------------------------------------------------
|
|
6
|
+
// Abstract class
|
|
7
|
+
// ---------------------------------------------------------------------------
|
|
8
|
+
/**
|
|
9
|
+
* Base class for all provider adapters.
|
|
10
|
+
*
|
|
11
|
+
* Implements the Template Method pattern: `spawn()` provides the common
|
|
12
|
+
* lifecycle skeleton (abort controller, timeout, error handling) and
|
|
13
|
+
* delegates the actual provider interaction to `executeSession()`.
|
|
14
|
+
*/
|
|
15
|
+
export class BaseProviderAdapter {
|
|
16
|
+
// -- Public lifecycle methods ---------------------------------------------
|
|
17
|
+
/**
|
|
18
|
+
* Spawn a provider session for the given task.
|
|
19
|
+
*
|
|
20
|
+
* Template method: checks terminal state, sets up AbortController + timeout,
|
|
21
|
+
* calls `executeSession`, and handles errors.
|
|
22
|
+
*/
|
|
23
|
+
async spawn(options, handle) {
|
|
24
|
+
// Guard: do nothing if already in a terminal state
|
|
25
|
+
if (handle.isTerminal()) {
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
const controller = new AbortController();
|
|
29
|
+
handle.registerAbort(controller);
|
|
30
|
+
let timer;
|
|
31
|
+
if (options.timeout > 0) {
|
|
32
|
+
timer = setTimeout(() => {
|
|
33
|
+
controller.abort();
|
|
34
|
+
}, options.timeout);
|
|
35
|
+
// Allow the Node.js process to exit even if this timer is pending
|
|
36
|
+
if (timer && typeof timer === 'object' && 'unref' in timer) {
|
|
37
|
+
timer.unref();
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
try {
|
|
41
|
+
await this.executeSession(handle, options.prompt, controller.signal, options);
|
|
42
|
+
}
|
|
43
|
+
catch (err) {
|
|
44
|
+
if (controller.signal.aborted) {
|
|
45
|
+
handle.markCancelled('Session timed out');
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
49
|
+
handle.markFailed(message);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
finally {
|
|
53
|
+
if (timer !== undefined) {
|
|
54
|
+
clearTimeout(timer);
|
|
55
|
+
}
|
|
56
|
+
handle.unregisterAbort();
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Attempt to abort a running task by ID.
|
|
61
|
+
* Default implementation returns false (not supported).
|
|
62
|
+
*/
|
|
63
|
+
async abort(_taskId) {
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Graceful shutdown hook. Called when the server is stopping.
|
|
68
|
+
* Default implementation is a no-op.
|
|
69
|
+
*/
|
|
70
|
+
async shutdown() {
|
|
71
|
+
// no-op by default
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=base-adapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base-adapter.js","sourceRoot":"","sources":["../../../src/execution/base-adapter.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,uEAAuE;AACvE,uBAAuB;AACvB,8EAA8E;AA4B9E,8EAA8E;AAC9E,iBAAiB;AACjB,8EAA8E;AAE9E;;;;;;GAMG;AACH,MAAM,OAAgB,mBAAmB;IA6BvC,4EAA4E;IAE5E;;;;;OAKG;IACH,KAAK,CAAC,KAAK,CAAC,OAA6B,EAAE,MAAkB;QAC3D,mDAAmD;QACnD,IAAI,MAAM,CAAC,UAAU,EAAE,EAAE,CAAC;YACxB,OAAO;QACT,CAAC;QAED,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;QACzC,MAAM,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC;QAEjC,IAAI,KAAgD,CAAC;QAErD,IAAI,OAAO,CAAC,OAAO,GAAG,CAAC,EAAE,CAAC;YACxB,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;gBACtB,UAAU,CAAC,KAAK,EAAE,CAAC;YACrB,CAAC,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;YACpB,kEAAkE;YAClE,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,OAAO,IAAI,KAAK,EAAE,CAAC;gBAC3D,KAAK,CAAC,KAAK,EAAE,CAAC;YAChB,CAAC;QACH,CAAC;QAED,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,cAAc,CAAC,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,UAAU,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAChF,CAAC;QAAC,OAAO,GAAY,EAAE,CAAC;YACtB,IAAI,UAAU,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;gBAC9B,MAAM,CAAC,aAAa,CAAC,mBAAmB,CAAC,CAAC;YAC5C,CAAC;iBAAM,CAAC;gBACN,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;gBACjE,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;YAC7B,CAAC;QACH,CAAC;gBAAS,CAAC;YACT,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;gBACxB,YAAY,CAAC,KAAK,CAAC,CAAC;YACtB,CAAC;YACD,MAAM,CAAC,eAAe,EAAE,CAAC;QAC3B,CAAC;IACH,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,KAAK,CAAC,OAAe;QACzB,OAAO,KAAK,CAAC;IACf,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,QAAQ;QACZ,mBAAmB;IACrB,CAAC;CACF"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { Provider } from '../task/task-state.js';
|
|
2
|
+
import type { TaskHandle } from '../task/task-handle.js';
|
|
3
|
+
import type { ProviderCapabilities } from './provider-capabilities.js';
|
|
4
|
+
import { BaseProviderAdapter, type ProviderSpawnOptions, type AvailabilityResult } from './base-adapter.js';
|
|
5
|
+
export declare class ClaudeAdapter extends BaseProviderAdapter {
|
|
6
|
+
readonly id: Provider;
|
|
7
|
+
readonly displayName = "Claude";
|
|
8
|
+
checkAvailability(): AvailabilityResult;
|
|
9
|
+
getCapabilities(): ProviderCapabilities;
|
|
10
|
+
getStats(): Record<string, unknown>;
|
|
11
|
+
protected executeSession(_handle: TaskHandle, _prompt: string, _signal: AbortSignal, _options: ProviderSpawnOptions): Promise<void>;
|
|
12
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// ClaudeAdapter — Phase 2 stub
|
|
3
|
+
// Spec reference: §3.4
|
|
4
|
+
// ---------------------------------------------------------------------------
|
|
5
|
+
import { CLAUDE_CAPABILITIES } from './provider-capabilities.js';
|
|
6
|
+
import { BaseProviderAdapter, } from './base-adapter.js';
|
|
7
|
+
export class ClaudeAdapter extends BaseProviderAdapter {
|
|
8
|
+
id = 'claude-cli';
|
|
9
|
+
displayName = 'Claude';
|
|
10
|
+
checkAvailability() {
|
|
11
|
+
return { available: false, reason: 'Phase 2 — not yet implemented' };
|
|
12
|
+
}
|
|
13
|
+
getCapabilities() {
|
|
14
|
+
return CLAUDE_CAPABILITIES;
|
|
15
|
+
}
|
|
16
|
+
getStats() {
|
|
17
|
+
return {};
|
|
18
|
+
}
|
|
19
|
+
async executeSession(_handle, _prompt, _signal, _options) {
|
|
20
|
+
throw new Error('Not implemented — Phase 2');
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=claude-adapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude-adapter.js","sourceRoot":"","sources":["../../../src/execution/claude-adapter.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,+BAA+B;AAC/B,uBAAuB;AACvB,8EAA8E;AAK9E,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EACL,mBAAmB,GAGpB,MAAM,mBAAmB,CAAC;AAE3B,MAAM,OAAO,aAAc,SAAQ,mBAAmB;IAC3C,EAAE,GAAa,YAAY,CAAC;IAC5B,WAAW,GAAG,QAAQ,CAAC;IAEhC,iBAAiB;QACf,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,+BAA+B,EAAE,CAAC;IACvE,CAAC;IAED,eAAe;QACb,OAAO,mBAAmB,CAAC;IAC7B,CAAC;IAED,QAAQ;QACN,OAAO,EAAE,CAAC;IACZ,CAAC;IAES,KAAK,CAAC,cAAc,CAC5B,OAAmB,EACnB,OAAe,EACf,OAAoB,EACpB,QAA8B;QAE9B,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;IAC/C,CAAC;CACF"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { Provider } from '../task/task-state.js';
|
|
2
|
+
import type { TaskHandle } from '../task/task-handle.js';
|
|
3
|
+
import type { ProviderCapabilities } from './provider-capabilities.js';
|
|
4
|
+
import { BaseProviderAdapter, type ProviderSpawnOptions, type AvailabilityResult } from './base-adapter.js';
|
|
5
|
+
export interface CodexAdapterOptions {
|
|
6
|
+
command?: string;
|
|
7
|
+
args?: string[];
|
|
8
|
+
env?: NodeJS.ProcessEnv;
|
|
9
|
+
}
|
|
10
|
+
export declare class CodexAdapter extends BaseProviderAdapter {
|
|
11
|
+
readonly id: Provider;
|
|
12
|
+
readonly displayName = "Codex";
|
|
13
|
+
private readonly options;
|
|
14
|
+
private runtime?;
|
|
15
|
+
constructor(options: CodexAdapterOptions);
|
|
16
|
+
checkAvailability(): AvailabilityResult;
|
|
17
|
+
getCapabilities(): ProviderCapabilities;
|
|
18
|
+
getStats(): Record<string, unknown>;
|
|
19
|
+
protected executeSession(_handle: TaskHandle, _prompt: string, _signal: AbortSignal, _options: ProviderSpawnOptions): Promise<void>;
|
|
20
|
+
shutdown(): Promise<void>;
|
|
21
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// CodexAdapter — wraps CodexRuntime behind the BaseProviderAdapter contract
|
|
3
|
+
// Spec reference: §3.4
|
|
4
|
+
// ---------------------------------------------------------------------------
|
|
5
|
+
import { CODEX_CAPABILITIES } from './provider-capabilities.js';
|
|
6
|
+
import { BaseProviderAdapter, } from './base-adapter.js';
|
|
7
|
+
// ---------------------------------------------------------------------------
|
|
8
|
+
// Adapter
|
|
9
|
+
// ---------------------------------------------------------------------------
|
|
10
|
+
export class CodexAdapter extends BaseProviderAdapter {
|
|
11
|
+
id = 'codex';
|
|
12
|
+
displayName = 'Codex';
|
|
13
|
+
options;
|
|
14
|
+
runtime;
|
|
15
|
+
constructor(options) {
|
|
16
|
+
super();
|
|
17
|
+
this.options = options;
|
|
18
|
+
}
|
|
19
|
+
checkAvailability() {
|
|
20
|
+
return { available: true };
|
|
21
|
+
}
|
|
22
|
+
getCapabilities() {
|
|
23
|
+
return CODEX_CAPABILITIES;
|
|
24
|
+
}
|
|
25
|
+
getStats() {
|
|
26
|
+
return {};
|
|
27
|
+
}
|
|
28
|
+
async executeSession(_handle, _prompt, _signal, _options) {
|
|
29
|
+
throw new Error('CodexAdapter.executeSession is not yet implemented');
|
|
30
|
+
}
|
|
31
|
+
async shutdown() {
|
|
32
|
+
await this.runtime?.shutdown();
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=codex-adapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codex-adapter.js","sourceRoot":"","sources":["../../../src/execution/codex-adapter.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,4EAA4E;AAC5E,uBAAuB;AACvB,8EAA8E;AAK9E,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAChE,OAAO,EACL,mBAAmB,GAGpB,MAAM,mBAAmB,CAAC;AAa3B,8EAA8E;AAC9E,UAAU;AACV,8EAA8E;AAE9E,MAAM,OAAO,YAAa,SAAQ,mBAAmB;IAC1C,EAAE,GAAa,OAAO,CAAC;IACvB,WAAW,GAAG,OAAO,CAAC;IAEd,OAAO,CAAsB;IACtC,OAAO,CAAgB;IAE/B,YAAY,OAA4B;QACtC,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACzB,CAAC;IAED,iBAAiB;QACf,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;IAC7B,CAAC;IAED,eAAe;QACb,OAAO,kBAAkB,CAAC;IAC5B,CAAC;IAED,QAAQ;QACN,OAAO,EAAE,CAAC;IACZ,CAAC;IAES,KAAK,CAAC,cAAc,CAC5B,OAAmB,EACnB,OAAe,EACf,OAAoB,EACpB,QAA8B;QAE9B,MAAM,IAAI,KAAK,CAAC,oDAAoD,CAAC,CAAC;IACxE,CAAC;IAED,KAAK,CAAC,QAAQ;QACZ,MAAM,IAAI,CAAC,OAAO,EAAE,QAAQ,EAAE,CAAC;IACjC,CAAC;CACF"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { AppServerClient } from '../services/app-server-client.js';
|
|
2
|
+
import type { TaskHandle } from '../task/task-handle.js';
|
|
3
|
+
import type { PendingQuestion } from '../task/task-state.js';
|
|
4
|
+
import type { JsonLineRequest } from '../types/codex.js';
|
|
5
|
+
/**
|
|
6
|
+
* Translate a raw Codex JSON-RPC server request into a provider-blind
|
|
7
|
+
* PendingQuestion variant.
|
|
8
|
+
*
|
|
9
|
+
* Returns `null` for:
|
|
10
|
+
* - Guardian Subagent auto-approval events (method contains `autoApprovalReview`)
|
|
11
|
+
* - Unrecognised / unmapped methods
|
|
12
|
+
*
|
|
13
|
+
* Spec reference: §6.1, §6.2
|
|
14
|
+
*/
|
|
15
|
+
export declare function translateCodexRequestToPendingQuestion(req: JsonLineRequest): PendingQuestion | null;
|
|
16
|
+
/**
|
|
17
|
+
* Listen for `server-request` events on the AppServerClient, translate each
|
|
18
|
+
* to a PendingQuestion, queue it on the handle, and transition to
|
|
19
|
+
* WAITING_ANSWER. Returns an unsubscribe function.
|
|
20
|
+
*
|
|
21
|
+
* Spec reference: §6.2, §6.3
|
|
22
|
+
*/
|
|
23
|
+
export declare function attachPauseFlow(client: AppServerClient, handle: TaskHandle, threadId: string): () => void;
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// Helpers
|
|
3
|
+
// ---------------------------------------------------------------------------
|
|
4
|
+
function asObject(value) {
|
|
5
|
+
if (!value || typeof value !== 'object' || Array.isArray(value)) {
|
|
6
|
+
return undefined;
|
|
7
|
+
}
|
|
8
|
+
return value;
|
|
9
|
+
}
|
|
10
|
+
function asArray(value) {
|
|
11
|
+
return Array.isArray(value) ? value : undefined;
|
|
12
|
+
}
|
|
13
|
+
function asString(value) {
|
|
14
|
+
return typeof value === 'string' ? value : undefined;
|
|
15
|
+
}
|
|
16
|
+
// ---------------------------------------------------------------------------
|
|
17
|
+
// Translation: Codex server-request → PendingQuestion
|
|
18
|
+
// ---------------------------------------------------------------------------
|
|
19
|
+
/**
|
|
20
|
+
* Translate a raw Codex JSON-RPC server request into a provider-blind
|
|
21
|
+
* PendingQuestion variant.
|
|
22
|
+
*
|
|
23
|
+
* Returns `null` for:
|
|
24
|
+
* - Guardian Subagent auto-approval events (method contains `autoApprovalReview`)
|
|
25
|
+
* - Unrecognised / unmapped methods
|
|
26
|
+
*
|
|
27
|
+
* Spec reference: §6.1, §6.2
|
|
28
|
+
*/
|
|
29
|
+
export function translateCodexRequestToPendingQuestion(req) {
|
|
30
|
+
// Guardian Subagent bypass (PR #13860) — never surface as a pause
|
|
31
|
+
if (req.method.includes('autoApprovalReview')) {
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
const params = asObject(req.params);
|
|
35
|
+
const requestId = String(req.id);
|
|
36
|
+
switch (req.method) {
|
|
37
|
+
// -- user_input --------------------------------------------------------
|
|
38
|
+
case 'tool/requestUserInput':
|
|
39
|
+
case 'item/tool/requestUserInput': {
|
|
40
|
+
const rawQuestions = asArray(params?.questions) ?? [];
|
|
41
|
+
const questions = rawQuestions.map((raw) => {
|
|
42
|
+
const q = asObject(raw) ?? {};
|
|
43
|
+
return {
|
|
44
|
+
id: asString(q.id) ?? '',
|
|
45
|
+
text: asString(q.text) ?? asString(q.question) ?? '',
|
|
46
|
+
...(asArray(q.options)
|
|
47
|
+
? { options: q.options.map(String) }
|
|
48
|
+
: {}),
|
|
49
|
+
...(q.isOther !== undefined || q.allowEmpty !== undefined
|
|
50
|
+
? { allowFreeform: Boolean(q.isOther ?? q.allowEmpty) }
|
|
51
|
+
: {}),
|
|
52
|
+
};
|
|
53
|
+
});
|
|
54
|
+
return { type: 'user_input', requestId, questions };
|
|
55
|
+
}
|
|
56
|
+
// -- command_approval --------------------------------------------------
|
|
57
|
+
case 'item/commandExecution/requestApproval':
|
|
58
|
+
case 'execCommandApproval': {
|
|
59
|
+
const command = asString(params?.command) ?? '';
|
|
60
|
+
const sandboxPolicy = asString(params?.sandbox_policy) ?? asString(params?.sandboxPolicy);
|
|
61
|
+
return {
|
|
62
|
+
type: 'command_approval',
|
|
63
|
+
requestId,
|
|
64
|
+
command,
|
|
65
|
+
...(sandboxPolicy !== undefined ? { sandboxPolicy } : {}),
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
// -- file_approval -----------------------------------------------------
|
|
69
|
+
case 'item/fileChange/requestApproval':
|
|
70
|
+
case 'applyPatchApproval': {
|
|
71
|
+
const rawChanges = asArray(params?.file_changes) ?? asArray(params?.fileChanges) ?? [];
|
|
72
|
+
const fileChanges = rawChanges.map((raw) => {
|
|
73
|
+
const fc = asObject(raw) ?? {};
|
|
74
|
+
return {
|
|
75
|
+
path: asString(fc.path) ?? '',
|
|
76
|
+
patch: asString(fc.patch) ?? '',
|
|
77
|
+
};
|
|
78
|
+
});
|
|
79
|
+
return { type: 'file_approval', requestId, fileChanges };
|
|
80
|
+
}
|
|
81
|
+
// -- elicitation -------------------------------------------------------
|
|
82
|
+
case 'mcpServer/elicitation/request': {
|
|
83
|
+
const serverName = asString(params?.server_name) ?? asString(params?.serverName);
|
|
84
|
+
const message = asString(params?.message) ?? '';
|
|
85
|
+
const schema = params?.schema;
|
|
86
|
+
return {
|
|
87
|
+
type: 'elicitation',
|
|
88
|
+
requestId,
|
|
89
|
+
...(serverName !== undefined ? { serverName } : {}),
|
|
90
|
+
message,
|
|
91
|
+
...(schema !== undefined ? { schema } : {}),
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
// -- dynamic_tool ------------------------------------------------------
|
|
95
|
+
case 'item/tool/call': {
|
|
96
|
+
const toolName = asString(params?.tool_name) ?? asString(params?.toolName) ?? '';
|
|
97
|
+
const rawArgs = params?.arguments;
|
|
98
|
+
const args = typeof rawArgs === 'string'
|
|
99
|
+
? rawArgs
|
|
100
|
+
: rawArgs !== undefined
|
|
101
|
+
? JSON.stringify(rawArgs)
|
|
102
|
+
: '{}';
|
|
103
|
+
return { type: 'dynamic_tool', requestId, toolName, arguments: args };
|
|
104
|
+
}
|
|
105
|
+
default:
|
|
106
|
+
return null;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
// ---------------------------------------------------------------------------
|
|
110
|
+
// Elicitation auto-decline (Issue #11816 workaround)
|
|
111
|
+
// ---------------------------------------------------------------------------
|
|
112
|
+
const ELICITATION_AUTO_DECLINE_MS = 30_000;
|
|
113
|
+
function scheduleElicitationAutoDecline(client, handle, question, timeoutMs = ELICITATION_AUTO_DECLINE_MS) {
|
|
114
|
+
const timer = setTimeout(() => {
|
|
115
|
+
const still = handle
|
|
116
|
+
.getPendingQuestions()
|
|
117
|
+
.find((q) => q.requestId === question.requestId);
|
|
118
|
+
if (!still)
|
|
119
|
+
return;
|
|
120
|
+
client
|
|
121
|
+
.respondToServerRequest(question.requestId, {
|
|
122
|
+
action: 'decline',
|
|
123
|
+
content: {},
|
|
124
|
+
})
|
|
125
|
+
.catch(() => { });
|
|
126
|
+
const head = handle.getPendingQuestions()[0];
|
|
127
|
+
if (head?.requestId === question.requestId) {
|
|
128
|
+
handle.dequeuePendingQuestion();
|
|
129
|
+
}
|
|
130
|
+
handle.writeOutput(`[elicitation] auto-declined after ${timeoutMs}ms (issue #11816 workaround)`);
|
|
131
|
+
}, timeoutMs);
|
|
132
|
+
timer.unref();
|
|
133
|
+
}
|
|
134
|
+
// ---------------------------------------------------------------------------
|
|
135
|
+
// Attachment: wire pause-flow onto an AppServerClient + TaskHandle
|
|
136
|
+
// ---------------------------------------------------------------------------
|
|
137
|
+
function extractThreadIdFromParams(params) {
|
|
138
|
+
const obj = asObject(params);
|
|
139
|
+
const threadId = obj?.threadId;
|
|
140
|
+
if (typeof threadId === 'string')
|
|
141
|
+
return threadId;
|
|
142
|
+
const thread = asObject(obj?.thread);
|
|
143
|
+
if (typeof thread?.id === 'string')
|
|
144
|
+
return thread.id;
|
|
145
|
+
return undefined;
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Listen for `server-request` events on the AppServerClient, translate each
|
|
149
|
+
* to a PendingQuestion, queue it on the handle, and transition to
|
|
150
|
+
* WAITING_ANSWER. Returns an unsubscribe function.
|
|
151
|
+
*
|
|
152
|
+
* Spec reference: §6.2, §6.3
|
|
153
|
+
*/
|
|
154
|
+
export function attachPauseFlow(client, handle, threadId) {
|
|
155
|
+
const onServerRequest = (pending) => {
|
|
156
|
+
const reqThreadId = extractThreadIdFromParams(pending.params);
|
|
157
|
+
if (reqThreadId !== threadId)
|
|
158
|
+
return;
|
|
159
|
+
// Guardian Subagent bypass — log but don't surface
|
|
160
|
+
if (pending.method.includes('autoApprovalReview')) {
|
|
161
|
+
handle.writeOutputFileOnly(`[guardian] ${pending.method}`);
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
const req = {
|
|
165
|
+
method: pending.method,
|
|
166
|
+
id: pending.id,
|
|
167
|
+
params: pending.params,
|
|
168
|
+
};
|
|
169
|
+
const question = translateCodexRequestToPendingQuestion(req);
|
|
170
|
+
if (!question)
|
|
171
|
+
return;
|
|
172
|
+
handle.queuePendingQuestion(question);
|
|
173
|
+
if (!handle.isTerminal()) {
|
|
174
|
+
handle.markInputRequired();
|
|
175
|
+
}
|
|
176
|
+
if (question.type === 'elicitation') {
|
|
177
|
+
scheduleElicitationAutoDecline(client, handle, question);
|
|
178
|
+
}
|
|
179
|
+
};
|
|
180
|
+
client.on('server-request', onServerRequest);
|
|
181
|
+
return () => {
|
|
182
|
+
client.off('server-request', onServerRequest);
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
//# sourceMappingURL=codex-pause-flow.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codex-pause-flow.js","sourceRoot":"","sources":["../../../src/execution/codex-pause-flow.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { Provider } from '../task/task-state.js';
|
|
2
|
+
import type { TaskHandle } from '../task/task-handle.js';
|
|
3
|
+
import type { ProviderCapabilities } from './provider-capabilities.js';
|
|
4
|
+
import { BaseProviderAdapter, type ProviderSpawnOptions, type AvailabilityResult } from './base-adapter.js';
|
|
5
|
+
export declare class CopilotAdapter extends BaseProviderAdapter {
|
|
6
|
+
readonly id: Provider;
|
|
7
|
+
readonly displayName = "Copilot";
|
|
8
|
+
checkAvailability(): AvailabilityResult;
|
|
9
|
+
getCapabilities(): ProviderCapabilities;
|
|
10
|
+
getStats(): Record<string, unknown>;
|
|
11
|
+
protected executeSession(_handle: TaskHandle, _prompt: string, _signal: AbortSignal, _options: ProviderSpawnOptions): Promise<void>;
|
|
12
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// CopilotAdapter — Phase 2 stub
|
|
3
|
+
// Spec reference: §3.4
|
|
4
|
+
// ---------------------------------------------------------------------------
|
|
5
|
+
import { COPILOT_CAPABILITIES } from './provider-capabilities.js';
|
|
6
|
+
import { BaseProviderAdapter, } from './base-adapter.js';
|
|
7
|
+
export class CopilotAdapter extends BaseProviderAdapter {
|
|
8
|
+
id = 'copilot';
|
|
9
|
+
displayName = 'Copilot';
|
|
10
|
+
checkAvailability() {
|
|
11
|
+
return { available: false, reason: 'Phase 2 — not yet implemented' };
|
|
12
|
+
}
|
|
13
|
+
getCapabilities() {
|
|
14
|
+
return COPILOT_CAPABILITIES;
|
|
15
|
+
}
|
|
16
|
+
getStats() {
|
|
17
|
+
return {};
|
|
18
|
+
}
|
|
19
|
+
async executeSession(_handle, _prompt, _signal, _options) {
|
|
20
|
+
throw new Error('Not implemented — Phase 2');
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=copilot-adapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"copilot-adapter.js","sourceRoot":"","sources":["../../../src/execution/copilot-adapter.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,gCAAgC;AAChC,uBAAuB;AACvB,8EAA8E;AAK9E,OAAO,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AAClE,OAAO,EACL,mBAAmB,GAGpB,MAAM,mBAAmB,CAAC;AAE3B,MAAM,OAAO,cAAe,SAAQ,mBAAmB;IAC5C,EAAE,GAAa,SAAS,CAAC;IACzB,WAAW,GAAG,SAAS,CAAC;IAEjC,iBAAiB;QACf,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,+BAA+B,EAAE,CAAC;IACvE,CAAC;IAED,eAAe;QACb,OAAO,oBAAoB,CAAC;IAC9B,CAAC;IAED,QAAQ;QACN,OAAO,EAAE,CAAC;IACZ,CAAC;IAES,KAAK,CAAC,cAAc,CAC5B,OAAmB,EACnB,OAAe,EACf,OAAoB,EACpB,QAA8B;QAE9B,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;IAC/C,CAAC;CACF"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { PendingQuestionType } from '../task/task-state.js';
|
|
2
|
+
/**
|
|
3
|
+
* Declares what a provider adapter can do at runtime.
|
|
4
|
+
* TaskManager reads these at startup and uses them to route behavior.
|
|
5
|
+
*/
|
|
6
|
+
export interface ProviderCapabilities {
|
|
7
|
+
/** Session survives server restart (e.g. Codex rollout files). */
|
|
8
|
+
sessionPersistence: boolean;
|
|
9
|
+
/** Distinct approve/decline protocol (e.g. Codex 4 approval types). */
|
|
10
|
+
structuredApproval: boolean;
|
|
11
|
+
/** Can stream tokens/chunks. */
|
|
12
|
+
streamingOutput: boolean;
|
|
13
|
+
/** Has explicit cancel primitive (e.g. turn/interrupt). */
|
|
14
|
+
abortPrimitive: boolean;
|
|
15
|
+
/** Supports thread/read-style probe for crash recovery. */
|
|
16
|
+
crashRecovery: boolean;
|
|
17
|
+
/** How the provider selects a model. */
|
|
18
|
+
modelRouting: 'config' | 'api-param' | 'none';
|
|
19
|
+
/** Emits structured rate-limit error. */
|
|
20
|
+
rateLimitSignal: boolean;
|
|
21
|
+
/** Subset of the 5 PendingQuestion types this provider supports. */
|
|
22
|
+
pauseTypes: readonly PendingQuestionType[];
|
|
23
|
+
}
|
|
24
|
+
export declare const CODEX_CAPABILITIES: Readonly<ProviderCapabilities>;
|
|
25
|
+
export declare const COPILOT_CAPABILITIES: Readonly<ProviderCapabilities>;
|
|
26
|
+
export declare const CLAUDE_CAPABILITIES: Readonly<ProviderCapabilities>;
|
|
27
|
+
export interface ValidationResult {
|
|
28
|
+
ok: boolean;
|
|
29
|
+
reason?: string;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Validates that a pause type is supported by the provider's capabilities.
|
|
33
|
+
* Returns `{ ok: false, reason }` if the provider does not support the given type.
|
|
34
|
+
*/
|
|
35
|
+
export declare function validateResponseAgainstCapabilities(caps: ProviderCapabilities, pauseType: PendingQuestionType): ValidationResult;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// CapabilityMatrix — runtime-enforced provider contract
|
|
3
|
+
// Spec reference: §3.4
|
|
4
|
+
// ---------------------------------------------------------------------------
|
|
5
|
+
// ---------------------------------------------------------------------------
|
|
6
|
+
// Concrete capability declarations — Phase 1 matrix
|
|
7
|
+
// ---------------------------------------------------------------------------
|
|
8
|
+
const ALL_PAUSE_TYPES = [
|
|
9
|
+
'user_input',
|
|
10
|
+
'command_approval',
|
|
11
|
+
'file_approval',
|
|
12
|
+
'elicitation',
|
|
13
|
+
'dynamic_tool',
|
|
14
|
+
];
|
|
15
|
+
export const CODEX_CAPABILITIES = {
|
|
16
|
+
sessionPersistence: true,
|
|
17
|
+
structuredApproval: true,
|
|
18
|
+
streamingOutput: true,
|
|
19
|
+
abortPrimitive: true,
|
|
20
|
+
crashRecovery: true,
|
|
21
|
+
modelRouting: 'config',
|
|
22
|
+
rateLimitSignal: true,
|
|
23
|
+
pauseTypes: ALL_PAUSE_TYPES,
|
|
24
|
+
};
|
|
25
|
+
export const COPILOT_CAPABILITIES = {
|
|
26
|
+
sessionPersistence: false,
|
|
27
|
+
structuredApproval: false,
|
|
28
|
+
streamingOutput: true,
|
|
29
|
+
abortPrimitive: true,
|
|
30
|
+
crashRecovery: false,
|
|
31
|
+
modelRouting: 'api-param',
|
|
32
|
+
rateLimitSignal: true,
|
|
33
|
+
pauseTypes: ['user_input'],
|
|
34
|
+
};
|
|
35
|
+
export const CLAUDE_CAPABILITIES = {
|
|
36
|
+
sessionPersistence: false,
|
|
37
|
+
structuredApproval: false,
|
|
38
|
+
streamingOutput: true,
|
|
39
|
+
abortPrimitive: true,
|
|
40
|
+
crashRecovery: false,
|
|
41
|
+
modelRouting: 'api-param',
|
|
42
|
+
rateLimitSignal: true,
|
|
43
|
+
pauseTypes: ['user_input'],
|
|
44
|
+
};
|
|
45
|
+
/**
|
|
46
|
+
* Validates that a pause type is supported by the provider's capabilities.
|
|
47
|
+
* Returns `{ ok: false, reason }` if the provider does not support the given type.
|
|
48
|
+
*/
|
|
49
|
+
export function validateResponseAgainstCapabilities(caps, pauseType) {
|
|
50
|
+
if (caps.pauseTypes.includes(pauseType)) {
|
|
51
|
+
return { ok: true };
|
|
52
|
+
}
|
|
53
|
+
return {
|
|
54
|
+
ok: false,
|
|
55
|
+
reason: `this provider does not support ${pauseType} responses`,
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=provider-capabilities.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provider-capabilities.js","sourceRoot":"","sources":["../../../src/execution/provider-capabilities.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,wDAAwD;AACxD,uBAAuB;AACvB,8EAA8E;AA2B9E,8EAA8E;AAC9E,oDAAoD;AACpD,8EAA8E;AAE9E,MAAM,eAAe,GAAmC;IACtD,YAAY;IACZ,kBAAkB;IAClB,eAAe;IACf,aAAa;IACb,cAAc;CACN,CAAC;AAEX,MAAM,CAAC,MAAM,kBAAkB,GAAmC;IAChE,kBAAkB,EAAE,IAAI;IACxB,kBAAkB,EAAE,IAAI;IACxB,eAAe,EAAE,IAAI;IACrB,cAAc,EAAE,IAAI;IACpB,aAAa,EAAE,IAAI;IACnB,YAAY,EAAE,QAAQ;IACtB,eAAe,EAAE,IAAI;IACrB,UAAU,EAAE,eAAe;CAC5B,CAAC;AAEF,MAAM,CAAC,MAAM,oBAAoB,GAAmC;IAClE,kBAAkB,EAAE,KAAK;IACzB,kBAAkB,EAAE,KAAK;IACzB,eAAe,EAAE,IAAI;IACrB,cAAc,EAAE,IAAI;IACpB,aAAa,EAAE,KAAK;IACpB,YAAY,EAAE,WAAW;IACzB,eAAe,EAAE,IAAI;IACrB,UAAU,EAAE,CAAC,YAAY,CAAU;CACpC,CAAC;AAEF,MAAM,CAAC,MAAM,mBAAmB,GAAmC;IACjE,kBAAkB,EAAE,KAAK;IACzB,kBAAkB,EAAE,KAAK;IACzB,eAAe,EAAE,IAAI;IACrB,cAAc,EAAE,IAAI;IACpB,aAAa,EAAE,KAAK;IACpB,YAAY,EAAE,WAAW;IACzB,eAAe,EAAE,IAAI;IACrB,UAAU,EAAE,CAAC,YAAY,CAAU;CACpC,CAAC;AAWF;;;GAGG;AACH,MAAM,UAAU,mCAAmC,CACjD,IAA0B,EAC1B,SAA8B;IAE9B,IAAI,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;QACxC,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;IACtB,CAAC;IACD,OAAO;QACL,EAAE,EAAE,KAAK;QACT,MAAM,EAAE,kCAAkC,SAAS,YAAY;KAChE,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { Provider, TaskTypeName } from '../task/task-state.js';
|
|
2
|
+
import type { BaseProviderAdapter } from './base-adapter.js';
|
|
3
|
+
/**
|
|
4
|
+
* Central registry for provider adapters.
|
|
5
|
+
*
|
|
6
|
+
* Supports:
|
|
7
|
+
* - Registration by provider ID
|
|
8
|
+
* - Default fallback provider
|
|
9
|
+
* - Per-task-type routing overrides
|
|
10
|
+
* - Bulk shutdown
|
|
11
|
+
*/
|
|
12
|
+
export declare class ProviderRegistry {
|
|
13
|
+
private readonly adapters;
|
|
14
|
+
private defaultProvider;
|
|
15
|
+
private readonly taskTypeRoutes;
|
|
16
|
+
/** Register an adapter. Keyed by its `id` property. */
|
|
17
|
+
register(adapter: BaseProviderAdapter): void;
|
|
18
|
+
/** Set the fallback provider used when no task-type route matches. */
|
|
19
|
+
setDefault(provider: Provider): void;
|
|
20
|
+
/** Override routing for a specific task type. */
|
|
21
|
+
setTaskTypeRoute(taskType: TaskTypeName, provider: Provider): void;
|
|
22
|
+
/** Look up an adapter by provider ID. */
|
|
23
|
+
getAdapter(provider: Provider): BaseProviderAdapter | undefined;
|
|
24
|
+
/**
|
|
25
|
+
* Select the best adapter for a given task type.
|
|
26
|
+
*
|
|
27
|
+
* Resolution order:
|
|
28
|
+
* 1. Explicit task-type route
|
|
29
|
+
* 2. Default provider
|
|
30
|
+
* 3. First registered adapter (arbitrary but deterministic)
|
|
31
|
+
*/
|
|
32
|
+
selectForTaskType(taskType: TaskTypeName): BaseProviderAdapter | undefined;
|
|
33
|
+
/** Return all registered adapters. */
|
|
34
|
+
getAllAdapters(): BaseProviderAdapter[];
|
|
35
|
+
/** Shut down all registered adapters in parallel. */
|
|
36
|
+
shutdownAll(): Promise<void>;
|
|
37
|
+
}
|