Repository navigation
An agent for every app that declares one; shell-drawn "Ask <app>" panel (ADR 0004 §4) - #184
Merged
Merged
Conversation
ymote
force-pushed
the
feat/agents-for-apps
branch
from
September 30, 2026 02:20
f39f6f0 to
a189b7c
Compare
ADR 0004 section 4. A live run found News (tools.json, no octos.*) with no peer: the system agent's peer_list was empty, News's tools never registered, Settings listed only Rinx, and the person had nowhere to talk to an app's agent. - Which apps: a native app granted agent.octos; a script app whose manifest declares octos.* or an agent block, or whose admitted bundle ships tools.json (App Hub's AgentBundle::load). Settings lists all. - Peers once allowed: when the person allows an agent (first-use sheet, Settings) and at startup, the shell prepares its peer (contained::prepare -> OctosAppService::prepare -> peer/prepare, tools registered), so peer_list shows it. One peer per app, shared by the app, its cards, the panel and the system agent; the app's own context still holds only the octos.* services its manifest declares. - The system agent is told about agents it cannot list: a note with the system chat's turn when the apps' agents changed, and host tools agents.list / agents.ask (the latter shows the first-use sheet). - "Ask <app>": the system chat's pane in app mode (app_chat/): a sharing context via open_conversation, both lanes merged with speakers, a composer, Stop (both lanes), the app's questions; from the bar's "Ask <app>", Shift+F8 or Setup > Assistant; beside the system chat on a desktop, full screen on a phone. - Revocation releases the peer and closes the panel's context. Tests: News is listed; the panel opens a sharing context and sends person turns there; allowed agents are prepared (fake peer); and on a real kernel: prepared with News's tools, listed by the system agent's peer_list, the panel's person turn seen by the system agent's peer/input turn, revoked. Docs: ADR 0004 section 4 and a follow-up; architecture. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
ymote
force-pushed
the
feat/agents-for-apps
branch
from
September 30, 2026 03:07
a189b7c to
9a59d7d
Compare
This was referenced Sep 30, 2026
guofoo
added a commit
that referenced
this pull request
Oct 2, 2026
docs/ai-services.md and its Chinese twin still described the contained apps' octos service as it was before #184: - the gate is off by default and needs OCTOSENSE_CONTAINED_APPS=1; the code's default is first-use consent (contained_gate_from), with 1 the developer override that asks nobody and 0 off; - a contained peer's tool approvals are declined; the broker hands them to the shell's approval router, and only a host without one declines; - octos.turn.start takes only text; it also takes trigger and from; - nothing in the shells runs an app's agent; since #184 an app that declares one, declares octos.*, or ships tools.json gets a prepared peer with its tools and the "Ask <app>" panel; - the News bundle does not declare `news` yet; it does, and reads from it when host.has("news").
chrislearn
pushed a commit
to chrislearn/OctoSense
that referenced
this pull request
Oct 8, 2026
…y test Four follow-ups from the live run of "Ask <app>" (OctoSense-org#184). 1. Order across lanes. Each lane counts its own cursor.seq (the peer's session is long, the person's context new), so sorting both by seq drew the system agent's request below the person's later question. The kernel also sends a turn's user message only when the turn ENDS, and never for a stopped turn, so the request line sat after its answer and a stopped request never showed. Now: within a lane, ledger order; across lanes, one clock (the order events reached the panel: stream events carry no time; history comes merged by persisted_at). A turn's request line stands where the turn started: the broker records the words it sent (the person's message, the system agent's peer/input) and hands them over with turn/started (`request`), and the conversation's history adds a stopped turn's request the kernel never recorded, at the time it started. 2. Stop said "turn interrupted by client" twice: once from the turn's end, once from the send's error. The send's error is shown only when the turn never started. 3. The system agent tried the app id (os.news) with peer_send_input. The note and agents.list now give the peer slug (os-news-22a12f90; OctosAppService::peer_slug) and say to use it, or to find it with peer_list, never the app id. 4. the_person_and_the_system_agent_talk_in_parallel_lanes_that_share_history failed under load with turn_in_progress: the test drives the system session itself and started its second turn while the first was still finishing (after peer_send_input the system agent still writes its own answer). Not a broker race: the test now waits for its session, as the system chat does. Reproduced by slowing that answer in the scripted model; 20 runs at --test-threads=4 pass. Tests: two lanes replayed with interleaved arrival (out-of-order envelopes, user messages at the end, a stopped turn); the panel's Stop shows one notice; the broker hands a turn's words over at its start and keeps a stopped turn's request in history; the note and agents.list carry the slug. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
ADR 0004 §4 promises an agent for every app. A live run on 625d6cc found:
tools.json(G3) but declares nooctos.*and never callsoctos, so it had no peer;peer_listwas empty and News's tools never registered;Builds on #183 (merged).
Which apps have an agent
This comes from manifests and grants, never names (
apps::agent_apps,crates/shell/src/agents.rs):agent.octos;octos.*or anagentblock;tools.json(App Hub'sAgentBundle::load).Settings lists every one of them.
Peers once allowed
octoscall, or from the system agent'sagents.ask, which shows the first-use sheet over the system chat.contained::prepare→OctosAppService::prepare(new;Broker::bind), i.e.peer/preparewith the tools andgeneric_toolsregistered. The system agent'speer_listthen shows it, andpeer_send_inputreaches it.card.<app id>). The app, its cards, the panel and the system agent all share it.octos.*service for the shell's panel. The app's own context is still opened with only what its manifest declares, andContainedOctosstill checksdeclaredfirst.agents.listandagents.askon the system session, answered by the shell.peer/inputto it, as before."Ask "
This is the system chat's pane in app mode (
app_chat/,system_chat/view.rsapp_panel: true):open_conversation;You can open it from:
On desktop it sits beside the system chat, so both lanes are visible; on phone it is a full-screen sheet.
Tests
news_is_listed_as_having_an_agent,allowing_an_agent_queues_its_preparation.both_lanes_show_with_their_speakers_and_run_in_parallel,the_merged_history_names_its_speakers.the_panel_opens_a_sharing_context_and_sends_person_turns_there: consent first, thenopen_conversation(never a plain context), history, aTurnFrom { Person }, preparation, and revocation. Runs on fake peers.the_shell_prepares_a_consented_apps_peer_and_its_panel_shares_it(ai-host).real_kernel_an_allowed_apps_agent_is_prepared_listed_and_shares_its_conversation(pinned kernel, scripted model):peer_listshowsos-news-…;peer/inputturn sees it through the shared history;news_list/news_read;the_system_agent_is_told_about_agents_it_cannot_list.Local checks: shell lib tests (desktop 568, phone 588, with the real kernel), app-peers (incl. real kernel), ai-host (with and without
octos-core,llm), kernel, clippy for app-peers and ai-host,cargo checkfor desktop and phone,native_apps.py --check,setup.py --check --cargo. I also ran a hidden-window desktop pass against a scripted model: the bar showed "Ask News", the first-use sheet appeared, the panel reached "ready", it answered with speakers, and it sat side by side with the system chat.Known limits (also in ADR 0004's follow-ups)
HostLimits::offered_tools), so an admitted manifest cannot listask_user_questioninagent.tools(found by test: the two-lane scenario against the real kernel (and two fixes it found) #182). The panel shows and answers the app's questions once it can. The fix belongs in App Hub (offerask_user_questionto contained agents), not in a shell-side exception.🤖 Generated with Claude Code