Skip to content

fix(cli): open a session in which nobody typed again with session/load and session/resume - #34

Merged
zy1233 merged 1 commit into
mainfrom
fix/load-blank-session
Oct 25, 2026
Merged

zy1233 merged 1 commit into
mainfrom
fix/load-blank-session

Conversation

@zy1233

@zy1233 zy1233 commented Oct 23, 2026

Copy link
Copy Markdown
Owner

Summary

session/load and session/resume of an id that has no file now open an empty session, if the id is a canonical UUID.

session/load(id) / session/resume(id)
  a file has this id?
    yes -> open it, replay it (load only)                      unchanged
    no  -> id is a UUID (lower case, hyphens)?
             no  -> resource_not_found                         unchanged
             yes -> already open in this process?
                      yes -> return, bind nothing              new
                      no  -> open an empty session             new
                             - id kept like a chosen id
                             - no file until the first message
                             - not in session/list

Why. Zed saves the id of every thread that shows something, and a notice of the agent counts (the "ignored MCP servers" notice, the project-trust question). Decision 17 gives a session in which nobody typed no file. After a restart Zed asked for the thread with session/load, got -32002, and showed "Failed to Launch". Retry asks for the same id and fails the same way. A blank thread opened again from the history fails too.

packages/pi-agent-cli/
├── pi_agent_cli/agent.py                  # _reopen_blank_session; load/resume call it when find() is None
├── AGENTS.md                              # the session-file paragraph
└── tests/
    ├── test_blank_session_reopen.py (new) # 17 tests
    └── test_acp_stdio_contract.py         # 2 new stdio tests; one old test no longer expects an error
scripts/tui_pty/resume_matrix.py           # `export <unknown uuid>` may say "no conversation content"
scripts/tests/test_tui_pty.py              # unit test for that predicate
CHANGELOG.md                               # new Fixed entry; the Changed entry of decision 17 reworded

Evidence

  • Before (main): session/new with an MCP server (the agent sends its notice), restart the agent, then what Zed does at start-up.

    [run 2] session/load   -> -32002 Resource not found {"uri": "01a168b9-b217-79c7-8555-0381c3936623"}
    [run 2] session/new after the failed load -> OK
    [run 2] session/resume -> -32002 Resource not found {"uri": "01a168b9-b217-79c7-8555-0381c3936623"}
    [run 2] session/list   -> []
    

    After (this branch), same script:

    [run 2] session/load   -> OK
    [run 2] session/new after the failed load -> OK
    [run 2] session/resume -> OK
    [run 2] session/list   -> []
    
  • Tests. 17 new in test_blank_session_reopen.py and 2 stdio tests. On the old agent 12 of them fail; the others pin what did not change (ids of other kinds, a session that has a file). Two one-line mutations of the new code (accept any id; do not recognise a session that is already open) are each caught.

  • pytest: Windows 2606 passed / 42 skipped; Linux (WSL2) 2628 passed / 20 skipped. ruff check . and ruff format --check .: clean.

  • Not done: scripts/tui_pty/resume_matrix.py was not run (it needs a built zypi and a Linux pty); only its predicate changed, and a unit test covers that. The plan document (decision 17 text, a revision entry) is left for after docs(plan): set the V0.6 release milestone and record the merge of #27 to #31 (plan r19) #33, which edits the same file.

Merge Danger

Door: two-way.

Blast Radius: every ACP client that calls load or resume for an id without a file.

  • These calls succeed now (before: resource_not_found). A UUID that no session ever had also opens, empty. zypi export <uuid> of such an id says "has no conversation content to export", not "not found".
  • A reopened blank session keeps its id (_reserved_ids). If a second agent process saved it first, the first message of this process fails (a session with this id already exists). The other order is not guarded: the process that made the session would have to list the directory at the first message of every session (0.07 s at 1,000 sessions, 0.3 s at 5,000).
  • The file behaviour of decision 17 is unchanged: a blank session has no file and is not listed.

…d and session/resume

A session in which nobody typed has no file (plan decision 17), but Zed saves the
id of every thread that shows something, and a notice of the agent counts. After a
restart Zed asked for the thread with session/load, the agent answered
resource_not_found, and Zed showed "Failed to Launch" with a Retry that failed in
the same way. The same happened when a blank thread was opened from the history.

session/load and session/resume now open an id that has no file as an empty
session when the id is in the form the agent gives out (a UUID, lower case,
hyphens). The session still has no file until its first message, and session/list
does not show it. Any other id is still resource_not_found. A blank session that
is open in the same process is left as it is. The id of a reopened blank session
is kept like a chosen id, so a second process that saved it first makes the first
message of this one fail instead of writing a second file.
@zy1233
zy1233 added this pull request to stack #37 October 25, 2026 04:50
@zy1233
zy1233 merged commit fa4887b into main Oct 25, 2026
7 checks passed
@zy1233
zy1233 deleted the fix/load-blank-session branch October 25, 2026 04:50
zy1233 added a commit that referenced this pull request Oct 25, 2026
…erge of #33 to #36 (plan r20) (#38)

* docs(plan): record the MCP direction, the blank-session fix and the merge of #33 to #36 (plan r20)

The owner came back on 2026-10-23 with two problems in Zed: the MCP notice at the start
of each new thread, and a thread without a message that cannot be opened after Zed
restarts. The owner chose an optional extension package for MCP (core, harness and CLI
stay without an MCP client) and asked for the blank-session fix as a PR at once. On
2026-10-25 the owner asked for the release content first, then for the merge of #33 to
#36.

The merge is done. #33 with `gh pr merge --squash` (ca2ab85). #34 to #36 with
`gh stack link 34 35 36` (stack #37) and `gh stack merge 37 --yes --squash` (fa4887b,
34c11d9, e0f2a36). The tree of each commit is the tree of its PR head plus the two plan
files of #33. CI and TUI CI pass on e0f2a36 (pytest 2,908 passed on Python 3.11, 3.12
and 3.13; nextest 8,490 passed, 0 failed, 22 skipped).

PLAN-RUST-AGENT-RUNTIME-REMOVAL.md:
- Decision 17 gets a correction (#34: session/load and session/resume open an empty
  session for a canonical UUID that has no file).
- New decisions: 19 (the MCP direction, decided), 20 (the versions of the extension
  packages and their core floors), 21 (the 11 defaults of the MCP design).
- V0.6: 14 commits, one more package. Conditions 1, 3, 5 and 6 and the known issues are
  rewritten.
- r19 said the three extension packages stay as they are. That is wrong. The packaging
  test requires that each floor equals the workspace version, so a core of 0.6.0 needs
  `>=0.6.0` in all four extension packages (checked: 4 tests fail). This is decision 20.
- The status, section 7, appendix A.1 and A.2, the index and the revision log carry the
  same facts.

The execution log gets section 10.23: the cause of both problems, the three PRs, the
release content, the merge, the check of the trees, CI on main, the floors, and what is
not verified.

docs/TUI-AND-CODE-AGENT.md: the paragraph about MCP servers now says that `pi-mcp-py`
connects them and what the agent says without it.

No condition of V0.6 is met yet. Only documents change.

* docs(plan): record the answer of the owner to decisions 20 and 21 (plan r20)

The owner answered "follow your lean" for the two open decisions of r20.

Decision 20 (versions and core floors of the extension packages): option (a). At the
version bump (V0.6 condition 5) the four extension packages get the core floor
`>=0.6.0`. pi-web-access-py, pi-goal-x-py and pi-dynamic-workflows-py go from 0.2.0 to
0.3.0, as V0.5 did in 7e7d4d4 (0.1.0 to 0.2.0). pi-mcp-py stays at 0.1.0 (first upload).
The lean did not say which digit to raise. 0.3.0 is my choice from the V0.5 precedent;
the plan and the execution log say so.

Decision 21 (the 11 defaults of the MCP design): all defaults stay, including Q3
(annotations are trusted) and Q5 (no way to configure servers in zypi). No code change.

Neither decision changes code. The change of decision 20 belongs to the PR of
condition 5, which is not open yet.

Files: the plan (status, V0.6 section, next steps, decisions 20 and 21, the lists of the
decision section, index, revision log, one link definition), the execution log (section
10.23 and its revision-log entry), the MCP design (section 10: one sentence). Only
documents change.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant