feat: inline Anthropic managed agents into main Go app#4748
Open
supernandor wants to merge 11 commits into
Open
feat: inline Anthropic managed agents into main Go app#4748supernandor wants to merge 11 commits into
supernandor wants to merge 11 commits into
Conversation
Replaces the external agent service (Python/agent2) with pkg/agents/ directly in the main app: - pkg/agents/client.go: Anthropic Sessions API client - pkg/agents/store.go: GORM-based session + message persistence - pkg/agents/stream.go: SSE handler (poll Anthropic, stream events) - pkg/agents/service.go: Business logic (GetOrCreate, Resume, Delete) - pkg/public/agent_stream.go: HTTP route with cookie auth - DB migration: agent_sessions + agent_messages tables Single session per canvas/user. Messages stored locally. No separate service, no internal gRPC, no JWT token exchange. Stream endpoint uses cookie auth like all other routes.
- Delete agent/ directory (Python/Pydantic AI agent service) - Delete protos/private/agents.proto (internal gRPC) - Remove agent container from docker-compose.dev.yml - Remove AGENT_GRPC_URL config - Frontend: don't require token (cookie auth), add credentials:include - Add binaries to .gitignore
20e73bf to
82e6990
Compare
- anthropic-version: 2023-06-01 (not 2025-01-01) - event type: user.message (not user_message) - events endpoint needs ?beta=true - Add integration test that validates full flow against live API
Gorilla mux PathPrefix('/api/v1/agents') was shadowing the more specific
HandleFunc for the stream endpoint. Register stream route first.
- Frontend: include X-Organization-Id header in stream fetch (was causing 400) - Backend: better error messages with field names in 400 responses - Backend: add logging to stream handler for debugging - Tests: 11 unit tests for Client (request format, headers, errors) and StreamHandler (validation, SSE format, text extraction)
The logging middleware wraps ResponseWriter but didn't implement http.Flusher, breaking SSE streaming. Added Flush() delegation.
- ListAgentChats now returns the existing session for the canvas/user - ListAgentChatMessages loads messages by chat_id directly - Frontend auto-selects the existing session on sidebar open - Single session per canvas/user — always continues the conversation
Before sending a message, snapshot existing event IDs. When polling, skip all pre-existing events so only the new turn's events are streamed to the frontend.
When session goes idle, do one more ListEvents call to catch any events that arrived between the status check and the event list. Prevents missing the final agent.message in multi-tool-call turns.
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.
Summary
Replaces the external agent service with
pkg/agents/inline in the main Go app.Before: Go app → internal gRPC → Python agent (or agent2) → AI provider
After: Go app → Anthropic Sessions API directly
Key changes
pkg/agents/client.gopkg/agents/store.gopkg/agents/stream.gopkg/agents/service.gopkg/public/agent_stream.godb/migrations/...agent_sessions+agent_messagestablesDesign decisions
Config
What's NOT in this PR (follow-up)
agent/,agent2/,protos/private/agents.proto