From 75411af0ceb11848872d18bd50e8e9ec3b639ec3 Mon Sep 17 00:00:00 2001 From: Ishaan Jaffer Date: Wed, 3 Jun 2026 10:08:45 -0700 Subject: [PATCH] feat: support optional Lite Harness CLI provider --- lib/services/cli/agent-sdk.ts | 56 +++++++++++++++++++++++++++++++++++ lib/services/cli/claude.ts | 2 +- lib/services/cli/glm.ts | 2 +- 3 files changed, 58 insertions(+), 2 deletions(-) create mode 100644 lib/services/cli/agent-sdk.ts diff --git a/lib/services/cli/agent-sdk.ts b/lib/services/cli/agent-sdk.ts new file mode 100644 index 00000000..66c619c2 --- /dev/null +++ b/lib/services/cli/agent-sdk.ts @@ -0,0 +1,56 @@ +import { query as claudeAgentQuery } from '@anthropic-ai/claude-agent-sdk'; +import type { SDKMessage } from '@anthropic-ai/claude-agent-sdk'; + +export type { SDKMessage }; + +type QueryArgs = Parameters[0]; +type QueryReturn = ReturnType; +type QueryFunction = (args: QueryArgs) => QueryReturn; +type LiteHarnessOptions = QueryArgs['options'] & { + agent?: string; + harness?: string; +}; + +const LITE_HARNESS_PROVIDER = 'lite-harness'; +const LITE_HARNESS_DEFAULT_HARNESS = 'claude-code'; + +function getProvider() { + return (process.env.CLAUDABLE_AGENT_SDK_PROVIDER || 'claude-agent-sdk') + .trim() + .toLowerCase(); +} + +function withLiteHarnessOptions(args: QueryArgs): QueryArgs { + const options = (args.options || {}) as LiteHarnessOptions; + + return { + ...args, + options: { + ...options, + harness: + process.env.LITE_HARNESS_HARNESS || + process.env.LITE_HARNESS_AGENT || + options.harness || + options.agent || + LITE_HARNESS_DEFAULT_HARNESS, + ...(process.env.LITE_HARNESS_MODEL + ? { model: process.env.LITE_HARNESS_MODEL } + : {}), + } as QueryArgs['options'], + }; +} + +async function loadQuery(): Promise { + if (getProvider() !== LITE_HARNESS_PROVIDER) { + return claudeAgentQuery; + } + + const liteHarnessPackage = process.env.LITE_HARNESS_PACKAGE || '@lite-harness/sdk'; + const liteHarness = (await import(liteHarnessPackage)) as { + query: QueryFunction; + }; + + return (args) => liteHarness.query(withLiteHarnessOptions(args)); +} + +export const query = await loadQuery(); diff --git a/lib/services/cli/claude.ts b/lib/services/cli/claude.ts index 5f15f3cf..29ab2b53 100644 --- a/lib/services/cli/claude.ts +++ b/lib/services/cli/claude.ts @@ -4,7 +4,7 @@ * Interacts with projects using the Claude Agent SDK. */ -import { query, type SDKMessage } from '@anthropic-ai/claude-agent-sdk'; +import { query, type SDKMessage } from './agent-sdk'; import type { ClaudeSession, ClaudeResponse } from '@/types/backend'; import { streamManager } from '../stream'; import { serializeMessage, createRealtimeMessage } from '@/lib/serializers/chat'; diff --git a/lib/services/cli/glm.ts b/lib/services/cli/glm.ts index 509c2623..45899df7 100644 --- a/lib/services/cli/glm.ts +++ b/lib/services/cli/glm.ts @@ -3,7 +3,7 @@ * Minimal Claude Agent SDK integration configured for Zhipu GLM models. */ -import { query } from '@anthropic-ai/claude-agent-sdk'; +import { query } from './agent-sdk'; import path from 'node:path'; import fs from 'node:fs/promises'; import { randomUUID } from 'node:crypto';