feat: deepseek agent adapter for pipeline — Ollama-based model runtime
runDeepSeekAgent() implements the runAgent callback for execution-pipeline.ts. Configurable endpoint/model/temperature. Uses fetch (Node 18+), no new deps. Exports from index.ts.
This commit is contained in:
parent
e59700325a
commit
6a0e4cd9d9
|
|
@ -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<string> {
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
@ -55,6 +55,8 @@ export { buildRepoMap, repoTreeString, minifiedTree, gitLsTree } from "./repo-ma
|
||||||
export type { RepoMap, RepoNode } from "./repo-mapper.js";
|
export type { RepoMap, RepoNode } from "./repo-mapper.js";
|
||||||
export { runPipeline } from "./execution-pipeline.js";
|
export { runPipeline } from "./execution-pipeline.js";
|
||||||
export type { PipelineSpec, PipelineResult } 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 { formatCapabilityReport, loadFactoryCapabilities, parseFactoryCapabilities, probeFactoryCapabilities } from "./factory-capabilities.js";
|
||||||
export type { CapabilityProbeResult, CapabilityReport, FactoryCapabilityService } from "./factory-capabilities.js";
|
export type { CapabilityProbeResult, CapabilityReport, FactoryCapabilityService } from "./factory-capabilities.js";
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue