-
Notifications
You must be signed in to change notification settings - Fork 1
Remote phone-control pairing + account/sandbox restructure #90
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 2 commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
8e11019
feat: Remote phone-control pairing (RemoteRelay) + account/sandbox re…
Ravikxx bc64d42
feat: publish remote-pairing (RemoteRelay) + account/sandbox restruct…
Ravikxx 064a9f7
fix: close remote-relay sockets when the pairing TTL expires
Ravikxx ff6962e
Add guardrail-flag observability log and announcement send-history to…
Ravikxx File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
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
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,122 @@ | ||
| # Inter-Session Communication — Design Spec | ||
|
|
||
| Status: **IMPLEMENTED** (CLI). Built on the existing `BUS`/`send_message` | ||
| infrastructure rather than a parallel channel. | ||
|
|
||
| ## What shipped | ||
| - `src/agent/sessionRegistry.js` — live session registry (keyed by agent label). | ||
| `registerSession()` broadcasts a creation notice to every other session's | ||
| mailbox; `trackToolFiles()` records recently-touched files per session. | ||
| - `src/agent/agent.js` — every `Agent` registers itself (with model) and updates | ||
| its goal/status each turn; file-touching tools feed `trackToolFiles`. | ||
| - `src/agent/tools.js` — `list_sessions` (peer discovery) and `query_session` | ||
| (returns a peer's goal/status + recently-touched files; optional `question` | ||
| delivered to the peer's inbox). Both added to the hosted-model allowlist and | ||
| the grant-independent set. | ||
| - `src/tui/App.jsx` — hidden `/create-external-model <https://url> <model> <key>` | ||
| dev command (absent from `COMMANDS`, so it never tab-completes). | ||
|
|
||
| ## Known gap | ||
| - The user-facing `main` agent does not see creation notices via `read_messages` | ||
| (BUS routes `to:"main"` to an internal inbox that `read_messages` doesn't read; | ||
| `main` can still call `list_sessions` to discover peers). Spawned sub-agents | ||
| *are* notified correctly. Fixing `main` would require changing `read_messages` | ||
| and risks colliding with the spawn flow's own `readMain()` consumption. | ||
|
|
||
| ## Original design notes (kept for reference) | ||
|
|
||
|
|
||
| ## Goal (from request) | ||
|
|
||
| 1. Code-chat **sessions** can talk to each other. | ||
| 2. A model is **notified when another session is created**. | ||
| 3. A session can **ask another session what it's doing / how to avoid each other**. | ||
| 4. A **tool** the model can call to do the above. | ||
| 5. A **developer command** `/create-external-model <https://url> <model name> <api key>` | ||
| that registers an external OpenAI-compatible model — and is **deliberately NOT | ||
| tab-completable**. | ||
|
|
||
| ## Integration reality (from reading the code) | ||
|
|
||
| - Slash-command dispatch = `runCommand(raw)` in `src/tui/App.jsx` (big `switch`). | ||
| - `src/ui/commands.js` `COMMANDS` array is **only** for suggestions + tab | ||
| completion (`getSuggestions` / `getTabCompletion`). A command omitted from | ||
| `COMMANDS` still runs via the `runCommand` switch but never autocompletes. | ||
| → `/create-external-model` is hidden simply by not listing it in `COMMANDS`. | ||
| - Custom endpoints live in `CUSTOM_ENDPOINTS` (mutable, `src/config.js`); the | ||
| `/endpoint` handler (App.jsx ~2168) shows the exact mutate + `saveCustomEndpoints(...)` | ||
| pattern to mirror. | ||
| - Tools are defined in `src/agent/tools.js`; agents get them filtered via | ||
| `agentRegistry.filterTools` (permission rulesets). | ||
| - Sessions/agent loop: `src/agent/agentRegistry.js` (named agents, not live | ||
| sessions) + the live chat loop in `src/tui/App.jsx` / `src/agent/agent.js`. | ||
|
|
||
| ## Proposed design | ||
|
|
||
| ### 1. `src/agent/sessionRegistry.js` (new, process-wide singleton) | ||
| In-memory registry of **currently-running** sessions (live coordination only — | ||
| no persistence needed). | ||
|
|
||
| Record shape: | ||
| ``` | ||
| { id, name, model, goal, status, owner, createdAt, lastActivity, running, turnCount } | ||
| ``` | ||
| API: | ||
| - `register(session)` / `unregister(id)` | ||
| - `list()` → public descriptors (omit sensitive fields) | ||
| - `get(id)` | ||
| - `updateStatus(id, { goal, status })` — called each turn so peers can answer | ||
| "what are you doing" | ||
| - `notifyCreation(session)` — enqueue a creation notice into every *other* | ||
| session's `inbound` queue | ||
| - per-session `inbound` queue drained at the start of each agent turn | ||
|
|
||
| ### 2. Creation notifications | ||
| Hook `register()` + `notifyCreation()` wherever a new chat/code-session spawns | ||
| (new chat in App.jsx; any spawned agent loop in agent.js). Each other live | ||
| session drains its `inbound` queue at the top of its next turn and surfaces the | ||
| notice as a `system` message: | ||
| `"New session '<name>' started on model <model> — goal: <goal>."` | ||
| (Draining at turn-start avoids interrupting a mid-turn agent.) | ||
|
|
||
| ### 3. Model tools (`src/agent/tools.js`) | ||
| - `list_sessions` → returns peer sessions (id, name, model, status, goal), | ||
| **excluding the calling session itself**. | ||
| - `query_session({ sessionId, question })` → "what are you working on / how | ||
| should we avoid conflicts?". **v1 = synchronous status lookup**: returns the | ||
| target's last `goal` + `status` + recent file activity (from the registry | ||
| record), not a full back-and-forth. True async peer-to-peer chat = v2. | ||
| - Both gated through `agentRegistry.filterTools` so denied/allowed tool rules | ||
| still apply. `query_session` must never return another session's full message | ||
| history — only goal/status + summarized activity (privacy boundary). | ||
|
|
||
| ### 4. `/create-external-model` (hidden dev command) | ||
| Signature: `/create-external-model <https://url> <model name> <api key>` | ||
| Handler (new `case` in `runCommand`, App.jsx), mirroring `/endpoint`: | ||
| ``` | ||
| CUSTOM_ENDPOINTS[name] = { baseURL: url, model: name, apiKey: key, context: 0 } | ||
| CONTEXT_WINDOWS[name] = <fetched or default> | ||
| saveCustomEndpoints({ ...CUSTOM_ENDPOINTS }) | ||
| setModel(name); agentRef.current?.setModel(name); saveModel(name) | ||
|
Ravikxx marked this conversation as resolved.
|
||
| ``` | ||
| Validation: `url` must start with `http(s)://`. Gated as developer-only | ||
| (undocumented; always available but absent from `COMMANDS`, so no tab-complete). | ||
|
Ravikxx marked this conversation as resolved.
Ravikxx marked this conversation as resolved.
|
||
|
|
||
| ## Open questions to resolve before implementing | ||
| - **Scope**: CLI sessions only, or also the desktop "code chats" (Axion App | ||
| Code tab)? Tools/slash-commands here are CLI-only. | ||
| - **Session definition**: a whole chat, or a spawned sub-agent? Affects where | ||
| `register()` is hooked. | ||
| - **v1 vs v2** for `query_session`: status-polling (simple, synchronous) vs. | ||
| real async agent-to-agent messaging (needs a request/response channel + | ||
| timeout). Recommend v1 status-polling first. | ||
| - Notification timing: turn-start drain (chosen) vs. push interrupt. | ||
|
|
||
| ## Files touched (when implemented) | ||
| - new: `src/agent/sessionRegistry.js` | ||
| - `src/agent/tools.js` (2 tools) | ||
| - `src/tui/App.jsx` (runCommand: creation hook + `/create-external-model` case; | ||
| model tool available to tools list) | ||
| - `src/agent/agent.js` (drain `inbound` + `updateStatus` each turn) | ||
| - `src/ui/commands.js` — **NOT** modified for the hidden command (intentionally | ||
| absent so it stays out of tab-completion). | ||
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| -- Client-side error reports from the iPhone app (and any future native client). | ||
| -- The app shows the user only a generic "Something went wrong" and ships the | ||
| -- real failure here so we can triage crashes and exceptions without ever | ||
| -- exposing internal details (stacks, underlying errors) to users. | ||
| CREATE TABLE client_errors ( | ||
| id TEXT PRIMARY KEY, | ||
| user_id TEXT, | ||
| app_version TEXT, | ||
| build_number TEXT, | ||
| os_version TEXT, | ||
| device_model TEXT, | ||
| type TEXT, | ||
| message TEXT, | ||
| stack TEXT, | ||
| context TEXT, | ||
| created_at INTEGER NOT NULL | ||
| ); | ||
|
|
||
| CREATE INDEX idx_client_errors_created ON client_errors (created_at DESC); | ||
| CREATE INDEX idx_client_errors_user ON client_errors (user_id, created_at DESC); |
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
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
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
Oops, something went wrong.
Oops, something went wrong.
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.
Uh oh!
There was an error while loading. Please reload this page.