mirror of
https://github.com/shareAI-lab/analysis_claude_code.git
synced 2026-09-19 01:51:06 +08:00
Merge remote-tracking branch 'upstream/main'
This commit is contained in:
@@ -232,10 +232,8 @@ register_hook("Stop", summary_hook)
|
||||
# agent_loop — same as s04 + nag reminder counter
|
||||
# ═══════════════════════════════════════════════════════════
|
||||
|
||||
rounds_since_todo = 0
|
||||
|
||||
def agent_loop(messages: list):
|
||||
global rounds_since_todo
|
||||
rounds_since_todo = 0
|
||||
while True:
|
||||
# s05: nag reminder — inject if model hasn't updated todos for 3 rounds
|
||||
if rounds_since_todo >= 3 and messages:
|
||||
|
||||
@@ -312,10 +312,8 @@ register_hook("Stop", summary_hook)
|
||||
# agent_loop — same as s05 + nag reminder, task auto-dispatches
|
||||
# ═══════════════════════════════════════════════════════════
|
||||
|
||||
rounds_since_todo = 0
|
||||
|
||||
def agent_loop(messages: list):
|
||||
global rounds_since_todo
|
||||
rounds_since_todo = 0
|
||||
while True:
|
||||
# s05: nag reminder
|
||||
if rounds_since_todo >= 3 and messages:
|
||||
|
||||
@@ -356,10 +356,8 @@ register_hook("Stop", summary_hook)
|
||||
# agent_loop — same as s05-s06 + nag reminder
|
||||
# ═══════════════════════════════════════════════════════════
|
||||
|
||||
rounds_since_todo = 0
|
||||
|
||||
def agent_loop(messages: list):
|
||||
global rounds_since_todo
|
||||
rounds_since_todo = 0
|
||||
while True:
|
||||
if rounds_since_todo >= 3 and messages:
|
||||
messages.append({"role": "user",
|
||||
|
||||
@@ -136,7 +136,7 @@ def compact_history(messages):
|
||||
|
||||
Sometimes the API still returns `prompt_too_long` (413) — when context grows faster than compression triggers.
|
||||
|
||||
This triggers **reactive_compact**: more aggressive than compact_history, it retreats from the tail, but still avoids leaving an orphaned `tool_result`.
|
||||
This triggers **reactive_compact**: more aggressive than compact_history in trigger (emergency response to a 413 error), but more conservative in what it removes, keeping ~5 recent messages and only summarizing earlier history. Still avoids an orphaned `tool_result`.
|
||||
|
||||
```python
|
||||
def reactive_compact(messages):
|
||||
|
||||
@@ -136,7 +136,7 @@ def compact_history(messages):
|
||||
|
||||
API がまだ `prompt_too_long`(413)を返すことがある。コンテキストの増加速度が圧縮のトリガー速度を上回る場合。
|
||||
|
||||
この時 **reactive_compact** がトリガーされる:compact_history よりもさらに積極的だが、末尾を残す際も孤立した `tool_result` を残さないようにする。
|
||||
この時 **reactive_compact** がトリガーされる。トリガー方式は compact_history より積極的(413 エラー後の緊急対応)だが、圧縮方針はより温和で、末尾約 5 件のメッセージを保持し、早期の履歴だけを要約する。孤立した `tool_result` を残さないよう配慮する。
|
||||
|
||||
```python
|
||||
def reactive_compact(messages):
|
||||
|
||||
@@ -136,7 +136,7 @@ def compact_history(messages):
|
||||
|
||||
有时候 API 还是返回 `prompt_too_long`(413),上下文增长速度快于压缩触发速度时。
|
||||
|
||||
这时触发 **reactive_compact**:比 compact_history 更激进,从尾部回退,但仍要避免留下孤立 `tool_result`。
|
||||
这时触发 **reactive_compact**:触发方式比 compact_history 更激进(API 报错后的应急手段),但压缩策略更温和,保留最近约 5 条原始消息,只总结较早历史。同样避免留下孤立 `tool_result`。
|
||||
|
||||
```python
|
||||
def reactive_compact(messages):
|
||||
|
||||
@@ -68,9 +68,6 @@ Split the monolithic string into a dictionary, each key is a topic:
|
||||
```python
|
||||
PROMPT_SECTIONS = {
|
||||
"identity": "You are a coding agent. Act, don't explain.",
|
||||
"tools": "Available tools: bash, read_file, write_file.",
|
||||
"workspace": f"Working directory: {WORKDIR}",
|
||||
"memory": "Relevant memories are injected below when available.",
|
||||
}
|
||||
```
|
||||
|
||||
@@ -86,8 +83,12 @@ def assemble_system_prompt(context: dict) -> str:
|
||||
|
||||
# Always loaded
|
||||
sections.append(PROMPT_SECTIONS["identity"])
|
||||
sections.append(PROMPT_SECTIONS["tools"])
|
||||
sections.append(PROMPT_SECTIONS["workspace"])
|
||||
|
||||
# Dynamic — tools and workspace from context
|
||||
tools = ", ".join(context.get("enabled_tools", []))
|
||||
if tools:
|
||||
sections.append(f"Available tools: {tools}.")
|
||||
sections.append(f"Working directory: {context.get("workspace", WORKDIR)}")
|
||||
|
||||
# On-demand — based on real state, not keywords
|
||||
memories = context.get("memories", "")
|
||||
|
||||
@@ -68,9 +68,6 @@ s10 は prompt アセンブリ機構に焦点を当てる。s08-s09 の能力を
|
||||
```python
|
||||
PROMPT_SECTIONS = {
|
||||
"identity": "You are a coding agent. Act, don't explain.",
|
||||
"tools": "Available tools: bash, read_file, write_file.",
|
||||
"workspace": f"Working directory: {WORKDIR}",
|
||||
"memory": "Relevant memories are injected below when available.",
|
||||
}
|
||||
```
|
||||
|
||||
@@ -86,8 +83,12 @@ def assemble_system_prompt(context: dict) -> str:
|
||||
|
||||
# 常にロード
|
||||
sections.append(PROMPT_SECTIONS["identity"])
|
||||
sections.append(PROMPT_SECTIONS["tools"])
|
||||
sections.append(PROMPT_SECTIONS["workspace"])
|
||||
|
||||
# context から動的に tools と workspace を取得
|
||||
tools = ", ".join(context.get("enabled_tools", []))
|
||||
if tools:
|
||||
sections.append(f"Available tools: {tools}.")
|
||||
sections.append(f"Working directory: {context.get("workspace", WORKDIR)}")
|
||||
|
||||
# オンデマンド — 実際の状態に基づく、キーワードではない
|
||||
memories = context.get("memories", "")
|
||||
|
||||
@@ -68,9 +68,6 @@ s10 聚焦 prompt 组装机制。以 s08-s09 的能力为背景,但不重复
|
||||
```python
|
||||
PROMPT_SECTIONS = {
|
||||
"identity": "You are a coding agent. Act, don't explain.",
|
||||
"tools": "Available tools: bash, read_file, write_file.",
|
||||
"workspace": f"Working directory: {WORKDIR}",
|
||||
"memory": "Relevant memories are injected below when available.",
|
||||
}
|
||||
```
|
||||
|
||||
@@ -86,8 +83,12 @@ def assemble_system_prompt(context: dict) -> str:
|
||||
|
||||
# 始终加载
|
||||
sections.append(PROMPT_SECTIONS["identity"])
|
||||
sections.append(PROMPT_SECTIONS["tools"])
|
||||
sections.append(PROMPT_SECTIONS["workspace"])
|
||||
|
||||
# 从 context 动态获取 tools 和 workspace
|
||||
tools = ", ".join(context.get("enabled_tools", []))
|
||||
if tools:
|
||||
sections.append(f"Available tools: {tools}.")
|
||||
sections.append(f"Working directory: {context.get("workspace", WORKDIR)}")
|
||||
|
||||
# 按需加载 — 基于真实状态,不是关键词
|
||||
memories = context.get("memories", "")
|
||||
|
||||
@@ -41,9 +41,6 @@ MODEL = os.environ["MODEL_ID"]
|
||||
|
||||
PROMPT_SECTIONS = {
|
||||
"identity": "You are a coding agent. Act, don't explain.",
|
||||
"tools": "Available tools: bash, read_file, write_file.",
|
||||
"workspace": f"Working directory: {WORKDIR}",
|
||||
"memory": "Relevant memories are injected below when available.",
|
||||
}
|
||||
|
||||
|
||||
@@ -51,10 +48,14 @@ def assemble_system_prompt(context: dict) -> str:
|
||||
"""Select and join prompt sections based on current context."""
|
||||
sections = []
|
||||
|
||||
# Always loaded — identity, tools, workspace
|
||||
# Always loaded — identity
|
||||
sections.append(PROMPT_SECTIONS["identity"])
|
||||
sections.append(PROMPT_SECTIONS["tools"])
|
||||
sections.append(PROMPT_SECTIONS["workspace"])
|
||||
|
||||
# Dynamic — tools and workspace from context
|
||||
tools = ", ".join(context.get("enabled_tools", []))
|
||||
if tools:
|
||||
sections.append(f"Available tools: {tools}.")
|
||||
sections.append(f"Working directory: {context.get("workspace", WORKDIR)}")
|
||||
|
||||
# Conditional — memory loaded when MEMORY.md exists and has content
|
||||
memories = context.get("memories", "")
|
||||
|
||||
@@ -272,10 +272,10 @@ def agent_loop(messages: list, context: dict):
|
||||
# ── LLM call: with_retry handles 429/529, outer handles rest ──
|
||||
try:
|
||||
response = with_retry(
|
||||
lambda mt=max_tokens, mdl=state.current_model:
|
||||
client.messages.create(
|
||||
model=mdl, system=system, messages=messages,
|
||||
tools=TOOLS, max_tokens=mt),
|
||||
lambda: client.messages.create(
|
||||
model=state.current_model, system=system,
|
||||
messages=messages, tools=TOOLS,
|
||||
max_tokens=max_tokens),
|
||||
state)
|
||||
except Exception as e:
|
||||
# Path 2: prompt_too_long -> reactive compact (once)
|
||||
|
||||
@@ -195,15 +195,15 @@ Two teammates claim and work in parallel. Lead only creates tasks and spawns tea
|
||||
| Component | Before (s16) | After (s17) |
|
||||
|-----------|-------------|-------------|
|
||||
| Task assignment | Lead manually assigns | Teammates auto-claim (can_start checks deps) |
|
||||
| Teammate state | WORK or exit | WORK → IDLE (60s poll) → SHUTDOWN |
|
||||
| Teammate state | WORK → IDLE (1s inbox poll) → WORK / SHUTDOWN | WORK → IDLE (5s inbox + task board poll, 60s timeout) → WORK / SHUTDOWN |
|
||||
| claim_task | No owner check | Rejects tasks that already have an owner |
|
||||
| IDLE phase shutdown | Doesn't handle shutdown_request | Dispatches shutdown immediately and exits |
|
||||
| Lead inbox | Prints only, not in context | consume_lead_inbox injects into history |
|
||||
| New functions | — | idle_poll, scan_unclaimed_tasks, consume_lead_inbox |
|
||||
| IDLE phase shutdown | Exits after receiving shutdown_request | Dispatches shutdown immediately and exits |
|
||||
| Lead inbox | consume_lead_inbox routes protocol responses and injects into context | Reuses consume_lead_inbox mechanism |
|
||||
| New functions | consume_lead_inbox already exists | idle_poll, scan_unclaimed_tasks (reuses consume_lead_inbox) |
|
||||
| Identity persistence | System prompt only | Auto re-inject after compression |
|
||||
| Lead tools | 14 (s16) | 14 (unchanged) |
|
||||
| Lead tools | 14 | 14 (unchanged) |
|
||||
| Teammate tools | 5 | 8 (+ list_tasks, claim_task, complete_task) |
|
||||
| Teammate exit | Exit after task done | Exit only after 60s idle timeout |
|
||||
| Teammate exit | WORK ends → enters IDLE, waits for shutdown_request (no timeout) | Exits after 60s idle timeout or receiving shutdown_request |
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -195,15 +195,15 @@ if len(messages) <= 3:
|
||||
| コンポーネント | 変更前 (s16) | 変更後 (s17) |
|
||||
|--------------|------------|------------|
|
||||
| タスク割り当て | Lead が手動 assign | チームメイトが自動認領(can_start で依存確認) |
|
||||
| チームメイト状態 | WORK または終了 | WORK → IDLE(60s ポーリング) → SHUTDOWN |
|
||||
| チームメイト状態 | WORK → IDLE(1s 間隔で inbox をポーリング)→ WORK / SHUTDOWN | WORK → IDLE(5s 間隔で inbox + タスクボードをポーリング、60s タイムアウト)→ WORK / SHUTDOWN |
|
||||
| claim_task | owner チェックなし | 既に owner があるタスクを拒否 |
|
||||
| IDLE フェーズシャットダウン | shutdown_request を処理しない | 即座にシャットダウンをディスパッチして終了 |
|
||||
| Lead inbox | 印刷のみ、コンテキストに入らない | consume_lead_inbox で history に注入 |
|
||||
| 新規関数 | — | idle_poll, scan_unclaimed_tasks, consume_lead_inbox |
|
||||
| IDLE フェーズシャットダウン | shutdown_request を受信後に終了 | 即座にシャットダウンをディスパッチして終了 |
|
||||
| Lead inbox | consume_lead_inbox がプロトコル応答をルーティングしコンテキストに注入 | consume_lead_inbox 機構を踏襲 |
|
||||
| 新規関数 | consume_lead_inbox は既存 | idle_poll, scan_unclaimed_tasks(consume_lead_inbox を踏襲) |
|
||||
| 身份保持 | system prompt のみ | 圧縮後に自動再注入 |
|
||||
| Lead ツール | 14 (s16) | 14(変更なし) |
|
||||
| Lead ツール | 14 | 14(変更なし) |
|
||||
| チームメイトツール | 5 | 8(+ list_tasks, claim_task, complete_task) |
|
||||
| チームメイト終了条件 | タスク完了後即終了 | 60s アイドルタイムアウト後のみ終了 |
|
||||
| チームメイト終了条件 | WORK 完了後 IDLE に入り、shutdown_request を待って終了(タイムアウトなし) | 60s アイドルタイムアウトまたは shutdown_request 受信で終了 |
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -195,15 +195,15 @@ if len(messages) <= 3:
|
||||
| 组件 | 之前 (s16) | 之后 (s17) |
|
||||
|------|-----------|-----------|
|
||||
| 任务分配 | Lead 手动 assign | 队友自动认领(can_start 检查依赖) |
|
||||
| 队友状态 | WORK 或退出 | WORK → IDLE(轮询 60s) → SHUTDOWN |
|
||||
| 队友状态 | WORK → IDLE(每 1s 轮询 inbox)→ WORK / SHUTDOWN | WORK → IDLE(每 5s 轮询 inbox + 任务板,60s 超时)→ WORK / SHUTDOWN |
|
||||
| claim_task | 无 owner 检查 | 拒绝已有 owner 的任务 |
|
||||
| IDLE 阶段关机 | 不处理 shutdown_request | 直接 dispatch shutdown 并退出 |
|
||||
| Lead inbox | 只打印,不进上下文 | consume_lead_inbox 统一注入 history |
|
||||
| 新函数 | — | idle_poll, scan_unclaimed_tasks, consume_lead_inbox |
|
||||
| IDLE 阶段关机 | 收到 shutdown_request 后退出 | 直接 dispatch shutdown 并退出 |
|
||||
| Lead inbox | consume_lead_inbox 路由协议响应并注入上下文 | 沿用 consume_lead_inbox 机制 |
|
||||
| 新函数 | 已有 consume_lead_inbox | idle_poll, scan_unclaimed_tasks(沿用 consume_lead_inbox) |
|
||||
| 身份保持 | 仅 system prompt | 压缩后自动重注入 |
|
||||
| Lead 工具 | 14 (s16) | 14(不变) |
|
||||
| Lead 工具 | 14 | 14(不变) |
|
||||
| 队友工具 | 5 | 8(+ list_tasks, claim_task, complete_task) |
|
||||
| 队友退出条件 | 完成任务即退出 | 60s 无新任务才退出 |
|
||||
| 队友退出条件 | WORK 完进入 IDLE,等待 shutdown_request 后退出(无超时) | 60s 无新任务或收到 shutdown_request 后退出 |
|
||||
|
||||
---
|
||||
|
||||
|
||||
Reference in New Issue
Block a user