Skip to content

Commit d228b57

Browse files
committed
Merge remote-tracking branch 'origin/main' into fix/background-task-notifications-clean
2 parents 51f1157 + d882d01 commit d228b57

File tree

5 files changed

+49
-47
lines changed

5 files changed

+49
-47
lines changed

agents/s01_agent_loop.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,8 @@ def run_bash(command: str) -> str:
7373
return out[:50000] if out else "(no output)"
7474
except subprocess.TimeoutExpired:
7575
return "Error: Timeout (120s)"
76+
except (FileNotFoundError, OSError) as e:
77+
return f"Error: {e}"
7678

7779

7880
# -- The core pattern: a while loop that calls tools until the model stops --

agents/s04_subagent.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@ def run_bash(command: str) -> str:
6161
return out[:50000] if out else "(no output)"
6262
except subprocess.TimeoutExpired:
6363
return "Error: Timeout (120s)"
64+
except (FileNotFoundError, OSError) as e:
65+
return f"Error: {e}"
6466

6567
def run_read(path: str, limit: int = None) -> str:
6668
try:
@@ -155,8 +157,9 @@ def agent_loop(messages: list):
155157
if block.type == "tool_use":
156158
if block.name == "task":
157159
desc = block.input.get("description", "subtask")
158-
print(f"> task ({desc}): {block.input['prompt'][:80]}")
159-
output = run_subagent(block.input["prompt"])
160+
prompt = block.input.get("prompt", "")
161+
print(f"> task ({desc}): {prompt[:80]}")
162+
output = run_subagent(prompt)
160163
else:
161164
handler = TOOL_HANDLERS.get(block.name)
162165
output = handler(**block.input) if handler else f"Unknown tool: {block.name}"

agents/s06_context_compact.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,9 @@ def auto_compact(messages: list) -> list:
118118
"Be concise but preserve critical details.\n\n" + conversation_text}],
119119
max_tokens=2000,
120120
)
121-
summary = response.content[0].text
121+
summary = next((block.text for block in response.content if hasattr(block, "text")), "")
122+
if not summary:
123+
summary = "No summary generated."
122124
# Replace all messages with compressed summary
123125
return [
124126
{"role": "user", "content": f"[Conversation compressed. Transcript: {transcript_path}]\n\n{summary}"},

docs/zh/s04-subagent.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
99
## 问题
1010

11-
Agent 工作越久, messages 数组越胖。每次读文件、跑命令的输出都永久留在上下文里。"这个项目用什么测试框架?" 可能要读 5 个文件, 但父 Agent 只需要一个词: "pytest。"
11+
Agent 工作越久, messages 数组越臃肿。每次读文件、跑命令的输出都永久留在上下文里。"这个项目用什么测试框架?" 可能要读 5 个文件, 但父 Agent 只需要一个词: "pytest。"
1212

1313
## 解决方案
1414

web/src/components/architecture/execution-flow.tsx

Lines changed: 38 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
import { useEffect, useState } from "react";
44
import { motion } from "framer-motion";
5-
import { useTranslations } from "@/lib/i18n";
65
import { getFlowForVersion } from "@/data/execution-flows";
76
import type { FlowNode, FlowEdge } from "@/types/agent-data";
87

@@ -186,7 +185,6 @@ interface ExecutionFlowProps {
186185
}
187186

188187
export function ExecutionFlow({ version }: ExecutionFlowProps) {
189-
const t = useTranslations("version");
190188
const [flow, setFlow] = useState<ReturnType<typeof getFlowForVersion>>(null);
191189

192190
useEffect(() => {
@@ -198,46 +196,43 @@ export function ExecutionFlow({ version }: ExecutionFlowProps) {
198196
const maxY = Math.max(...flow.nodes.map((n) => n.y)) + 50;
199197

200198
return (
201-
<section>
202-
<h2 className="mb-4 text-xl font-semibold">{t("execution_flow")}</h2>
203-
<div className="overflow-x-auto rounded-xl border border-[var(--color-border)] bg-[var(--color-bg)] p-4">
204-
<svg
205-
viewBox={`0 0 600 ${maxY}`}
206-
className="mx-auto w-full max-w-[600px]"
207-
style={{ minHeight: 300 }}
208-
>
209-
<defs>
210-
<marker
211-
id="arrowhead"
212-
markerWidth={8}
213-
markerHeight={6}
214-
refX={8}
215-
refY={3}
216-
orient="auto"
217-
>
218-
<polygon
219-
points="0 0, 8 3, 0 6"
220-
fill="var(--color-text-secondary)"
221-
/>
222-
</marker>
223-
</defs>
224-
225-
{flow.edges.map((edge, i) => (
226-
<EdgePath key={`${edge.from}-${edge.to}`} edge={edge} nodes={flow.nodes} index={i} />
227-
))}
228-
229-
{flow.nodes.map((node, i) => (
230-
<motion.g
231-
key={node.id}
232-
initial={{ opacity: 0, y: -10 }}
233-
animate={{ opacity: 1, y: 0 }}
234-
transition={{ delay: i * 0.06, duration: 0.3 }}
235-
>
236-
<NodeShape node={node} />
237-
</motion.g>
238-
))}
239-
</svg>
240-
</div>
241-
</section>
199+
<div className="overflow-x-auto rounded-xl border border-[var(--color-border)] bg-[var(--color-bg)] p-4">
200+
<svg
201+
viewBox={`0 0 600 ${maxY}`}
202+
className="mx-auto w-full max-w-[600px]"
203+
style={{ minHeight: 300 }}
204+
>
205+
<defs>
206+
<marker
207+
id="arrowhead"
208+
markerWidth={8}
209+
markerHeight={6}
210+
refX={8}
211+
refY={3}
212+
orient="auto"
213+
>
214+
<polygon
215+
points="0 0, 8 3, 0 6"
216+
fill="var(--color-text-secondary)"
217+
/>
218+
</marker>
219+
</defs>
220+
221+
{flow.edges.map((edge, i) => (
222+
<EdgePath key={`${edge.from}-${edge.to}`} edge={edge} nodes={flow.nodes} index={i} />
223+
))}
224+
225+
{flow.nodes.map((node, i) => (
226+
<motion.g
227+
key={node.id}
228+
initial={{ opacity: 0, y: -10 }}
229+
animate={{ opacity: 1, y: 0 }}
230+
transition={{ delay: i * 0.06, duration: 0.3 }}
231+
>
232+
<NodeShape node={node} />
233+
</motion.g>
234+
))}
235+
</svg>
236+
</div>
242237
);
243238
}

0 commit comments

Comments
 (0)