server: remove statewait file, use event stream instead
The event stream with filtering replaces statewait: - echo filter | rdwrs event Removed: - statewait file from agent namespace - All non-historical references in docs and code The state file remains for simple polling reads.
This commit is contained in:
parent
7e7c29c900
commit
86fbc90b43
|
|
@ -69,7 +69,8 @@ session/
|
||||||
├── cfg configuration
|
├── cfg configuration
|
||||||
├── ctl control commands
|
├── ctl control commands
|
||||||
├── state current state
|
├── state current state
|
||||||
├── statewait block until state changes
|
├── state current state (idle, calling, thinking, paused)
|
||||||
|
├── status human-readable status
|
||||||
├── prompt submit a prompt
|
├── prompt submit a prompt
|
||||||
├── peer/ write to peer/{name} to message a peer agent
|
├── peer/ write to peer/{name} to message a peer agent
|
||||||
├── chat conversation history
|
├── chat conversation history
|
||||||
|
|
@ -106,7 +107,7 @@ Persistent memory is provided by [OptMem](https://github.com/VictorTaelin/OptMem
|
||||||
|
|
||||||
## Frontends
|
## Frontends
|
||||||
|
|
||||||
Shell scripts, Acme, KDE components, and other clients create sessions, write prompts, and read files such as `chat`, `statewait`, `context`, and `feed`. They do not embed provider, tool, or agent-loop logic.
|
Shell scripts, KDE components, and other clients create sessions, write prompts, and read files such as `chat`, `state`, and `feed`. They subscribe to state changes via the `event` stream. They do not embed provider, tool, or agent-loop logic.
|
||||||
|
|
||||||
See [`doc/architecture-ide.md`](doc/architecture-ide.md) for integrating Ollie with an editor or IDE.
|
See [`doc/architecture-ide.md`](doc/architecture-ide.md) for integrating Ollie with an editor or IDE.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
//
|
//
|
||||||
// The agent state tracks execution progress: idle, running, completed, error.
|
// The agent state tracks execution progress: idle, running, completed, error.
|
||||||
// WaitChange blocks until a field changes, enabling 9P clients to observe
|
// WaitChange blocks until a field changes, enabling 9P clients to observe
|
||||||
// state transitions via statewait.
|
// state transitions via the event stream.
|
||||||
|
|
||||||
package agent
|
package agent
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -27,13 +27,14 @@
|
||||||
//
|
//
|
||||||
// prompt - submit prompt (write)
|
// prompt - submit prompt (write)
|
||||||
// chat - conversation history (streaming read)
|
// chat - conversation history (streaming read)
|
||||||
// statewait - block until state changes
|
// state - current agent state
|
||||||
|
// status - human-readable status
|
||||||
// plan - agent's plan (survives compaction)
|
// plan - agent's plan (survives compaction)
|
||||||
// ctl - agent control commands
|
// ctl - agent control commands
|
||||||
//
|
//
|
||||||
// # Blocking Reads
|
// # Blocking Reads
|
||||||
//
|
//
|
||||||
// Files like statewait and event block until their condition is met.
|
// Files like event block until their condition is met.
|
||||||
// This is the primary coordination mechanism — clients read these files
|
// This is the primary coordination mechanism — clients read these files
|
||||||
// in a loop to react to state changes.
|
// in a loop to react to state changes.
|
||||||
//
|
//
|
||||||
|
|
|
||||||
|
|
@ -883,13 +883,6 @@ func buildAgentChildren(a *agent.Agent, s *session.Session) []virtfs.FsNodeDecl
|
||||||
return []byte(a.State() + "\n"), nil
|
return []byte(a.State() + "\n"), nil
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
virtfs.FileNode("statewait", 0444,
|
|
||||||
virtfs.Doc("Blocks until state changes; returns new value"),
|
|
||||||
virtfs.BlockOnce(func() ([]byte, string, error) {
|
|
||||||
st := a.State()
|
|
||||||
return []byte(st + "\n"), st, nil
|
|
||||||
}, a.SignalCh),
|
|
||||||
),
|
|
||||||
virtfs.FileNode("status", 0444,
|
virtfs.FileNode("status", 0444,
|
||||||
virtfs.Doc("Human-readable status: current activity and elapsed time"),
|
virtfs.Doc("Human-readable status: current activity and elapsed time"),
|
||||||
virtfs.Read(func() ([]byte, error) {
|
virtfs.Read(func() ([]byte, error) {
|
||||||
|
|
|
||||||
|
|
@ -191,7 +191,7 @@ Use `client_9p` for all 9P operations. Your session ID is `${OLLIE_SESSION_ID}`.
|
||||||
| `fifo` | r/w | Prompt queue. Write: enqueue. Read: dequeue. |
|
| `fifo` | r/w | Prompt queue. Write: enqueue. Read: dequeue. |
|
||||||
| `chat` | read | Conversation (filtered text, streamable) |
|
| `chat` | read | Conversation (filtered text, streamable) |
|
||||||
| `chat.raw` | read | Full conversation with block markers |
|
| `chat.raw` | read | Full conversation with block markers |
|
||||||
| `statewait` | read | Blocks until state changes; returns new value |
|
| `state` | r/w | Current state; subscribe via event stream |
|
||||||
| `cfg` | r/w | Agent config (key=value: backend, model, cwd, temperature, etc.) |
|
| `cfg` | r/w | Agent config (key=value: backend, model, cwd, temperature, etc.) |
|
||||||
| `ctl` | rdwr | Control: stop, compact, clear, inject, agent, model, tools, tool_load, tool_unload, cwd, name, peeradd, peerdel, peers, proc |
|
| `ctl` | rdwr | Control: stop, compact, clear, inject, agent, model, tools, tool_load, tool_unload, cwd, name, peeradd, peerdel, peers, proc |
|
||||||
| `peer/` | dir | Peer agent links. Write to `peer/{name}` to send a message to that peer. |
|
| `peer/` | dir | Peer agent links. Write to `peer/{name}` to send a message to that peer. |
|
||||||
|
|
|
||||||
|
|
@ -90,7 +90,7 @@ echo "name=coding cwd=$PWD" | ollie-9p write session/myproj/agent/new
|
||||||
| `agent/{aname}/feed` | r/w | Change-detecting input stream. |
|
| `agent/{aname}/feed` | r/w | Change-detecting input stream. |
|
||||||
| `agent/{aname}/chat` | r | Filtered streaming chat output. |
|
| `agent/{aname}/chat` | r | Filtered streaming chat output. |
|
||||||
| `agent/{aname}/chat.raw` | r | Full streaming output with markers. |
|
| `agent/{aname}/chat.raw` | r | Full streaming output with markers. |
|
||||||
| `agent/{aname}/statewait` | r | Blocking state-change read. |
|
| `agent/{aname}/state` | r | Current agent state (idle, calling, thinking, paused). |
|
||||||
| `agent/{aname}/log` | r | Conversation snapshot. |
|
| `agent/{aname}/log` | r | Conversation snapshot. |
|
||||||
| `agent/{aname}/plan` | r/w | Persistent planning scratch space. |
|
| `agent/{aname}/plan` | r/w | Persistent planning scratch space. |
|
||||||
| `agent/{aname}/cfg` | r/w | Agent configuration. |
|
| `agent/{aname}/cfg` | r/w | Agent configuration. |
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,8 @@ editor or IDE
|
||||||
├─ file, selection, cursor, project, or diff
|
├─ file, selection, cursor, project, or diff
|
||||||
└─ 9P client → agent/.../prompt
|
└─ 9P client → agent/.../prompt
|
||||||
├─ chat / chat.raw
|
├─ chat / chat.raw
|
||||||
├─ statewait
|
├─ state
|
||||||
|
├─ status
|
||||||
└─ ctl
|
└─ ctl
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
@ -49,7 +50,7 @@ The editor does not need to display agent output or reload files itself. Use the
|
||||||
| Operation | 9P integration |
|
| Operation | 9P integration |
|
||||||
|---|---|
|
|---|---|
|
||||||
| Explain file or selection | Write a read-only prompt; read `chat`. |
|
| Explain file or selection | Write a read-only prompt; read `chat`. |
|
||||||
| Fix, refactor, document, or add tests | Write a mutating prompt; read `statewait`; reload the buffer. |
|
| Fix, refactor, document, or add tests | Write a mutating prompt; subscribe to state events; reload the buffer on completion. |
|
||||||
| Review a diff | Send the diff as fenced `diff` context. |
|
| Review a diff | Send the diff as fenced `diff` context. |
|
||||||
| Inline completion | Send a bounded prefix/suffix request to root `generate`. |
|
| Inline completion | Send a bounded prefix/suffix request to root `generate`. |
|
||||||
| Agent control | Write a command to `ctl`. |
|
| Agent control | Write a command to `ctl`. |
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ flowchart TB
|
||||||
|
|
||||||
The daemon constructs an `fs.Tree`. The tree is the session collection; there is no separate manager abstraction. Session operations are package functions over the tree. A session owns its agents, context, cancellation, and lifecycle. An agent owns history and runs the model/tool loop.
|
The daemon constructs an `fs.Tree`. The tree is the session collection; there is no separate manager abstraction. Session operations are package functions over the tree. A session owns its agents, context, cancellation, and lifecycle. An agent owns history and runs the model/tool loop.
|
||||||
|
|
||||||
The daemon exposes the 9P namespace directly. Reads and writes are the protocol: writing `session/new` creates a session, writing an agent's `prompt` submits work, reading `chat` observes history, and reading `statewait` blocks until a state transition.
|
The daemon exposes the 9P namespace directly. Reads and writes are the protocol: writing `session/new` creates a session, writing an agent's `prompt` submits work, reading `chat` observes history, and subscribing to the `event` stream monitors state transitions.
|
||||||
|
|
||||||
### Agent loop
|
### Agent loop
|
||||||
|
|
||||||
|
|
@ -43,7 +43,7 @@ Ollie deliberately does not build the following into the agent runtime:
|
||||||
- **Native MCP client support.** Use executable or metadata-only tools. An external bridge can invoke an MCP client when required.
|
- **Native MCP client support.** Use executable or metadata-only tools. An external bridge can invoke an MCP client when required.
|
||||||
- **Embedded tool frameworks.** Tools live outside the agent loop; toolsrv owns discovery, loading, execution, sandboxing, and process state. See [`architecture-tools.md`](architecture-tools.md) and [`architecture-toolsrv.md`](architecture-toolsrv.md).
|
- **Embedded tool frameworks.** Tools live outside the agent loop; toolsrv owns discovery, loading, execution, sandboxing, and process state. See [`architecture-tools.md`](architecture-tools.md) and [`architecture-toolsrv.md`](architecture-toolsrv.md).
|
||||||
- **Plan-and-execute workflow engines.** Ollie does not own planners, task graphs, schedulers, retries, compensation, or durable workflow state. A system such as [Beads](https://github.com/steveyegge/beads) can expose those capabilities through a tool.
|
- **Plan-and-execute workflow engines.** Ollie does not own planners, task graphs, schedulers, retries, compensation, or durable workflow state. A system such as [Beads](https://github.com/steveyegge/beads) can expose those capabilities through a tool.
|
||||||
- **External coordination protocols.** Ollie does not expose a workflow engine, actor framework, master coordinator, or public message bus. It does have an internal session event bus for observers. Inter-agent communication uses peer links (`peer/` directory) for topology-controlled messaging within a session. External coordination uses sessions, agents, `prompt`, `chat`, `statewait`, `feed`, and `ctl`.
|
- **External coordination protocols.** Ollie does not expose a workflow engine, actor framework, master coordinator, or public message bus. It does have an internal session event bus for observers. Inter-agent communication uses peer links (`peer/` directory) for topology-controlled messaging within a session. External coordination uses sessions, agents, `prompt`, `chat`, `event`, `feed`, and `ctl`.
|
||||||
- **Separate frontend control planes.** UIs, editor integrations, shell clients, and automation are 9P clients. They do not maintain a parallel session store or frontend-specific API. See [`architecture-9p.md`](architecture-9p.md).
|
- **Separate frontend control planes.** UIs, editor integrations, shell clients, and automation are 9P clients. They do not maintain a parallel session store or frontend-specific API. See [`architecture-9p.md`](architecture-9p.md).
|
||||||
- **Distributed agent state.** Remote execution moves toolsrv and tool execution, not the agent loop, prompts, history, or model calls. See [`architecture-remote.md`](architecture-remote.md).
|
- **Distributed agent state.** Remote execution moves toolsrv and tool execution, not the agent loop, prompts, history, or model calls. See [`architecture-remote.md`](architecture-remote.md).
|
||||||
- **A competing memory store.** [OptMem](https://github.com/VictorTaelin/OptMem) owns persistent memory; Ollie exposes it through tools.
|
- **A competing memory store.** [OptMem](https://github.com/VictorTaelin/OptMem) owns persistent memory; Ollie exposes it through tools.
|
||||||
|
|
|
||||||
|
|
@ -45,7 +45,7 @@ public:
|
||||||
bool mkdir(const QString &path);
|
bool mkdir(const QString &path);
|
||||||
bool rename(const QString &oldPath, const QString &newName);
|
bool rename(const QString &oldPath, const QString &newName);
|
||||||
|
|
||||||
// Streaming API - for continuous reads (chat, statewait, etc.)
|
// Streaming API - for continuous reads (chat, event, etc.)
|
||||||
int open(const QString &path); // Returns fid handle, -1 on error
|
int open(const QString &path); // Returns fid handle, -1 on error
|
||||||
int readFid(int fid, char *buf, int bufLen); // Returns bytes read, 0 on EOF, -1 on error
|
int readFid(int fid, char *buf, int bufLen); // Returns bytes read, 0 on EOF, -1 on error
|
||||||
void closeFid(int fid);
|
void closeFid(int fid);
|
||||||
|
|
|
||||||
|
|
@ -70,7 +70,7 @@ void Lib9pStreamer::Worker::run()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (n == 0) {
|
if (n == 0) {
|
||||||
// EOF — normal for statewait/event after returning data
|
// EOF — normal for event stream after returning data
|
||||||
emit finished(true, QString());
|
emit finished(true, QString());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -64,7 +64,7 @@ void Ollie9pClient::setActiveSessionId(const QString &id)
|
||||||
qDebug() << "setActiveSessionId" << id << "prev session" << m_activeSessionId << "prev agent" << m_agentId;
|
qDebug() << "setActiveSessionId" << id << "prev session" << m_activeSessionId << "prev agent" << m_agentId;
|
||||||
// Session selection must be side-effect free for per-agent streams.
|
// Session selection must be side-effect free for per-agent streams.
|
||||||
// Even re-selecting the same session should clear agent selection and stop
|
// Even re-selecting the same session should clear agent selection and stop
|
||||||
// statewait/chat so the UI can stay in a pure "session selected" state.
|
// chat so the UI can stay in a pure "session selected" state.
|
||||||
stopStreams();
|
stopStreams();
|
||||||
m_activeSessionId = id;
|
m_activeSessionId = id;
|
||||||
m_agentId.clear();
|
m_agentId.clear();
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue