@prateek_ai/agents-maker 1.0.0 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. package/PROMPT_TEMPLATE.md +143 -0
  2. package/README.md +92 -25
  3. package/agents/brain.md +90 -0
  4. package/agents/orchestrator.md +24 -3
  5. package/agents/planpro.md +91 -0
  6. package/bin/cli.js +40 -4
  7. package/claude/agents/architect.md +182 -0
  8. package/claude/agents/brain.md +97 -0
  9. package/claude/agents/code.md +185 -0
  10. package/claude/agents/compress.md +233 -0
  11. package/claude/agents/execute.md +164 -0
  12. package/claude/agents/orchestrate.md +434 -0
  13. package/claude/agents/planpro.md +98 -0
  14. package/claude/agents/review.md +141 -0
  15. package/claude/agents/ui.md +154 -0
  16. package/claude/agents/ux.md +151 -0
  17. package/claude/commands/architect.md +15 -0
  18. package/claude/commands/brain.md +15 -0
  19. package/claude/commands/code.md +15 -0
  20. package/claude/commands/compress.md +15 -0
  21. package/claude/commands/execute.md +15 -0
  22. package/claude/commands/orchestrate.md +15 -0
  23. package/claude/commands/planpro.md +15 -0
  24. package/claude/commands/review.md +15 -0
  25. package/claude/commands/ui.md +15 -0
  26. package/claude/commands/ux.md +15 -0
  27. package/config/agents.yaml +56 -0
  28. package/context_loaders/project_summary.py +5 -0
  29. package/docs/architecture.md +318 -0
  30. package/docs/domains.md +154 -0
  31. package/docs/workflows.md +548 -0
  32. package/examples/generic_project_lifecycle.md +518 -0
  33. package/examples/proof/README.md +138 -0
  34. package/examples/proof/implement-a-python-function-that-parses-an-iso-8/grade.md +14 -0
  35. package/examples/proof/implement-a-python-function-that-parses-an-iso-8/naive_output.md +211 -0
  36. package/examples/proof/implement-a-python-function-that-parses-an-iso-8/naive_prompt.txt +1 -0
  37. package/examples/proof/implement-a-python-function-that-parses-an-iso-8/structured_output.md +210 -0
  38. package/examples/proof/implement-a-python-function-that-parses-an-iso-8/structured_user.txt +35 -0
  39. package/examples/proof/write-a-runbook-for-recovering-from-a-redis-prim/grade.md +14 -0
  40. package/examples/proof/write-a-runbook-for-recovering-from-a-redis-prim/naive_output.md +274 -0
  41. package/examples/proof/write-a-runbook-for-recovering-from-a-redis-prim/naive_prompt.txt +1 -0
  42. package/examples/proof/write-a-runbook-for-recovering-from-a-redis-prim/structured_output.md +127 -0
  43. package/examples/proof/write-a-runbook-for-recovering-from-a-redis-prim/structured_user.txt +35 -0
  44. package/package.json +10 -2
  45. package/platforms/antigravity.md +195 -0
  46. package/platforms/claude.md +305 -0
  47. package/platforms/openai.md +333 -0
  48. package/skills/analyze_repo.md +86 -86
  49. package/token_optimization/compressor.py +4 -7
  50. package/tools/_core.py +102 -0
  51. package/tools/compare_prompts.py +196 -0
  52. package/tools/generate_claude_agents.py +162 -0
  53. package/tools/generate_claude_md.py +14 -80
  54. package/tools/generate_platform_configs.py +26 -36
  55. package/tools/generate_prompt.py +79 -79
  56. package/tools/grade_proof.py +118 -0
  57. package/tools/init_project.py +11 -58
  58. package/tools/routing.py +103 -0
  59. package/tools/test_kit.py +392 -363
  60. package/tools/validate_kit.py +15 -43
  61. package/context_loaders/__pycache__/__init__.cpython-314.pyc +0 -0
  62. package/context_loaders/__pycache__/file_chunker.cpython-314.pyc +0 -0
  63. package/context_loaders/__pycache__/project_summary.cpython-314.pyc +0 -0
  64. package/context_loaders/__pycache__/repo_tree.cpython-314.pyc +0 -0
  65. package/token_optimization/__pycache__/compressor.cpython-314.pyc +0 -0
  66. package/tools/__pycache__/domain_utils.cpython-314.pyc +0 -0
  67. package/tools/__pycache__/generate_claude_md.cpython-314.pyc +0 -0
  68. package/tools/__pycache__/validate_kit.cpython-314.pyc +0 -0
@@ -0,0 +1,305 @@
1
+ # Claude Integration Guide
2
+
3
+ How to use this kit with Anthropic Claude: Projects, Claude.ai, and the Anthropic API.
4
+
5
+ ---
6
+
7
+ ## Companion Mode (Recommended)
8
+
9
+ The fastest way to use this kit with Claude. Run two commands once, then one command before every session.
10
+
11
+ ### One-time setup (per project)
12
+
13
+ ```bash
14
+ # 1. Bootstrap the project
15
+ python agents-maker/tools/init_project.py
16
+
17
+ # 2. Paste system_prompt.md into Claude as the system prompt or Project Instructions
18
+ # (do this once — it contains all agents + skills pre-assembled)
19
+ ```
20
+
21
+ ### Before every session
22
+
23
+ ```bash
24
+ python agents-maker/tools/generate_prompt.py "what you want to work on"
25
+ ```
26
+
27
+ Copy the printed block and paste it as your next message to Claude. That's it.
28
+
29
+ **What you get back from Claude in Companion Mode:**
30
+
31
+ Every response ends with a structured block:
32
+ ```
33
+ ---
34
+ [Companion] Phase: implementation | Domain: software | Est. token budget: ~42%
35
+
36
+ What to do next (pick one):
37
+ [Recommended] A: Write unit tests for the new middleware
38
+ Command: python agents-maker/tools/generate_prompt.py "write tests for rate-limiting middleware"
39
+
40
+ B: Open Phase 4 review on the full auth service
41
+ C: Document rate-limit config in the runbook
42
+ ---
43
+ ```
44
+
45
+ You always know what to do next. Paste the `Command:` from option A to continue.
46
+
47
+ ---
48
+
49
+ ## Option A — Claude Projects (claude.ai)
50
+
51
+ Claude Projects lets you set a persistent system prompt. This is the recommended zero-code integration — one paste, no file uploads needed.
52
+
53
+ ### Setup steps
54
+
55
+ **1. Create a project**
56
+
57
+ In Claude.ai, create a new Project. Name it something like "Dev Assistant" or after your project.
58
+
59
+ **2. Set the Project Instructions**
60
+
61
+ Open Project Settings → Instructions. Paste the entire contents of `system_prompt.md` as the Project Instructions.
62
+
63
+ That's it — `system_prompt.md` contains all 8 agents and 12 skills pre-assembled (~28K tokens). No individual file uploads needed.
64
+
65
+ ```
66
+ # Copy the full contents of system_prompt.md and paste here:
67
+ cat agents-maker/system_prompt.md | pbcopy # macOS
68
+ type agents-maker\system_prompt.md | clip # Windows
69
+ ```
70
+
71
+ **3. Start a session**
72
+
73
+ Fill in `PROMPT_TEMPLATE.md` and paste it as your first message. Or use the CLI:
74
+
75
+ ```bash
76
+ python agents-maker/tools/generate_prompt.py "your task here"
77
+ # Copy the printed block → paste as your message
78
+ ```
79
+
80
+ ---
81
+
82
+ ### Keeping your system prompt current
83
+
84
+ When you add new agents or skills to the kit, regenerate `system_prompt.md` and repaste it into Project Instructions:
85
+
86
+ ```bash
87
+ python agents-maker/tools/init_project.py --update
88
+ # Then copy the updated system_prompt.md into Project Instructions
89
+ ```
90
+
91
+ Run `python tools/validate_kit.py` first to confirm all 8 integrity checks pass before regenerating.
92
+
93
+ ---
94
+
95
+ ## Option B — Claude API (programmatic)
96
+
97
+ ### Minimal example
98
+
99
+ ```python
100
+ import anthropic
101
+ from pathlib import Path
102
+
103
+ client = anthropic.Anthropic() # reads ANTHROPIC_API_KEY from env
104
+
105
+ def load_agent_kit() -> str:
106
+ """Load orchestrator + all agent specs + skills as system context."""
107
+ parts = []
108
+ for path in [
109
+ "agents/orchestrator.md",
110
+ "agents/code_agent.md",
111
+ "agents/ui_agent.md",
112
+ "agents/ux_agent.md",
113
+ "agents/architect_agent.md",
114
+ "agents/compression_agent.md",
115
+ ]:
116
+ parts.append(f"# {path}\n\n{Path(path).read_text()}")
117
+ for skill_file in Path("skills").glob("*.md"):
118
+ parts.append(f"# {skill_file}\n\n{skill_file.read_text()}")
119
+ return "\n\n---\n\n".join(parts)
120
+
121
+ system_prompt = load_agent_kit()
122
+
123
+ response = client.messages.create(
124
+ model="claude-sonnet-4-6",
125
+ max_tokens=4096,
126
+ system=system_prompt,
127
+ messages=[
128
+ {
129
+ "role": "user",
130
+ "content": (
131
+ "## Project State\n<paste project_summary.py output here>\n\n"
132
+ "Task: Add soft-delete to UserService."
133
+ ),
134
+ }
135
+ ],
136
+ )
137
+ print(response.content[0].text)
138
+ ```
139
+
140
+ ### With token optimization (using compressor.py)
141
+
142
+ ```python
143
+ from token_optimization.compressor import Compressor, ContextBlock, FileEntry, PolicyLoader
144
+ from context_loaders.repo_tree import list_files
145
+ from context_loaders.file_chunker import chunk_files
146
+
147
+ # Load policy
148
+ loader = PolicyLoader()
149
+ loader.load()
150
+ policy = loader.get_workflow_policy("feature_implementation")
151
+
152
+ # Build context block
153
+ files = chunk_files(list_files("/your/repo", filter_paths=["src/"]))
154
+ block = ContextBlock(
155
+ project_state=project_summary,
156
+ files=[FileEntry(path=f["path"], content=f["content"]) for f in files],
157
+ conversation_state=conversation_state,
158
+ active_query="Add soft-delete to UserService",
159
+ )
160
+
161
+ compressor = Compressor(policy)
162
+ compressed_context, report = compressor.compress(block)
163
+
164
+ # Send to Claude
165
+ response = client.messages.create(
166
+ model="claude-sonnet-4-6",
167
+ max_tokens=4096,
168
+ system=system_prompt,
169
+ messages=[{"role": "user", "content": compressed_context}],
170
+ )
171
+ ```
172
+
173
+ ---
174
+
175
+ ## Token-optimized defaults for Claude
176
+
177
+ ### Concise mode system prompt suffix
178
+
179
+ Append to the orchestrator system prompt to enable concise mode by default:
180
+
181
+ ```
182
+ Output style: concise_bullets
183
+ Max response length: 600 tokens
184
+ Omit introductory sentences. Start all responses with the first finding or action.
185
+ ```
186
+
187
+ ### Context window guidance
188
+
189
+ | Claude model | Max input tokens | Recommended max_input_tokens policy |
190
+ |---|---|---|
191
+ | claude-haiku-4-5 | 200K | 60,000 |
192
+ | claude-sonnet-4-6 | 200K | 100,000 |
193
+ | claude-opus-4-7 | 200K | 150,000 |
194
+
195
+ Set `max_input_tokens` in `token_policies.yaml` well below the model limit to leave room for the system prompt and output.
196
+
197
+ ---
198
+
199
+ ## Using extended thinking (Claude Sonnet / Opus)
200
+
201
+ For complex architecture tasks, enable extended thinking:
202
+
203
+ ```python
204
+ response = client.messages.create(
205
+ model="claude-sonnet-4-6",
206
+ max_tokens=16000,
207
+ thinking={"type": "enabled", "budget_tokens": 10000},
208
+ system=system_prompt,
209
+ messages=[...],
210
+ )
211
+ ```
212
+
213
+ Route only to `architect_agent` when thinking is enabled — it is expensive and most specialist tasks do not benefit.
214
+
215
+ ---
216
+
217
+ ## Option C — Claude.ai Free Tier (no Projects access)
218
+
219
+ If you are on the Claude.ai free plan and do not have access to Projects, use this approach each session:
220
+
221
+ **1. Open a new Claude.ai conversation.**
222
+
223
+ **2. Paste `system_prompt.md` as your very first message** (before describing your task):
224
+
225
+ ```
226
+ # Paste the full contents of agents-maker/system_prompt.md here as your first message.
227
+ # On macOS:
228
+ cat agents-maker/system_prompt.md | pbcopy
229
+
230
+ # On Windows:
231
+ type agents-maker\system_prompt.md | clip
232
+ ```
233
+
234
+ Send this message first. Claude will acknowledge the agent kit and wait for your task.
235
+
236
+ **3. Send your task using `PROMPT_TEMPLATE.md`:**
237
+
238
+ Open `PROMPT_TEMPLATE.md`, fill in the blanks, and send it as your second message. Or use the CLI:
239
+
240
+ ```bash
241
+ python agents-maker/tools/generate_prompt.py "your task here"
242
+ # Copy the printed block → paste as your second message
243
+ ```
244
+
245
+ **Limitations vs. Option A (Projects):** The system prompt uses ~6K–24K tokens of your context window each session. On free-tier models, this leaves less room for file content and conversation history. Use `context_loaders/file_chunker.py` with `--max-lines 100` to keep file snippets small.
246
+
247
+ **Tip:** Save a `project_state.md` at the end of each session by copying the Orchestrator's final state block. Paste it at the start of the next session (after `system_prompt.md`) to resume without replaying history.
248
+
249
+ ---
250
+
251
+ ## Routing without a project (API-only)
252
+
253
+ If you cannot use Projects, prepend the relevant agent spec inline:
254
+
255
+ ```python
256
+ specialist_prompt = Path("agents/code_agent.md").read_text()
257
+ user_message = f"{specialist_prompt}\n\n---\n\n{context}\n\n{user_query}"
258
+ ```
259
+
260
+ This is less elegant but fully functional.
261
+
262
+ ---
263
+
264
+ ## Minimal Lifecycle Invocation
265
+
266
+ You do not need to specify a domain or configure anything beyond a task description. The Orchestrator detects the domain automatically from your message.
267
+
268
+ ### Example — auto-detected domain
269
+
270
+ ```
271
+ User: "Help me write a product requirements document for a mobile checkout flow."
272
+
273
+ Orchestrator behavior:
274
+ 1. Scores signals: "product" (strong), "requirements" (strong), "mobile" (weak) → domain = product_design, confidence = high
275
+ 2. Produces task_profile and asks 3–5 scoping questions (Phase 0, qa_brief style)
276
+ 3. Awaits user approval before advancing to Phase 1
277
+ ```
278
+
279
+ No domain hint required. Just describe the task.
280
+
281
+ ### Example — domain hint prefix
282
+
283
+ If auto-detection might be ambiguous, prefix your message with `[domain: <key>]`:
284
+
285
+ ```
286
+ [domain: ops_process] Write an SOP for our employee offboarding process.
287
+ ```
288
+
289
+ Valid domain keys: `software`, `content`, `research`, `data_analytics`, `product_design`, `marketing`, `ops_process`. To add a custom domain, see [`docs/domains.md`](../docs/domains.md).
290
+
291
+ ### Example — resuming a prior session
292
+
293
+ Paste the contents of a saved `project_state.md` file as your opening message:
294
+
295
+ ```
296
+ [Paste contents of project_state.md here]
297
+
298
+ Continue from where we left off.
299
+ ```
300
+
301
+ The Orchestrator detects the `project_state.md` format, loads the state, and resumes at the recorded `current_phase` without replaying history.
302
+
303
+ ### Adding `domain_profiles.yaml` to project knowledge (Claude Projects)
304
+
305
+ For the Orchestrator to load domain profiles at runtime, add `config/domain_profiles.yaml` to your Project knowledge documents alongside the other config files. Without it, the Orchestrator falls back to its built-in inline defaults (same 7 domains, same confidence thresholds).
@@ -0,0 +1,333 @@
1
+ # OpenAI Integration Guide
2
+
3
+ How to use this kit with OpenAI: Chat Completions API, Assistants API, and Responses API (Agents SDK).
4
+
5
+ ---
6
+
7
+ ## Using Companion Mode on OpenAI
8
+
9
+ Companion Mode works the same on OpenAI as on any other platform. Every response ends with a structured `[Companion]` block offering three ranked next steps. Here is the minimal setup using the Chat Completions API:
10
+
11
+ ### One-time setup
12
+
13
+ ```bash
14
+ python agents-maker/tools/init_project.py
15
+ # Generates system_prompt.md — load this as the system role every session
16
+ ```
17
+
18
+ ### Before every session
19
+
20
+ ```bash
21
+ python agents-maker/tools/generate_prompt.py "your task here"
22
+ # Copy the printed block → send as the user message
23
+ ```
24
+
25
+ ### Minimal Chat Completions example
26
+
27
+ ```python
28
+ from openai import OpenAI
29
+ from pathlib import Path
30
+
31
+ client = OpenAI() # reads OPENAI_API_KEY from env
32
+
33
+ system_prompt = Path("agents-maker/system_prompt.md").read_text(encoding="utf-8")
34
+
35
+ # Generate a routed prompt with the CLI, then send it:
36
+ user_message = Path("my_prompt.txt").read_text(encoding="utf-8")
37
+
38
+ response = client.chat.completions.create(
39
+ model="gpt-4o",
40
+ messages=[
41
+ {"role": "system", "content": system_prompt},
42
+ {"role": "user", "content": user_message},
43
+ ],
44
+ max_tokens=4096,
45
+ )
46
+ print(response.choices[0].message.content)
47
+ # → Response ends with [Companion] block: three ranked next steps
48
+ ```
49
+
50
+ The `system_prompt.md` contains all 8 agents + 12 skills pre-assembled. Pass it once as the `system` role. Use `generate_prompt.py` output as the `user` role each turn. For multi-turn sessions, append prior `assistant` + `user` messages to the `messages` list normally.
51
+
52
+ See [platforms/claude.md](claude.md) for the full Companion Mode walkthrough and lifecycle example.
53
+
54
+ ---
55
+
56
+ ## Option A — Chat Completions API (simplest)
57
+
58
+ No assistant setup required. Load agent specs as the system message.
59
+
60
+ ```python
61
+ from openai import OpenAI
62
+ from pathlib import Path
63
+
64
+ client = OpenAI() # reads OPENAI_API_KEY from env
65
+
66
+ def load_orchestrator_system() -> str:
67
+ parts = [Path("agents/orchestrator.md").read_text()]
68
+ for path in Path("agents").glob("*.md"):
69
+ if path.name != "orchestrator.md":
70
+ parts.append(f"# {path.name}\n\n{path.read_text()}")
71
+ for path in Path("skills").glob("*.md"):
72
+ parts.append(f"# {path.name}\n\n{path.read_text()}")
73
+ return "\n\n---\n\n".join(parts)
74
+
75
+ response = client.chat.completions.create(
76
+ model="gpt-4o",
77
+ messages=[
78
+ {"role": "system", "content": load_orchestrator_system()},
79
+ {"role": "user", "content": f"{project_summary}\n\nTask: {user_task}"},
80
+ ],
81
+ max_tokens=4096,
82
+ )
83
+ print(response.choices[0].message.content)
84
+ ```
85
+
86
+ ---
87
+
88
+ ## Option B — Assistants API
89
+
90
+ Create one Assistant per agent. The Orchestrator assistant calls specialist assistants via tool calls or by spawning threads.
91
+
92
+ ### Step 1 — Create assistants
93
+
94
+ ```python
95
+ from openai import OpenAI
96
+ from pathlib import Path
97
+
98
+ client = OpenAI()
99
+
100
+ AGENT_FILES = {
101
+ "orchestrator": "agents/orchestrator.md",
102
+ "code_agent": "agents/code_agent.md",
103
+ "ui_agent": "agents/ui_agent.md",
104
+ "ux_agent": "agents/ux_agent.md",
105
+ "architect_agent": "agents/architect_agent.md",
106
+ "compression_agent": "agents/compression_agent.md",
107
+ }
108
+
109
+ assistants = {}
110
+ for name, path in AGENT_FILES.items():
111
+ instructions = Path(path).read_text()
112
+ # Append skill cards to each agent's instructions
113
+ # (Only skills listed in config/agents.yaml for that agent)
114
+ asst = client.beta.assistants.create(
115
+ name=name,
116
+ instructions=instructions,
117
+ model="gpt-4o",
118
+ tools=[], # add file_search or code_interpreter if needed
119
+ )
120
+ assistants[name] = asst.id
121
+ print(f"Created {name}: {asst.id}")
122
+ ```
123
+
124
+ Save the returned IDs to a local file (e.g., `.assistant_ids.json`) for reuse.
125
+
126
+ ### Step 2 — Run a thread
127
+
128
+ ```python
129
+ import json, time
130
+
131
+ ids = json.loads(Path(".assistant_ids.json").read_text())
132
+
133
+ thread = client.beta.threads.create()
134
+ client.beta.threads.messages.create(
135
+ thread_id=thread.id,
136
+ role="user",
137
+ content=f"{project_summary}\n\nTask: {user_task}",
138
+ )
139
+
140
+ run = client.beta.threads.runs.create(
141
+ thread_id=thread.id,
142
+ assistant_id=ids["orchestrator"],
143
+ )
144
+
145
+ # Poll for completion
146
+ while run.status in ("queued", "in_progress"):
147
+ time.sleep(1)
148
+ run = client.beta.threads.runs.retrieve(thread_id=thread.id, run_id=run.id)
149
+
150
+ messages = client.beta.threads.messages.list(thread_id=thread.id)
151
+ print(messages.data[0].content[0].text.value)
152
+ ```
153
+
154
+ ### Step 3 — Register routing as a tool (optional)
155
+
156
+ To enable the Orchestrator to explicitly call specialists, define a tool:
157
+
158
+ ```python
159
+ route_tool = {
160
+ "type": "function",
161
+ "function": {
162
+ "name": "route_to_specialist",
163
+ "description": "Invoke a specialist agent with a structured context block.",
164
+ "parameters": {
165
+ "type": "object",
166
+ "properties": {
167
+ "agent": {
168
+ "type": "string",
169
+ "enum": ["code_agent", "ui_agent", "ux_agent", "architect_agent", "compression_agent"],
170
+ "description": "Which specialist to invoke."
171
+ },
172
+ "context_block": {
173
+ "type": "string",
174
+ "description": "Full context block to send to the specialist."
175
+ },
176
+ },
177
+ "required": ["agent", "context_block"],
178
+ },
179
+ },
180
+ }
181
+
182
+ # Add to orchestrator assistant:
183
+ client.beta.assistants.update(
184
+ assistant_id=ids["orchestrator"],
185
+ tools=[route_tool],
186
+ )
187
+ ```
188
+
189
+ Handle the tool call in your run loop and spawn a new thread to the appropriate specialist assistant.
190
+
191
+ ---
192
+
193
+ ## Option C — Responses API / Agents SDK
194
+
195
+ The OpenAI Agents SDK (beta) supports multi-agent handoffs natively.
196
+
197
+ ```python
198
+ from agents import Agent, Runner
199
+
200
+ orchestrator = Agent(
201
+ name="Orchestrator",
202
+ instructions=Path("agents/orchestrator.md").read_text(),
203
+ model="gpt-4o",
204
+ )
205
+
206
+ code_agent = Agent(
207
+ name="CodeAgent",
208
+ instructions=Path("agents/code_agent.md").read_text(),
209
+ model="gpt-4o",
210
+ )
211
+
212
+ # Register specialists as handoff targets
213
+ orchestrator.handoffs = [code_agent]
214
+
215
+ result = Runner.run_sync(orchestrator, f"{project_summary}\n\nTask: {user_task}")
216
+ print(result.final_output)
217
+ ```
218
+
219
+ ---
220
+
221
+ ## Token policy integration
222
+
223
+ Apply `token_policies.yaml` via `compressor.py` before constructing messages:
224
+
225
+ ```python
226
+ from token_optimization.compressor import Compressor, ContextBlock, PolicyLoader
227
+
228
+ loader = PolicyLoader()
229
+ loader.load()
230
+ policy = loader.get_workflow_policy("feature_implementation")
231
+ compressor = Compressor(policy)
232
+ compressed, report = compressor.compress(context_block)
233
+
234
+ messages = [
235
+ {"role": "system", "content": system_prompt},
236
+ {"role": "user", "content": compressed},
237
+ ]
238
+ ```
239
+
240
+ ---
241
+
242
+ ## Token and cost guidance
243
+
244
+ | Model | Context window | Recommended max_input_tokens |
245
+ |---|---|---|
246
+ | gpt-4o | 128K | 50,000 |
247
+ | gpt-4o-mini | 128K | 60,000 |
248
+ | o3 / o4-mini | 200K | 100,000 |
249
+
250
+ Set `max_input_tokens` in `token_policies.yaml` to leave at least 4K tokens for the output.
251
+
252
+ ---
253
+
254
+ ## Mapping agents.yaml to OpenAI primitives
255
+
256
+ | `agents.yaml` field | OpenAI equivalent |
257
+ |---|---|
258
+ | `name` | `Assistant.name` |
259
+ | `description` | `Assistant.description` |
260
+ | `skills` | Included inline in `Assistant.instructions` |
261
+ | `routing_tags` | Used in Orchestrator's `route_to_specialist` tool logic |
262
+ | `cost_tier: high` | Consider `o3` or `gpt-4o`; `cost_tier: low` → `gpt-4o-mini` |
263
+ | `default_output_style` | Append style instructions to `Assistant.instructions` |
264
+
265
+ ---
266
+
267
+ ## Minimal Lifecycle Invocation
268
+
269
+ You do not need to specify a domain. The Orchestrator scores the user's message against `config/domain_profiles.yaml` automatically.
270
+
271
+ ### Example — auto-detected domain
272
+
273
+ ```python
274
+ # No domain configuration needed — just describe the task
275
+ user_task = "Write a go-to-market strategy brief for our new developer tool."
276
+
277
+ response = client.chat.completions.create(
278
+ model="gpt-4o",
279
+ messages=[
280
+ {"role": "system", "content": load_orchestrator_system()},
281
+ {"role": "user", "content": user_task},
282
+ ],
283
+ )
284
+ # Orchestrator detects domain = marketing (signals: "strategy", "brief" → medium confidence)
285
+ # then asks 3–5 scoping questions before producing task_profile
286
+ ```
287
+
288
+ ### Example — domain hint prefix
289
+
290
+ For unambiguous routing, prefix the user message:
291
+
292
+ ```python
293
+ user_task = "[domain: ops_process] Write a runbook for our database failover procedure."
294
+ # Orchestrator skips scoring, uses ops_process directly with domain_confidence = high
295
+ ```
296
+
297
+ ### Storing project_state across threads (Assistants API)
298
+
299
+ The Orchestrator emits a `project_state.md` snapshot after each approved phase. To persist it across Assistants API sessions, attach it as a file on the thread:
300
+
301
+ ```python
302
+ # Save project_state.md emitted by the Orchestrator
303
+ project_state_content = extract_project_state_from_response(last_response)
304
+ Path("project_state.md").write_text(project_state_content)
305
+
306
+ # Resume in a new thread by attaching it
307
+ new_thread = client.beta.threads.create()
308
+ with open("project_state.md", "rb") as f:
309
+ file = client.files.create(file=f, purpose="assistants")
310
+
311
+ client.beta.threads.messages.create(
312
+ thread_id=new_thread.id,
313
+ role="user",
314
+ content="Continue from where we left off.",
315
+ attachments=[{"file_id": file.id, "tools": [{"type": "file_search"}]}],
316
+ )
317
+ ```
318
+
319
+ ### domain_profiles.yaml via file_search
320
+
321
+ To give the Orchestrator access to domain profiles at runtime, upload `config/domain_profiles.yaml` as a vector store file and enable `file_search` on the orchestrator assistant. The Orchestrator will retrieve it when scoring domain signals.
322
+
323
+ ```python
324
+ vector_store = client.beta.vector_stores.create(name="agent-kit-config")
325
+ client.beta.vector_stores.file_batches.upload_and_poll(
326
+ vector_store_id=vector_store.id,
327
+ files=[open("config/domain_profiles.yaml", "rb"),
328
+ open("config/token_policies.yaml", "rb")],
329
+ )
330
+ client.beta.assistants.update(
331
+ assistant_id=ids["orchestrator"],
332
+ tool_resources={"file_search": {"vector_store_ids": [vector_store.id]}},
333
+ )