541 lines
22 KiB
Markdown
541 lines
22 KiB
Markdown
# Agent Definitions Pattern: Research & HUD/AUI Implications
|
|
|
|
## 1. alkhub_ts Agent Definitions
|
|
|
|
### 1.1 Directory Structure
|
|
|
|
Agent definitions in alkhub_ts live in `.opencode/agents/` as individual Markdown files:
|
|
|
|
```
|
|
.opencode/agents/
|
|
├── architect.md
|
|
├── architecture-reviewer.md
|
|
├── code-reviewer.md
|
|
├── coordinator.md
|
|
├── decomposer.md
|
|
├── implementation-specialist.md
|
|
├── poc-specialist.md
|
|
└── research-specialist.md
|
|
```
|
|
|
|
### 1.2 File Format: YAML Frontmatter + Markdown Body
|
|
|
|
Each file uses gray-matter frontmatter for structured metadata and a Markdown body for the system prompt:
|
|
|
|
```yaml
|
|
---
|
|
description: Short one-liner describing the agent's purpose
|
|
mode: primary | subagent
|
|
temperature: 0.2
|
|
---
|
|
|
|
You are the **Role Name**, [long-form system prompt...]
|
|
```
|
|
|
|
**Frontmatter fields observed across all 8 agents:**
|
|
|
|
| Field | Type | Required | Purpose |
|
|
|-------|------|----------|---------|
|
|
| `description` | string | yes | One-line summary shown in agent picker / `@` autocomplete |
|
|
| `mode` | `"primary"` \| `"subagent"` | yes | Whether the agent appears as a top-level mode or only as a subagent |
|
|
| `temperature` | number | sometimes | Model sampling temperature override |
|
|
|
|
**Additional fields supported by OpenCode but not used in alkhub_ts:**
|
|
|
|
| Field | Type | Purpose |
|
|
|-------|------|---------|
|
|
| `model` | string | Override the model (e.g., `"anthropic/claude-sonnet-4"`) |
|
|
| `variant` | string | Model variant to use when using this agent's configured model |
|
|
| `top_p` | number | Top-p sampling override |
|
|
| `hidden` | boolean | Hide from the UI (for internal agents like compaction, title) |
|
|
| `color` | string | Hex color or theme color for UI display |
|
|
| `steps` | number | Maximum agentic iterations before forcing text-only response |
|
|
| `permission` | object | Per-tool permission rules (allow/deny/ask) |
|
|
| `options` | object | Arbitrary provider options merged into model calls |
|
|
| `disable` | boolean | Disable a built-in agent |
|
|
|
|
### 1.3 Agent Roles in alkhub_ts
|
|
|
|
The 8 agents form a coordinated workflow:
|
|
|
|
| Agent | Mode | Role |
|
|
|-------|------|------|
|
|
| `coordinator` | primary | Orchestrates parallel task execution across worktrees |
|
|
| `architect` | primary | Creates/maintains architecture specifications (WHAT & WHY) |
|
|
| `decomposer` | primary | Breaks architecture into atomic, dependency-ordered tasks |
|
|
| `implementation-specialist` | primary | Executes atomic tasks in isolated worktrees |
|
|
| `poc-specialist` | primary | Creates proof-of-concepts in research worktrees |
|
|
| `research-specialist` | subagent | Researches technical topics, documents findings |
|
|
| `code-reviewer` | subagent | Reviews code quality at checkpoints |
|
|
| `architecture-reviewer` | subagent | Reviews architecture specs for gaps/risks |
|
|
|
|
Key patterns:
|
|
- **Primary agents** are selectable top-level modes in the TUI
|
|
- **Subagents** are invoked only via the `@agent-name` syntax or programmatically via the task tool
|
|
- Each agent has a detailed system prompt defining its workflow, constraints, and output format
|
|
- The coordinator describes both current (open-coordinator plugin) and future (hub operations) execution models
|
|
|
|
### 1.4 Agent Prompt Design Patterns
|
|
|
|
The alkhub_ts agents demonstrate several reusable patterns:
|
|
|
|
1. **Environment scoping**: Implementation specialist and POC specialist both specify exact worktree paths and use `workdir` parameter patterns
|
|
2. **Workflow phases**: Structured numbered steps (1. Load Task → 2. Verify → 3. Implement → 4. Verify → 5. Update → 6. Commit)
|
|
3. **Safe Exit protocol**: Standardized failure handling with status updates and escalation
|
|
4. **Role constraints**: "You coordinate, you do not implement" — explicit boundaries
|
|
5. **Template outputs**: Structured output templates (review reports, research documents)
|
|
6. **Tool gating**: References to specific tools available to the agent
|
|
|
|
---
|
|
|
|
## 2. OpenCode Agent System (Source Code Analysis)
|
|
|
|
### 2.1 Agent Schema (`Agent.Info`)
|
|
|
|
Defined in `/workspace/opencode/packages/opencode/src/agent/agent.ts` (lines 27-52):
|
|
|
|
```typescript
|
|
export const Info = z.object({
|
|
name: z.string(),
|
|
description: z.string().optional(),
|
|
mode: z.enum(["subagent", "primary", "all"]),
|
|
native: z.boolean().optional(),
|
|
hidden: z.boolean().optional(),
|
|
topP: z.number().optional(),
|
|
temperature: z.number().optional(),
|
|
color: z.string().optional(),
|
|
permission: Permission.Ruleset,
|
|
model: z.object({
|
|
modelID: ModelID.zod,
|
|
providerID: ProviderID.zod,
|
|
}).optional(),
|
|
variant: z.string().optional(),
|
|
prompt: z.string().optional(),
|
|
options: z.record(z.string(), z.any()),
|
|
steps: z.number().int().positive().optional(),
|
|
})
|
|
```
|
|
|
|
### 2.2 Config Schema (`Config.Agent`)
|
|
|
|
Defined in `/workspace/opencode/packages/opencode/src/config/config.ts` (lines 466-553):
|
|
|
|
```typescript
|
|
export const Agent = z.object({
|
|
model: ModelId.optional(),
|
|
variant: z.string().optional(),
|
|
temperature: z.number().optional(),
|
|
top_p: z.number().optional(),
|
|
prompt: z.string().optional(),
|
|
tools: z.record(z.string(), z.boolean()).optional(), // deprecated
|
|
disable: z.boolean().optional(),
|
|
description: z.string().optional(),
|
|
mode: z.enum(["subagent", "primary", "all"]).optional(),
|
|
hidden: z.boolean().optional(),
|
|
options: z.record(z.string(), z.any()).optional(),
|
|
color: z.union([z.string().regex(...), z.enum([...])]).optional(),
|
|
steps: z.number().int().positive().optional(),
|
|
maxSteps: z.number().int().positive().optional(), // deprecated
|
|
permission: Permission.optional(),
|
|
}).catchall(z.any()).transform(...)
|
|
```
|
|
|
|
Notable: The `catchall(z.any())` means any unknown fields in the YAML frontmatter or JSON config are swept into `options`. This is by design — it allows arbitrary per-agent configuration that gets merged into model call parameters.
|
|
|
|
### 2.3 Loading Pipeline
|
|
|
|
Agent definitions are loaded from four directory patterns (in `/workspace/opencode/packages/opencode/src/config/config.ts`, line 209):
|
|
|
|
```
|
|
/.opencode/agent/ (singular)
|
|
/.opencode/agents/ (plural)
|
|
/agent/ (singular, no dot)
|
|
/agents/ (plural, no dot)
|
|
```
|
|
|
|
The loading function `loadAgent()` (lines 189-226):
|
|
|
|
1. Globs for `*.md` files in all matching directories
|
|
2. Parses each file with `ConfigMarkdown.parse()` which uses `gray-matter` to extract YAML frontmatter
|
|
3. Extracts the agent name from the file path (stripping directory prefixes and `.md` extension)
|
|
4. Combines frontmatter data + markdown body as `prompt`
|
|
5. Validates against the `Agent` schema
|
|
6. Returns a `Record<string, Agent>` mapping name → config
|
|
|
|
**Name resolution** (line 211):
|
|
```typescript
|
|
const patterns = ["/.opencode/agent/", "/.opencode/agents/", "/agent/", "/agents/"]
|
|
const file = rel(item, patterns) ?? path.basename(item)
|
|
const agentName = trim(file) // removes .md extension
|
|
```
|
|
|
|
This means:
|
|
- `.opencode/agents/coordinator.md` → agent name `"coordinator"`
|
|
- `.opencode/agents/nested/child.md` → agent name `"nested/child"`
|
|
|
|
### 2.4 Merge Strategy
|
|
|
|
Built-in agents (build, plan, general, explore, compaction, title, summary) are defined in code. User-defined agents from `.opencode/agents/*.md` are merged on top:
|
|
|
|
```typescript
|
|
for (const [key, value] of Object.entries(cfg.agent ?? {})) {
|
|
if (value.disable) {
|
|
delete agents[key]
|
|
continue
|
|
}
|
|
let item = agents[key]
|
|
if (!item) {
|
|
item = agents[key] = {
|
|
name: key,
|
|
mode: "all",
|
|
permission: Permission.merge(defaults, user),
|
|
options: {},
|
|
native: false,
|
|
}
|
|
}
|
|
// Merge each field: prompt, model, temperature, mode, etc.
|
|
item.prompt = value.prompt ?? item.prompt
|
|
item.model = value.model ? Provider.parseModel(value.model) : item.model
|
|
item.variant = value.variant ?? item.variant
|
|
// ... etc
|
|
}
|
|
```
|
|
|
|
Key behaviors:
|
|
- `disable: true` removes a built-in agent entirely
|
|
- If a new name doesn't match a built-in, a fresh agent with `mode: "all"` is created
|
|
- Frontmatter fields override built-in values (not deep-merge for most fields)
|
|
- Permission configs are merged (not replaced)
|
|
- `options` are deep-merged with `mergeDeep()`
|
|
|
|
### 2.5 System Prompt Assembly
|
|
|
|
When an LLM call is made, the system prompt is assembled in this order (from `/workspace/opencode/packages/opencode/src/session/llm.ts`, lines 101-126):
|
|
|
|
```typescript
|
|
const system: string[] = []
|
|
system.push(
|
|
[
|
|
// 1. Agent-specific prompt OR provider default prompt
|
|
...(input.agent.prompt ? [input.agent.prompt] : SystemPrompt.provider(input.model)),
|
|
// 2. Custom system prompt from the call
|
|
...input.system,
|
|
// 3. Custom system prompt from the user message
|
|
...(input.user.system ? [input.user.system] : []),
|
|
]
|
|
.filter((x) => x)
|
|
.join("\n"),
|
|
)
|
|
```
|
|
|
|
Then the plugin hook `experimental.chat.system.transform` is triggered, allowing plugins to modify the system prompt array.
|
|
|
|
After this, additional segments are added (from `/workspace/opencode/packages/opencode/src/session/prompt.ts`, lines 1500-1509):
|
|
|
|
```typescript
|
|
const [skills, env, instructions, modelMsgs] = yield* Effect.all([
|
|
Effect.promise(() => SystemPrompt.skills(agent)),
|
|
Effect.promise(() => SystemPrompt.environment(model)),
|
|
instruction.system(),
|
|
Effect.promise(() => MessageV2.toModelMessages(msgs, model)),
|
|
])
|
|
const system = [...env, ...(skills ? [skills] : []),
|
|
...instructions]
|
|
```
|
|
|
|
The full system prompt hierarchy (first message wins position, content accumulates):
|
|
|
|
1. **Agent prompt** (from `.opencode/agents/*.md` body) — or a model-specific default (anthropic.txt, gpt.txt, etc.)
|
|
2. **Custom system** (from plugin hooks, compaction, plan mode injection)
|
|
3. **User-provided system prompt** (from the user message)
|
|
4. **Plugin modifications** via `experimental.chat.system.transform`
|
|
5. **Environment info** (model name, working directory, platform, date)
|
|
6. **Skills list** (markdown-formatted available skills)
|
|
7. **Instruction files** (AGENTS.md, CLAUDE.md found walking up directory tree)
|
|
|
|
### 2.6 Agent Name Usage in Messages
|
|
|
|
The `AgentPart` type (SDK types, line 833-844):
|
|
```typescript
|
|
export type AgentPart = {
|
|
id: string
|
|
sessionID: string
|
|
messageID: string
|
|
type: "agent"
|
|
name: string // agent name, e.g. "explore"
|
|
source?: { value: string, start: number, end: number }
|
|
}
|
|
```
|
|
|
|
When a user types `@explore` in their message, OpenCode parses this into an `AgentPart`. During prompt processing, if the text contains `@agent-name`, it resolves to the corresponding agent definition, and the subagent is launched via the task tool.
|
|
|
|
### 2.7 Agent Generation
|
|
|
|
OpenCode includes an LLM-powered agent generator (`Agent.generate()`). When invoked, it:
|
|
|
|
1. Collects the list of existing agent names to avoid collisions
|
|
2. Uses a structured output call with schema `{ identifier, whenToUse, systemPrompt }`
|
|
3. The prompt (`generate.txt`) instructs the model to create an agent configuration
|
|
|
|
This is used by the `/agent` command in the CLI to dynamically create agents from descriptions.
|
|
|
|
---
|
|
|
|
## 3. Relationship Between Agents and Sessions
|
|
|
|
### 3.1 Agent per Message, Not per Session
|
|
|
|
Each **user message** carries an `agent` field indicating which agent handled it. This is NOT a session-level property — a single session can switch between agents:
|
|
|
|
```typescript
|
|
// Message info structure (simplified)
|
|
interface MessageInfo {
|
|
id: MessageID
|
|
role: "user" | "assistant"
|
|
agent: string // e.g. "build", "explore", "coordinator"
|
|
model: { providerID, modelID }
|
|
// ...
|
|
}
|
|
```
|
|
|
|
From `prompt.ts` line 1593:
|
|
```typescript
|
|
const agentName = cmd.agent ?? input.agent ?? (yield* agents.defaultAgent())
|
|
```
|
|
|
|
This means:
|
|
- A user can type `@explore` mid-conversation to switch to the explore agent for that turn
|
|
- The next turn may return to the default agent
|
|
- Each message remembers which agent produced it
|
|
|
|
### 3.2 Agent Switching and Plan Mode
|
|
|
|
Plan mode has special handling. From `prompt.ts` lines 261-302:
|
|
- When switching FROM plan TO build, a system reminder is injected explaining the transition
|
|
- When NOT in plan mode but the previous assistant message was from plan, a different reminder is injected
|
|
- Plan mode restricts edit permissions
|
|
|
|
### 3.3 No Agent-Scoped State or Memory
|
|
|
|
OpenCode does **not** have a concept of "agent state" or "agent-scoped memory". Each agent is stateless — it's defined by its:
|
|
- System prompt
|
|
- Permission ruleset
|
|
- Model configuration
|
|
- Tool access
|
|
|
|
State lives in the **session** (messages, tool results, compaction summaries). The agent definition is purely declarative configuration for how to run LLM calls within a session.
|
|
|
|
The `options` field on agents supports arbitrary key-value pairs that get merged into LLM call parameters, but these are static configuration, not runtime state.
|
|
|
|
---
|
|
|
|
## 4. Relevance to HUD/AUI Concept
|
|
|
|
### 4.1 Could HUD Sections Be Defined as Declarative Configs?
|
|
|
|
**Yes — and the agent definition pattern provides a strong analogy.**
|
|
|
|
An agent definition is essentially:
|
|
```yaml
|
|
frontmatter (structured metadata) → controls behavior
|
|
markdown body (unstructured prompt) → controls content
|
|
```
|
|
|
|
A HUD section definition could follow the same pattern:
|
|
```yaml
|
|
---
|
|
section: context-status
|
|
position: top
|
|
refresh: on-event # on-event | on-demand | periodic
|
|
priority: 10
|
|
collapse-threshold: 70 # percentage above which to always expand
|
|
always-show: false
|
|
---
|
|
|
|
Template for rendering this section (can reference data sources)...
|
|
```
|
|
|
|
Just as agent definitions declare their `mode`, `temperature`, and `permission`, HUD definitions would declare their `position`, `refresh strategy`, and `data requirements`.
|
|
|
|
### 4.2 Declarative vs. Imperative: What Agent Definitions Teach Us
|
|
|
|
Agent definitions are **declarative configs with a procedural core**:
|
|
|
|
| Aspect | Agent Definition | HUD Definition (Proposed) |
|
|
|--------|-----------------|---------------------------|
|
|
| Metadata | YAML frontmatter | YAML frontmatter |
|
|
| Content | Markdown system prompt | Markdown template or rendering spec |
|
|
| Behavior | Controls LLM call parameters | Controls HUD rendering and data fetching |
|
|
| Overrides | Built-in agents can be extended/overridden | Built-in HUD sections could be extended/overridden |
|
|
| Merge | `mergeDeep` with priority | Similar merge with project-level overrides |
|
|
|
|
The critical design insight from OpenCode's agent system: **the same merge strategy that allows `.opencode/agents/*.md` files to override built-in agents could allow `.opencode/hud/*.md` files to override built-in HUD sections**.
|
|
|
|
### 4.3 Project-Specific HUD Layouts
|
|
|
|
Different project types could have different HUD layouts, just as different projects have different agent rosters:
|
|
|
|
```
|
|
# A web app project might define:
|
|
.opencode/hud/context-bar.md → Shows token usage, model, cost
|
|
.opencode/hud/task-tracker.md → Shows task progress from tasks/*.md
|
|
.opencode/hud/test-runner.md → Shows test results
|
|
|
|
# A data pipeline project might define:
|
|
.opencode/hud/pipeline-status.md → Shows last pipeline run status
|
|
.opencode/hud/data-quality.md → Shows data quality metrics
|
|
.opencode/hud/context-bar.md → Override: add data volume info
|
|
```
|
|
|
|
This mirrors how `coordinator.md` uses worktree-specific context that implementation-specialist.md doesn't need.
|
|
|
|
### 4.4 How Could This Be Done Without Modifying OpenCode Core?
|
|
|
|
OpenCode's plugin system provides the necessary hooks. The relevant hooks are:
|
|
|
|
1. **`experimental.chat.system.transform`** — already used by open-memory to inject context status. This hook receives `{ sessionID, model }` and `{ system }` (a mutable array of system prompt strings).
|
|
|
|
2. **`experimental.session.compacting`** — receives compaction events.
|
|
|
|
3. **`event`** — receives all SSE events, which include message updates with token counts.
|
|
|
|
A HUD definition system could work as a **plugin**:
|
|
|
|
```
|
|
@alkdev/open-memory/ (or a separate @alkdev/open-hud plugin)
|
|
├── src/
|
|
│ ├── index.ts # Plugin entry
|
|
│ ├── hud/
|
|
│ │ ├── loader.ts # Load .opencode/hud/*.md files (like loadAgent)
|
|
│ │ ├── renderer.ts # Render HUD sections into system prompt
|
|
│ │ └── sections/ # Built-in section definitions
|
|
│ │ ├── context.md
|
|
│ │ ├── tasks.md
|
|
│ │ └── git.md
|
|
│ └── hooks/
|
|
│ ├── system-prompt.ts # experimental.chat.system.transform
|
|
│ └── event.ts # SSE event processing for data
|
|
```
|
|
|
|
The key architectural insight: **we don't need OpenCode to render a visual HUD**. Instead, we inject structured status information into the system prompt, and the agent's response becomes the "rendered" HUD. This is exactly what open-memory already does with context percentage injection.
|
|
|
|
### 4.5 Proposed HUD Definition Schema
|
|
|
|
Drawing from the agent definition pattern:
|
|
|
|
```yaml
|
|
---
|
|
# Section identity
|
|
name: context-status # unique identifier (from filename)
|
|
description: Context window usage and status
|
|
|
|
# Rendering behavior
|
|
position: header # header | sidebar | footer | inline
|
|
priority: 10 # lower = shown first
|
|
refresh: on-event # on-event | on-demand | periodic | once
|
|
collapse-threshold: 70 # auto-collapse below this threshold
|
|
|
|
# Data requirements
|
|
data-sources:
|
|
- context-tracker # from this plugin
|
|
- session-info # from OpenCode
|
|
|
|
# Rendering constraints
|
|
max-length: 500 # max chars in system prompt injection
|
|
always-show: false # always inject, even when collapsed
|
|
|
|
# Agent targeting
|
|
agents: # which agents should see this section
|
|
- build
|
|
- plan
|
|
# (null/undefined = all agents)
|
|
---
|
|
|
|
## Context Status
|
|
|
|
Your context window is at {{context.percentage}}% usage ({{context.tokens}} / {{context.limit}} tokens).
|
|
|
|
{{#if context.status.critical}}
|
|
⚠️ CRITICAL: Context usage above 92%. Consider using memory_compact() immediately.
|
|
{{else if context.status.red}}
|
|
🔴 Context usage above 85%. Consider compacting soon.
|
|
{{else if context.status.yellow}}
|
|
🟡 Context usage above 70%. Monitor but proceed normally.
|
|
{{else}}
|
|
🟢 Context usage is healthy (below 70%).
|
|
{{/if}}
|
|
```
|
|
|
|
### 4.6 Comparison: Agent Definitions vs. HUD Definitions
|
|
|
|
| Dimension | Agent Definition | HUD Definition (Proposed) |
|
|
|-----------|-----------------|--------------------------|
|
|
| **Format** | YAML frontmatter + Markdown body | YAML frontmatter + template body |
|
|
| **Loading** | `.opencode/agents/*.md` | `.opencode/hud/*.md` (or plugin-scoped) |
|
|
| **Merge** | Built-in + config + user overrides | Built-in + project overrides |
|
|
| **Scope** | Per-agent (LLM call config) | Per-section (status display config) |
|
|
| **State** | None (stateless config) | Reactive data sources |
|
|
| **Output** | System prompt content | System prompt injection (agent-visible) |
|
|
| **Trigger** | User selects `@agent-name` | System prompt assembly (every turn) |
|
|
| **Data** | Static config only | Dynamic (from SSE events, DB queries) |
|
|
|
|
### 4.7 Key Differences and Challenges
|
|
|
|
1. **Statefulness**: Agent definitions are purely static config. HUD sections need reactive data (context percentage, session counts, git status). This requires runtime state management that doesn't exist in the agent system.
|
|
|
|
2. **Rendering**: Agent definitions are consumed by the LLM as freeform text. HUD sections could be either:
|
|
- **Prompt-injection style** (like current open-memory context injection) — the agent "sees" the HUD
|
|
- **Tool-response style** — the agent queries HUD data via a memory tool
|
|
- The agent definition pattern suggests prompt-injection, but tool-response may be better for on-demand data
|
|
|
|
3. **Conditional visibility**: Agent definitions have `hidden` and `mode` fields. HUD sections need richer conditions — "show only when context > 70%" or "show only when git has uncommitted changes". This is more complex than the simple boolean/enum agent system.
|
|
|
|
4. **Layout ordering**: Agent definitions don't have a concept of ordering (they're selected by name). HUD sections need positional semantics (which section appears first, which is collapsible, etc.).
|
|
|
|
5. **Refresh cadence**: Agent configs are loaded once. HUD data may need to refresh on events, periodically, or on-demand. The agent system has no equivalent concept.
|
|
|
|
### 4.8 Recommended Approach
|
|
|
|
**Phase 1: Mimic the agent definition loading pattern exactly.**
|
|
|
|
Store HUD section templates as `.opencode/hud/*.md` with YAML frontmatter. Load them using the same `gray-matter` + glob pattern that OpenCode uses for agents. Inject them via the `experimental.chat.system.transform` hook.
|
|
|
|
This requires no OpenCode core changes and establishes the file format convention.
|
|
|
|
**Phase 2: Add data binding and conditional rendering.**
|
|
|
|
Extend the template body with simple `${variable}` interpolation. The plugin maintains a reactive data store (context tracker, session stats) that fills in these variables at system prompt assembly time.
|
|
|
|
**Phase 3: Consider proposing first-class HUD support to OpenCode.**
|
|
|
|
If the pattern proves valuable, propose that OpenCode adds a `.opencode/hud/` directory as a first-class concept, similar to `.opencode/agents/` and `.opencode/skills/`. The loading infrastructure already exists (glob + gray-matter + merge). The new concept is just the "HUD section" schema with its position, refresh, and data-source metadata.
|
|
|
|
---
|
|
|
|
## 5. Summary of Findings
|
|
|
|
### Agent Definition System (OpenCode)
|
|
|
|
- **Format**: YAML frontmatter + Markdown body in `.opencode/agents/*.md`
|
|
- **Schema**: `AgentConfig` with fields for model, prompt, mode, permissions, options, etc.
|
|
- **Loading**: Glob + gray-matter parsing, merged over built-in agents
|
|
- **Resolution**: Agent name derived from filename (with directory prefix for nested files)
|
|
- **Usage**: Selected per-message via `@agent-name` syntax or as default agent
|
|
- **System prompt**: Agent's `prompt` field becomes the primary system prompt (replacing provider default)
|
|
- **No state**: Agents are stateless config; state lives in sessions
|
|
|
|
### alkhub_ts Agent Definitions
|
|
|
|
- **8 agents** forming a coordinated workflow (architect → decomposer → implementation-specialist)
|
|
- **Rich prompts**: Detailed workflows, constraints, output templates, tool references
|
|
- **Pattern**: Primary agents for top-level use, subagents for specialized delegation
|
|
- **Innovation**: Worktree-scoped environment constraints, safe exit protocols, AAR processes
|
|
|
|
### HUD/AUI Implications
|
|
|
|
- The agent definition pattern (YAML frontmatter + template body, glob loading, merge strategy) translates directly to HUD section definitions
|
|
- Agent definitions prove the pattern works for declarative, project-specific configuration
|
|
- The key difference is state: agents are static config, HUD needs reactive data
|
|
- Can be implemented as a plugin without OpenCode core changes using `experimental.chat.system.transform`
|
|
- The same `.opencode/` directory convention would make HUD definitions discoverable and project-specific
|