# How to Author Custom Frames with Domain-Specific Tags for Specialized Ideation

> Learn to author custom frames with domain-specific tags for specialized ideation by extending the FRAMES array in src/frames.ts. Add unique IDs, labels, prompts, and tags easily.

- Repository: [Udit Akhouri/adhd](https://github.com/UditAkhourii/adhd)
- Tags: how-to-guide
- Published: 2026-08-19

---

**You author custom frames by extending the `FRAMES` array in [`src/frames.ts`](https://github.com/UditAkhourii/adhd/blob/main/src/frames.ts) with objects that define a unique `id`, human-readable `label`, domain-specific `prompt`, and relevant `tags`, then run the type checker to validate the new `Frame` type.**

The ADHD repository implements a parallel ideation engine that uses lightweight vantage operators called *frames* to re-pose problems from distinct cognitive angles. To author custom frames with domain-specific tags for specialized ideation, you extend the frame registry and optionally expand the tag union type so the orchestrator can bias or guarantee selection during a run.

## Understanding the Frame Architecture

ADHD frames are structured objects consumed by the engine in [`src/engine.ts`](https://github.com/UditAkhourii/adhd/blob/main/src/engine.ts). Each frame requires four properties: an **`id`** for internal lookup via `selectFrames`, a **`label`** for UI and log output (logged at line 56 of [`src/engine.ts`](https://github.com/UditAkhourii/adhd/blob/main/src/engine.ts)), a **`prompt`** that is injected into every divergent LLM call inside `divergeBranch` (lines 54-57), and a **`tags`** array that the `selectFrames` function (lines 37-38) uses to filter and bias the frame pool. The pool is shuffled before sampling using the `shuffle` utility (lines 24-31), so array order in [`src/frames.ts`](https://github.com/UditAkhourii/adhd/blob/main/src/frames.ts) does not affect runtime selection.

## Step-by-Step Guide to Authoring a Custom Frame

### 1. Choose a Descriptive ID and Label

Pick a kebab-case `id` that serves as the lookup key and a human-readable `label` that appears in execution logs. For example, `id: "bio-sensor"` and `label: "Bio-sensor designer"` let you trace frame usage through the engine's logging pipeline.

### 2. Write a Domain-Specific Prompt

Craft a concise prompt that embeds the vocabulary and constraints of your target domain. The engine injects this prompt fragment into each divergent branch call, so it must clearly tell the LLM which cognitive stance to adopt. Referencing [`documentation/frames.md`](https://github.com/UditAkhourii/adhd/blob/main/documentation/frames.md) (lines 34-38), effective prompts emphasize distinct vocabulary unique to the domain.

### 3. Assign Domain Tags

Attach one or more tags from the built-in set—`code`, `design`, `general`, or `wild`—or introduce a new tag by extending the union type. Tags drive deterministic selection logic in `selectFrames`; `codeMode: true` biases selection toward frames tagged `code` or `design`, while the `wild` tag guarantees at least one unconventional frame appears in every run.

### 4. Register the Frame in FRAMES

Append your object to the exported `FRAMES` constant in [`src/frames.ts`](https://github.com/UditAkhourii/adhd/blob/main/src/frames.ts). Because the engine builds and shuffles the pool dynamically, insertion position does not matter.

### 5. Validate and Document

Run `npm test` or `npx jest` to catch compile-time errors, then run `npm run build` to confirm the TypeScript parser accepts the new object. Update [`documentation/frames.md`](https://github.com/UditAkhourii/adhd/blob/main/documentation/frames.md) and [`CONTRIBUTING.md`](https://github.com/UditAkhourii/adhd/blob/main/CONTRIBUTING.md) to keep the frame discoverable for downstream users.

## Extending the Tag System with New Domains

If the four built-in tags are insufficient, extend the `tags` union type in [`src/frames.ts`](https://github.com/UditAkhourii/adhd/blob/main/src/frames.ts) (line 13) to include your new domain identifier. After adding the tag value, apply it to any relevant frames. You must also update `selectFrames` in [`src/engine.ts`](https://github.com/UditAkhourii/adhd/blob/main/src/engine.ts) if you want the built-in selector to filter on the new tag; otherwise, invoke `selectFrames` manually with a custom filter to surface frames carrying the new tag during a run.

## Practical Code Examples

### Adding a Quantum-Hardware Frame

```typescript
// src/frames.ts – append to the FRAMES array
{
  id: "quantum-hw",
  label: "Quantum‑hardware architect",
  prompt:
    "You think in qubits, decoherence times, cryogenic constraints, and quantum gate fidelity. Re‑ask the problem as if it were a quantum‑hardware design challenge. Which physical limits, error‑correction schemes, or cryostat layouts surface?",
  tags: ["code", "wild"],   // “code” makes it eligible when codeMode=true, “wild” guarantees a slot
},

```

This frame injects domain-specific vocabulary—`qubits`, `decoherence`, `cryogenic`—into the LLM context. Because it carries both `"code"` and `"wild"` tags, the `selectFrames` logic will consider it during code-biased runs while the wild-card guarantee ensures it is not filtered out.

### Running the Ideation Pipeline

```typescript
import { run, renderText } from "adhd-agent";

const result = await run({
  problem: "How can we reduce latency in our distributed cache?",
  framesPerRun: 6,          // one extra slot will be filled by the new quantum frame if codeMode=true
  ideasPerFrame: 5,
  topK: 3,
  codeMode: true,
});

console.log(renderText(result));

```

When `codeMode` is enabled, the engine biases the random pool toward frames tagged `"code"` or `"design"` according to `selectFrames` (lines 37-38). The quantum frame above qualifies under this bias and is guaranteed a slot by its `"wild"` tag.

### Creating a Brand-New Domain Tag

```typescript
// src/frames.ts – extend the Frame type first
export type Frame = {
  id: string;
  label: string;
  prompt: string;
  tags: ("code" | "design" | "general" | "wild" | "bio")[];
};

// Then add a frame that uses the new tag
{
  id: "bio-sensor",
  label: "Bio‑sensor designer",
  prompt:
    "You design biosensors that translate biological signals into electronic readouts. Re‑frame the problem in terms of molecular detection, signal transduction, and biocompatibility.",
  tags: ["bio", "design"],
},

```

The built-in selector does not filter on `"bio"` by default, so standard runs with `codeMode: true` will not automatically include this frame unless you modify `selectFrames` or call it directly with a custom tag filter.

## Key Files and Selection Logic

- **[`src/frames.ts`](https://github.com/UditAkhourii/adhd/blob/main/src/frames.ts)** — Defines the `Frame` type and the `FRAMES` constant that feeds the engine.
- **[`src/engine.ts`](https://github.com/UditAkhourii/adhd/blob/main/src/engine.ts)** — Implements the divergent-then-convergent loop; `divergeBranch` (lines 54-57) injects frame prompts, and `selectFrames` (lines 37-38) applies tag-based filtering before the `shuffle` function (lines 24-31) randomizes the pool.
- **[`documentation/frames.md`](https://github.com/UditAkhourii/adhd/blob/main/documentation/frames.md)** — Documents built-in frames and authoring guidelines (lines 34-38).
- **[`documentation/api.md`](https://github.com/UditAkhourii/adhd/blob/main/documentation/api.md)** — Exposes the public `run` signature and CLI flags such as `framesPerRun` and `codeMode`.
- **[`CONTRIBUTING.md`](https://github.com/UditAkhourii/adhd/blob/main/CONTRIBUTING.md)** — Contains the contributor checklist for testing and documentation updates.

## Summary

- ADHD frames are lightweight operators defined in [`src/frames.ts`](https://github.com/UditAkhourii/adhd/blob/main/src/frames.ts) that require an `id`, `label`, `prompt`, and `tags`.
- To author custom frames with domain-specific tags for specialized ideation, append a typed object to the `FRAMES` array and optionally extend the tag union type.
- The `prompt` is injected into every divergent LLM call via `divergeBranch` in [`src/engine.ts`](https://github.com/UditAkhourii/adhd/blob/main/src/engine.ts), so it must capture the target domain's core vocabulary.
- Built-in tags (`code`, `design`, `general`, `wild`) control selection bias in `selectFrames`; `wild` guarantees inclusion, while `codeMode` biases toward `code` and `design`.
- Always run `npm run build` and `npm test` after modifications, then update [`documentation/frames.md`](https://github.com/UditAkhourii/adhd/blob/main/documentation/frames.md) and [`CONTRIBUTING.md`](https://github.com/UditAkhourii/adhd/blob/main/CONTRIBUTING.md).

## Frequently Asked Questions

### What file do I edit to add a new frame in ADHD?

Edit [`src/frames.ts`](https://github.com/UditAkhourii/adhd/blob/main/src/frames.ts). This file exports the `FRAMES` constant and defines the `Frame` type used by the engine. Append your new frame object to the array and ensure it conforms to the TypeScript interface so the compiler validates the shape at build time.

### How do domain-specific tags affect which frames are selected?

Tags control the filtering logic inside `selectFrames` in [`src/engine.ts`](https://github.com/UditAkhourii/adhd/blob/main/src/engine.ts) (lines 37-38). When `codeMode` is enabled, the engine preferentially selects frames tagged `"code"` or `"design"`. The `"wild"` tag overrides exclusion and guarantees at least one unconventional frame per run.

### Can I create a completely new tag outside the built-in set?

Yes. Extend the `tags` union type in [`src/frames.ts`](https://github.com/UditAkhourii/adhd/blob/main/src/frames.ts) (line 13) to include your new string literal, then assign it to any frame. Note that the built-in `selectFrames` logic will not automatically filter on custom tags unless you update the selection function or invoke it directly with a custom filter.

### Does the order of frames in the FRAMES array matter?

No. The engine calls the `shuffle` function (lines 24-31 of [`src/engine.ts`](https://github.com/UditAkhourii/adhd/blob/main/src/engine.ts)) on the frame pool before sampling, so insertion order has no effect on runtime selection probability.