Skip to content

Native Yeaft Engine ​

The native engine lives in agent/yeaft/. It does not require Claude Code or GitHub Copilot CLI. It owns its LLM adapters, Session/VP orchestration, tool loop, memory, persistence, sub-agents, background jobs, and Work Center runner integration.

This page is for developers. For the product behavior, read Yeaft Sessions and Projects and Work Center.

Main modules ​

text
agent/yeaft/
  engine.js             query/tool loop, retries, folding, persistence
  session.js            loads one engine context and supporting subsystems
  web-bridge.js         Web Session/VP and event bridge
  cli-session-runner.js transport-neutral multi-VP CLI Session runner
  sessions/             roster, store, coordinator, pre-flow, CRUD
  projects/             Agent-side Project context store
  vp/                   VP library, persona loader, defaults, registry
  llm/                  adapter router, Anthropic, OpenAI Responses, credentials
  memory/               retained, disabled H2-AMS implementation
  conversation/         durable message persistence and search
  tools/                33 built-in tool definitions and registry
  sub-agent/            child-agent runner, logs, liveness, notifications
  tasks/                persistent background shell jobs
  work-center/          WorkItem/Action/Run planner, store, watcher, runner
  tool-folding/         execution log, duplicate hints, legacy reflection helpers
  history-window.js     deterministic provider history window
  dream/                retained, disabled maintenance implementation
  archive/              large/raw tool-result archive helpers
  templates/            bilingual base, unified, retained dream, plan, persona prompts

One native turn ​

A normal VP turn follows this shape. history-window.js is deterministic and never produces a persisted summary:

  1. Pre-query — resolve Agent/Session/VP/Project identity, project instructions, runtime platform, pending child-agent notifications, project docs, and bounded current-Session history.
  2. Build context — combine the system prompt, VP persona, deterministic budgeted history window, current user content, and supported attachments. The Web Session source is a bounded disposable runtime cache; the complete transcript stays in ConversationStore, and no LLM conversation summary is loaded from disk.
  3. Stream LLM — select the configured provider/model and call either the Anthropic Messages or OpenAI Responses adapter.
  4. Execute tools — run allowed calls through ToolRegistry, append result blocks, and continue streaming.
  5. Compact under pressure — when current-turn results exceed the actual model-window budget (including system, schemas, and output reserve), compact older tool-result text in the provider copy first. Preserve tool pairing and raw persistence/debug output; no periodic reflection or extra in-turn summary call runs. If still oversized, use deterministic protocol-unit eviction and bounded overflow recovery.
  6. Finish — persist messages, usage, traces, task state, and terminal result; acknowledge injected notifications; optionally produce the separate post-turn compact for a future history window.
  7. Recover — auto-continue max_tokens responses within the configured limit; surface context errors without a hidden summary call; use an eligible fallback model for classified retryable failures.

An abort signal is threaded through the adapter and tools. The engine distinguishes user aborts, auth errors, rate limits, server failures, idle timeouts, and context failures instead of treating every stop as a generic error.

Session and VP orchestration ​

The Session coordinator resolves recipients from the roster:

js
const recipients = resolveVps(mentions, roster, defaultVpId);
await Promise.all(recipients.map(vp => runVpTurn(session, vp, input)));

The actual API has additional identity, attachments, quoting, routing, and persistence fields; this pseudocode only shows fan-out. The important rules are:

  • one canonical user message is persisted for the turn;
  • no mention targets the default VP;
  • explicit mentions target the matching roster members;
  • each selected VP has independent engine/persona/memory context;
  • VP events retain sessionId, vpId, turn/thread identity, and source order;
  • peer handoff uses the RouteForward tool and loop guards, not text mentions.

The Web path uses web-bridge.js. The direct yeaft CLI uses the transport-neutral Session runner so Session ID and multi-VP semantics stay aligned.

Prompt construction ​

prompts.js combines:

  • templates/base.md, identity-yeaft.md, and common-rules.md;
  • the single interactive mode-unified.md contract;
  • plan instructions, plus retained Dream templates that are no longer dispatched;
  • the selected persona and VP metadata;
  • runtime platform metadata;
  • project docs and Project instruction;
  • optional harness-level instructions.

Historical interactive modes have been folded into the unified contract. Dream is disabled; legacy dispatch commands return disabled.

LLM adapters ​

AdapterRouter resolves provider and protocol from config:

  1. per-model protocol override;
  2. provider protocol;
  3. model-ID heuristic;
  4. OpenAI Responses fallback.

Supported protocols are anthropic and openai-responses. Provider entries may use static apiKey values or supported dynamic credential providers. Context/output limits come from model overrides, the bundled catalog, or conservative defaults. Model effort is translated to Anthropic thinking/output effort or OpenAI reasoning effort where supported.

See Native LLM layer.

Tool system ​

createFullRegistry() currently registers 33 built-in tools:

  • files and patches;
  • grep/glob/directory/disk/history search;
  • foreground/background shell jobs and task logs;
  • Git worktree entry/exit;
  • Web search/fetch, local image viewing, and image generation;
  • JavaScript REPL and notebook editing;
  • planning, visible todos, and user questions;
  • persistent WorkItem creation;
  • sub-agent spawn/prompt/wait/list/close and explicit VP routing;
  • Skills.

MCP tools are added at runtime. Registry policy can deny tools for the current execution context.

Tool events and raw results are persisted for audit/debug. The context-facing representation is separately budgeted and can be folded or replaced by archive stubs; UI truncation does not mean the raw record was discarded.

Retired H2-AMS memory ​

Dream/H2-AMS modules and legacy data remain for compatibility and technical reference, but the current runtime does not migrate, synchronize, read, recall, or inject them. Interactive turns and Work Center use their own current sources instead. Legacy enable/manual commands return disabled; the Web debug surface has no Dream tab or settings. Historical messages and ordinary debug records remain intact. Post-turn compact is a separate active history-window feature.

See Retired H2-AMS implementation.

Background tasks and sub-agents ​

  • Bash with background=true creates a persistent Session task with a log.
  • ListTasks, ReadTaskLog, and CancelTask operate on that record.
  • An Agent restart marks unresolved process handles orphaned instead of pretending they are still controllable.
  • Sub-agents have their own output log, liveness counters, optional budgets, and terminal/idle notifications.
  • Terminal notifications are parent re-entry control context, not new user-authored semantic memory.

Work Center integration ​

Work Center reuses Engine.query() through a runner adapter. It does not implement a second LLM/tool loop. The Run freezes Action, VP, model/effort, tool-policy, workspace, and attempt identity. A structured completion tool submits completed, waiting, retryable, or failed; a normal model turn_end alone cannot advance the Action.

The Coordinator uses the same model infrastructure but a restricted decision contract without file/shell/external side-effect tools.

Persistence and compatibility ​

Agent-local Session metadata, history, memory, tasks, and Work Center data live under the resolved Yeaft directory. A Session workDir is project context only.

Web Session 上传附件保存在 <yeaftDir>/sessions/<sessionId>/attachments/,transcript 仅保存轻量引用,不写入图片 base64。当前消息直接携带图片,无须 ViewImage。attachments.js 的 hydratePersistedUserAttachmentContent(row, { yeaftDir, sessionId, legacyRoot }) 将原始用户行还原为标准图片 content parts;批量入口为 hydratePersistedAttachmentHistory(rows, opts)。Engine 在 canonical history 和 relatedHistoryTurns[].messages 进入历史预算前各调用一次,不能依赖 Web bridge 装饰 store,也不能把还原结果写回 transcript。历史预览与模型历史共用受控读取,拒绝跨 Session、跨实例、任意路径与符号链接;缺失或不可访问的图片会在返回的模型上下文中明确提示重新上传。legacyRoot 指旧上传时的 Agent CWD(默认当前进程 CWD),仅兼容其下 .claude-tmp-attachments/<sessionId>/ 的相对引用,不搜索项目 workDir。Session copy/fork 在历史前缀筛选后安全读取并复制可用附件至目标 Session,重映射引用;目标 Session 不能借原路径读取源 Session 图片。显式开启 DebugTrace 的全量诊断记录仍可能包含图片数据,不属于轻量 transcript 保证范围。

Older wire aliases, payload identifiers, and storage scope prefixes remain where changing them would break deployed clients or data. New code uses Session/Yeaft terminology and the canonical Session memory layout is sessions/<id>. Readers may still handle legacy session/<id> and group/<id> aliases during migration.

Verification map ​

The test tree is organized by subsystem rather than historical phase files:

  • test/agent/yeaft/ covers history-window, conversation, memory, Sessions, sub-agents, tasks, tool folding, Work Center, and related modules;
  • test/agent/yeaft-*.test.js covers cross-module native-engine behavior;
  • test/server/yeaft-*.test.js and test/web/yeaft-*.test.js cover relay and UI integration;
  • e2e/ covers browser-visible flows.

Use npm test, npm run test:e2e, and npm run release:guard for the current repository-wide gates.

Released under the MIT License.