From 6a0e4cd9d95de0e5b0d8279dd713e889dbd913ee Mon Sep 17 00:00:00 2001 From: artale Date: Sun, 5 Jul 2026 00:58:31 +0200 Subject: [PATCH] =?UTF-8?q?feat:=20deepseek=20agent=20adapter=20for=20pipe?= =?UTF-8?q?line=20=E2=80=94=20Ollama-based=20model=20runtime?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit runDeepSeekAgent() implements the runAgent callback for execution-pipeline.ts. Configurable endpoint/model/temperature. Uses fetch (Node 18+), no new deps. Exports from index.ts. --- src/fable5/deepseek-agent.ts | 92 ++++++++++++++++++++++++++++++++++++ src/fable5/index.ts | 2 + 2 files changed, 94 insertions(+) create mode 100644 src/fable5/deepseek-agent.ts diff --git a/src/fable5/deepseek-agent.ts b/src/fable5/deepseek-agent.ts new file mode 100644 index 0000000..31d6f1c --- /dev/null +++ b/src/fable5/deepseek-agent.ts @@ -0,0 +1,92 @@ +/** + * Agent adapter for DeepSeek models via Ollama. + * Uses fetch (Node 18+ built-in, no new deps). + * Designed as the runAgent callback for execution-pipeline.ts. + * + * Configurable endpoint — defaults to localhost:11434. + * Point at 77.42.112.29:11434 when Ollama is reachable externally. + */ + +export interface DeepSeekAgentConfig { + /** Ollama endpoint, e.g. "http://localhost:11434" */ + endpoint?: string; + /** Model name, e.g. "deepseek-coder-v2" or "deepseek-r1:32b" */ + model?: string; + /** Sampling temperature. Default 0.2 for coding tasks. */ + temperature?: number; + /** System prompt injected before the user prompt. */ + systemPrompt?: string; + /** Max tokens to generate. Default 4096. */ + maxTokens?: number; +} + +const DEFAULTS = { + endpoint: "http://localhost:11434", + model: "deepseek-coder-v2", + temperature: 0.2, + systemPrompt: "You are a coding agent. Read the repo map and user prompt, then produce the required output.", + maxTokens: 4096, +}; + +export interface ChatMessage { + role: "system" | "user" | "assistant"; + content: string; +} + +export function buildDeepSeekMessages( + systemPrompt: string, + prompt: string +): ChatMessage[] { + return [ + { role: "system", content: systemPrompt }, + { role: "user", content: prompt }, + ]; +} + +/** + * Run a DeepSeek model via Ollama's /api/chat endpoint. + * Returns the assistant's response text. + * Throws on HTTP error or empty response. + */ +export async function runDeepSeekAgent( + config: DeepSeekAgentConfig, + _cwd: string, + prompt: string +): Promise { + const endpoint = config.endpoint ?? DEFAULTS.endpoint; + const model = config.model ?? DEFAULTS.model; + const temperature = config.temperature ?? DEFAULTS.temperature; + const systemPrompt = config.systemPrompt ?? DEFAULTS.systemPrompt; + const maxTokens = config.maxTokens ?? DEFAULTS.maxTokens; + + const messages = buildDeepSeekMessages(systemPrompt, prompt); + + const response = await fetch(`${endpoint}/api/chat`, { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ + model, + messages, + options: { + temperature, + num_predict: maxTokens, + }, + stream: false, + }), + signal: AbortSignal.timeout(120_000), // 2-minute timeout + }); + + if (!response.ok) { + const body = await response.text().catch(() => ""); + throw new Error(`deepseek-agent: HTTP ${response.status} — ${body.slice(0, 200)}`); + } + + const data: any = await response.json(); + const text = data?.message?.content ?? ""; + + if (!text) { + throw new Error("deepseek-agent: empty response from model"); + } + + return text; +} diff --git a/src/fable5/index.ts b/src/fable5/index.ts index 11afa4b..219be4c 100644 --- a/src/fable5/index.ts +++ b/src/fable5/index.ts @@ -55,6 +55,8 @@ export { buildRepoMap, repoTreeString, minifiedTree, gitLsTree } from "./repo-ma export type { RepoMap, RepoNode } from "./repo-mapper.js"; export { runPipeline } from "./execution-pipeline.js"; export type { PipelineSpec, PipelineResult } from "./execution-pipeline.js"; +export { runDeepSeekAgent, buildDeepSeekMessages } from "./deepseek-agent.js"; +export type { DeepSeekAgentConfig, ChatMessage } from "./deepseek-agent.js"; export { formatCapabilityReport, loadFactoryCapabilities, parseFactoryCapabilities, probeFactoryCapabilities } from "./factory-capabilities.js"; export type { CapabilityProbeResult, CapabilityReport, FactoryCapabilityService } from "./factory-capabilities.js";