Documentation source
Documentation source
Documentation source
Tenant shared context rules, lessons, routing guidance, and memories that are loaded into agent prompts.
# Context
## Overview
The context module lives in `features/context/`. It manages durable `shared_context` rows that are formatted into prompt sections for agents. The module is part of the agent prompt pipeline described in [Agent System](/docs/features/agent-system), and its agent-callable write path is exposed through the platform [Tool System](/docs/features/tool-system).
The primary runtime path is:
1. Humans or agents write `shared_context` rows.
2. `loadSharedContextPrompt()` reads active rows for the tenant.
3. `features/context/lib/format.ts` formats each context type into Markdown sections.
4. `loadAgentPromptContext()` in `features/agents/lib/build-context.ts` stores that rendered text as `sharedContextPrompt`.
5. `buildAgentSystemPrompt()` appends `sharedContextPrompt` to the stable system prompt as a `corrections` section.
## Key Concepts
### SharedContextType
`features/context/types.ts` defines the allowed `shared_context.type` values:
```typescript
export type SharedContextType =
| "correction"
| "lesson"
| "routing"
| "insight"
| "guideline";
```
The exported `SHARED_CONTEXT_TYPES` array lists the same five values. Each row is typed as `SharedContextRecord = Tables<"shared_context">`, with insert and update aliases from the generated Supabase database types.
### Corrections And Lessons
Corrections and lessons are the two original high-use shared context kinds:
- `correction` rows render under `## Workspace Corrections (apply to all work)`.
- `lesson` rows render under `## Workspace Lessons Learned`.
Lessons can include their row `context` field as a parenthetical suffix. The formatter also supports:
- `routing`, rendered as `## Workspace Routing Guidance`.
- `insight`, rendered as `## Workspace Insights`.
- `guideline`, rendered as `## Workspace Guidelines`.
`features/context/lib/format.ts` truncates each item to 180 characters and caps each type at 8 items in the rendered prompt. `features/context/lib/load.ts` selects the newest 8 active rows per type, then renders each per-type window in ascending `(created_at, id)` order so the prompt prefix is stable for caching.
### Scope And Filtering
`loadSharedContextPrompt(admin, tenantId, options)` always includes tenant-wide active rows where both `agent_id` and `entity_type_id` are null. When callers pass valid UUID `agentId` or `entityTypeId` options, it also includes matching scoped rows.
The loader rejects non-UUID scope values before building the PostgREST `.or()` clause. If the `shared_context` query fails, it logs `[shared_context] load failed` and throws instead of silently dropping injected context.
`loadAgentPromptContext()` currently calls `loadSharedContextPrompt(admin, tenantId)` without scope options, so the standard agent system prompt receives tenant-wide active rows.
### Remember Tool
`remember` is the canonical agent-callable write path for team-scoped shared context. It is defined in `features/tools/memory-tools.ts` by `createMemoryToolDefinitions()`, belongs to both the `"memory"` and `"context"` groups, and requires `entities.team.update`.
The tool accepts:
- `content`: required string, max 180 characters.
- `kind`: one of `correction`, `lesson`, `routing`, `insight`, or `guideline`.
- `context`: optional citation or scoping note.
The actual insert is delegated to `insertSharedContext()` in `features/context/server/insert-shared-context.ts`. That helper gets the active tenant from tool context, writes tenant-global rows, checks near-duplicates within the same type, and returns `deduplicated: true` instead of inserting when a near match already exists.
The old split write tools `addCorrection`, `addLesson`, and `addInsight` are retired. `features/tools/context-tools.ts` states that the shared-context write path is owned solely by `remember`, and `features/tools/context-tools.test.ts` asserts those retired keys are no longer exposed.
### Usage Stats Tool
`getUsageStats` is not implemented in `features/context/`; it lives in `features/tools/context-tools.ts`. It is the only tool returned by `createContextToolDefinitions()`, belongs to both `"context"` and `"memory"` groups, requires `entities.team.read`, and is annotated with `readOnlyHint: true`.
The tool reads workspace cost and runtime telemetry through `getCostData()` and returns event counts, total cost, input/output tokens, cache read/write counts, reasoning tokens, context-management counts, and top models.
## Architecture / Data Flow
### Prompt Injection
`loadAgentPromptContext()` in `features/agents/lib/build-context.ts` loads shared context in parallel with entity types, skills, workspace agent context, user memories, visible agents, and recent feedback. It catches shared-context load failures with `captureNonFatal()` and falls back to an empty shared context prompt for that run.
`buildAgentSystemPrompt()` appends sections in a stable order: platform, entity types, session, user memories, skills, workspace context, agent directory, tooling guide, extra system sections, and finally `loadedContext.sharedContextPrompt` as a `corrections` prompt section. `buildAgentPrompt()` then appends that prompt section without changing its Markdown.
### Human Admin Writes
`features/context/server/actions.ts` owns the server-action CRUD path:
- `createSharedContextRule()` inserts a new active row after checking near-duplicates in the same tenant/type/scope.
- `listSharedContext()` lists active or inactive rows with pagination.
- `updateSharedContextRule()` updates a row in the active tenant.
- `deactivateSharedContextRule()` soft-deletes by setting `active = false`.
- `deleteSharedContextRule()` hard-deletes a row.
The admin UI in `features/context/components/` uses these server actions and API endpoints to create, list, deactivate, and delete shared-context rows.
### Legacy HTTP Compatibility
`upsertSharedContext()` and `getSharedContext()` in `features/context/server/actions.ts` are deprecated compatibility helpers for the old `/api/context` and `/api/context/[key]` routes. New UI and tool write paths should use `createSharedContextRule()` or `remember` instead.
## Key APIs
```typescript
export async function loadSharedContextPrompt(
admin: SupabaseAdminClient,
tenantId: string,
options: LoadSharedContextOptions = {},
): Promise<string>;
```
Loads active tenant shared-context rows, applies optional agent/entity-type scope filters, stabilizes the per-type window, and returns formatted Markdown.
```typescript
export function buildCorrectionsPrompt(rows: SharedContextRecord[]): string;
export function buildLessonsPrompt(rows: SharedContextRecord[]): string;
export function buildRoutingPrompt(rows: SharedContextRecord[]): string;
export function buildInsightsPrompt(rows: SharedContextRecord[]): string;
export function buildGuidelinesPrompt(rows: SharedContextRecord[]): string;
```
Formats active rows by type into the prompt sections consumed by the agent prompt builder.
```typescript
export async function createSharedContextRule(
input: CreateSharedContextInput,
): Promise<CreateSharedContextRuleResult>;
```
Creates a governed shared-context row from the admin/server-action path.
```typescript
export async function insertSharedContext(
supabase: ReturnType<typeof createAdminClient>,
type: SharedContextType,
content: string,
context?: string | null,
): Promise<InsertSharedContextResult>;
```
Canonical write helper for the `remember` tool. It writes tenant-global shared context from tool execution context and deduplicates near matches.
```typescript
export function createMemoryToolDefinitions(): ToolDefinition[];
```
Registers the `remember` tool in the `"memory"` and `"context"` groups.
```typescript
export function createContextToolDefinitions(): ToolDefinition[];
```
Registers the read-only `getUsageStats` tool.
## Agent Instructions
Use `remember({ content, kind, context })` when an agent needs to create durable team-wide context. Keep `content` concise because the tool schema caps it at 180 characters and the prompt formatter also truncates long rows.
Choose the narrowest truthful `kind`:
| Kind | Use for |
| ------------ | ------------------------------------------------------------------- |
| `correction` | A repeatable mistake agents should stop making |
| `lesson` | A durable fact, preference, or learned operating note |
| `routing` | A rule about which agent, tool, or source should handle a situation |
| `insight` | A durable observation or pattern |
| `guideline` | A standing policy or convention |
Treat `deduplicated: true` from `remember` as success. It means the same or near-same active rule already exists.
Do not reintroduce `addCorrection`, `addLesson`, or `addInsight`. The current code and tests make `remember` the sole agent-callable `shared_context` write surface.
For human admin CRUD, use `createSharedContextRule()`, `updateSharedContextRule()`, `deactivateSharedContextRule()`, or `deleteSharedContextRule()` from `features/context/server/actions.ts`. Do not write `shared_context` directly from a component or route when one of those helpers fits.
When changing prompt loading or formatting, run the focused tests under `features/context/lib/` and the prompt-builder tests that assert section order. Preserve the stable ordering in `loadSharedContextPrompt()` and `buildAgentSystemPrompt()` because prompt caching depends on byte-stable prefixes.