Skip to content

Plan mode, subagent reporting, generate_image, mid-turn compaction, Windows fixes - #10

Merged
gaoyu06 merged 19 commits into
JuCode-Team:mainfrom
Libra1337:updates-2026-10-09
Oct 9, 2026
Merged

gaoyu06 merged 19 commits into
JuCode-Team:mainfrom
Libra1337:updates-2026-10-09

Conversation

@Libra1337

Copy link
Copy Markdown
Contributor

The CLI side of the last two days' work, ported onto JuCode's main with JuCode's names, hosts and skill marketplace kept. One commit per change, each with its own description.

Depends on JuCode-Team/llm-provider-kit#1: the submodule points at that PR's head (51fd509). Merge the kit PR first.

What's in it

  • Plan mode. In plan mode the agent investigates read-only, then proposes a plan (propose_plan → proposed_plan event). The plan runs once the user approves it. While the model writes the plan, it streams to clients as plan_draft events.
  • Subagents report what they do. New agent_runs and subagent_transcript ops/events; headless output counts them.
  • generate_image tool. Draws or edits images through the provider's OpenAI-compatible /images/* endpoints.
    • The model is the call's model, else image_model in config.json, else the first configured model named like an image model.
    • Images are written under the same rules as write.
  • Mid-turn compaction. A turn whose input passes the compaction threshold now compacts mid-turn instead of running into the context limit.
  • Subagents pick from every configured model. When the user names a model, it is used.
  • Clearer shell hints for a write to a finished shell session and for a timeout.
  • Steer joins the running turn instead of restarting it.
  • Windows fixes:
    • The search tool works without rg (it searches in-process when rg can't start).
    • config.json saves retry briefly while another process holds the file.
    • Titles retry once with the next effort when a model refuses the lightest one.
  • Skills marketplace: community repositories (Ikaleio, Superpowers, Composio) are listed beside the JuCode marketplace and Anthropic's skills.
    • JUCODE_SKILL_SOURCES replaces the community list; set it empty for none.
    • The daemon test is JuCode's own again (fake JuCode API), with community sources off so it stays offline.

Checks

  • cargo fmt --all --check
  • cargo clippy --workspace --all-targets -D warnings
  • cargo test --workspace: all passing.

🤖 Generated with Claude Code

Libra1337 and others added 11 commits October 9, 2026 13:54
The agent can now draw or edit images through the provider's
OpenAI-compatible images endpoints: POST {base_url}/images/generations
(JSON) for a prompt, POST {base_url}/images/edits (multipart, image[])
when workspace images are given. It uses the chat requests' bearer key
and per-model routing headers (X-JuCode-Group), a
read timeout of at least 180 s, and accepts b64_json or url results.
gpt-image models are not sent response_format; others ask for b64_json.

Images are saved in the workspace under write's rules (workspace and
sandbox confinement, subagent write isolation, approval in manual mode)
at the requested path or images/<timestamp>-<slug>.<ext>; an existing
file is never overwritten, a numeric suffix is added instead.

The model is the call's `model`, else the new `image_model` config key,
else the first configured model whose name contains "image". The tool is
offered only when such a model resolves on a responses or chat endpoint
(not anthropic, codex or azure) with an API key.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
A new approval mode, plan (like Codex's and Claude Code's): only read-only
tools run (reads, search, web, provably read-only shell commands, MCP tools
marked readOnlyHint, subagents in plan mode too); everything else is refused
with a note to plan instead. The model delivers its plan with propose_plan
(goal, a File | Change | Why table, steps, risks, verification), which emits
proposed_plan and ends the turn. approve_plan approves it and runs it in the
chosen mode, or revises it with feedback. Plans are saved in the session and
replayed with their latest status. The TUI cycles through plan with Shift+Tab.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
A native subagent ran on its own thread and only told front-ends that it
started and finished, so the desktop showed nothing of it. Each subagent now
keeps a bounded trace (its task, messages, reasoning, tool calls with input
and output, its latest action as one line, usage; at most 300 items and
256 KB). The engine answers the agent-trace ops the desktop already uses for
Claude Code and Codex: agent_runs (also pushed while agents work, twice a
second at most) and subagent_transcript. subagent_lifecycle carries the
agent's label, model and the spawn_agent call it came from. Agents of
earlier turns stay listed.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The root binary's headless stats matched every event and broke the build.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
A rename over config.json fails on Windows while the desktop or another
engine has it open (PermissionDenied); a model pick then did not save.
Retry briefly before giving up.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
A message sent while the agent works used to stop the turn (killing running
tools and subagents) and start again. It now goes into the running turn: the
model reads it before its next request, after the current tool calls finish,
and it is saved and shown as the user's message. If the turn ends before the
model reads it, it runs next. A message with images still restarts as before.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The ripgrep tool failed on every machine without rg (a stock Windows has
none). It now searches in-process when rg cannot start, printing what rg
prints for the options the tool takes.

A title model that refuses its lightest effort (gpt-6-astra takes no none)
left every conversation untitled; the title request now retries once with
the next effort up.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
A long turn of tool calls only checked the context window when it started,
so it ran up to the limit without compacting. The turn now stops between
requests once the last one passed the compaction threshold, and the core
compacts and continues it (the overflow path, with its own notice).

Without subagent_models, spawn_agent offers every chat model of the
provider (image models left out); the agent picks per task and takes the
one the user names.

write_stdin to a session that is not running says that a finished bash
command already returned its output. A timed-out command in the sandbox
suggests escalate for programs that write outside it.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The catalog lists the JuCode marketplace, Anthropic's skills, and now
Ikaleio, Superpowers (obra) and Composio, read from each repository's
SKILL.md files wherever they sit (skills/ or the top level), an hour at a
time. A source that cannot be read is a warning. JUCODE_SKILL_SOURCES
("Name=https://github.com/o/r;…", or empty for none) replaces the
community list. Frontmatter reads folded and literal block values.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
ToolArgumentsDelta lets the plan stream while the model writes it;
response.reasoning_text.delta is read as reasoning.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The parsers emit tool-call argument fragments; the core reads the title and
plan out of propose_plan's half-written JSON and sends plan_draft events with
the text added since the last one. The finished plan follows as
proposed_plan with the same id, so a client grows one plan in place.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The main turn stopped for compaction whenever the last request's input
passed the threshold, even when nothing before the current user message
could be folded; the retry then had no plan and the turn failed. It also
compared API usage (system prompt and tools included) with a tokenizer
count, so it could fire on every request, and closed running subagents.

Now the core arms it only for a turn that starts uncompacted with earlier
history to fold, and measures how much the input grew since the turn's
first request against the headroom left under the threshold. The
continuation compacts at its start and is not armed again, keeps the
turn's subagents and unread steers, and a mid-turn stop always continues
the turn (compacting if it can) instead of failing it.
git grep -O/--open-files-in-pager runs a program; git reflog expire and
delete rewrite history (only reflog and reflog show run); --textconv and
cat-file --filters run filters. sort's -o inside a short-option cluster
(-uo) and --compress-program, file -C/--compile, tree -o in a cluster and
-R (it writes 00Tree.html files), and rg --hostname-bin are refused too.
A message steered into the running turn reached the model without the
user_prompt_submit hook that a new turn runs; it now runs first, and a
block drops the message with the same error.

A turn interrupted or failed before reading a steered message lost it
from view, and the next turn requeued it behind the message that
started that turn. The core now requeues what the session has not
recorded (including a message the worker read whose event was dropped)
as soon as the turn stops, ahead of later messages, and shows it as
pending.
An empty subagent_models list offered every chat model of the provider;
it is back to meaning subagents run on the main agent's own model, as
config documents. With a list, the guidance still tells the agent to use
the model the user names, and is left out when there is nothing to pick.
The desktop catalog fetched three community repositories by default.
They are now listed only when JUCODE_SKILL_SOURCES names them, so a
default install shows the JuCode marketplace and Anthropic's index alone;
the docs describe the variable and the catalog's sourceName field.
The TUI shows a proposed plan but cannot approve it, so a session cycled
into plan mode ended every turn on a plan that stayed pending.
The retry covers Windows refusing to replace a file another process has
open; on Unix a permission error is permanent and now fails at once
instead of after five seconds of retries.
@gaoyu06
gaoyu06 merged commit 901221a into JuCode-Team:main Oct 9, 2026
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.

2 participants