From 9e6d2430e8aee4291d82c532e51b64c208e31810 Mon Sep 17 00:00:00 2001 From: Khaliq Date: Tue, 17 Mar 2026 10:01:05 +0100 Subject: [PATCH 1/5] docs: clarify that relay coordination works with natural language, not just slash commands Add a paragraph explaining that slash commands are prompt templates (a convenience, not a requirement) and a new "Natural language usage" subsection with examples of plain-language prompts that trigger the same coordination machinery. Co-Authored-By: Claude Opus 4.6 (1M context) --- plugins/claude-relay-plugin/README.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/plugins/claude-relay-plugin/README.md b/plugins/claude-relay-plugin/README.md index 9359a7b94..b1d7bc8e6 100644 --- a/plugins/claude-relay-plugin/README.md +++ b/plugins/claude-relay-plugin/README.md @@ -98,6 +98,24 @@ Use the built-in skills to orchestrate multi-agent work: - **`/relay-fanout`** — Best for embarrassingly parallel work (same task across different targets). Workers run independently with no inter-dependencies. - **`/relay-pipeline`** — Best for sequential work where each stage depends on the previous one's output. Stages run one at a time with explicit handoffs. +These slash commands are prompt templates — they load orchestration instructions into Claude's context as a convenience. They are not the only way to trigger relay coordination. You can also describe what you want in plain language and Claude will set up the workspace, spawn relay-workers, and coordinate them. The plugin's hooks and agent definitions handle the infrastructure automatically regardless of how the request is phrased. + +### Natural language usage + +You don't need slash commands to coordinate agents. Any prompt that describes multi-agent work will trigger the same coordination machinery: + +``` +> Use relay fan-out to lint all packages in parallel + +> Split the migration into three relay workers — one for the database schema, + one for the API routes, and one for the frontend types + +> Set up a relay pipeline: first gather all TODO comments in the codebase, + then categorize them by priority, then open GitHub issues for the top 10 +``` + +Claude recognizes these requests because the plugin's skills, hooks, and agent definitions are already loaded. The slash commands are simply a shortcut for loading the same instructions. + ### How agent spawning works The plugin uses two separate mechanisms — **Claude Code's Agent tool** for spawning processes, and **Relay** for communication between them: From dd6be86435e0e1981fc7ac2d4ac030dd8c48fd17 Mon Sep 17 00:00:00 2001 From: Khaliq Date: Tue, 17 Mar 2026 10:04:55 +0100 Subject: [PATCH 2/5] docs: add marketplace install command to relay plugin README Add `/plugin marketplace add Agentworkforce/relay` as the primary installation method, keeping the manual copy/symlink approach as an alternative. Co-Authored-By: Claude Opus 4.6 (1M context) --- plugins/claude-relay-plugin/README.md | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/plugins/claude-relay-plugin/README.md b/plugins/claude-relay-plugin/README.md index b1d7bc8e6..3a7b09d07 100644 --- a/plugins/claude-relay-plugin/README.md +++ b/plugins/claude-relay-plugin/README.md @@ -16,7 +16,17 @@ This plugin connects Claude Code agents to [Agent Relay](https://agent-relay.com ### 1. Install the plugin -Copy or symlink the plugin into your project: +The easiest way to install is via the Claude Code plugin marketplace: + +``` +/plugin marketplace add Agentworkforce/relay +``` + +This downloads and configures the plugin automatically. + +**Alternative: manual install** + +If you prefer, you can copy or symlink the plugin into your project: ```bash cp -r plugins/claude-relay-plugin /path/to/your/project/.claude-plugin From 6f88db5683fcef93b8e40362060ea15abf09e260 Mon Sep 17 00:00:00 2001 From: Khaliq Date: Tue, 17 Mar 2026 10:10:19 +0100 Subject: [PATCH 3/5] docs: add Claude Code plugin section to README and docs Add a "Claude Code Plugin" section showing the marketplace install command, slash commands, and natural language usage to: - Top-level README.md - docs/introduction.mdx (Mintlify) - docs/markdown/introduction.md (plain markdown mirror) Co-Authored-By: Claude Opus 4.6 (1M context) --- README.md | 25 +++++++++++++++++++++++++ docs/introduction.mdx | 23 +++++++++++++++++++++++ docs/markdown/introduction.md | 25 +++++++++++++++++++++++++ 3 files changed, 73 insertions(+) diff --git a/README.md b/README.md index b3bb3539d..9d671b2f0 100644 --- a/README.md +++ b/README.md @@ -67,6 +67,31 @@ await AgentRelay.waitForAny([x, o], FIVE_MINUTES); await relay.shutdown(); ``` +## Claude Code Plugin + +Use Agent Relay directly inside Claude Code — no SDK required. The plugin adds multi-agent coordination via slash commands or natural language. + +``` +/plugin marketplace add Agentworkforce/relay +``` + +Once installed, coordinate agents with built-in skills: + +``` +> /relay-team Refactor the auth module — split the middleware, update tests, and update docs +> /relay-fanout Run linting fixes across all packages in the monorepo +> /relay-pipeline Analyze the API logs, then generate a summary report, then draft an email +``` + +Or just describe what you want in plain language: + +``` +> Use relay fan-out to lint all packages in parallel +> Split the migration into three relay workers — one for the schema, one for the API, one for the frontend +``` + +See the [plugin README](plugins/claude-relay-plugin/README.md) for full details. + ## Supported CLI’s - Claude - Codex diff --git a/docs/introduction.mdx b/docs/introduction.mdx index 032bb2406..97cff8dfe 100644 --- a/docs/introduction.mdx +++ b/docs/introduction.mdx @@ -75,6 +75,29 @@ const config = onRelay('MyAgent', piConfig, new Relay('MyAgent')); +## Claude Code Plugin + +Use Agent Relay directly inside Claude Code — no SDK required. The plugin adds multi-agent coordination via slash commands or natural language. + +``` +/plugin marketplace add Agentworkforce/relay +``` + +Once installed, coordinate agents with built-in skills: + +``` +/relay-team Refactor the auth module — split the middleware, update tests, and update docs +/relay-fanout Run linting fixes across all packages in the monorepo +/relay-pipeline Analyze the API logs, then generate a summary report, then draft an email +``` + +Or just describe what you want in plain language — the plugin's hooks and agent definitions handle the infrastructure automatically: + +``` +Use relay fan-out to lint all packages in parallel +Split the migration into three relay workers — one for the schema, one for the API, one for the frontend +``` + ## LLM / Machine-Readable Docs These docs are also available as plain Markdown for LLMs, CLI tools, and programmatic access: diff --git a/docs/markdown/introduction.md b/docs/markdown/introduction.md index 72a36765a..b0bb57b51 100644 --- a/docs/markdown/introduction.md +++ b/docs/markdown/introduction.md @@ -28,6 +28,31 @@ pip install agent-relay-sdk - **Connect Frameworks** — Put OpenAI Agents, Claude SDK, Google ADK, Pi, Agno, Swarms, or CrewAI agents on the relay. - **Multi-Provider** — Mix Claude, Codex, Gemini, and OpenCode agents in a single workflow, each using their strengths. +## Claude Code Plugin + +Use Agent Relay directly inside Claude Code — no SDK required. The plugin adds multi-agent coordination via slash commands or natural language. + +``` +/plugin marketplace add Agentworkforce/relay +``` + +Once installed, coordinate agents with built-in skills: + +``` +/relay-team Refactor the auth module — split the middleware, update tests, and update docs +/relay-fanout Run linting fixes across all packages in the monorepo +/relay-pipeline Analyze the API logs, then generate a summary report, then draft an email +``` + +Or just describe what you want in plain language — the plugin's hooks and agent definitions handle the infrastructure automatically: + +``` +Use relay fan-out to lint all packages in parallel +Split the migration into three relay workers — one for the schema, one for the API, one for the frontend +``` + +See the [plugin README](https://github.com/AgentWorkforce/relay/tree/main/plugins/claude-relay-plugin) for full details. + ## LLM / Machine-Readable Docs You're reading the plain Markdown version. These docs mirror the [Mintlify site](https://docs.agent-relay.com) but are designed for LLMs, CLI tools, and programmatic access — no MDX components, no JavaScript. From e0e87998cb165230a6552e4fd8c3e84751008748 Mon Sep 17 00:00:00 2001 From: Khaliq Date: Tue, 17 Mar 2026 12:23:14 +0100 Subject: [PATCH 4/5] feat(config): add reasoning effort metadata to CLI model registry Add per-model reasoning effort levels and defaults to the CLI registry, codegen pipeline, and SDK exports. Includes ModelMetadata lookup maps, helper functions (getModelMetadata, getSupportedReasoningEfforts, getDefaultReasoningEffort), and tests. Co-Authored-By: Claude Opus 4.6 (1M context) --- packages/config/src/cli-registry.generated.ts | 226 +++++++++++++++++- packages/sdk/src/__tests__/models.test.ts | 61 +++++ packages/sdk/src/models.ts | 6 + packages/sdk/tsconfig.build.json | 5 + packages/shared/cli-registry.yaml | 14 ++ packages/shared/codegen-ts.mjs | 108 ++++++++- skills/writing-agent-relay-workflows/SKILL.md | 3 + 7 files changed, 412 insertions(+), 11 deletions(-) create mode 100644 packages/sdk/src/__tests__/models.test.ts diff --git a/packages/config/src/cli-registry.generated.ts b/packages/config/src/cli-registry.generated.ts index 8003982f0..a783d0c11 100644 --- a/packages/config/src/cli-registry.generated.ts +++ b/packages/config/src/cli-registry.generated.ts @@ -318,10 +318,22 @@ export const OpencodeModels = { export type OpencodeModel = (typeof OpencodeModels)[keyof typeof OpencodeModels]; -/** Model option type for UI dropdowns */ +/** Reasoning effort levels supported by model providers. */ +export const ReasoningEfforts = { + LOW: 'low', + MEDIUM: 'medium', + HIGH: 'high', + XHIGH: 'xhigh', +} as const; + +export type ReasoningEffort = (typeof ReasoningEfforts)[keyof typeof ReasoningEfforts]; + +/** Model option type for UI dropdowns and model capability metadata. */ export interface ModelOption { value: string; label: string; + reasoningEfforts?: ReasoningEffort[]; + defaultReasoningEffort?: ReasoningEffort; } /** @@ -337,13 +349,13 @@ export const CLAUDE_MODEL_OPTIONS: ModelOption[] = [ * Codex CLI model options for UI dropdowns. */ export const CODEX_MODEL_OPTIONS: ModelOption[] = [ - { value: 'gpt-5.4', label: 'GPT-5.4 — Latest frontier agentic coding model' }, - { value: 'gpt-5.3-codex', label: 'GPT-5.3 Codex — Frontier agentic coding model' }, - { value: 'gpt-5.3-codex-spark', label: 'GPT-5.3 Codex Spark — Ultra-fast coding model' }, - { value: 'gpt-5.2-codex', label: 'GPT-5.2 Codex — Frontier agentic coding model' }, - { value: 'gpt-5.2', label: 'GPT-5.2 — Frontier model, knowledge & reasoning' }, - { value: 'gpt-5.1-codex-max', label: 'GPT-5.1 Codex Max — Deep and fast reasoning' }, - { value: 'gpt-5.1-codex-mini', label: 'GPT-5.1 Codex Mini — Cheaper, faster' }, + { value: 'gpt-5.4', label: 'GPT-5.4 — Latest frontier agentic coding model', reasoningEfforts: ["low","medium","high","xhigh"], defaultReasoningEffort: 'xhigh' }, + { value: 'gpt-5.3-codex', label: 'GPT-5.3 Codex — Frontier agentic coding model', reasoningEfforts: ["low","medium","high","xhigh"], defaultReasoningEffort: 'xhigh' }, + { value: 'gpt-5.3-codex-spark', label: 'GPT-5.3 Codex Spark — Ultra-fast coding model', reasoningEfforts: ["low","medium","high","xhigh"], defaultReasoningEffort: 'xhigh' }, + { value: 'gpt-5.2-codex', label: 'GPT-5.2 Codex — Frontier agentic coding model', reasoningEfforts: ["low","medium","high","xhigh"], defaultReasoningEffort: 'xhigh' }, + { value: 'gpt-5.2', label: 'GPT-5.2 — Frontier model, knowledge & reasoning', reasoningEfforts: ["low","medium","high","xhigh"], defaultReasoningEffort: 'xhigh' }, + { value: 'gpt-5.1-codex-max', label: 'GPT-5.1 Codex Max — Deep and fast reasoning', reasoningEfforts: ["low","medium","high","xhigh"], defaultReasoningEffort: 'xhigh' }, + { value: 'gpt-5.1-codex-mini', label: 'GPT-5.1 Codex Mini — Cheaper, faster', reasoningEfforts: ["medium","high"], defaultReasoningEffort: 'high' }, ]; /** @@ -472,6 +484,154 @@ export const OPENCODE_MODEL_OPTIONS: ModelOption[] = [ { value: 'openai/o4-mini-deep-research', label: 'O4 Mini Deep Research' }, ]; +/** + * Claude Code model metadata keyed by model id. + */ +export const CLAUDE_MODEL_METADATA: Record = { + 'sonnet': { value: 'sonnet', label: 'Sonnet' }, + 'opus': { value: 'opus', label: 'Opus' }, + 'haiku': { value: 'haiku', label: 'Haiku' }, +}; + +/** + * Codex CLI model metadata keyed by model id. + */ +export const CODEX_MODEL_METADATA: Record = { + 'gpt-5.4': { value: 'gpt-5.4', label: 'GPT-5.4 — Latest frontier agentic coding model', reasoningEfforts: ["low","medium","high","xhigh"], defaultReasoningEffort: 'xhigh' }, + 'gpt-5.3-codex': { value: 'gpt-5.3-codex', label: 'GPT-5.3 Codex — Frontier agentic coding model', reasoningEfforts: ["low","medium","high","xhigh"], defaultReasoningEffort: 'xhigh' }, + 'gpt-5.3-codex-spark': { value: 'gpt-5.3-codex-spark', label: 'GPT-5.3 Codex Spark — Ultra-fast coding model', reasoningEfforts: ["low","medium","high","xhigh"], defaultReasoningEffort: 'xhigh' }, + 'gpt-5.2-codex': { value: 'gpt-5.2-codex', label: 'GPT-5.2 Codex — Frontier agentic coding model', reasoningEfforts: ["low","medium","high","xhigh"], defaultReasoningEffort: 'xhigh' }, + 'gpt-5.2': { value: 'gpt-5.2', label: 'GPT-5.2 — Frontier model, knowledge & reasoning', reasoningEfforts: ["low","medium","high","xhigh"], defaultReasoningEffort: 'xhigh' }, + 'gpt-5.1-codex-max': { value: 'gpt-5.1-codex-max', label: 'GPT-5.1 Codex Max — Deep and fast reasoning', reasoningEfforts: ["low","medium","high","xhigh"], defaultReasoningEffort: 'xhigh' }, + 'gpt-5.1-codex-mini': { value: 'gpt-5.1-codex-mini', label: 'GPT-5.1 Codex Mini — Cheaper, faster', reasoningEfforts: ["medium","high"], defaultReasoningEffort: 'high' }, +}; + +/** + * Gemini CLI model metadata keyed by model id. + */ +export const GEMINI_MODEL_METADATA: Record = { + 'gemini-3.1-pro-preview': { value: 'gemini-3.1-pro-preview', label: 'Gemini 3.1 Pro Preview' }, + 'gemini-3-flash-preview': { value: 'gemini-3-flash-preview', label: 'Gemini 3 Flash Preview' }, + 'gemini-2.5-pro': { value: 'gemini-2.5-pro', label: 'Gemini 2.5 Pro' }, + 'gemini-2.5-flash': { value: 'gemini-2.5-flash', label: 'Gemini 2.5 Flash' }, + 'gemini-2.5-flash-lite': { value: 'gemini-2.5-flash-lite', label: 'Gemini 2.5 Flash Lite' }, +}; + +/** + * Cursor model metadata keyed by model id. + */ +export const CURSOR_MODEL_METADATA: Record = { + 'opus-4.6-thinking': { value: 'opus-4.6-thinking', label: 'Claude 4.6 Opus (Thinking)' }, + 'opus-4.6': { value: 'opus-4.6', label: 'Claude 4.6 Opus' }, + 'opus-4.5': { value: 'opus-4.5', label: 'Claude 4.5 Opus' }, + 'opus-4.5-thinking': { value: 'opus-4.5-thinking', label: 'Claude 4.5 Opus (Thinking)' }, + 'sonnet-4.6': { value: 'sonnet-4.6', label: 'Claude 4.6 Sonnet' }, + 'sonnet-4.6-thinking': { value: 'sonnet-4.6-thinking', label: 'Claude 4.6 Sonnet (Thinking)' }, + 'sonnet-4.5': { value: 'sonnet-4.5', label: 'Claude 4.5 Sonnet' }, + 'sonnet-4.5-thinking': { value: 'sonnet-4.5-thinking', label: 'Claude 4.5 Sonnet (Thinking)' }, + 'composer-1.5': { value: 'composer-1.5', label: 'Composer 1.5' }, + 'composer-1': { value: 'composer-1', label: 'Composer 1' }, + 'gpt-5.4-xhigh': { value: 'gpt-5.4-xhigh', label: 'GPT-5.4 Extra High' }, + 'gpt-5.4-xhigh-fast': { value: 'gpt-5.4-xhigh-fast', label: 'GPT-5.4 Extra High Fast' }, + 'gpt-5.4-high': { value: 'gpt-5.4-high', label: 'GPT-5.4 High' }, + 'gpt-5.4-high-fast': { value: 'gpt-5.4-high-fast', label: 'GPT-5.4 High Fast' }, + 'gpt-5.4-medium': { value: 'gpt-5.4-medium', label: 'GPT-5.4' }, + 'gpt-5.4-medium-fast': { value: 'gpt-5.4-medium-fast', label: 'GPT-5.4 Fast' }, + 'gpt-5.4-low': { value: 'gpt-5.4-low', label: 'GPT-5.4 Low' }, + 'gpt-5.3-codex-xhigh': { value: 'gpt-5.3-codex-xhigh', label: 'GPT-5.3 Codex Extra High' }, + 'gpt-5.3-codex-xhigh-fast': { value: 'gpt-5.3-codex-xhigh-fast', label: 'GPT-5.3 Codex Extra High Fast' }, + 'gpt-5.3-codex-high': { value: 'gpt-5.3-codex-high', label: 'GPT-5.3 Codex High' }, + 'gpt-5.3-codex-high-fast': { value: 'gpt-5.3-codex-high-fast', label: 'GPT-5.3 Codex High Fast' }, + 'gpt-5.3-codex': { value: 'gpt-5.3-codex', label: 'GPT-5.3 Codex' }, + 'gpt-5.3-codex-fast': { value: 'gpt-5.3-codex-fast', label: 'GPT-5.3 Codex Fast' }, + 'gpt-5.3-codex-low': { value: 'gpt-5.3-codex-low', label: 'GPT-5.3 Codex Low' }, + 'gpt-5.3-codex-low-fast': { value: 'gpt-5.3-codex-low-fast', label: 'GPT-5.3 Codex Low Fast' }, + 'gpt-5.3-codex-spark-preview': { value: 'gpt-5.3-codex-spark-preview', label: 'GPT-5.3 Codex Spark' }, + 'gpt-5.2-codex-xhigh': { value: 'gpt-5.2-codex-xhigh', label: 'GPT-5.2 Codex Extra High' }, + 'gpt-5.2-codex-xhigh-fast': { value: 'gpt-5.2-codex-xhigh-fast', label: 'GPT-5.2 Codex Extra High Fast' }, + 'gpt-5.2-codex-high': { value: 'gpt-5.2-codex-high', label: 'GPT-5.2 Codex High' }, + 'gpt-5.2-codex-high-fast': { value: 'gpt-5.2-codex-high-fast', label: 'GPT-5.2 Codex High Fast' }, + 'gpt-5.2-codex': { value: 'gpt-5.2-codex', label: 'GPT-5.2 Codex' }, + 'gpt-5.2-codex-fast': { value: 'gpt-5.2-codex-fast', label: 'GPT-5.2 Codex Fast' }, + 'gpt-5.2-codex-low': { value: 'gpt-5.2-codex-low', label: 'GPT-5.2 Codex Low' }, + 'gpt-5.2-codex-low-fast': { value: 'gpt-5.2-codex-low-fast', label: 'GPT-5.2 Codex Low Fast' }, + 'gpt-5.2': { value: 'gpt-5.2', label: 'GPT-5.2' }, + 'gpt-5.2-high': { value: 'gpt-5.2-high', label: 'GPT-5.2 High' }, + 'gpt-5.1-codex-max': { value: 'gpt-5.1-codex-max', label: 'GPT-5.1 Codex Max' }, + 'gpt-5.1-codex-max-high': { value: 'gpt-5.1-codex-max-high', label: 'GPT-5.1 Codex Max High' }, + 'gpt-5.1-codex-mini': { value: 'gpt-5.1-codex-mini', label: 'GPT-5.1 Codex Mini' }, + 'gpt-5.1-high': { value: 'gpt-5.1-high', label: 'GPT-5.1 High' }, + 'gemini-3.1-pro': { value: 'gemini-3.1-pro', label: 'Gemini 3.1 Pro' }, + 'gemini-3-pro': { value: 'gemini-3-pro', label: 'Gemini 3 Pro' }, + 'gemini-3-flash': { value: 'gemini-3-flash', label: 'Gemini 3 Flash' }, + 'grok': { value: 'grok', label: 'Grok' }, + 'kimi-k2.5': { value: 'kimi-k2.5', label: 'Kimi K2.5' }, +}; + +/** + * Droid model metadata keyed by model id. + */ +export const DROID_MODEL_METADATA: Record = { + 'opus-4.6-fast': { value: 'opus-4.6-fast', label: 'Opus 4.6 Fast Mode (12x)' }, + 'opus-4.5': { value: 'opus-4.5', label: 'Opus 4.5 (2x)' }, + 'sonnet-4.5': { value: 'sonnet-4.5', label: 'Sonnet 4.5 (1.2x)' }, + 'haiku-4.5': { value: 'haiku-4.5', label: 'Haiku 4.5 (0.4x)' }, + 'gpt-5.2': { value: 'gpt-5.2', label: 'GPT-5.2 (0.7x)' }, + 'gpt-5.2-codex': { value: 'gpt-5.2-codex', label: 'GPT-5.2 Codex (0.7x)' }, + 'gemini-3-flash': { value: 'gemini-3-flash', label: 'Gemini 3 Flash (0.2x)' }, + 'droid-core-glm-4.7': { value: 'droid-core-glm-4.7', label: 'Droid Core (GLM-4.7) (0.25x)' }, +}; + +/** + * OpenCode model metadata keyed by model id. + */ +export const OPENCODE_MODEL_METADATA: Record = { + 'opencode/big-pickle': { value: 'opencode/big-pickle', label: 'Big Pickle' }, + 'opencode/gpt-5-nano': { value: 'opencode/gpt-5-nano', label: 'GPT-5 Nano (OpenCode)' }, + 'opencode/mimo-v2-flash-free': { value: 'opencode/mimo-v2-flash-free', label: 'Mimo V2 Flash Free' }, + 'opencode/minimax-m2.5-free': { value: 'opencode/minimax-m2.5-free', label: 'MiniMax M2.5 Free' }, + 'openai/codex-mini-latest': { value: 'openai/codex-mini-latest', label: 'Codex Mini Latest' }, + 'openai/gpt-3.5-turbo': { value: 'openai/gpt-3.5-turbo', label: 'GPT-3.5 Turbo' }, + 'openai/gpt-4': { value: 'openai/gpt-4', label: 'GPT-4' }, + 'openai/gpt-4-turbo': { value: 'openai/gpt-4-turbo', label: 'GPT-4 Turbo' }, + 'openai/gpt-4.1': { value: 'openai/gpt-4.1', label: 'GPT-4.1' }, + 'openai/gpt-4.1-mini': { value: 'openai/gpt-4.1-mini', label: 'GPT-4.1 Mini' }, + 'openai/gpt-4.1-nano': { value: 'openai/gpt-4.1-nano', label: 'GPT-4.1 Nano' }, + 'openai/gpt-4o': { value: 'openai/gpt-4o', label: 'GPT-4o' }, + 'openai/gpt-4o-2024-05-13': { value: 'openai/gpt-4o-2024-05-13', label: 'GPT-4o (2024-05-13)' }, + 'openai/gpt-4o-2024-08-06': { value: 'openai/gpt-4o-2024-08-06', label: 'GPT-4o (2024-08-06)' }, + 'openai/gpt-4o-2024-11-20': { value: 'openai/gpt-4o-2024-11-20', label: 'GPT-4o (2024-11-20)' }, + 'openai/gpt-4o-mini': { value: 'openai/gpt-4o-mini', label: 'GPT-4o Mini' }, + 'openai/gpt-5': { value: 'openai/gpt-5', label: 'GPT-5' }, + 'openai/gpt-5-codex': { value: 'openai/gpt-5-codex', label: 'GPT-5 Codex' }, + 'openai/gpt-5-mini': { value: 'openai/gpt-5-mini', label: 'GPT-5 Mini' }, + 'openai/gpt-5-nano': { value: 'openai/gpt-5-nano', label: 'GPT-5 Nano' }, + 'openai/gpt-5-pro': { value: 'openai/gpt-5-pro', label: 'GPT-5 Pro' }, + 'openai/gpt-5.1': { value: 'openai/gpt-5.1', label: 'GPT-5.1' }, + 'openai/gpt-5.1-chat-latest': { value: 'openai/gpt-5.1-chat-latest', label: 'GPT-5.1 Chat Latest' }, + 'openai/gpt-5.1-codex': { value: 'openai/gpt-5.1-codex', label: 'GPT-5.1 Codex' }, + 'openai/gpt-5.1-codex-max': { value: 'openai/gpt-5.1-codex-max', label: 'GPT-5.1 Codex Max' }, + 'openai/gpt-5.1-codex-mini': { value: 'openai/gpt-5.1-codex-mini', label: 'GPT-5.1 Codex Mini' }, + 'openai/gpt-5.2': { value: 'openai/gpt-5.2', label: 'GPT-5.2' }, + 'openai/gpt-5.2-chat-latest': { value: 'openai/gpt-5.2-chat-latest', label: 'GPT-5.2 Chat Latest' }, + 'openai/gpt-5.2-codex': { value: 'openai/gpt-5.2-codex', label: 'GPT-5.2 Codex' }, + 'openai/gpt-5.2-pro': { value: 'openai/gpt-5.2-pro', label: 'GPT-5.2 Pro' }, + 'openai/gpt-5.3-codex': { value: 'openai/gpt-5.3-codex', label: 'GPT-5.3 Codex' }, + 'openai/gpt-5.3-codex-spark': { value: 'openai/gpt-5.3-codex-spark', label: 'GPT-5.3 Codex Spark' }, + 'openai/gpt-5.4': { value: 'openai/gpt-5.4', label: 'GPT-5.4' }, + 'openai/gpt-5.4-pro': { value: 'openai/gpt-5.4-pro', label: 'GPT-5.4 Pro' }, + 'openai/o1': { value: 'openai/o1', label: 'O1' }, + 'openai/o1-mini': { value: 'openai/o1-mini', label: 'O1 Mini' }, + 'openai/o1-preview': { value: 'openai/o1-preview', label: 'O1 Preview' }, + 'openai/o1-pro': { value: 'openai/o1-pro', label: 'O1 Pro' }, + 'openai/o3': { value: 'openai/o3', label: 'O3' }, + 'openai/o3-deep-research': { value: 'openai/o3-deep-research', label: 'O3 Deep Research' }, + 'openai/o3-mini': { value: 'openai/o3-mini', label: 'O3 Mini' }, + 'openai/o3-pro': { value: 'openai/o3-pro', label: 'O3 Pro' }, + 'openai/o4-mini': { value: 'openai/o4-mini', label: 'O4 Mini' }, + 'openai/o4-mini-deep-research': { value: 'openai/o4-mini-deep-research', label: 'O4 Mini Deep Research' }, +}; + /** * All models grouped by CLI tool. * @@ -513,6 +673,56 @@ export const ModelOptions = { Opencode: OPENCODE_MODEL_OPTIONS, } as const; +/** + * All model metadata grouped by CLI tool and keyed by model id. + */ +export const ModelMetadata = { + Claude: CLAUDE_MODEL_METADATA, + Codex: CODEX_MODEL_METADATA, + Gemini: GEMINI_MODEL_METADATA, + Cursor: CURSOR_MODEL_METADATA, + Droid: DROID_MODEL_METADATA, + Opencode: OPENCODE_MODEL_METADATA, +} as const; + +const MODEL_METADATA_BY_CLI: Record> = { + claude: CLAUDE_MODEL_METADATA, + codex: CODEX_MODEL_METADATA, + gemini: GEMINI_MODEL_METADATA, + cursor: CURSOR_MODEL_METADATA, + droid: DROID_MODEL_METADATA, + opencode: OPENCODE_MODEL_METADATA, + aider: {}, + goose: {}, +}; + +/** + * Look up metadata for a specific CLI/model pair. + */ +export function getModelMetadata(cli: CLI, model: string): ModelOption | undefined { + return MODEL_METADATA_BY_CLI[cli]?.[model]; +} + +/** + * Supported reasoning effort values for a specific CLI/model pair. + */ +export function getSupportedReasoningEfforts( + cli: CLI, + model: string +): ReasoningEffort[] | undefined { + return getModelMetadata(cli, model)?.reasoningEfforts; +} + +/** + * Default reasoning effort for a specific CLI/model pair. + */ +export function getDefaultReasoningEffort( + cli: CLI, + model: string +): ReasoningEffort | undefined { + return getModelMetadata(cli, model)?.defaultReasoningEffort; +} + /** * Swarm patterns for multi-agent workflows. */ diff --git a/packages/sdk/src/__tests__/models.test.ts b/packages/sdk/src/__tests__/models.test.ts new file mode 100644 index 000000000..489220258 --- /dev/null +++ b/packages/sdk/src/__tests__/models.test.ts @@ -0,0 +1,61 @@ +/** + * Model metadata tests. + * + * Run: + * npm run build && node --test dist/__tests__/models.test.js + */ +import assert from 'node:assert/strict'; +import test from 'node:test'; + +import { + ModelMetadata, + ModelOptions, + Models, + ReasoningEfforts, + getDefaultReasoningEffort, + getModelMetadata, + getSupportedReasoningEfforts, +} from '../models.js'; + +test('codex model options include reasoning effort metadata', () => { + const mini = ModelOptions.Codex.find((model) => model.value === Models.Codex.GPT_5_1_CODEX_MINI); + const frontier = ModelOptions.Codex.find((model) => model.value === Models.Codex.GPT_5_4); + + assert.deepEqual(mini?.reasoningEfforts, [ReasoningEfforts.MEDIUM, ReasoningEfforts.HIGH]); + assert.equal(mini?.defaultReasoningEffort, ReasoningEfforts.HIGH); + + assert.deepEqual(frontier?.reasoningEfforts, [ + ReasoningEfforts.LOW, + ReasoningEfforts.MEDIUM, + ReasoningEfforts.HIGH, + ReasoningEfforts.XHIGH, + ]); + assert.equal(frontier?.defaultReasoningEffort, ReasoningEfforts.XHIGH); +}); + +test('reasoning helper lookups return codex defaults and supported values', () => { + assert.equal( + getDefaultReasoningEffort('codex', Models.Codex.GPT_5_1_CODEX_MINI), + ReasoningEfforts.HIGH, + ); + assert.equal( + getDefaultReasoningEffort('codex', Models.Codex.GPT_5_4), + ReasoningEfforts.XHIGH, + ); + assert.deepEqual( + getSupportedReasoningEfforts('codex', Models.Codex.GPT_5_1_CODEX_MINI), + [ReasoningEfforts.MEDIUM, ReasoningEfforts.HIGH], + ); + assert.equal(getDefaultReasoningEffort('claude', Models.Claude.SONNET), undefined); +}); + +test('model metadata is keyed by model id for direct lookup', () => { + assert.deepEqual( + ModelMetadata.Codex[Models.Codex.GPT_5_1_CODEX_MINI], + getModelMetadata('codex', Models.Codex.GPT_5_1_CODEX_MINI), + ); + assert.equal( + ModelMetadata.Codex[Models.Codex.GPT_5_1_CODEX_MINI].defaultReasoningEffort, + ReasoningEfforts.HIGH, + ); +}); diff --git a/packages/sdk/src/models.ts b/packages/sdk/src/models.ts index 600053fbb..3dfc29b96 100644 --- a/packages/sdk/src/models.ts +++ b/packages/sdk/src/models.ts @@ -11,6 +11,7 @@ export { CLIs, CLIVersions, CLIRegistry, + ReasoningEfforts, // Model constants ClaudeModels, CodexModels, @@ -23,7 +24,11 @@ export { CODEX_MODEL_OPTIONS, GEMINI_MODEL_OPTIONS, CURSOR_MODEL_OPTIONS, + ModelMetadata, ModelOptions, + getDefaultReasoningEffort, + getModelMetadata, + getSupportedReasoningEfforts, // Swarm patterns (type is in workflows/types.ts) SwarmPatterns, // Types @@ -33,4 +38,5 @@ export { type GeminiModel, type CursorModel, type ModelOption, + type ReasoningEffort, } from '@agent-relay/config'; diff --git a/packages/sdk/tsconfig.build.json b/packages/sdk/tsconfig.build.json index bf9f9c577..b9a0e835b 100644 --- a/packages/sdk/tsconfig.build.json +++ b/packages/sdk/tsconfig.build.json @@ -3,6 +3,11 @@ "target": "ES2022", "module": "ES2022", "moduleResolution": "Bundler", + "baseUrl": ".", + "paths": { + "@agent-relay/config": ["../config/dist/index.d.ts"], + "@agent-relay/config/*": ["../config/dist/*"] + }, "strict": true, "declaration": true, "declarationMap": true, diff --git a/packages/shared/cli-registry.yaml b/packages/shared/cli-registry.yaml index 357825850..11852a93b 100644 --- a/packages/shared/cli-registry.yaml +++ b/packages/shared/cli-registry.yaml @@ -37,24 +37,38 @@ clis: id: "gpt-5.4" label: "GPT-5.4 — Latest frontier agentic coding model" default: true + reasoning_efforts: ["low", "medium", "high", "xhigh"] + default_reasoning_effort: "xhigh" gpt_5_3_codex: id: "gpt-5.3-codex" label: "GPT-5.3 Codex — Frontier agentic coding model" + reasoning_efforts: ["low", "medium", "high", "xhigh"] + default_reasoning_effort: "xhigh" gpt_5_3_codex_spark: id: "gpt-5.3-codex-spark" label: "GPT-5.3 Codex Spark — Ultra-fast coding model" + reasoning_efforts: ["low", "medium", "high", "xhigh"] + default_reasoning_effort: "xhigh" gpt_5_2_codex: id: "gpt-5.2-codex" label: "GPT-5.2 Codex — Frontier agentic coding model" + reasoning_efforts: ["low", "medium", "high", "xhigh"] + default_reasoning_effort: "xhigh" gpt_5_2: id: "gpt-5.2" label: "GPT-5.2 — Frontier model, knowledge & reasoning" + reasoning_efforts: ["low", "medium", "high", "xhigh"] + default_reasoning_effort: "xhigh" gpt_5_1_codex_max: id: "gpt-5.1-codex-max" label: "GPT-5.1 Codex Max — Deep and fast reasoning" + reasoning_efforts: ["low", "medium", "high", "xhigh"] + default_reasoning_effort: "xhigh" gpt_5_1_codex_mini: id: "gpt-5.1-codex-mini" label: "GPT-5.1 Codex Mini — Cheaper, faster" + reasoning_efforts: ["medium", "high"] + default_reasoning_effort: "high" gemini: name: "Gemini CLI" diff --git a/packages/shared/codegen-ts.mjs b/packages/shared/codegen-ts.mjs index 5a3e8404f..f39462c98 100644 --- a/packages/shared/codegen-ts.mjs +++ b/packages/shared/codegen-ts.mjs @@ -25,6 +25,19 @@ function toConstantCase(str) { return str.toUpperCase().replace(/-/g, '_'); } +function formatModelOption(modelConfig) { + const parts = [`value: '${modelConfig.id}'`, `label: '${modelConfig.label || modelConfig.id}'`]; + + if (Array.isArray(modelConfig.reasoning_efforts) && modelConfig.reasoning_efforts.length > 0) { + parts.push(`reasoningEfforts: ${JSON.stringify(modelConfig.reasoning_efforts)}`); + } + if (modelConfig.default_reasoning_effort) { + parts.push(`defaultReasoningEffort: '${modelConfig.default_reasoning_effort}'`); + } + + return `{ ${parts.join(', ')} }`; +} + let output = `/** * CLI Registry - AUTO-GENERATED FILE - DO NOT EDIT * Generated from packages/shared/cli-registry.yaml @@ -91,10 +104,22 @@ export type ${pascalCli}Model = (typeof ${pascalCli}Models)[keyof typeof ${pasca } // Generate model options per CLI (for dashboard dropdowns) -output += `/** Model option type for UI dropdowns */ +output += `/** Reasoning effort levels supported by model providers. */ +export const ReasoningEfforts = { + LOW: 'low', + MEDIUM: 'medium', + HIGH: 'high', + XHIGH: 'xhigh', +} as const; + +export type ReasoningEffort = (typeof ReasoningEfforts)[keyof typeof ReasoningEfforts]; + +/** Model option type for UI dropdowns and model capability metadata. */ export interface ModelOption { value: string; label: string; + reasoningEfforts?: ReasoningEffort[]; + defaultReasoningEffort?: ReasoningEffort; } `; @@ -110,8 +135,7 @@ for (const [cli, config] of Object.entries(registry.clis)) { export const ${constantCli}_MODEL_OPTIONS: ModelOption[] = [ `; for (const [, modelConfig] of Object.entries(models)) { - const label = modelConfig.label || modelConfig.id; - output += ` { value: '${modelConfig.id}', label: '${label}' },\n`; + output += ` ${formatModelOption(modelConfig)},\n`; } output += `]; @@ -119,6 +143,27 @@ export const ${constantCli}_MODEL_OPTIONS: ModelOption[] = [ } } +// Generate model metadata per CLI (keyed by model id) +for (const [cli, config] of Object.entries(registry.clis)) { + const pascalCli = toPascalCase(cli); + const constantCli = toConstantCase(cli); + const models = config.models || {}; + + if (Object.keys(models).length > 0) { + output += `/** + * ${config.name} model metadata keyed by model id. + */ +export const ${constantCli}_MODEL_METADATA: Record<${pascalCli}Model, ModelOption> = { +`; + for (const [, modelConfig] of Object.entries(models)) { + output += ` '${modelConfig.id}': ${formatModelOption(modelConfig)},\n`; + } + output += `}; + +`; + } +} + // Generate combined Models object output += `/** * All models grouped by CLI tool. @@ -171,6 +216,63 @@ output += `} as const; `; +output += `/** + * All model metadata grouped by CLI tool and keyed by model id. + */ +export const ModelMetadata = { +`; +for (const [cli, config] of Object.entries(registry.clis)) { + const pascalCli = toPascalCase(cli); + const constantCli = toConstantCase(cli); + const models = config.models || {}; + if (Object.keys(models).length > 0) { + output += ` ${pascalCli}: ${constantCli}_MODEL_METADATA,\n`; + } +} +output += `} as const; + +const MODEL_METADATA_BY_CLI: Record> = { +`; +for (const [cli, config] of Object.entries(registry.clis)) { + const constantCli = toConstantCase(cli); + const models = config.models || {}; + if (Object.keys(models).length > 0) { + output += ` ${cli}: ${constantCli}_MODEL_METADATA,\n`; + } else { + output += ` ${cli}: {},\n`; + } +} +output += `}; + +/** + * Look up metadata for a specific CLI/model pair. + */ +export function getModelMetadata(cli: CLI, model: string): ModelOption | undefined { + return MODEL_METADATA_BY_CLI[cli]?.[model]; +} + +/** + * Supported reasoning effort values for a specific CLI/model pair. + */ +export function getSupportedReasoningEfforts( + cli: CLI, + model: string +): ReasoningEffort[] | undefined { + return getModelMetadata(cli, model)?.reasoningEfforts; +} + +/** + * Default reasoning effort for a specific CLI/model pair. + */ +export function getDefaultReasoningEffort( + cli: CLI, + model: string +): ReasoningEffort | undefined { + return getModelMetadata(cli, model)?.defaultReasoningEffort; +} + +`; + // Generate swarm patterns output += `/** * Swarm patterns for multi-agent workflows. diff --git a/skills/writing-agent-relay-workflows/SKILL.md b/skills/writing-agent-relay-workflows/SKILL.md index dc6246024..9573eee51 100644 --- a/skills/writing-agent-relay-workflows/SKILL.md +++ b/skills/writing-agent-relay-workflows/SKILL.md @@ -601,6 +601,9 @@ But if the owner doesn't post either format, the runner still resolves completio | Using `fan-out`/`hub-spoke` for simple parallel workers | Use `dag` — hub patterns trigger auto owner/supervisor/reviewer pipeline | | Workers without `preset: 'worker'` in lead+worker workflows | Add `preset: 'worker'` — it auto-sets `interactive: false` and produces clean stdout for `{{steps.X.output}}` injection | | Lead running concurrently with workers, monitoring channel | Make lead `dependsOn` workers — use `{{steps.X.output}}` injection instead of real-time channel monitoring | +| Using `_` in YAML numbers (e.g., `timeoutMs: 1_200_000`) | YAML doesn't support `_` as a numeric separator — use `1200000`. TypeScript separators don't work in YAML | +| Setting workflow timeout under 30 minutes for complex workflows | Claude leads reading large codebases take 5-15 min per step. Use `3600000` (1 hour) as a safe default | +| Passing too much context in `read-context` deterministic steps | Trim to only the relevant code. Use `grep`, `sed -n`, `head` instead of full `cat`. Large context slows lead design | ## Verification Tokens with Non-Interactive Workers From 5213a5eb725ac99240acc001997d15c2db5505fb Mon Sep 17 00:00:00 2001 From: Khaliq Date: Tue, 17 Mar 2026 12:35:23 +0100 Subject: [PATCH 5/5] bump --- prpm.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/prpm.json b/prpm.json index d645669c8..289c78552 100644 --- a/prpm.json +++ b/prpm.json @@ -46,7 +46,7 @@ }, { "name": "writing-agent-relay-workflows", - "version": "1.0.2", + "version": "1.0.3", "description": "Use when building multi-agent workflows with the relay broker-sdk - covers the WorkflowBuilder API, DAG step dependencies, agent definitions, step output chaining via {{steps.X.output}}, verification gates, deterministic steps, dedicated channels, swarm patterns, error handling, event listeners, step sizing rules, and the lead+workers team pattern for complex steps", "format": "claude", "subtype": "skill",