doc: add Streaming section to REMOTE_EXECUTION
This commit is contained in:
parent
365be9ae32
commit
be041cff1a
|
|
@ -345,7 +345,7 @@ The remote config is ~20 lines vs ~170 locally.
|
|||
- **Fallback**: If SSH drops mid-execution, retry? Fail the tool call? The agent can handle tool errors gracefully already.
|
||||
- **Session restore**: `remote=` is not persisted in PersistedSession. Restored sessions always come back as local.
|
||||
- **Eager dial**: Session creation blocks on SSH connect. Should be async with lazy tool list.
|
||||
- **Streaming output**: No partial-result notifications yet. Agent can't see output until command completes.
|
||||
- **Streaming output**: ✓ Resolved. See Streaming section below.
|
||||
|
||||
## Lessons Learned
|
||||
|
||||
|
|
@ -355,3 +355,43 @@ The remote config is ~20 lines vs ~170 locally.
|
|||
4. **Tool scripts must be self-contained.** They need fallbacks when rg/ripgrep isn't available (GNU grep, find).
|
||||
5. **Embed over sync.** Embedding tools in the binary (go:embed) is simpler than rsync — single artifact, atomic deploy, no state management.
|
||||
6. **Build from source, not installed copies.** The justfile must copy from the repo's tools/ submodule, not ~/.config/ollie/tools/.
|
||||
7. **No new event roles.** Streaming uses the same `"tool"` role as final results. Empty content signals stream start; frontends need no changes.
|
||||
|
||||
## Streaming
|
||||
|
||||
Tool output streams in real-time over the SSH channel, visible to the user as it arrives.
|
||||
|
||||
### Protocol
|
||||
|
||||
Remote → local streaming uses JSON-RPC notifications (no `id` field):
|
||||
|
||||
```json
|
||||
{"jsonrpc":"2.0","result":{"data":"compiling...\n"}}
|
||||
```
|
||||
|
||||
`remote.Server.CallTool` reads these in a loop, calling `tools.StreamOutput(ctx, data)` for each, until the actual response (with matching `id`) arrives.
|
||||
|
||||
### Agent Loop Integration
|
||||
|
||||
The agent loop wraps the execution context with a streaming callback:
|
||||
|
||||
```go
|
||||
streamCtx := tools.WithOutputStream(ctx, func(data string) {
|
||||
emit(cfg, Event{Role: "tool", Name: tc.Name, Content: data})
|
||||
})
|
||||
```
|
||||
|
||||
On first chunk, an empty-content tool event is emitted to signal stream start. If streaming occurred, the final result emit is suppressed (the content was already delivered chunk-by-chunk).
|
||||
|
||||
### Execute Server
|
||||
|
||||
`limitedWriter` has a `stream func(string)` field, wired to `tools.StreamFunc(ctx)`. Every `Write()` call flushes the chunk both to the output buffer (for the full result) and to the stream callback (for real-time display).
|
||||
|
||||
### Chat Log
|
||||
|
||||
`startEventLog` treats tool streaming like assistant streaming:
|
||||
- Empty-content tool event → writes `[tool:name]\n` header, enters streaming mode
|
||||
- Subsequent tool events → content appended directly (no repeated header)
|
||||
- Non-tool event → closes the stream with a newline
|
||||
|
||||
For non-streamed tools (fast results), the single tool event renders as before.
|
||||
|
|
|
|||
Loading…
Reference in New Issue