Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
ce85097
chore: ignore local worktrees
gaoxiaobei Jul 26, 2026
4ce0a33
miracle: 官方逻辑零改动运行 + 规则策略对战闭环(Phase 1)
gaoxiaobei Aug 2, 2026
0610dc4
feat(miracle): 要求3——决策空间定义
gaoxiaobei Aug 2, 2026
6fd264a
docs(miracle): 决策空间定义文档(要求 3 配套)
gaoxiaobei Aug 2, 2026
87bc33b
feat(miracle): 要求4——信息增益实现
gaoxiaobei Aug 2, 2026
423a345
feat(miracle): 要求2——Agent 看游戏回放 Skill + 实际回放解析验证
gaoxiaobei Aug 2, 2026
3c77230
feat(miracle): 要求2配套——官方 .mrc 二进制回放解析为事件时间线
gaoxiaobei Aug 2, 2026
fb66e4a
feat(miracle): 要求1后半+要求5——迭代闭环、数据契约与曲线
gaoxiaobei Aug 2, 2026
67c11a2
feat(miracle): 迭代编排/版本快照/CLI(要求1后半配套)
gaoxiaobei Aug 2, 2026
540cbfb
feat(miracle): 面向外部 LLM 的 harness 使用 SOP skill(要求 1 后半配套)
gaoxiaobei Aug 2, 2026
c3b5a0e
feat(miracle): 要求5——curves.py 曲线模块(SVG+数据 JSON,版本对齐,无数据如实报告)
gaoxiaobei Aug 2, 2026
fbd1b7b
docs(miracle): 交付汇总——5 项要求逐条对照、产物清单、数据契约说明
gaoxiaobei Aug 2, 2026
5246fdb
docs: design Miracle OpenAI harness loop
gaoxiaobei Aug 2, 2026
c129c90
docs: plan Miracle OpenAI harness loop
gaoxiaobei Aug 2, 2026
59ebeeb
feat(miracle): add validated loop configuration
gaoxiaobei Aug 2, 2026
ea2d58f
feat(miracle): add Chat Completions strategy client
gaoxiaobei Aug 2, 2026
bc45d10
feat(miracle): validate immutable strategy snapshots
gaoxiaobei Aug 2, 2026
07d0953
feat(miracle): add observable Run storage and budgets
gaoxiaobei Aug 2, 2026
5b78a4f
feat(miracle): add aligned score and budget AUC metrics
gaoxiaobei Aug 2, 2026
7387d4b
feat(miracle): orchestrate saved LLM strategy iterations
gaoxiaobei Aug 2, 2026
de91b19
feat(miracle): expose one saved harness loop command
gaoxiaobei Aug 2, 2026
6607af8
test(miracle): verify OpenAI harness loop end to end
gaoxiaobei Aug 2, 2026
6e1689a
refactor(miracle): keep single core harness interfaces
gaoxiaobei Aug 2, 2026
1bdd26f
fix(miracle): support reasoning controls and failed usage accounting
gaoxiaobei Aug 2, 2026
4b41ec8
docs: design default streaming Chat Completions
gaoxiaobei Aug 2, 2026
03a3935
docs: define one-million-token context budget
gaoxiaobei Aug 2, 2026
54a422a
docs: plan streaming Chat Completions
gaoxiaobei Aug 2, 2026
1fbb843
feat(miracle): stream LLM updates by default
gaoxiaobei Aug 2, 2026
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
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
__pycache__/
.worktrees/
agentbench_data/
469 changes: 469 additions & 0 deletions docs/superpowers/plans/2026-08-02-miracle-openai-harness-loop.md

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
# Miracle Streaming Chat Completions Implementation Plan

> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.

**Goal:** Make SSE streaming the default Chat Completions transport, remove the default completion-length limit, and account against a configurable one-million-token context budget before rerunning three real iterations.

**Architecture:** Extend `LLMConfig` with default streaming, optional `max_tokens`, and `max_context_tokens`. Split the client response path into JSON and SSE readers that normalize into the existing proposal parser, keeping the Loop and Results schemas stable except for additional stream telemetry.

**Tech Stack:** Python 3.11 standard library `urllib.request`, JSON, OpenAI-compatible SSE, pytest.

## Global Constraints

- `stream` defaults to `true`; explicit `false` retains non-streaming compatibility.
- Do not retry streaming failures as non-streaming.
- `max_tokens` defaults to absent and is sent only when configured.
- `max_context_tokens` defaults to `1_000_000`, is not sent to the API, and uses authoritative returned usage.
- Do not estimate tokens locally or add a tokenizer dependency.
- Preserve partial stream content, usage, timings, and failure reason.

---

### Task 1: Streaming and Context Configuration

**Files:**
- Modify: `src/agentbench_frame/miracle/loop_config.py`
- Modify: `tests/miracle/test_loop_config.py`
- Modify: `examples/miracle-loop.toml`

**Interfaces:**
- `LLMConfig.stream: bool = True`
- `LLMConfig.max_tokens: int | None = None`
- `LLMConfig.max_context_tokens: int = 1_000_000`

- [ ] Write tests asserting defaults, explicit `stream=false`, optional positive `max_tokens`, and rejection of nonpositive context limits.
- [ ] Run `uv run --with pytest python -m pytest tests/miracle/test_loop_config.py -q` and verify RED.
- [ ] Implement strict TOML parsing and public serialization.
- [ ] Rerun the configuration tests and verify PASS.
- [ ] Commit with `feat(miracle): configure default streaming context budget`.

### Task 2: SSE Reader and Normalized Response

**Files:**
- Modify: `src/agentbench_frame/miracle/llm_client.py`
- Modify: `tests/miracle/test_llm_client.py`

**Interfaces:**
- `_read_stream(response, started: float) -> tuple[dict, float]`
- Normalized response adds `stream`, `chunk_count`, `first_chunk_seconds`, and `usage_missing`
- New error stages: `stream_chunk_json`, `stream_incomplete`

- [ ] Add a local SSE fixture emitting heartbeat lines, split reasoning/content deltas, final usage, and `[DONE]`; assert reconstructed content and telemetry.
- [ ] Add tests for malformed JSON and EOF without `[DONE]`, including preserved partial response and usage.
- [ ] Add an explicit `stream=false` test asserting the JSON path still works and `max_tokens` is omitted by default.
- [ ] Run `uv run --with pytest python -m pytest tests/miracle/test_llm_client.py -q` and verify RED.
- [ ] Implement line-oriented SSE parsing, normalized response construction, and shared proposal parsing.
- [ ] Rerun client tests and verify PASS.
- [ ] Commit with `feat(miracle): stream Chat Completions by default`.

### Task 3: Context Budget and Stream Telemetry in Loop

**Files:**
- Modify: `src/agentbench_frame/miracle/loop.py`
- Modify: `src/agentbench_frame/miracle/run_store.py`
- Modify: `tests/miracle/test_loop.py`
- Modify: `skills/miracle-harness/SKILL.md`

**Interfaces:**
- `BudgetLedger.charge_context(total_tokens: int, limit: int) -> None`
- Saved LLM response contains stream telemetry and real usage on success or failure

- [ ] Add tests that successful streaming usage is charged, proposal failures retain usage, and reported usage above `max_context_tokens` creates a preserved `context_tokens` failure.
- [ ] Run Loop tests and verify RED.
- [ ] Implement context checking after charging API usage; save telemetry without API secrets.
- [ ] Document default streaming, optional non-streaming, omitted `max_tokens`, and the 1M context budget.
- [ ] Run Loop, store, and client tests and verify PASS.
- [ ] Commit with `feat(miracle): account streaming context usage`.

### Task 4: Real API Verification and Three-Iteration Run

**Files:**
- Modify only temporary `/tmp` configuration for the live run.
- Write Run artifacts beneath `AgentBenchResults/runs/24_miracle/temporary_deepseek_v4_flash/`.

- [ ] Run one minimal streaming request and verify multiple SSE chunks, `[DONE]`, content, usage, and no 60-second idle 504.
- [ ] Run the complete command with `stream=true`, no `max_tokens`, `max_context_tokens=1000000`, and three iterations.
- [ ] Inspect all iteration statuses, replay/trace files, score/IG curves, token/time accounting, and secret absence.
- [ ] Run `agentbench data check` against AgentBenchResults.
- [ ] Run `uv run --with pytest python -m pytest tests/miracle -q` and `git diff --check`.
- [ ] Remove generated Framework caches and commit code changes; do not delete failed Run records.
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
# Miracle Chat Completions Streaming Design

## Goal

Make OpenAI-compatible Chat Completions streaming the default Miracle Harness transport so upstream proxies receive continuous response bytes during long reasoning/generation and do not terminate an otherwise active request at an idle 60-second boundary.

## Configuration

`LLMConfig` adds:

```toml
[llm]
stream = true
max_context_tokens = 1000000
```

The default is `true`. Set `stream = false` only for endpoints that do not support SSE streaming. The client never silently retries a failed streaming request as non-streaming because that could issue two billable requests for one iteration.

`max_tokens` becomes optional and defaults to absent. When absent, the Harness does not send a generation-length limit. `max_context_tokens` defaults to `1_000_000` and limits reported prompt plus completion usage for accounting. Because tokenizer behavior is model-specific and the project has no tokenizer dependency, the Harness does not claim an exact pre-request token count; input size remains controlled by episode/decision-read budgets, and actual API usage is authoritative.

## Request

Streaming requests add:

```json
{
"stream": true,
"stream_options": {"include_usage": true}
}
```

All existing fields, including `reasoning_effort`, remain unchanged. Non-streaming requests add `"stream": false` and omit `stream_options`.

The request includes `max_tokens` only when the user explicitly configures it. It never sends `max_context_tokens`, which is a Harness budget rather than an OpenAI request field.

## SSE Parsing

The client reads UTF-8 Server-Sent Events line by line. It ignores blank lines and comment/heartbeat lines beginning with `:`. Every `data:` payload must be either `[DONE]` or one JSON object.

For each chunk it:

- appends `choices[0].delta.reasoning_content` when present;
- appends `choices[0].delta.content` when present;
- preserves the latest non-null `finish_reason`;
- preserves response `id`, `object`, `created`, `model`, and `system_fingerprint` when present;
- reads usage from any chunk containing `usage`, with the last value authoritative;
- counts parsed chunks and records first-chunk latency.

At `[DONE]`, the accumulated stream is normalized into the same Chat Completions response shape consumed by the existing proposal parser:

```json
{
"choices": [{
"message": {
"role": "assistant",
"content": "...",
"reasoning_content": "..."
},
"finish_reason": "stop"
}],
"usage": {}
}
```

The stored response additionally contains `stream=true`, `chunk_count`, `first_chunk_seconds`, and `usage_missing`.

## Error and Budget Semantics

- HTTP, connection, or idle socket failures remain `request` failures.
- Invalid SSE JSON is `stream_chunk_json` and preserves the accumulated response.
- EOF without `[DONE]` is `stream_incomplete`, preserving accumulated content, usage, and timing.
- A complete stream whose assistant content is empty or invalid remains `assistant_content` or `proposal_json` as today.
- Usage is charged even when later proposal parsing or strategy validation fails.
- If the endpoint omits final usage, token counters remain zero and `usage_missing=true`; the Harness does not estimate tokens and does not invent accounting data.
- When an endpoint or explicit `max_tokens` truncates output, `finish_reason="length"` remains visible; streaming prevents idle gateway timeout but does not remove provider-side output limits.
- Reported `total_tokens > max_context_tokens` is preserved as a context-budget failure after charging the real usage.

## Compatibility Boundary

Only `ChatCompletionsClient` and `LLMConfig` change. The Loop continues to receive one `StrategyProposal`, and strategy snapshots, battles, replay parsing, IG, score curves, budgets, and AgentBenchResults schemas remain unchanged.

## Verification

Tests use a local HTTP SSE server and cover:

1. split reasoning and content deltas;
2. final usage and `[DONE]`;
3. heartbeat/comment lines;
4. malformed chunk JSON;
5. EOF before `[DONE]`;
6. explicit `stream=false` compatibility;
7. secret redaction and failed-response usage accounting;
8. a minimal real request to the temporary API followed by a full three-iteration Run.
Loading
Loading