feat: add claw backend adapter
This commit is contained in:
103
src/lib/execution/backends/claw-backend.ts
Normal file
103
src/lib/execution/backends/claw-backend.ts
Normal file
@@ -0,0 +1,103 @@
|
||||
import type { ExecutionBackend } from "@/lib/execution/execution-backend";
|
||||
import type {
|
||||
ExecutionBackendDescription,
|
||||
ExecutionImmediateResult,
|
||||
ExecutionRequest,
|
||||
ExecutionRequestKind,
|
||||
} from "@/lib/execution/types";
|
||||
import {
|
||||
getClawBackendConfig,
|
||||
isClawBackendConfigured,
|
||||
type ClawBackendConfig,
|
||||
} from "@/lib/execution/backends/claw-config";
|
||||
import { runClawCommand } from "@/lib/execution/backends/claw-runner";
|
||||
|
||||
export const CLAW_BACKEND_ID = "claw-runtime";
|
||||
|
||||
export const CLAW_BACKEND = {
|
||||
backendId: CLAW_BACKEND_ID,
|
||||
label: "Claw Runtime",
|
||||
mode: "local",
|
||||
} as const satisfies ExecutionBackendDescription;
|
||||
|
||||
const SUPPORTED_CLAW_KINDS = new Set<ExecutionRequestKind>([
|
||||
"master_agent_reply",
|
||||
"thread_reply",
|
||||
]);
|
||||
|
||||
type ClawRunnerInput = Parameters<typeof runClawCommand>[0];
|
||||
type ClawRunner = (input: ClawRunnerInput) => Promise<ExecutionImmediateResult>;
|
||||
|
||||
export interface ClawBackendSelectionState {
|
||||
enabled: boolean;
|
||||
supportsKinds: ExecutionRequestKind[];
|
||||
}
|
||||
|
||||
function createFailedResult(error: string): ExecutionImmediateResult {
|
||||
return {
|
||||
status: "failed",
|
||||
backendId: CLAW_BACKEND_ID,
|
||||
error,
|
||||
};
|
||||
}
|
||||
|
||||
export function isClawRequestKindSupported(kind: ExecutionRequestKind) {
|
||||
return SUPPORTED_CLAW_KINDS.has(kind);
|
||||
}
|
||||
|
||||
export function getClawBackendSelectionState(
|
||||
config: ClawBackendConfig = getClawBackendConfig(),
|
||||
): ClawBackendSelectionState {
|
||||
return {
|
||||
enabled: isClawBackendConfigured(config),
|
||||
supportsKinds: [...SUPPORTED_CLAW_KINDS],
|
||||
};
|
||||
}
|
||||
|
||||
function buildClawPayload(input: ExecutionRequest, config: ClawBackendConfig) {
|
||||
return {
|
||||
kind: input.kind,
|
||||
projectId: input.projectId,
|
||||
requestMessageId: input.requestMessageId,
|
||||
body: input.body,
|
||||
executionPrompt: input.executionPrompt ?? input.body,
|
||||
model: input.modelOverride ?? config.defaultModel,
|
||||
reasoningEffort: input.reasoningEffortOverride ?? "medium",
|
||||
...(input.targetProjectId ? { targetProjectId: input.targetProjectId } : {}),
|
||||
...(input.targetThreadId ? { targetThreadId: input.targetThreadId } : {}),
|
||||
...(input.requestedByAccount ? { requestedByAccount: input.requestedByAccount } : {}),
|
||||
...(input.requestedByLabel ? { requestedByLabel: input.requestedByLabel } : {}),
|
||||
...(input.taskId ? { taskId: input.taskId } : {}),
|
||||
};
|
||||
}
|
||||
|
||||
export function createClawBackend(options?: {
|
||||
config?: ClawBackendConfig;
|
||||
runner?: ClawRunner;
|
||||
}): ExecutionBackend {
|
||||
const config = options?.config ?? getClawBackendConfig();
|
||||
const runner = options?.runner ?? runClawCommand;
|
||||
|
||||
return {
|
||||
backendId: CLAW_BACKEND_ID,
|
||||
async canHandle(input) {
|
||||
return isClawBackendConfigured(config) && isClawRequestKindSupported(input.kind);
|
||||
},
|
||||
async execute(input) {
|
||||
const canHandle = await this.canHandle(input);
|
||||
if (!canHandle) {
|
||||
return createFailedResult("CLAW_BACKEND_NOT_AVAILABLE");
|
||||
}
|
||||
return runner({
|
||||
config,
|
||||
payload: buildClawPayload(input, config),
|
||||
});
|
||||
},
|
||||
async describe() {
|
||||
return CLAW_BACKEND;
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export const CLAW_BACKEND_ADAPTER = createClawBackend();
|
||||
export const createClawBackendForTesting = createClawBackend;
|
||||
Reference in New Issue
Block a user