diff --git a/README.md b/README.md index 98d360e1..616ccd9c 100644 --- a/README.md +++ b/README.md @@ -6,11 +6,12 @@

-

AI coding agent with persistent memory and control plane

+

AI coding agent with persistent memory, autonomous goals, and a control plane

English | - 简体中文 + 简体中文 | + Enterprise

Desktop v1.3

@@ -41,11 +42,11 @@ The features below start from a real need — something a plain coding agent, op **What DeepAgent does:** Fork any conversation from a chosen message. The fork opens carrying the parent's memory up to that point, shows a full-width "derived from" marker at the top of its transcript, and nests folder-style under its origin in the session tree (subagents and forks alike, up to three levels deep). Knowledge flows up a scope hierarchy — what one session learns can be promoted to the whole project, and cross-project preferences live at the user-global layer — so switching windows is a clean handoff, not a reset. -### Ask roughly, and let the agent sharpen it +### Pick how much autonomy you want, per task -**The need:** A half-formed prompt gets a half-useful answer, and you don't always know how to phrase what you want. +**The need:** Some asks want a fast answer in your exact words; others want the agent to plan first, or to run on its own until the job is done. One fixed behavior can't serve all three. -**What DeepAgent does:** Two scenario modes on the composer. **Direct** sends your prompt as-is — you own the wording. **Intelligence** refines a rough ask into a sharper prompt, surfaces a draft plan and decision suggestions, and waits for your confirmation before it automates anything. You decide how much the agent shapes the request. +**What DeepAgent does:** Three modes on the composer. **Auto** decides how to plan and act on your request. **Design** explores the problem and proposes a design before building anything. **Loop** turns a request into a supervised goal the agent works toward autonomously — iterating plan → execute → verify until the criteria are met — while you stay in control. You choose the autonomy level per task, not once for the whole tool. ### Choose how much the agent drives — and who writes the plan @@ -71,6 +72,18 @@ The features below start from a real need — something a plain coding agent, op **What DeepAgent does:** At higher work strengths the primary agent decomposes the task, fans it out to focused subagents that research modules in parallel, synthesizes their findings, and then runs independent reviewers whose job is to *break* the plan rather than agree with it. Fan-out is bounded by a configurable concurrency ceiling, and live subagents surface in a session side panel and inline in the transcript so you can watch and jump into any of them. +### Set a goal and let it run — supervised, not unsupervised + +**The need:** Some work is a long haul — a migration, a green-the-suite push, a multi-step feature. You want to hand it off and walk away, but "walk away" can't mean "lose control." + +**What DeepAgent does:** Loop mode drives an autonomous goal loop against an objectively decidable finish line (tests pass, no diagnostics, reviewer clean, plan complete). It runs plan → execute → verify → iterate in the background, with hard ceilings on ticks, tokens, wall-clock, and cost so it can never run away. A status bar shows live progress; you can hot-edit the plan mid-run, pause and resume from exactly where it stopped, or take over — a takeover pauses autonomy escalation and hands control back to you. A goal with steps that need a human never reports "done"; it routes to you. Autonomy is a dial you hold, not a switch you flip and hope. + +### Get a second opinion that actually argues + +**The need:** For a high-stakes decision, one confident answer isn't enough — you want independent experts who see the same evidence, disagree, and defend their positions. + +**What DeepAgent does:** Convene an Expert Panel on the current conversation from the composer. Pick single-round for a quick multi-lens review, or multi-round for a real debate: panelists (correctness, security, design, …) each render a verdict, then see each other's *anonymized* opinions and revise across up to three rounds — identity stripped so nobody anchors on "the security expert said." An arbiter synthesizes the surviving verdict. Fan-out and rounds are bounded, and every opinion (including the losers') is archived. The panel convenes on demand, or a running goal loop can convene it at high-risk decision points. + ### Chat with your team and your agents in one place **The need:** Coordinating with teammates and driving agents usually happens in two different tools. @@ -89,6 +102,8 @@ Each capability above is served by a control-plane primitive underneath. These a **Self-learning** — After work lands, the agent proposes candidate knowledge, facts, and methodologies. Promotion is evidence-gated (a test passed, a diagnostic cleared, a validation confirmed) and user-controllable — durable knowledge is carried over deliberately, not silently guessed. Session-stable conclusions consolidate into project memory over time, so the next session starts smarter about *your* codebase. +**Supervised autonomy** — The goal loop, expert panel, and multi-agent fan-out run on an event-driven substrate with the guardrails autonomy needs: hard budget ceilings (ticks/tokens/wall-clock/cost), a stall detector that stops rather than spins, layered permission and safety gates that fail closed, human takeover that pauses escalation, and a full audit trail written back to the document graph. An Agent Dashboard surfaces task success rate, conflicts, and dead-letter events. Autonomy is bounded and observable by construction — never a black box you can't stop. + ## Installation ```bash @@ -143,6 +158,7 @@ On your next session, when you ask to add rate limiting elsewhere, the agent alr │ • Domain pack system (composable, auto-activating knowledge)│ │ • Context assembly & admission gates │ │ • Multi-agent orchestration & adversarial review │ +│ • Supervised goal loop & expert panel (event-driven) │ │ • Evidence-gated learning & work-strength ladder │ └─────────────────────────────────────────────────────────────┘ │ diff --git a/README.zh.md b/README.zh.md index 0a17532a..e59e34c5 100644 --- a/README.zh.md +++ b/README.zh.md @@ -6,11 +6,12 @@

-

具备持久记忆与控制平面的 AI 编程智能体

+

具备持久记忆、自主目标与控制平面的 AI 编程智能体

English | - 简体中文 + 简体中文 | + Enterprise 版本

桌面版 v1.3

@@ -41,11 +42,11 @@ DeepAgent Code 是一个构建在持久文档记忆之上的 AI 编程智能体 **DeepAgent 的做法:** 从任意一条消息分叉当前对话。分叉出的新对话会继承父对话到该点为止的记忆,在时间线顶部显示一条贯穿窗口的"从对话派生"分割线,并像文件夹一样嵌套挂在来源对话之下(子 agent 与分叉同理,最多三层深)。知识沿作用域层级向上流动——单个会话学到的东西可提升到整个项目,跨项目的偏好则沉淀在用户全局层——所以换窗口是一次干净的交接,而非一次清零重来。 -### 想到哪问到哪,让智能体替你打磨 +### 自主程度,按任务自己挑 -**需求:** 半成品的提问只能换来半有用的回答,而你未必总知道该怎么把想要的东西说清楚。 +**需求:** 有些提问想要一个快速、原话作答;有些希望智能体先规划;还有些希望它自己跑到把活干完为止。一种固定行为伺候不了这三种。 -**DeepAgent 的做法:** 输入框上有两种情景模式。**直接**模式原样发送你的提示——措辞由你做主。**智能**模式会把粗糙的想法打磨成更精准的提示,给出草拟的方案和决策建议,并在自动执行任何操作前等你确认。智能体替你塑形到什么程度,由你决定。 +**DeepAgent 的做法:** 输入框上有三种模式。**自动(Auto)** 由智能体决定如何规划并执行你的请求。**设计(Design)** 先探索问题、给出设计方案,再动手构建。**循环(Loop)** 把请求变成一个受监督的目标,智能体朝它自主推进——不断地"规划 → 执行 → 校验"直到满足完成判据——而掌控权始终在你手里。自主程度按任务来选,而不是为整个工具一次性定死。 ### 选择智能体驱动的方式——以及由谁来写计划 @@ -71,6 +72,18 @@ DeepAgent Code 是一个构建在持久文档记忆之上的 AI 编程智能体 **DeepAgent 的做法:** 在更高的工作强度下,主智能体会拆解任务,扇出给专注的子 agent 并行调研各个模块,综合它们的发现,再运行独立的审阅者——审阅者的职责是"击破"方案,而不是附和。扇出受可配置的并发上限约束;运行中的子 agent 会出现在会话侧栏面板和时间线内联卡片里,你可以旁观并随时跳进任意一个。 +### 定个目标让它自己跑——是受监督,而非放养 + +**需求:** 有些工作是场持久战——一次迁移、一轮把测试全刷绿、一个多步骤的特性。你想把它交出去然后走开,但"走开"不能等于"失控"。 + +**DeepAgent 的做法:** 循环模式驱动一个自主目标回路,朝着一条可客观判定的终点线推进(测试通过、无诊断、审阅无异议、计划完成)。它在后台跑"规划 → 执行 → 校验 → 迭代",并对轮次、令牌、墙钟时间和成本设有硬上限,绝不会失控狂奔。状态条实时显示进度;你可以在运行中热编辑计划、暂停后从中断处精确恢复,或直接接管——接管会暂停自主升级、把控制权交还给你。一个包含需要人工处理步骤的目标绝不会谎报"完成",而是转交给你。自主是你握在手里的旋钮,不是拨一下就听天由命的开关。 + +### 要一个真会争论的第二意见 + +**需求:** 面对高风险决策,一个自信的答案不够——你想要一批独立专家,看着同样的证据,各持己见、各自辩护。 + +**DeepAgent 的做法:** 从输入框就当前对话召集专家团。选单轮做一次快速的多视角评审,或选多轮进行真正的辩论:各位专家(正确性、安全、设计……)先各自给出裁定,然后看到彼此**匿名化**的意见并在最多三轮里修正——身份被抹去,谁都无法因"是安全专家说的"而锚定。一位仲裁者综合出最终存活的裁定。扇出与轮数都有界,每一条意见(包括落败的)都会被归档。专家团可按需召集,运行中的目标回路也能在高风险决策点上召集它。 + ### 团队与智能体,在同一处协作 **需求:** 和队友协调、驱动智能体,通常发生在两个不同的工具里。 @@ -89,6 +102,8 @@ DeepAgent Code 是一个构建在持久文档记忆之上的 AI 编程智能体 **自学习** — 工作落地后,智能体会提出候选的知识、事实与方法论。晋升是证据门控的(一项测试通过、一条诊断清零、一次校验确认)且由用户掌控——持久知识是被有意结转的,而非后台悄悄猜出来的。会话中稳定的结论会随时间巩固进项目记忆,于是下一次会话对*你的*代码库上手更聪明。 +**受监督的自主** — 目标回路、专家团与多智能体扇出都跑在一套事件驱动的底座上,并带着自主所必需的护栏:硬性预算上限(轮次/令牌/墙钟/成本)、宁停不空转的停滞检测、层层失败即关闭的权限与安全门、暂停升级的人工接管,以及写回文档图的完整审计轨迹。一个 Agent 面板会呈现任务成功率、冲突与死信事件。自主在构造上就是有界且可观测的——绝不是一个你停不下来的黑盒。 + ## 安装 ```bash @@ -143,6 +158,7 @@ deepagent-code "为 /api/users 端点添加限流" │ • 领域包系统(可组合、自动激活的知识) │ │ • 上下文装配与准入门 │ │ • 多智能体编排与对抗式审阅 │ +│ • 受监督的目标回路与专家团(事件驱动) │ │ • 证据门控的学习 + 工作强度阶梯 │ └─────────────────────────────────────────────────────────────┘ │ diff --git a/bun.lock b/bun.lock index 63a61400..82ed0bd7 100644 --- a/bun.lock +++ b/bun.lock @@ -29,7 +29,7 @@ }, "packages/app": { "name": "@deepagent-code/app", - "version": "1.0.0-beta", + "version": "1.4.0", "dependencies": { "@codemirror/autocomplete": "6", "@codemirror/commands": "6", @@ -344,7 +344,7 @@ }, "packages/desktop": { "name": "@deepagent-code/desktop", - "version": "1.2.0", + "version": "1.4.0", "dependencies": { "@zip.js/zip.js": "2.7.62", "effect": "catalog:", diff --git a/packages/app/package.json b/packages/app/package.json index 888f9b32..9435d21f 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -1,6 +1,6 @@ { "name": "@deepagent-code/app", - "version": "1.0.0-beta", + "version": "1.4.0", "description": "", "type": "module", "exports": { diff --git a/packages/app/src/components/deepagent/goal-plan-edit-dialog.tsx b/packages/app/src/components/deepagent/goal-plan-edit-dialog.tsx new file mode 100644 index 00000000..a7d3a00d --- /dev/null +++ b/packages/app/src/components/deepagent/goal-plan-edit-dialog.tsx @@ -0,0 +1,164 @@ +import { For, Index, Show, createSignal } from "solid-js" +import { Dialog, DialogFooter } from "@deepagent-code/ui/v2/dialog-v2" +import { Button } from "@deepagent-code/ui/button" +import { Icon } from "@deepagent-code/ui/icon" +import { useLanguage } from "@/context/language" +import { showToast } from "@/utils/toast" +import { editPlanGoal, type GoalPlanInput, type PanelGoalClient } from "./panel-goal.api" +import type { SessionPlan } from "@/context/global-sync/types" + +/** + * V4.1 §S2 — the goal plan HOT-EDIT dialog. Opened from the goal status bar for a running/paused goal. + * Pre-fills from the live session_plan (the same plan the status bar reads), lets the user revise the + * goal text + step titles/statuses (add/remove steps), and POSTs the revision via editPlanGoal. The + * backend applies it between ticks (durable-doc upsert + stall re-baseline) — see goal-loop.applyPlanEdit. + * + * step_id is preserved for existing steps (so the backend reconciles ids + runtime evidence via + * buildPlanFromInput); a NEW step is sent without an id and the backend assigns one. Evidence is + * runtime-owned and never sent from the client. + */ + +// The status values a user can pick — mirrors PlanStepStatus. `active` is included so a user can point +// the goal at a specific step; the backend re-derives active_step_id from the first active step. +const STATUS_OPTIONS = ["pending", "active", "done", "blocked", "cancelled"] as const +type StatusOption = (typeof STATUS_OPTIONS)[number] + +const STATUS_LABEL_KEY: Record = { + pending: "composer.goal.editPlan.status.pending", + active: "composer.goal.editPlan.status.active", + done: "composer.goal.editPlan.status.done", + blocked: "composer.goal.editPlan.status.blocked", + cancelled: "composer.goal.editPlan.status.cancelled", +} + +// A local editable step row. `step_id` is undefined for a freshly-added step (the backend assigns one). +type EditStep = { + step_id?: string + title: string + status: StatusOption +} + +const normStatus = (s: string): StatusOption => + (STATUS_OPTIONS as readonly string[]).includes(s) ? (s as StatusOption) : "pending" + +export function GoalPlanEditDialog(props: { + sessionID: string + plan: SessionPlan | undefined + client: PanelGoalClient + onClose: () => void +}) { + const language = useLanguage() + const [goal, setGoal] = createSignal(props.plan?.goal ?? "") + const [steps, setSteps] = createSignal( + (props.plan?.steps ?? []).map((s) => ({ step_id: s.step_id, title: s.title, status: normStatus(s.status) })), + ) + const [busy, setBusy] = createSignal(false) + + const setStep = (i: number, patch: Partial) => + setSteps((prev) => prev.map((s, idx) => (idx === i ? { ...s, ...patch } : s))) + const addStep = () => setSteps((prev) => [...prev, { title: "", status: "pending" }]) + const removeStep = (i: number) => setSteps((prev) => prev.filter((_, idx) => idx !== i)) + + // Valid to submit: a non-empty goal and at least one step whose title is non-empty. Empty-title steps + // are dropped on submit (a user adding a row then leaving it blank shouldn't create a titleless step). + const canSave = () => goal().trim().length > 0 && steps().some((s) => s.title.trim().length > 0) + + const onSave = async () => { + if (busy() || !canSave()) return + setBusy(true) + try { + const plan: GoalPlanInput = { + goal: goal().trim(), + steps: steps() + .filter((s) => s.title.trim().length > 0) + .map((s) => ({ + ...(s.step_id ? { step_id: s.step_id } : {}), + title: s.title.trim(), + status: s.status, + })), + } + const ok = await editPlanGoal(props.client, props.sessionID, plan) + if (ok) { + showToast({ title: language.t("composer.goal.editPlan.saved"), variant: "success" }) + props.onClose() + } else { + showToast({ title: language.t("composer.goal.editPlan.failed") }) + } + } catch { + showToast({ title: language.t("composer.goal.editPlan.failed") }) + } finally { + setBusy(false) + } + } + + return ( + +
+