Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ Mac 客户端(v1 即将发布):拖入 Applications → 首启完成 onboar
| [docs/DEVELOPMENT_PLAN.md](docs/DEVELOPMENT_PLAN.md) | 整体开发方案 v0.5(1500+ 行 / §3 模块 / §6 里程碑) |
| [docs/VISUAL_DESIGN.html](docs/VISUAL_DESIGN.html) | 视觉设计 v0.4(11 屏 mockup) |
| [docs/security-model.md](docs/security-model.md) | 威胁模型 + 防御层 + 攻击向量测试 + 已知缺口 |
| [docs/design/session-format-v1.md](docs/design/session-format-v1.md) | 统一 session JSONL、旧格式迁移与 writer ownership |
| [docs/design/sandbox-plan-worktree.md](docs/design/sandbox-plan-worktree.md) | sandbox × plan mode × worktree 关系矩阵 |
| [docs/design/plugin-security.md](docs/design/plugin-security.md) | plugin 信任 ladder + sandbox 子进程 |
| [docs/design/effort-levels.md](docs/design/effort-levels.md) | 5 档 effort 到 DeepSeek API 参数映射 |
Expand Down
22 changes: 13 additions & 9 deletions apps/cli/src/headless.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import {
EFFORT_PARAMS,
HookDispatcher,
ReadTool,
RuntimeHost,
SessionManager,
ToolRegistry,
WebFetchTool,
Expand All @@ -39,7 +40,6 @@ import {
loadSkills,
makeSkillTool,
resolveCredentials,
runAgent,
wirePlugins,
collectPluginContributions,
type AgentEvent,
Expand Down Expand Up @@ -271,25 +271,28 @@ export async function runHeadless(opts: HeadlessOpts): Promise<number> {
}
let exitCode = 0;
try {
const result = await runAgent({
const runtime = new RuntimeHost({
provider,
tools,
cwd,
mode,
permissions: settings.permissions,
hooks,
pluginDirs: pluginContrib.dirs,
autoMode: settings.autoMode,
sandboxConfig: settings.sandbox,
});
const result = await runtime.run({
systemPrompt,
userMessage,
history: [],
model,
maxTokens,
temperature,
maxTurns,
cwd,
signal: ctrl.signal,
session: { manager: sessions, id: session.id },
mode,
permissions: settings.permissions,
hooks,
pluginDirs: pluginContrib.dirs,
autoCompact: { contextWindow: contextWindowFor(model), threshold: 0.8 },
autoMode: settings.autoMode,
sandboxConfig: settings.sandbox,
// In headless mode there's no human to ask: auto-deny anything that
// would normally need approval. Users wanting auto-yes should pass
// --mode dontAsk or --mode bypassPermissions (gated by trust).
Expand Down Expand Up @@ -441,6 +444,7 @@ function formatEventText(out: Writable, e: AgentEvent): void {
return;
case 'usage':
case 'thinking_delta':
case 'model_step_complete':
case 'turn_complete':
return;
}
Expand Down
58 changes: 29 additions & 29 deletions apps/cli/src/repl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
EFFORT_PARAMS,
HookDispatcher,
ReadTool,
RuntimeHost,
SessionManager,
TaskManager,
ToolRegistry,
Expand Down Expand Up @@ -37,7 +38,6 @@ import {
contextWindowFor,
makeSkillTool,
resolveCredentials,
runAgent,
settingsPaths,
wirePlugins,
collectPluginContributions,
Expand Down Expand Up @@ -429,6 +429,17 @@ export async function startRepl(opts: ReplOpts): Promise<number> {
}

let history: StoredMessage[] = resolved.seededHistory;
const runtime = new RuntimeHost({
provider,
tools,
cwd,
mode,
permissions: settings.permissions,
hooks,
pluginDirs: pluginContrib.dirs,
autoMode: settings.autoMode,
sandboxConfig: settings.sandbox,
});
const ctx: SessionContext = {
cwd,
model,
Expand Down Expand Up @@ -471,25 +482,20 @@ export async function startRepl(opts: ReplOpts): Promise<number> {
// reading ctx.model/ctx.mode live so /model and /mode switches are honored.
const tasks = new TaskManager((spec) => {
const ac = new AbortController();
const done = runAgent({
provider,
tools,
systemPrompt,
userMessage: spec.prompt,
model: ctx.model,
maxTokens,
temperature,
cwd: ctx.cwd,
signal: ac.signal,
mode: ctx.mode as Mode,
permissions: settings.permissions,
hooks,
pluginDirs: pluginContrib.dirs,
sandboxConfig: settings.sandbox,
autoMode: settings.autoMode,
subAgentDepth: 1,
systemReminders: false,
}).then((r) => assistantText(r.history));
const done = runtime
.run({
systemPrompt,
userMessage: spec.prompt,
model: ctx.model,
maxTokens,
temperature,
cwd: ctx.cwd,
signal: ac.signal,
modeOverride: ctx.mode as Mode,
subAgentDepth: 1,
systemReminders: false,
})
.then((r) => assistantText(r.history));
return { done, abort: () => ac.abort() };
});
ctx.tasks = tasks;
Expand Down Expand Up @@ -649,9 +655,7 @@ export async function startRepl(opts: ReplOpts): Promise<number> {
}

// Otherwise: send to agent (with mode/permission/hooks gating from M3b)
const result = await runAgent({
provider,
tools,
const result = await runtime.run({
systemPrompt,
userMessage: userInput,
history,
Expand All @@ -663,13 +667,8 @@ export async function startRepl(opts: ReplOpts): Promise<number> {
// ctx.sessionId (not the launch `session.id`) so a live `/resume <id>`
// switch redirects new messages to the resumed session.
session: { manager: sessions, id: ctx.sessionId },
mode: ctx.mode as Mode,
permissions: settings.permissions,
hooks,
pluginDirs: pluginContrib.dirs,
modeOverride: ctx.mode as Mode,
autoCompact: { contextWindow: contextWindowFor(ctx.model), threshold: 0.8 },
autoMode: settings.autoMode,
sandboxConfig: settings.sandbox,
// Session-scoped manager: the agent's TaskCreate calls land here too, so
// background tasks persist across turns and show up in /tasks.
taskManager: tasks,
Expand Down Expand Up @@ -762,6 +761,7 @@ function formatEvent(out: Writable, e: AgentEvent): void {
else out.write(` ✓ ${truncate(e.result.content, 200)}\n`);
return;
case 'usage':
case 'model_step_complete':
return;
case 'error':
out.write(`\n ✕ ${e.error}\n`);
Expand Down
1 change: 1 addition & 0 deletions apps/desktop/src-tauri/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions apps/desktop/src-tauri/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ sha2 = "0.10"
thiserror = "1"
tokio = { version = "1", features = ["fs", "rt-multi-thread", "macros", "sync", "time", "process"] }
dirs = "5"
libc = "0.2"

[profile.release]
panic = "abort"
Expand Down
Loading
Loading