Files
legal-ai/adapters/deepseek-paperclip-adapter/dist/index.js
Chaim a4e006ab50
All checks were successful
G12 Leak-Guard / leak-guard (pull_request) Successful in 8s
feat(agents): deepseek_local טוען פרומפט מקובץ — איחוד מקור-אמת לפרומפט של Hermes (G2)
כל סוכני המערכת טוענים את ה-system prompt מקובץ תחת .claude/agents/ דרך
instructionsFilePath (claude_local + gemini_local), פרט ל-Hermes/curator על
deepseek_local שתמך רק ב-promptTemplate inline ב-DB — מסלול-פרומפט מקביל (הפרת G2),
לא מגורסת ב-git, ושני המקורות (DB ↔ hermes-curator.md) כבר התפצלו בתוכן.

מה השתנה:
- adapters/deepseek-paperclip-adapter: buildPrompt קורא instructionsFilePath אם הוגדר
  (resolveTemplate; עדיפות file > promptTemplate > DEFAULT). הקובץ עובר renderTemplate
  כך ש-{{wakeReason}}/{{#taskId}}/… ממשיכים לעבוד. כשל-רועש אם הקובץ הוגדר ואינו
  קריא — לא fallback שקט (כלל-הנדסה §6, feedback_silent_swallow).
- hermes-curator.md הופך ממסמך-תיעוד למקור-האמת בפועל: מיזוג current-from-both —
  ה-runbook התפעולי מה-DB (PIPELINE-WAKE/X16 + §A/§B + interactions) + שער
  anti-hallucination (INV-AH) וקריאת-ספ (INV-AG1) שהיו רק ב-md ומעולם לא הגיעו
  ל-runtime של הרמס. ה-ingest_final_version/lessons הידני הושמט — ה-pipeline (X16)
  כבר מריץ אותו durably; הרצה ידנית הייתה כפילה.

נותר תפעולי (לא ב-git): עדכון 2 רשומות deepseek_local ב-Paperclip DB
(instructionsFilePath=.../hermes-curator.md, ריקון promptTemplate) + git pull בעץ
הראשי + pm2 restart paperclip + sync-agents.

Invariants: מקיים G2 (ביטול מסלול-פרומפט מקביל), G12/X15 (מגע-פלטפורמה רק במעטפת
המוצהרת — adapter), INV-AH + INV-AG1 (מגיעים סוף-סוף ל-Hermes), כלל-הנדסה §6
(כשל-רועש). ללא שינוי התנהגות-runtime פרט להוספת שער-ה-AH (כוונה מפורשת, אישור יו"ר).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-11 12:16:33 +00:00

101 lines
4.5 KiB
JavaScript

/**
* DeepSeek (via Hermes) — external Paperclip adapter.
*
* Loaded by Paperclip's plugin-loader. Contract:
* The package's main module must export createServerAdapter() returning
* a single ServerAdapterModule object with all fields wired in.
*
* Runtime: spawns the local `hermes` CLI with HERMES_HOME pinned to a
* DeepSeek profile that defines model.base_url=https://api.deepseek.com/v1
* and model.key_env=DEEPSEEK_API_KEY.
*/
import {
ADAPTER_TYPE,
ADAPTER_LABEL,
DEEPSEEK_MODELS,
DEFAULT_PROFILE_HOME,
} from "./shared/constants.js";
import { execute } from "./server/execute.js";
import { testEnvironment } from "./server/test.js";
import { sessionCodec } from "./server/session-codec.js";
import { listSkills, syncSkills } from "./server/skills.js";
const AGENT_CONFIGURATION_DOC = `# DeepSeek (via Hermes) — Agent Configuration
DeepSeek-pinned variant of the Hermes adapter. Runs the local \`hermes\` CLI
with \`HERMES_HOME\` pointed at a DeepSeek profile (\`config.yaml\` declares
\`base_url=https://api.deepseek.com/v1\` and \`key_env=DEEPSEEK_API_KEY\`).
## Prerequisites
- Hermes Agent installed (\`pip install hermes-agent\`) — \`hermes --version\` works.
- DeepSeek profile dir exists (default: \`/home/chaim/.hermes/profiles/deepseek\`)
with \`config.yaml\` + \`.env\` (containing \`DEEPSEEK_API_KEY\`).
## Core Configuration
| Field | Type | Default | Description |
|-------|------|---------|-------------|
| model | string | \`deepseek-v4-pro\` | DeepSeek model id (\`deepseek-v4-pro\` or \`deepseek-v4-flash\`). |
| provider | string | \`custom\` | Hermes provider name. The DeepSeek profile defines \`provider: custom\` so \`custom\` is the right value. |
| hermesProfileHome | string | \`/home/chaim/.hermes/profiles/deepseek\` | Absolute path to a Hermes profile dir. Set per-agent if you maintain multiple DeepSeek profiles. |
| timeoutSec | number | 1800 | Execution timeout in seconds. |
| graceSec | number | 30 | SIGTERM grace period in seconds. |
## Tools / Workspace
| Field | Type | Default | Description |
|-------|------|---------|-------------|
| toolsets | string | (profile default) | Comma-separated toolsets to enable. |
| persistSession | boolean | true | Resume sessions across heartbeats via \`--resume\`. |
| worktreeMode | boolean | false | Use git worktree for isolated changes. |
| checkpoints | boolean | false | Enable filesystem checkpoints. |
## Advanced
| Field | Type | Default | Description |
|-------|------|---------|-------------|
| hermesCommand | string | \`hermes\` | Path to the hermes binary. |
| verbose | boolean | false | Enable verbose Hermes logs. |
| extraArgs | string[] | [] | Extra CLI args appended after standard flags. |
| env | object | {} | Extra environment variables passed to Hermes. \`HERMES_HOME\` here overrides \`hermesProfileHome\`. |
| instructionsFilePath | string | (none) | Absolute path to a versioned prompt file (e.g. under \`.claude/agents/\`). When set, its contents become the prompt template — single source of truth, parity with \`claude_local\`/\`gemini_local\`. Takes precedence over \`promptTemplate\`. If set but unreadable, execution fails loudly (no silent fallback). The file still flows through the template renderer, so \`{{…}}\` placeholders work. |
| promptTemplate | string | (default) | Inline prompt override. Used only when \`instructionsFilePath\` is unset. |
| paperclipApiUrl | string | \`http://127.0.0.1:3100/api\` | Paperclip API URL injected into the prompt template. |
## Available template variables
\`{{agentId}}\`, \`{{agentName}}\`, \`{{companyId}}\`, \`{{companyName}}\`,
\`{{runId}}\`, \`{{taskId}}\`, \`{{taskTitle}}\`, \`{{taskBody}}\`,
\`{{commentId}}\`, \`{{wakeReason}}\`, \`{{projectName}}\`, \`{{paperclipApiUrl}}\`.
`;
export function createServerAdapter() {
return {
type: ADAPTER_TYPE,
label: ADAPTER_LABEL,
models: DEEPSEEK_MODELS,
agentConfigurationDoc: AGENT_CONFIGURATION_DOC,
execute,
testEnvironment,
sessionCodec,
listSkills,
syncSkills,
// Capability flags
supportsLocalAgentJwt: true,
supportsInstructionsBundle: false,
requiresMaterializedRuntimeSkills: false,
};
}
// Also export the loose constants for any caller that wants to inspect
// the package without invoking createServerAdapter (e.g., test harnesses).
export const type = ADAPTER_TYPE;
export const label = ADAPTER_LABEL;
export const models = DEEPSEEK_MODELS;
export const agentConfigurationDoc = AGENT_CONFIGURATION_DOC;
export const defaultProfileHome = DEFAULT_PROFILE_HOME;