104 lines
3.1 KiB
TypeScript
104 lines
3.1 KiB
TypeScript
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;
|