diff --git a/.env.example b/.env.example index 8047f7bc..c29bc915 100644 --- a/.env.example +++ b/.env.example @@ -2,7 +2,7 @@ # Copy to .env and fill in values. For Docker Compose, do NOT use 'export' prefix. # # Auto-generated by prepare-env.sh: GOCLAW_GATEWAY_TOKEN, GOCLAW_ENCRYPTION_KEY. -# LLM providers and channels are configured via the web dashboard setup wizard. +# LLM provider API keys: configure via the web dashboard setup wizard. # --- Gateway (required) --- GOCLAW_GATEWAY_TOKEN= diff --git a/api-reference.md b/api-reference.md index d62fb299..2e61dddf 100644 --- a/api-reference.md +++ b/api-reference.md @@ -9,13 +9,13 @@ | POST | `/v1/chat/completions` | OpenAI-compatible chat API | | POST | `/v1/responses` | Responses protocol | | POST | `/v1/tools/invoke` | Tool invocation | -| GET/POST | `/v1/agents/*` | Agent management (managed mode) | -| GET/POST | `/v1/skills/*` | Skills management (managed mode) | -| GET/POST/PUT/DELETE | `/v1/tools/custom/*` | Custom tool CRUD (managed mode) | -| GET/POST/PUT/DELETE | `/v1/mcp/*` | MCP server + grants management (managed mode) | -| GET | `/v1/traces/*` | Trace viewer (managed mode) | +| GET/POST | `/v1/agents/*` | Agent management | +| GET/POST | `/v1/skills/*` | Skills management | +| GET/POST/PUT/DELETE | `/v1/tools/custom/*` | Custom tool CRUD | +| GET/POST/PUT/DELETE | `/v1/mcp/*` | MCP server + grants management | +| GET | `/v1/traces/*` | Trace viewer | -## Custom Tools (Managed Mode) +## Custom Tools Define shell-based tools at runtime via HTTP API — no recompile or restart needed. The LLM can invoke custom tools identically to built-in tools. @@ -67,7 +67,7 @@ Connect external [Model Context Protocol](https://modelcontextprotocol.io) serve **Supported transports:** `stdio`, `sse`, `streamable-http` -**Standalone mode** — configure in `config.json`: +**Static config** — configure in `config.json` (deprecated; use HTTP API for dynamic management): ```json { @@ -87,7 +87,7 @@ Connect external [Model Context Protocol](https://modelcontextprotocol.io) serve } ``` -**Managed mode** — full CRUD via HTTP API with per-agent and per-user access grants: +**HTTP API** — full CRUD with per-agent and per-user access grants: | Method | Path | Description | |---|---|---| diff --git a/cmd/gateway.go b/cmd/gateway.go index a6e554d9..90871833 100644 --- a/cmd/gateway.go +++ b/cmd/gateway.go @@ -909,7 +909,6 @@ func runGateway() { slog.Info("goclaw gateway starting", "version", Version, "protocol", protocol.ProtocolVersion, - "mode", "managed", "agents", agentRouter.List(), "tools", toolsReg.Count(), "channels", channelMgr.GetEnabledChannels(), diff --git a/cmd/onboard.go b/cmd/onboard.go index 9c7c9dbb..4efa013e 100644 --- a/cmd/onboard.go +++ b/cmd/onboard.go @@ -37,25 +37,25 @@ func runOnboard() { } } - // ── Step 1: Postgres DSN ── + // ── Step 1: Postgres connection ── postgresDSN := os.Getenv("GOCLAW_POSTGRES_DSN") if postgresDSN == "" { postgresDSN = cfg.Database.PostgresDSN } if postgresDSN == "" { - var err error - postgresDSN, err = promptString("Postgres DSN", "Connection string (e.g. postgres://user:pass@host:5432/dbname)", "") + fmt.Println("── Database Connection ──") + fmt.Println(" Enter your PostgreSQL connection details (press Enter for defaults).") + fmt.Println() + + dsn, err := promptPostgresFields() if err != nil { fmt.Println("Cancelled.") return } + postgresDSN = dsn } else { fmt.Printf(" Using Postgres DSN from environment\n") } - if postgresDSN == "" { - fmt.Println(" Error: Postgres DSN is required.") - return - } // ── Step 2: Test connection ── fmt.Print(" Testing Postgres connection... ") diff --git a/cmd/onboard_helpers.go b/cmd/onboard_helpers.go index 6401ef91..88db7a55 100644 --- a/cmd/onboard_helpers.go +++ b/cmd/onboard_helpers.go @@ -4,6 +4,7 @@ import ( "crypto/rand" "encoding/hex" "fmt" + "net/url" "os" "strings" ) @@ -14,6 +15,44 @@ func onboardGenerateToken(bytes int) string { return hex.EncodeToString(b) } +// promptPostgresFields prompts for individual database fields and builds a DSN. +func promptPostgresFields() (string, error) { + host, err := promptString("Host", "", "localhost") + if err != nil { + return "", err + } + port, err := promptString("Port", "", "5432") + if err != nil { + return "", err + } + dbName, err := promptString("Database name", "", "goclaw") + if err != nil { + return "", err + } + user, err := promptString("Username", "", "postgres") + if err != nil { + return "", err + } + password, err := promptPassword("Password", "Leave empty if no password") + if err != nil { + return "", err + } + sslMode, err := promptString("SSL mode", "", "disable") + if err != nil { + return "", err + } + + // Build DSN with proper escaping + var userInfo *url.Userinfo + if password != "" { + userInfo = url.UserPassword(user, password) + } else { + userInfo = url.User(user) + } + dsn := fmt.Sprintf("postgres://%s@%s:%s/%s?sslmode=%s", userInfo.String(), host, port, dbName, sslMode) + return dsn, nil +} + // onboardWriteEnvFile writes the minimal .env.local with only the 3 required secrets. func onboardWriteEnvFile(path, postgresDSN, gatewayToken, encryptionKey string) { var lines []string diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh index 3edf2417..4c0438fb 100644 --- a/docker-entrypoint.sh +++ b/docker-entrypoint.sh @@ -3,9 +3,9 @@ set -e case "${1:-serve}" in serve) - # Managed mode: auto-upgrade (schema migrations + data hooks) before starting. - if [ "$GOCLAW_MODE" = "managed" ] && [ -n "$GOCLAW_POSTGRES_DSN" ]; then - echo "Managed mode: running upgrade..." + # Auto-upgrade (schema migrations + data hooks) before starting. + if [ -n "$GOCLAW_POSTGRES_DSN" ]; then + echo "Running database upgrade..." /app/goclaw upgrade || \ echo "Upgrade warning (may already be up-to-date)" fi diff --git a/docs/00-architecture-overview.md b/docs/00-architecture-overview.md index 64e78472..f4eee937 100644 --- a/docs/00-architecture-overview.md +++ b/docs/00-architecture-overview.md @@ -233,7 +233,7 @@ sequenceDiagram --- -## 7. Managed Mode Wiring +## 7. Database Wiring The `wireManagedExtras()` function in `cmd/gateway_managed.go` wires multi-tenant components: @@ -393,7 +393,7 @@ flowchart TD |------|---------| | `cmd/root.go` | Cobra CLI entry point, flag parsing | | `cmd/gateway.go` | Gateway startup orchestrator (`runGateway()`) | -| `cmd/gateway_managed.go` | Managed mode wiring (`wireManagedExtras()`, `wireManagedHTTP()`) | +| `cmd/gateway_managed.go` | Database wiring (`wireManagedExtras()`, `wireManagedHTTP()`) | | `cmd/gateway_callbacks.go` | Shared callbacks (user seeding, context file loading) | | `cmd/gateway_consumer.go` | Inbound message consumer (subagent, delegate, teammate, handoff routing) | | `cmd/gateway_providers.go` | Provider registration (config-based + DB-based) | @@ -423,7 +423,7 @@ flowchart TD | [02-providers.md](./02-providers.md) | LLM providers, retry logic, schema cleaning | | [03-tools-system.md](./03-tools-system.md) | Tool registry, policy engine, interceptors, custom tools, MCP grants | | [04-gateway-protocol.md](./04-gateway-protocol.md) | WebSocket protocol v3, HTTP API, RBAC, identity propagation | -| [05-channels-messaging.md](./05-channels-messaging.md) | Channel adapters, Telegram formatting, pairing, managed-mode user scoping | +| [05-channels-messaging.md](./05-channels-messaging.md) | Channel adapters, Telegram formatting, pairing, per-user scoping | | [06-store-data-model.md](./06-store-data-model.md) | Store interfaces, PostgreSQL schema, session caching, custom tool store | | [07-bootstrap-skills-memory.md](./07-bootstrap-skills-memory.md) | Bootstrap files, skills system, memory, skills grants | | [08-scheduling-cron.md](./08-scheduling-cron.md) | Scheduler lanes, cron lifecycle | diff --git a/docs/01-agent-loop.md b/docs/01-agent-loop.md index dbf47374..9973f46c 100644 --- a/docs/01-agent-loop.md +++ b/docs/01-agent-loop.md @@ -88,7 +88,7 @@ flowchart TD - Increment the `activeRuns` atomic counter (no mutex -- true concurrency, especially in group chats with `maxConcurrent = 3`). - Emit a `run.started` event to notify connected clients. -- Create a trace record (managed mode) with a generated trace UUID. +- Create a trace record with a generated trace UUID. - Propagate context values: `WithAgentID()`, `WithUserID()`, `WithAgentType()`. Downstream tools and interceptors rely on these. - Compute per-user workspace: `base + "/" + sanitize(userID)`. Inject via `WithToolWorkspace(ctx)` so all filesystem and shell tools use the correct directory. - Ensure per-user files exist. A `sync.Map` cache guarantees the seeding function runs at most once per user. @@ -381,7 +381,7 @@ flowchart TD --- -## 10. Resolver (Managed Mode) +## 10. Resolver The `ManagedResolver` lazy-creates Loop instances from PostgreSQL data when the Router encounters a cache miss. @@ -392,7 +392,7 @@ flowchart TD PROV --> BOOT["Step 3: Load bootstrap files
bootstrap.LoadFromStore(agentID)"] BOOT --> DEFAULTS["Step 4: Apply defaults
contextWindow <= 0 then 200K
maxIterations <= 0 then 20"] DEFAULTS --> CREATE["Step 5: Create Loop
NewLoop(LoopConfig)"] - CREATE --> WIRE["Step 6: Wire managed-mode hooks
EnsureUserFilesFunc, ContextFileLoaderFunc"] + CREATE --> WIRE["Step 6: Wire hooks
EnsureUserFilesFunc, ContextFileLoaderFunc"] WIRE --> DONE["Return Loop to Router for caching"] ``` diff --git a/docs/02-providers.md b/docs/02-providers.md index 72f08c89..39533f78 100644 --- a/docs/02-providers.md +++ b/docs/02-providers.md @@ -202,9 +202,9 @@ The Anthropic provider calls `CleanSchemaForProvider("anthropic", ...)` when con --- -## 7. Managed Mode -- Providers from Database +## 7. Providers from Database -In managed mode, providers are loaded from the `llm_providers` table in addition to the config file. Database providers override config providers with the same name. +Providers are loaded from the `llm_providers` table in addition to the config file. Database providers override config providers with the same name. ### Loading Flow diff --git a/docs/03-tools-system.md b/docs/03-tools-system.md index 40fca43d..f6fc41eb 100644 --- a/docs/03-tools-system.md +++ b/docs/03-tools-system.md @@ -141,7 +141,7 @@ Context keys ensure each tool call receives the correct per-call values without ## 3. Filesystem Tools and Virtual FS Routing -In managed mode, filesystem operations are intercepted before hitting the host disk. Two interceptor layers route specific paths to the database instead. +Filesystem operations are intercepted before hitting the host disk. Two interceptor layers route specific paths to the database instead. ```mermaid flowchart TD @@ -570,9 +570,9 @@ GoClaw integrates with Model Context Protocol (MCP) servers via `internal/mcp/`. - Tools are registered with a prefix (e.g., `mcp_servername_toolname`) - Dynamic tool group registration: `mcp` and `mcp:{serverName}` groups -### Access Control (Managed Mode) +### Access Control -In managed mode, MCP server access is controlled through per-agent and per-user grants stored in PostgreSQL. +MCP server access is controlled through per-agent and per-user grants stored in PostgreSQL. ```mermaid flowchart TD @@ -602,7 +602,7 @@ flowchart LR --- -## 13. Custom Tools (Managed Mode) +## 13. Custom Tools Define shell-based tools at runtime via the HTTP API -- no recompile or restart needed. Custom tools are stored in the `custom_tools` PostgreSQL table and loaded dynamically into the agent's tool registry. diff --git a/docs/04-gateway-protocol.md b/docs/04-gateway-protocol.md index c93acc26..f00f3313 100644 --- a/docs/04-gateway-protocol.md +++ b/docs/04-gateway-protocol.md @@ -96,7 +96,7 @@ flowchart TD Token comparison uses `crypto/subtle.ConstantTimeCompare` to prevent timing attacks. -In managed mode, `user_id` in the connect parameters is required for per-user session scoping and context file routing. GoClaw uses the **Identity Propagation** pattern — it trusts the upstream service to provide accurate user identity. The `user_id` is opaque (VARCHAR 255); multi-tenant deployments use the compound format `tenant.{tenantId}.user.{userId}`. See [00-architecture-overview.md Section 5](./00-architecture-overview.md) for details. +The `user_id` in the connect parameters is required for per-user session scoping and context file routing. GoClaw uses the **Identity Propagation** pattern — it trusts the upstream service to provide accurate user identity. The `user_id` is opaque (VARCHAR 255); multi-tenant deployments use the compound format `tenant.{tenantId}.user.{userId}`. See [00-architecture-overview.md Section 5](./00-architecture-overview.md) for details. ### Three Roles @@ -161,7 +161,7 @@ flowchart TD | `agent.wait` | Wait for an agent to become available | | `agent.identity.get` | Get agent identity (name, description) | | `agents.list` | List all accessible agents | -| `agents.create` | Create a new agent (managed mode) | +| `agents.create` | Create a new agent | | `agents.update` | Update agent configuration | | `agents.delete` | Soft-delete an agent | | `agents.files.list` | List agent context files | @@ -301,7 +301,7 @@ flowchart TD - `Authorization: Bearer ` -- timing-safe comparison via `crypto/subtle.ConstantTimeCompare` - No token configured: all requests allowed -- `X-GoClaw-User-Id`: required in managed mode for per-user scoping +- `X-GoClaw-User-Id`: required for per-user scoping - `X-GoClaw-Agent-Id`: specify target agent for the request ### Endpoints @@ -334,9 +334,9 @@ Direct tool invocation without the agent loop. Supports `dryRun: true` to return Returns `{"status":"ok","protocol":3}`. -#### Managed Mode CRUD Endpoints +#### CRUD Endpoints -All managed endpoints require `Authorization: Bearer ` and `X-GoClaw-User-Id` header for per-user scoping. +All CRUD endpoints require `Authorization: Bearer ` and `X-GoClaw-User-Id` header for per-user scoping. **Agents** (`/v1/agents`): @@ -482,9 +482,9 @@ Error responses include `retryable` (boolean) and `retryAfterMs` (integer) field | `internal/http/chat_completions.go` | POST /v1/chat/completions (OpenAI-compatible) | | `internal/http/responses.go` | POST /v1/responses (OpenResponses protocol) | | `internal/http/tools_invoke.go` | POST /v1/tools/invoke (direct tool execution) | -| `internal/http/agents.go` | Agent CRUD HTTP handlers (managed mode) | -| `internal/http/skills.go` | Skills HTTP handlers (managed mode) | -| `internal/http/traces.go` | Traces HTTP handlers (managed mode) | +| `internal/http/agents.go` | Agent CRUD HTTP handlers | +| `internal/http/skills.go` | Skills HTTP handlers | +| `internal/http/traces.go` | Traces HTTP handlers | | `internal/http/delegations.go` | Delegation history HTTP handlers | | `internal/http/summoner.go` | LLM-powered agent setup (XML parsing, context file generation) | | `internal/http/auth.go` | Bearer token authentication, timing-safe comparison | diff --git a/docs/05-channels-messaging.md b/docs/05-channels-messaging.md index d4981f81..c3ae7046 100644 --- a/docs/05-channels-messaging.md +++ b/docs/05-channels-messaging.md @@ -57,7 +57,7 @@ flowchart LR Internal channels (`cli`, `system`, `subagent`) are silently skipped by the outbound dispatcher and never forwarded to external platforms. -### Handoff Routing (Managed Mode) +### Handoff Routing Before normal agent routing, the consumer checks the `handoff_routes` table for an active routing override. If a handoff route exists for the incoming channel + chat ID, the message is redirected to the target agent instead of the original. @@ -504,7 +504,7 @@ flowchart TD WS2 --> USER3["user_charlie/"] ``` -In managed mode, channel instances are loaded from the database with their assigned agent ID. The agent key is resolved and propagated through the message pipeline, ensuring all filesystem tools, context files, and memory operations use the correct workspace. +Channel instances are loaded from the database with their assigned agent ID. The agent key is resolved and propagated through the message pipeline, ensuring all filesystem tools, context files, and memory operations use the correct workspace. --- @@ -570,7 +570,7 @@ flowchart TD |------|---------| | `internal/channels/channel.go` | Channel interface, BaseChannel, extended interfaces, HandleMessage | | `internal/channels/manager.go` | Manager: registration, StartAll, StopAll, outbound dispatch, webhook collection | -| `internal/channels/instance_loader.go` | DB-based channel instance loading (managed mode) | +| `internal/channels/instance_loader.go` | DB-based channel instance loading | | `internal/channels/telegram/channel.go` | Telegram core: long polling, mention gating, typing indicators | | `internal/channels/telegram/handlers.go` | Message handling, media processing, forum topic detection | | `internal/channels/telegram/topic_config.go` | Per-topic config layering and resolution | diff --git a/docs/06-store-data-model.md b/docs/06-store-data-model.md index 809ddd8a..c670e432 100644 --- a/docs/06-store-data-model.md +++ b/docs/06-store-data-model.md @@ -77,7 +77,7 @@ flowchart TD ## 4. Agent Access Control -In managed mode, agent access is checked via a 4-step pipeline. +Agent access is checked via a 4-step pipeline. ```mermaid flowchart TD @@ -477,7 +477,7 @@ flowchart TD | Key | Type | Purpose | |-----|------|---------| | `goclaw_user_id` | string | External user ID (e.g., Telegram user ID) | -| `goclaw_agent_id` | uuid.UUID | Agent UUID (managed mode) | +| `goclaw_agent_id` | uuid.UUID | Agent UUID | | `goclaw_agent_type` | string | Agent type: `"open"` or `"predefined"` | | `goclaw_sender_id` | string | Original individual sender ID (in group chats, `user_id` is group-scoped but `sender_id` preserves the actual person) | diff --git a/docs/07-bootstrap-skills-memory.md b/docs/07-bootstrap-skills-memory.md index a1b125e0..f74cd9d1 100644 --- a/docs/07-bootstrap-skills-memory.md +++ b/docs/07-bootstrap-skills-memory.md @@ -186,7 +186,7 @@ This ensures resolver-injected virtual files (`DELEGATION.md`, `TEAM.md`) surviv --- -## 7. Agent Summoning (Managed Mode) +## 7. Agent Summoning Creating a predefined agent requires 4 context files (SOUL.md, IDENTITY.md, AGENTS.md, TOOLS.md) with specific formatting conventions. Agent summoning generates all 4 files from a natural language description in a single LLM call. @@ -260,9 +260,9 @@ IDF is computed as: `log((N - df + 0.5) / (df + 0.5) + 1)` --- -## 11. Skills -- Embedding Search (Managed Mode) +## 11. Skills -- Embedding Search -In managed mode, skill search uses a hybrid approach combining BM25 and vector similarity. +Skill search uses a hybrid approach combining BM25 and vector similarity. ```mermaid flowchart TD @@ -283,9 +283,9 @@ flowchart TD --- -## 12. Skills Grants & Visibility (Managed Mode) +## 12. Skills Grants & Visibility -In managed mode, skill access is controlled through a 3-tier visibility model with explicit agent and user grants. +Skill access is controlled through a 3-tier visibility model with explicit agent and user grants. ```mermaid flowchart TD @@ -315,7 +315,7 @@ flowchart TD **Resolution**: `ListAccessible(agentID, userID)` performs a DISTINCT join across `skills`, `skill_agent_grants`, and `skill_user_grants` with the visibility filter, returning only active skills the caller can access. -**Managed-mode Tier 4**: In managed mode, global skills (Tier 4 in the hierarchy) are loaded from the `skills` PostgreSQL table instead of the filesystem. +**Tier 4**: Global skills (Tier 4 in the hierarchy) are loaded from the `skills` PostgreSQL table instead of the filesystem. --- @@ -489,7 +489,7 @@ The flush is idempotent per compaction cycle -- it will not run again until the | Document | Relevant Content | |----------|-----------------| -| [00-architecture-overview.md](./00-architecture-overview.md) | Startup sequence, managed mode wiring | +| [00-architecture-overview.md](./00-architecture-overview.md) | Startup sequence, database wiring | | [01-agent-loop.md](./01-agent-loop.md) | Agent loop calls BuildSystemPrompt, compaction flow | | [03-tools-system.md](./03-tools-system.md) | ContextFileInterceptor routing read_file/write_file to DB | | [06-store-data-model.md](./06-store-data-model.md) | memory_documents, memory_chunks tables | diff --git a/docs/09-security.md b/docs/09-security.md index b8b4ab90..46117f74 100644 --- a/docs/09-security.md +++ b/docs/09-security.md @@ -2,7 +2,7 @@ Defense-in-depth with five independent layers from transport to isolation. Each layer operates independently -- even if one layer is bypassed, the remaining layers continue to protect the system. -> **Managed mode**: Adds AES-256-GCM encryption for secrets stored in PostgreSQL (LLM provider API keys, MCP server API keys, custom tool environment variables), plus agent-level access control via the 4-step `CanAccess` pipeline (see [06-store-data-model.md](./06-store-data-model.md)). +> AES-256-GCM encryption protects secrets stored in PostgreSQL (LLM provider API keys, MCP server API keys, custom tool environment variables). Agent-level access control uses the 4-step `CanAccess` pipeline (see [06-store-data-model.md](./06-store-data-model.md)). --- @@ -123,7 +123,7 @@ The workspace is injected into tools via `WithToolWorkspace(ctx)` context inject --- -## 2. Encryption (Managed Mode) +## 2. Encryption AES-256-GCM encryption for secrets stored in PostgreSQL. Key provided via `GOCLAW_ENCRYPTION_KEY` environment variable. diff --git a/docs/10-tracing-observability.md b/docs/10-tracing-observability.md index 3916080f..b4301e12 100644 --- a/docs/10-tracing-observability.md +++ b/docs/10-tracing-observability.md @@ -106,7 +106,7 @@ The exporter lives in a separate sub-package (`internal/tracing/otelexport/`) so --- -## 5. Trace HTTP API (Managed Mode) +## 5. Trace HTTP API | Method | Path | Description | |--------|------|-------------| @@ -126,7 +126,7 @@ The exporter lives in a separate sub-package (`internal/tracing/otelexport/`) so --- -## 6. Delegation History (Managed Mode) +## 6. Delegation History Delegation history records are stored in the `delegation_history` table and exposed alongside traces for cross-referencing agent interactions. diff --git a/internal/agent/resolver.go b/internal/agent/resolver.go index a7dcefc5..9115ca09 100644 --- a/internal/agent/resolver.go +++ b/internal/agent/resolver.go @@ -323,7 +323,7 @@ func NewManagedResolver(deps ResolverDeps) ResolverFunc { } } - // Managed mode: filter skills by visibility + agent grants. + // Filter skills by visibility + agent grants. // Only public skills and explicitly granted internal skills appear in the system prompt. var skillAllowList []string if deps.SkillAccessStore != nil { diff --git a/internal/gateway/methods/agents_create.go b/internal/gateway/methods/agents_create.go index 4189e330..cefcaaf5 100644 --- a/internal/gateway/methods/agents_create.go +++ b/internal/gateway/methods/agents_create.go @@ -66,7 +66,7 @@ func (m *AgentsMethods) handleCreate(ctx context.Context, client *gateway.Client } if m.agentStore != nil { - // --- Managed mode: create agent in DB --- + // --- DB-backed: create agent in store --- ctx := context.Background() // Check if agent already exists in DB diff --git a/internal/gateway/methods/agents_delete.go b/internal/gateway/methods/agents_delete.go index bdf5a5f5..4e33c78f 100644 --- a/internal/gateway/methods/agents_delete.go +++ b/internal/gateway/methods/agents_delete.go @@ -39,7 +39,7 @@ func (m *AgentsMethods) handleDelete(ctx context.Context, client *gateway.Client var removedBindings int if m.agentStore != nil { - // --- Managed mode: delete from DB --- + // --- DB-backed: delete from store --- ctx := context.Background() ag, err := m.agentStore.GetByKey(ctx, params.AgentID) if err != nil { diff --git a/internal/gateway/methods/agents_files.go b/internal/gateway/methods/agents_files.go index 534c8377..a5d771f9 100644 --- a/internal/gateway/methods/agents_files.go +++ b/internal/gateway/methods/agents_files.go @@ -36,7 +36,7 @@ func (m *AgentsMethods) handleFilesList(ctx context.Context, client *gateway.Cli } if m.agentStore != nil { - // --- Managed mode: list from DB --- + // --- DB-backed: list from store --- ctx := context.Background() ag, err := m.agentStore.GetByKey(ctx, params.AgentID) if err != nil { @@ -135,7 +135,7 @@ func (m *AgentsMethods) handleFilesGet(ctx context.Context, client *gateway.Clie } if m.agentStore != nil { - // --- Managed mode: read from DB --- + // --- DB-backed: read from store --- ctx := context.Background() ag, err := m.agentStore.GetByKey(ctx, params.AgentID) if err != nil { @@ -234,7 +234,7 @@ func (m *AgentsMethods) handleFilesSet(ctx context.Context, client *gateway.Clie } if m.agentStore != nil { - // --- Managed mode: write to DB --- + // --- DB-backed: write to store --- ctx := context.Background() ag, err := m.agentStore.GetByKey(ctx, params.AgentID) if err != nil { diff --git a/internal/gateway/methods/agents_identity.go b/internal/gateway/methods/agents_identity.go index f8791911..8bd361e4 100644 --- a/internal/gateway/methods/agents_identity.go +++ b/internal/gateway/methods/agents_identity.go @@ -41,7 +41,7 @@ func (m *AgentsMethods) handleIdentityGet(_ context.Context, client *gateway.Cli } if m.agentStore != nil { - // --- Managed mode: read identity from DB --- + // --- DB-backed: read identity from store --- ctx := context.Background() ag, err := m.agentStore.GetByKey(ctx, params.AgentID) if err == nil { diff --git a/internal/gateway/methods/agents_update.go b/internal/gateway/methods/agents_update.go index 730d7fca..34a575cf 100644 --- a/internal/gateway/methods/agents_update.go +++ b/internal/gateway/methods/agents_update.go @@ -45,7 +45,7 @@ func (m *AgentsMethods) handleUpdate(ctx context.Context, client *gateway.Client } if m.agentStore != nil { - // --- Managed mode: update agent in DB --- + // --- DB-backed: update agent in store --- ctx := context.Background() ag, err := m.agentStore.GetByKey(ctx, params.AgentID) if err != nil { diff --git a/internal/gateway/server.go b/internal/gateway/server.go index 4ac84ea1..af43735f 100644 --- a/internal/gateway/server.go +++ b/internal/gateway/server.go @@ -160,52 +160,52 @@ func (s *Server) BuildMux() *http.ServeMux { mux.Handle("/v1/tools/invoke", toolsHandler) } - // Managed mode: agent CRUD + shares API + // Agent CRUD + shares API if s.agentsHandler != nil { s.agentsHandler.RegisterRoutes(mux) } - // Managed mode: skill management API + // Skill management API if s.skillsHandler != nil { s.skillsHandler.RegisterRoutes(mux) } - // Managed mode: LLM trace listing API + // LLM trace listing API if s.tracesHandler != nil { s.tracesHandler.RegisterRoutes(mux) } - // Managed mode: MCP server management API + // MCP server management API if s.mcpHandler != nil { s.mcpHandler.RegisterRoutes(mux) } - // Managed mode: custom tool CRUD API + // Custom tool CRUD API if s.customToolsHandler != nil { s.customToolsHandler.RegisterRoutes(mux) } - // Managed mode: channel instance CRUD API + // Channel instance CRUD API if s.channelInstancesHandler != nil { s.channelInstancesHandler.RegisterRoutes(mux) } - // Managed mode: provider & model CRUD API + // Provider & model CRUD API if s.providersHandler != nil { s.providersHandler.RegisterRoutes(mux) } - // Managed mode: delegation history API + // Delegation history API if s.delegationsHandler != nil { s.delegationsHandler.RegisterRoutes(mux) } - // Managed mode: builtin tool management API + // Builtin tool management API if s.builtinToolsHandler != nil { s.builtinToolsHandler.RegisterRoutes(mux) } - // Managed mode: pending messages API + // Pending messages API if s.pendingMessagesHandler != nil { s.pendingMessagesHandler.RegisterRoutes(mux) } diff --git a/internal/i18n/catalog_en.go b/internal/i18n/catalog_en.go index c74dc08d..51478852 100644 --- a/internal/i18n/catalog_en.go +++ b/internal/i18n/catalog_en.go @@ -53,7 +53,7 @@ func init() { // HTTP API MsgInvalidAuth: "invalid authentication", MsgMsgsRequired: "messages is required", - MsgUserIDHeader: "X-GoClaw-User-Id header is required in managed mode", + MsgUserIDHeader: "X-GoClaw-User-Id header is required", MsgFileTooLarge: "file too large or invalid multipart form", MsgMissingFileField: "missing 'file' field", MsgInvalidFilename: "invalid filename", diff --git a/internal/i18n/catalog_vi.go b/internal/i18n/catalog_vi.go index acca2a73..5c23c41d 100644 --- a/internal/i18n/catalog_vi.go +++ b/internal/i18n/catalog_vi.go @@ -53,7 +53,7 @@ func init() { // HTTP API MsgInvalidAuth: "xác thực không hợp lệ", MsgMsgsRequired: "messages là bắt buộc", - MsgUserIDHeader: "header X-GoClaw-User-Id là bắt buộc ở chế độ managed", + MsgUserIDHeader: "header X-GoClaw-User-Id là bắt buộc", MsgFileTooLarge: "tệp quá lớn hoặc form multipart không hợp lệ", MsgMissingFileField: "thiếu trường 'file'", MsgInvalidFilename: "tên tệp không hợp lệ", diff --git a/internal/i18n/catalog_zh.go b/internal/i18n/catalog_zh.go index 8fa77eca..00f4d8ef 100644 --- a/internal/i18n/catalog_zh.go +++ b/internal/i18n/catalog_zh.go @@ -53,7 +53,7 @@ func init() { // HTTP API MsgInvalidAuth: "身份验证无效", MsgMsgsRequired: "messages 是必填项", - MsgUserIDHeader: "托管模式下需要 X-GoClaw-User-Id 请求头", + MsgUserIDHeader: "需要 X-GoClaw-User-Id 请求头", MsgFileTooLarge: "文件过大或 multipart 表单无效", MsgMissingFileField: "缺少 'file' 字段", MsgInvalidFilename: "文件名无效", diff --git a/internal/mcp/bridge_server.go b/internal/mcp/bridge_server.go index e773dc27..5a76c3a7 100644 --- a/internal/mcp/bridge_server.go +++ b/internal/mcp/bridge_server.go @@ -17,7 +17,7 @@ import ( // BridgeToolNames is the subset of GoClaw tools exposed via the MCP bridge. // Excluded: spawn (agent loop), create_forum_topic (channels), -// handoff/delegate_search/evaluate_loop/team_* (managed mode stores). +// handoff/delegate_search/evaluate_loop/team_* (require database stores). var BridgeToolNames = map[string]bool{ // Filesystem "read_file": true, diff --git a/internal/mcp/manager.go b/internal/mcp/manager.go index 25917a5a..c4d64665 100644 --- a/internal/mcp/manager.go +++ b/internal/mcp/manager.go @@ -72,7 +72,7 @@ type Manager struct { // DB-backed servers store store.MCPServerStore - // Shared connection pool (nil = standalone mode) + // Shared connection pool (nil = config-only mode) pool *Pool poolServers map[string]struct{} // server names acquired from pool (for cleanup) poolToolNames map[string][]string // per-agent tool names for pool-backed servers @@ -179,7 +179,7 @@ func (m *Manager) LoadForAgent(ctx context.Context, agentID uuid.UUID, userID st continue } } else { - // Standalone mode: create per-agent connection + // Per-agent mode: create per-agent connection if err := m.connectServer(ctx, srv.Name, srv.Transport, srv.Command, args, env, srv.URL, headers, srv.ToolPrefix, srv.TimeoutSec); err != nil { diff --git a/internal/tools/delegate_prep.go b/internal/tools/delegate_prep.go index 29c0ae27..2558164e 100644 --- a/internal/tools/delegate_prep.go +++ b/internal/tools/delegate_prep.go @@ -18,7 +18,7 @@ import ( func (dm *DelegateManager) prepareDelegation(ctx context.Context, opts DelegateOpts, mode string) (*DelegationTask, *store.AgentLinkData, error) { sourceAgentID := store.AgentIDFromContext(ctx) if sourceAgentID == uuid.Nil { - return nil, nil, fmt.Errorf("delegation requires managed mode (no agent ID in context)") + return nil, nil, fmt.Errorf("delegation requires database stores (no agent ID in context)") } sourceAgent, err := dm.agentStore.GetByID(ctx, sourceAgentID) diff --git a/internal/tools/handoff_tool.go b/internal/tools/handoff_tool.go index 9f0622af..76077bf0 100644 --- a/internal/tools/handoff_tool.go +++ b/internal/tools/handoff_tool.go @@ -104,7 +104,7 @@ func (t *HandoffTool) executeTransfer(ctx context.Context, args map[string]any) // Get current agent and channel context sourceAgentID := store.AgentIDFromContext(ctx) if sourceAgentID == uuid.Nil { - return ErrorResult("handoff requires managed mode") + return ErrorResult("handoff requires database stores") } sourceAgent, err := t.delegateMgr.agentStore.GetByID(ctx, sourceAgentID) diff --git a/internal/tools/team_tool_manager.go b/internal/tools/team_tool_manager.go index fdcbe263..3eff80fe 100644 --- a/internal/tools/team_tool_manager.go +++ b/internal/tools/team_tool_manager.go @@ -47,7 +47,7 @@ func (m *TeamToolManager) SetDelegateManager(dm *DelegateManager) { func (m *TeamToolManager) resolveTeam(ctx context.Context) (*store.TeamData, uuid.UUID, error) { agentID := store.AgentIDFromContext(ctx) if agentID == uuid.Nil { - return nil, uuid.Nil, fmt.Errorf("no agent context — team tools require managed mode") + return nil, uuid.Nil, fmt.Errorf("no agent context — team tools require database stores") } // Check cache first diff --git a/prepare-env.sh b/prepare-env.sh index 85a02d52..90ecebec 100755 --- a/prepare-env.sh +++ b/prepare-env.sh @@ -81,33 +81,6 @@ else echo " [exists] GOCLAW_GATEWAY_TOKEN" fi -# 4. Check provider API key -has_provider=false -for key in GOCLAW_OPENROUTER_API_KEY GOCLAW_ANTHROPIC_API_KEY GOCLAW_OPENAI_API_KEY \ - GOCLAW_MINIMAX_API_KEY GOCLAW_GROQ_API_KEY GOCLAW_DEEPSEEK_API_KEY \ - GOCLAW_GEMINI_API_KEY GOCLAW_MISTRAL_API_KEY GOCLAW_XAI_API_KEY \ - GOCLAW_COHERE_API_KEY GOCLAW_PERPLEXITY_API_KEY; do - val="$(get_env_val "$key")" - if [ -n "$val" ]; then - has_provider=true - echo " [exists] $key" - break - fi -done - -if [ "$has_provider" = false ]; then - echo " [missing] No LLM provider API key found" - echo "" - echo " Add at least one provider key to .env before starting:" - echo " GOCLAW_OPENROUTER_API_KEY=sk-or-..." - echo " GOCLAW_ANTHROPIC_API_KEY=sk-ant-..." - echo " GOCLAW_MINIMAX_API_KEY=..." - echo "" - echo "=== Done (action required) ===" - echo "" - exit 0 -fi - echo "" echo "=== Done ===" echo ""