Replace the Vercel AI SDK with direct OpenAI SDK calls and a custom AgentLoop. The AI SDK has zero runtime integration today, so removing it costs nothing. Supply chain risk (2-5 releases/day, April 2026 Vercel breach, bus factor of 1) makes it a liability we don't need. Key changes: - ADR-018 accepted: openai package (zero runtime deps) replaces ai SDK - AgentLoop handles multi-step tool execution explicitly (~300 LOC vs AI SDK's ~2700 LOC streamText) - Hub owns UIMessage/UIPart/ToolCallState types (extends ADR-016) - Hub owns streaming protocol (subset of AI SDK's UIMessageChunk wire format with step boundaries, error handling, usage tracking) - operationToOpenAITool() maps TypeBox schemas directly, no adapter - Trade-off: ~1100 LOC total new code for the savings of 6+ transitive deps, supply chain risk, and release cadence coupling Updates AGENTS.md constraints and dependencies, adds OQ-63/OQ-64/OQ-65 and Theme 11 (Inference & LLM Integration) to open questions.
98 lines
4.9 KiB
Markdown
98 lines
4.9 KiB
Markdown
# AGENTS.md
|
|
|
|
Project orientation for agents working in this repository.
|
|
|
|
## Project
|
|
|
|
**@alkdev/hub** — Hub API server for the alk.dev platform. Deno + TypeScript, this is a standalone Deno project (not a workspace). Spokes are separate packages/repos.
|
|
|
|
## Repository Structure
|
|
|
|
```
|
|
src/
|
|
config/ — Configuration types, encrypted config loading
|
|
crypto/ — AES-256-GCM, PBKDF2, key management
|
|
logger/ — Logtape configuration
|
|
storage/ — Drizzle table definitions, relations, client, migrations
|
|
server/ — Hono HTTP server, routes, middleware
|
|
auth/ — API key auth (keypal), session tokens
|
|
coordination/ — coord.spawn/status/message/notify/abort/detect
|
|
redis/ — Redis EventTarget setup, event routing
|
|
inference/ — OpenAI-compatible proxy, LLM key management, AgentLoop, hub-own streaming
|
|
docs/
|
|
architecture/ — Architecture specs (see overview.md for index)
|
|
decisions/ — ADRs
|
|
research/ — Research docs
|
|
reviews/ — Review docs
|
|
tasks/
|
|
architecture/ — Architecture-phase tasks (storage/ has detailed tasks)
|
|
migrations/ — Drizzle SQL migrations
|
|
```
|
|
|
|
## External Dependencies (npm, pinned)
|
|
|
|
| Package | Version | Purpose |
|
|
|---------|---------|---------|
|
|
| `@alkdev/operations` | 0.1.0 | Operations registry, call protocol, MCP adapter, ResponseEnvelope |
|
|
| `@alkdev/pubsub` | 0.1.0 | PubSub, event targets (Redis/WS/Worker), operators, EventEnvelope |
|
|
| `@alkdev/taskgraph` | 0.0.2 | Task graph construction, analysis, frontmatter |
|
|
| `@alkdev/flowgraph` | 0.1.0 | Workflow graph: DAG construction, ujsx templates, reactive execution |
|
|
| `@alkdev/typebox` | 0.34.49 | Runtime type schemas (fork of @sinclair/typebox 0.x LTS) |
|
|
| `@alkdev/drizzlebox` | 0.1.0 | TypeBox schema generation from Drizzle tables |
|
|
| `hono` | 4.12.23 | HTTP framework |
|
|
| `drizzle-orm` | 0.45.2 | Postgres ORM |
|
|
| `ioredis` | 5.10.1 | Redis client |
|
|
| `keypal` | 0.2.0 | API key management |
|
|
| `openai` | TBD (pin on add) | OpenAI API client for LLM calls (zero runtime deps) |
|
|
| `pg` | 8.21.0 | Postgres driver |
|
|
| `@hono/mcp` | 0.3.0 | MCP server middleware |
|
|
| `@logtape/logtape` | 2.1.1 | Structured logging |
|
|
| `@modelcontextprotocol/sdk` | 1.29.0 | MCP SDK |
|
|
|
|
## Key Patterns
|
|
|
|
- **Operations**: Everything is a typed operation with TypeBox schemas. `IOperationDefinition` defines name, namespace, type (QUERY/MUTATION/SUBSCRIPTION), input/output schemas, access control, and handler. Registered in `OperationRegistry`, called via `registry.execute()` (returns `ResponseEnvelope<T>`) or call protocol `PendingRequestMap` / `CallHandler`. See operations.md and call-graph.md.
|
|
- **PubSub**: `@alkdev/pubsub` with `EventEnvelope` pattern for structured cross-process messages. `createPubSub` with pluggable `TypedEventTarget` — `EventTarget` (in-process), `RedisEventTarget` (cross-process), `WebSocketEventTarget` (hub<->spoke), `WorkerEventTarget`. 13 operators.
|
|
- **Task graph**: `@alkdev/taskgraph` for task DAG construction, analysis (critical path, parallel groups, bottlenecks, risk), and frontmatter parsing.
|
|
- **Flow graph**: `@alkdev/flowgraph` for workflow DAG construction, operation/call graph management, ujsx template composition, reactive execution, and type-compatibility analysis. Wraps graphology with DAG enforcement.
|
|
- **Drizzle+TypeBox**: Storage pattern uses `@alkdev/drizzlebox` for automatic TypeBox schema generation from Drizzle table definitions. Drizzle tables are the source of truth.
|
|
- **No Effect**: We do not use Effect. Plain async/await throughout.
|
|
- **call ≡ subscribe**: At protocol level, a call and a subscription are the same thing with different consumption patterns. See call-graph.md.
|
|
|
|
## Running
|
|
|
|
```bash
|
|
# Install dependencies
|
|
deno install
|
|
|
|
# Run tests
|
|
deno task test
|
|
|
|
# Type check
|
|
deno task typecheck
|
|
|
|
# Lint
|
|
deno lint
|
|
```
|
|
|
|
## Constraints
|
|
|
|
- Deno runtime (latest stable), TypeScript strict mode
|
|
- Postgres for all persistent state (Drizzle ORM)
|
|
- Redis for cross-process events (ioredis)
|
|
- OpenAI SDK (`openai` package) for LLM calls — no AI SDK (see ADR-018)
|
|
- TypeBox for all runtime schemas (`@alkdev/typebox`, not Zod or @sinclair/typebox)
|
|
- Hono for HTTP server
|
|
- WebSocket for hub<->spoke transport (not SSE as primary)
|
|
- Pin dependency versions in deno.json — update manually when needed, fix bugs upstream first
|
|
- No mocked/stubbed implementations — real code only
|
|
- No Effect dependency
|
|
- No DbType.Table storage abstraction — use @alkdev/drizzlebox pattern
|
|
- Do not duplicate code from `@alkdev/operations`, `@alkdev/pubsub`, `@alkdev/taskgraph`, or `@alkdev/flowgraph` — use the npm packages
|
|
|
|
## Security
|
|
|
|
- **No secrets in git**: .gitignore excludes .env*, *.key, *.pem
|
|
- **No secrets in environment variables**: See hub-config.md — all secrets come from encrypted config or Docker secrets
|
|
- **No private IPs/hostnames in git**: Infrastructure docs contain only patterns, not actual server addresses
|
|
- **Config file encryption**: Sensitive fields are AES-256-GCM encrypted, see hub-config.md and ADR-008 |