docs/decisions.md
Rama main · réplica de lectura del repositorio original.
# Architecture Decisions
This file records decisions that are still relevant to the current implementation.
## ADR-000: Platform-First Runtime
OpenHermit optimizes for hosted multi-agent operation instead of a single local assistant process. The gateway is the control plane, and agents are registered resources with durable state and lifecycle management.
## ADR-001: Internal State Is Outside The Workspace
Conversation history, memories, instructions, users, schedules, skills, MCP assignments, and sandbox rows (per-agent execution environments) are internal state. They live in PostgreSQL, scoped by `agent_id` where applicable.
The workspace is external task state: user files, generated artifacts, repositories, and mounted data.
## ADR-002: PostgreSQL With Drizzle Stores
`packages/store` uses Drizzle and PostgreSQL. SQL migrations live in `packages/store/drizzle/`; schema definitions live in `packages/store/src/schema.ts`.
PostgreSQL gives shared durable state for many agents, indexed event/session queries, and full-text memory search. Drizzle keeps query code close to TypeScript types without introducing a generated ORM client.
## ADR-003: Gateway-Managed In-Process Agents
The current gateway starts `AgentRunner` instances in-process through `AgentInstanceManager`. This is simpler than a reverse proxy over per-agent processes while preserving explicit `/api/agents/{agentId}/...` routing and per-agent lifecycle.
The `AgentInfo.port` field remains protocol-compatible metadata, but current managed agents do not require per-agent ports.
## ADR-004: Durable Sessions Do Not Close Permanently
Sessions are durable threads. They can be idle, running, awaiting approval, or inactive. `/new` and channel session switching mark old sessions inactive rather than destroying history.
## ADR-005: User Identity Is Channel-Based And Role-Gated
Users are resolved from `(channel, channelUserId)` identities. Roles are per-agent: `owner`, `user`, or `guest`.
Owners get full management tools. Users get standard memory/web/session access. Guests are intentionally restricted. Channel adapters can auto-create unknown identities as guests.
## ADR-006: Introspection And Compaction Are Separate
Compaction keeps model context within limits. Introspection maintains long-term memory, working memory, and session descriptions. They run on different triggers and use different tool surfaces.
## ADR-007: Program-Driven Scheduler
Scheduling is a first-class subsystem with cron and one-shot schedules. Schedules are stored in PostgreSQL, run through `Scheduler`, and post prompts back into agent sessions through `AgentRunner` host callbacks.
## ADR-008: Skills Are Prompt Assets, MCP Servers Are Tool Providers
Skills are directories containing `SKILL.md` and optional supporting files. They are indexed in the prompt and synced into each exec backend's sandbox at `<agent_home>/.openhermit/skills/system/` via `runner.syncSkills`.
MCP servers are executable external tool providers. Their tools are discovered at runtime and exposed as namespaced `mcp__{serverId}__{toolName}` tools.
## ADR-009: Built-In Channels Run Beside Agents
Telegram, Discord, and Slack adapters are built-in channel packages. The gateway starts them when the agent config enables them, registers per-channel bearer tokens, and records status for the UI/API.
Adapters use the OpenHermit SDK over gateway agent routes instead of reaching into runner internals.
## ADR-010: Execution Backends Are Pluggable
The `exec` tool runs through an `ExecBackendManager`, built from per-agent rows in the `sandboxes` table. Four backends are implemented: `docker`, `host`, `e2b`, and `daytona`. Gateway-created agents auto-provision a sandbox from the preset named by `autoProvisionSandbox` in `gateway.json` (default: `docker-ubuntu`); the `host` backend is reserved for the privileged "devops" agent (see [`sandbox-model.md`](./sandbox-model.md)).