@yeyuan98/opencode-bioresearcher-plugin 1.4.0 → 1.5.0-alpha.0

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 (72) hide show
  1. package/README.md +35 -20
  2. package/dist/db-tools/backends/index.d.ts +11 -0
  3. package/dist/db-tools/backends/index.js +48 -0
  4. package/dist/db-tools/backends/mongodb/backend.d.ts +15 -0
  5. package/dist/db-tools/backends/mongodb/backend.js +76 -0
  6. package/dist/db-tools/backends/mongodb/connection.d.ts +27 -0
  7. package/dist/db-tools/backends/mongodb/connection.js +107 -0
  8. package/dist/db-tools/backends/mongodb/index.d.ts +4 -0
  9. package/dist/db-tools/backends/mongodb/index.js +3 -0
  10. package/dist/db-tools/backends/mongodb/translator.d.ts +30 -0
  11. package/dist/db-tools/backends/mongodb/translator.js +407 -0
  12. package/dist/db-tools/backends/mysql/backend.d.ts +15 -0
  13. package/dist/db-tools/backends/mysql/backend.js +57 -0
  14. package/dist/db-tools/backends/mysql/connection.d.ts +25 -0
  15. package/dist/db-tools/backends/mysql/connection.js +83 -0
  16. package/dist/db-tools/backends/mysql/index.d.ts +3 -0
  17. package/dist/db-tools/backends/mysql/index.js +2 -0
  18. package/dist/db-tools/backends/mysql/translator.d.ts +7 -0
  19. package/dist/db-tools/backends/mysql/translator.js +67 -0
  20. package/dist/db-tools/core/base.d.ts +17 -0
  21. package/dist/db-tools/core/base.js +51 -0
  22. package/dist/db-tools/core/config-loader.d.ts +3 -0
  23. package/dist/db-tools/core/config-loader.js +46 -0
  24. package/dist/db-tools/core/index.d.ts +2 -0
  25. package/dist/db-tools/core/index.js +2 -0
  26. package/dist/db-tools/core/jsonc-parser.d.ts +2 -0
  27. package/dist/db-tools/core/jsonc-parser.js +77 -0
  28. package/dist/db-tools/core/validator.d.ts +16 -0
  29. package/dist/db-tools/core/validator.js +118 -0
  30. package/dist/db-tools/executor.d.ts +13 -0
  31. package/dist/db-tools/executor.js +54 -0
  32. package/dist/db-tools/index.d.ts +51 -0
  33. package/dist/db-tools/index.js +27 -0
  34. package/dist/db-tools/interface/backend.d.ts +24 -0
  35. package/dist/db-tools/interface/backend.js +1 -0
  36. package/dist/db-tools/interface/connection.d.ts +21 -0
  37. package/dist/db-tools/interface/connection.js +11 -0
  38. package/dist/db-tools/interface/index.d.ts +4 -0
  39. package/dist/db-tools/interface/index.js +4 -0
  40. package/dist/db-tools/interface/query.d.ts +60 -0
  41. package/dist/db-tools/interface/query.js +1 -0
  42. package/dist/db-tools/interface/schema.d.ts +22 -0
  43. package/dist/db-tools/interface/schema.js +1 -0
  44. package/dist/db-tools/pool.d.ts +8 -0
  45. package/dist/db-tools/pool.js +49 -0
  46. package/dist/db-tools/tools/index.d.ts +27 -0
  47. package/dist/db-tools/tools/index.js +191 -0
  48. package/dist/db-tools/tools.d.ts +27 -0
  49. package/dist/db-tools/tools.js +111 -0
  50. package/dist/db-tools/types.d.ts +94 -0
  51. package/dist/db-tools/types.js +40 -0
  52. package/dist/db-tools/utils.d.ts +33 -0
  53. package/dist/db-tools/utils.js +94 -0
  54. package/dist/index.js +2 -0
  55. package/dist/skills/bioresearcher-core/README.md +210 -210
  56. package/dist/skills/bioresearcher-core/SKILL.md +128 -128
  57. package/dist/skills/bioresearcher-core/examples/contexts.json +29 -29
  58. package/dist/skills/bioresearcher-core/examples/data-exchange-example.md +303 -303
  59. package/dist/skills/bioresearcher-core/examples/template.md +49 -49
  60. package/dist/skills/bioresearcher-core/patterns/calculator.md +215 -215
  61. package/dist/skills/bioresearcher-core/patterns/data-exchange.md +406 -406
  62. package/dist/skills/bioresearcher-core/patterns/json-tools.md +263 -263
  63. package/dist/skills/bioresearcher-core/patterns/progress.md +127 -127
  64. package/dist/skills/bioresearcher-core/patterns/retry.md +110 -110
  65. package/dist/skills/bioresearcher-core/patterns/shell-commands.md +79 -79
  66. package/dist/skills/bioresearcher-core/patterns/subagent-waves.md +186 -186
  67. package/dist/skills/bioresearcher-core/patterns/table-tools.md +260 -260
  68. package/dist/skills/bioresearcher-core/patterns/user-confirmation.md +187 -187
  69. package/dist/skills/bioresearcher-core/python/template.md +273 -273
  70. package/dist/skills/bioresearcher-core/python/template.py +323 -323
  71. package/dist/skills/env-jsonc-setup/SKILL.md +206 -0
  72. package/package.json +3 -1
@@ -1,406 +1,406 @@
1
- # Data Exchange Pattern
2
-
3
- Standardized protocol for data exchange between main agent and subagents.
4
-
5
- ## Overview
6
-
7
- This pattern ensures reliable communication between main agent and subagents using:
8
- - File-based prompts with embedded schemas
9
- - JSON output files with validation
10
- - Schema-first design for type safety
11
-
12
- ## Data Exchange Protocol
13
-
14
- ```
15
- Main Agent Subagent
16
- | |
17
- |--- Write prompt file ----------->|
18
- | (with embedded schema) |
19
- | |
20
- | |--- Read prompt
21
- | |--- Process data
22
- | |--- Write output JSON
23
- | |
24
- |<-- Write output file -------------|
25
- | (JSON matching schema) |
26
- | |
27
- |--- jsonExtract ------------------>|
28
- |--- jsonValidate ----------------->|
29
- |--- Process validated data |
30
- ```
31
-
32
- ## Main Agent Responsibilities
33
-
34
- ### 1. Create Prompt File with Embedded Schema
35
-
36
- Include the output schema directly in the prompt:
37
-
38
- ```markdown
39
- # Task Description
40
-
41
- Process the data and output results.
42
-
43
- ## Output Format
44
-
45
- Your output must be valid JSON matching this schema:
46
-
47
- ```json
48
- {
49
- "batch_number": <integer>,
50
- "row_count": <integer>,
51
- "summaries": [
52
- {
53
- "row_number": <integer>,
54
- "field1": "<string>",
55
- "field2": "<string>"
56
- }
57
- ]
58
- }
59
- ```
60
-
61
- Write your output to: {output_file}
62
-
63
- **CRITICAL:** Write ONLY the JSON object, no additional text.
64
- ```
65
-
66
- ### 2. Launch Subagent with File Reference
67
-
68
- ```
69
- task(
70
- subagent_type="general",
71
- description="Process batch 001",
72
- prompt="Read your prompt from ./prompts/batch001.md and perform the task exactly as written."
73
- )
74
- ```
75
-
76
- ### 3. Validate Subagent Output
77
-
78
- ```python
79
- # Extract JSON from output file
80
- result = jsonExtract(file_path="./outputs/batch001.md")
81
-
82
- if not result.success:
83
- log_error(f"Failed to extract JSON")
84
- handle_failure()
85
-
86
- # Validate against expected schema
87
- validation = jsonValidate(
88
- data=json.dumps(result.data),
89
- schema=expected_schema
90
- )
91
-
92
- if not validation.valid:
93
- log_error(f"Validation failed: {validation.errors}")
94
- handle_failure()
95
-
96
- # Process validated data
97
- process(result.data)
98
- ```
99
-
100
- ## Subagent Responsibilities
101
-
102
- ### 1. Read Prompt File
103
-
104
- The subagent reads the prompt file to understand:
105
- - Task description
106
- - Input data location
107
- - Output format (schema)
108
- - Output file path
109
-
110
- ### 2. Process and Generate Output
111
-
112
- The subagent:
113
- - Reads input data using available tools
114
- - Processes according to instructions
115
- - Generates output matching the schema exactly
116
-
117
- ### 3. Write Output File
118
-
119
- Write ONLY valid JSON to the specified output file:
120
-
121
- ```json
122
- {
123
- "batch_number": 1,
124
- "row_count": 30,
125
- "summaries": [
126
- {"row_number": 2, "field1": "value1", "field2": "value2"},
127
- {"row_number": 3, "field1": "value3", "field2": "value4"}
128
- ]
129
- }
130
- ```
131
-
132
- ## Schema Definition Guidelines
133
-
134
- ### Basic Schema Example
135
-
136
- ```json
137
- {
138
- "batch_number": <integer>,
139
- "row_count": <integer>,
140
- "summaries": [
141
- {
142
- "row_number": <integer>,
143
- "field_name": "<type_description>"
144
- }
145
- ]
146
- }
147
- ```
148
-
149
- ### Type Annotations in Schema
150
-
151
- Use clear type annotations in markdown:
152
-
153
- | Annotation | Type |
154
- |------------|------|
155
- | `<integer>` | Integer number |
156
- | `<number>` | Any number |
157
- | `<string>` | Text string |
158
- | `<boolean>` | true or false |
159
- | `<array>` | JSON array |
160
- | `<object>` | JSON object |
161
-
162
- ### Enum Values
163
-
164
- Specify allowed values:
165
-
166
- ```json
167
- {
168
- "status": "<one of: active/inactive/pending>"
169
- }
170
- ```
171
-
172
- ### Optional Fields
173
-
174
- Mark optional fields clearly:
175
-
176
- ```json
177
- {
178
- "required_field": "<string>",
179
- "optional_field?": "<string or null>"
180
- }
181
- ```
182
-
183
- ## Validation Flow
184
-
185
- ### Step 1: Infer Schema from First Output
186
-
187
- ```python
188
- # Get first output
189
- first_result = jsonExtract(file_path="./outputs/batch001.md")
190
-
191
- # Infer schema
192
- schema_result = jsonInfer(
193
- data=json.dumps(first_result.data),
194
- strict=true
195
- )
196
-
197
- # Store schema for validation
198
- expected_schema = json.dumps(schema_result.data)
199
- ```
200
-
201
- ### Step 2: Validate All Outputs
202
-
203
- ```python
204
- for file_path in output_files:
205
- # Extract
206
- result = jsonExtract(file_path=file_path)
207
- if not result.success:
208
- log_error(f"Extraction failed: {file_path}")
209
- continue
210
-
211
- # Validate
212
- validation = jsonValidate(
213
- data=json.dumps(result.data),
214
- schema=expected_schema
215
- )
216
-
217
- if not validation.valid:
218
- log_error(f"Validation failed: {file_path}")
219
- log_error(validation.errors)
220
- continue
221
-
222
- # Collect valid data
223
- valid_outputs.append(result.data)
224
- ```
225
-
226
- ## Error Handling
227
-
228
- ### Error Structures
229
-
230
- #### jsonExtract Error Response
231
- ```json
232
- {
233
- "success": false,
234
- "data": null,
235
- "metadata": {
236
- "error": {
237
- "code": "NO_JSON_FOUND",
238
- "message": "No valid JSON found in file"
239
- }
240
- }
241
- }
242
- ```
243
-
244
- #### Error Codes
245
- | Code | Description |
246
- |------|-------------|
247
- | `FILE_NOT_FOUND` | File does not exist |
248
- | `FILE_TOO_LARGE` | File exceeds 200MB limit |
249
- | `BINARY_FILE` | File is binary format |
250
- | `EMPTY_FILE` | File has no content |
251
- | `NO_JSON_FOUND` | No valid JSON found |
252
-
253
- #### jsonValidate Error Response
254
- ```json
255
- {
256
- "success": true,
257
- "valid": false,
258
- "errors": [
259
- {
260
- "path": "summaries.0.row_number",
261
- "message": "Expected number, received string",
262
- "code": "invalid_type",
263
- "expected": "number",
264
- "received": "string"
265
- }
266
- ]
267
- }
268
- ```
269
-
270
- ### Extraction Failures
271
-
272
- ```python
273
- if not result.success:
274
- error_code = result.metadata.get("error", {}).get("code", "UNKNOWN")
275
- if error_code == "NO_JSON_FOUND":
276
- log_error("Subagent did not output valid JSON")
277
- log_error("Check subagent output for errors")
278
- retry_or_skip()
279
- ```
280
-
281
- ### Validation Failures
282
-
283
- ```python
284
- if not validation.valid:
285
- for error in validation.errors:
286
- log_error(f"Field {error['path']}: {error['message']}")
287
- if error['code'] == "invalid_type":
288
- log_error(f" Expected: {error['expected']}")
289
- log_error(f" Received: {error['received']}")
290
- ```
291
-
292
- ### Subagent Execution Failures
293
-
294
- Beyond output validation, subagents may fail during execution:
295
-
296
- | Failure Type | Detection | Recovery |
297
- |--------------|-----------|----------|
298
- | Timeout | Task exceeds time limit | Retry with smaller batch |
299
- | Crash | No output file created | Retry or skip |
300
- | Partial output | Incomplete JSON | Retry or use partial data |
301
- | Wrong format | JSON doesn't match schema | Re-prompt with clearer instructions |
302
-
303
- ### Failure Handling Pattern
304
-
305
- ```python
306
- # After launching subagent wave
307
- failed_batches = []
308
-
309
- for batch_file in expected_outputs:
310
- if not file_exists(batch_file):
311
- log_error(f"Subagent failed to create output: {batch_file}")
312
- failed_batches.append(batch_file)
313
- continue
314
-
315
- result = jsonExtract(file_path=batch_file)
316
- if not result.success:
317
- log_error(f"Failed to extract JSON: {batch_file}")
318
- failed_batches.append(batch_file)
319
- continue
320
-
321
- validation = jsonValidate(data=json.dumps(result.data), schema=expected_schema)
322
- if not validation.valid:
323
- log_error(f"Validation failed: {batch_file}")
324
- failed_batches.append(batch_file)
325
- continue
326
-
327
- valid_outputs.append(result.data)
328
-
329
- # Retry failed batches using retry.md pattern
330
- if failed_batches:
331
- for batch in failed_batches:
332
- retry_subagent(batch, max_attempts=3, delay=5)
333
- ```
334
-
335
- > **Note:** Reference `patterns/retry.md` for implementing retry logic with exponential backoff.
336
-
337
- ## Complete Example
338
-
339
- ### Main Agent: Create Prompt
340
-
341
- ```markdown
342
- # Gene Classification Task
343
-
344
- ## Input
345
- - File: ./data/genes.xlsx
346
- - Sheet: Sheet1
347
- - Rows: 2-31
348
-
349
- ## Instructions
350
- For each row, classify the gene by species and function.
351
-
352
- ## Output Format
353
- Write JSON to: ./outputs/batch001.md
354
-
355
- ```json
356
- {
357
- "batch_number": 1,
358
- "row_count": 30,
359
- "summaries": [
360
- {
361
- "row_number": <integer>,
362
- "gene_name": "<string>",
363
- "species": "<one of: human/mouse/other>",
364
- "function": "<string>"
365
- }
366
- ]
367
- }
368
- ```
369
- ```
370
-
371
- ### Subagent: Write Output
372
-
373
- ```json
374
- {
375
- "batch_number": 1,
376
- "row_count": 30,
377
- "summaries": [
378
- {"row_number": 2, "gene_name": "BRAF", "species": "human", "function": "Kinase"},
379
- {"row_number": 3, "gene_name": "TP53", "species": "human", "function": "Tumor suppressor"}
380
- ]
381
- }
382
- ```
383
-
384
- ### Main Agent: Validate
385
-
386
- ```python
387
- # Extract
388
- result = jsonExtract(file_path="./outputs/batch001.md")
389
-
390
- # Validate
391
- validation = jsonValidate(
392
- data=json.dumps(result.data),
393
- schema='{"type":"object","properties":{"batch_number":{"type":"integer"},"summaries":{"type":"array"}}}'
394
- )
395
-
396
- if validation.valid:
397
- process(result.data)
398
- ```
399
-
400
- ## Best Practices
401
-
402
- 1. **Embed schema in prompt**: Don't rely on external schema files
403
- 2. **Use strict typing**: Specify exact types and allowed values
404
- 3. **Validate every output**: Never skip validation
405
- 4. **Handle errors gracefully**: Log and continue with other outputs
406
- 5. **Keep schemas simple**: Avoid complex nested structures
1
+ # Data Exchange Pattern
2
+
3
+ Standardized protocol for data exchange between main agent and subagents.
4
+
5
+ ## Overview
6
+
7
+ This pattern ensures reliable communication between main agent and subagents using:
8
+ - File-based prompts with embedded schemas
9
+ - JSON output files with validation
10
+ - Schema-first design for type safety
11
+
12
+ ## Data Exchange Protocol
13
+
14
+ ```
15
+ Main Agent Subagent
16
+ | |
17
+ |--- Write prompt file ----------->|
18
+ | (with embedded schema) |
19
+ | |
20
+ | |--- Read prompt
21
+ | |--- Process data
22
+ | |--- Write output JSON
23
+ | |
24
+ |<-- Write output file -------------|
25
+ | (JSON matching schema) |
26
+ | |
27
+ |--- jsonExtract ------------------>|
28
+ |--- jsonValidate ----------------->|
29
+ |--- Process validated data |
30
+ ```
31
+
32
+ ## Main Agent Responsibilities
33
+
34
+ ### 1. Create Prompt File with Embedded Schema
35
+
36
+ Include the output schema directly in the prompt:
37
+
38
+ ```markdown
39
+ # Task Description
40
+
41
+ Process the data and output results.
42
+
43
+ ## Output Format
44
+
45
+ Your output must be valid JSON matching this schema:
46
+
47
+ ```json
48
+ {
49
+ "batch_number": <integer>,
50
+ "row_count": <integer>,
51
+ "summaries": [
52
+ {
53
+ "row_number": <integer>,
54
+ "field1": "<string>",
55
+ "field2": "<string>"
56
+ }
57
+ ]
58
+ }
59
+ ```
60
+
61
+ Write your output to: {output_file}
62
+
63
+ **CRITICAL:** Write ONLY the JSON object, no additional text.
64
+ ```
65
+
66
+ ### 2. Launch Subagent with File Reference
67
+
68
+ ```
69
+ task(
70
+ subagent_type="general",
71
+ description="Process batch 001",
72
+ prompt="Read your prompt from ./prompts/batch001.md and perform the task exactly as written."
73
+ )
74
+ ```
75
+
76
+ ### 3. Validate Subagent Output
77
+
78
+ ```python
79
+ # Extract JSON from output file
80
+ result = jsonExtract(file_path="./outputs/batch001.md")
81
+
82
+ if not result.success:
83
+ log_error(f"Failed to extract JSON")
84
+ handle_failure()
85
+
86
+ # Validate against expected schema
87
+ validation = jsonValidate(
88
+ data=json.dumps(result.data),
89
+ schema=expected_schema
90
+ )
91
+
92
+ if not validation.valid:
93
+ log_error(f"Validation failed: {validation.errors}")
94
+ handle_failure()
95
+
96
+ # Process validated data
97
+ process(result.data)
98
+ ```
99
+
100
+ ## Subagent Responsibilities
101
+
102
+ ### 1. Read Prompt File
103
+
104
+ The subagent reads the prompt file to understand:
105
+ - Task description
106
+ - Input data location
107
+ - Output format (schema)
108
+ - Output file path
109
+
110
+ ### 2. Process and Generate Output
111
+
112
+ The subagent:
113
+ - Reads input data using available tools
114
+ - Processes according to instructions
115
+ - Generates output matching the schema exactly
116
+
117
+ ### 3. Write Output File
118
+
119
+ Write ONLY valid JSON to the specified output file:
120
+
121
+ ```json
122
+ {
123
+ "batch_number": 1,
124
+ "row_count": 30,
125
+ "summaries": [
126
+ {"row_number": 2, "field1": "value1", "field2": "value2"},
127
+ {"row_number": 3, "field1": "value3", "field2": "value4"}
128
+ ]
129
+ }
130
+ ```
131
+
132
+ ## Schema Definition Guidelines
133
+
134
+ ### Basic Schema Example
135
+
136
+ ```json
137
+ {
138
+ "batch_number": <integer>,
139
+ "row_count": <integer>,
140
+ "summaries": [
141
+ {
142
+ "row_number": <integer>,
143
+ "field_name": "<type_description>"
144
+ }
145
+ ]
146
+ }
147
+ ```
148
+
149
+ ### Type Annotations in Schema
150
+
151
+ Use clear type annotations in markdown:
152
+
153
+ | Annotation | Type |
154
+ |------------|------|
155
+ | `<integer>` | Integer number |
156
+ | `<number>` | Any number |
157
+ | `<string>` | Text string |
158
+ | `<boolean>` | true or false |
159
+ | `<array>` | JSON array |
160
+ | `<object>` | JSON object |
161
+
162
+ ### Enum Values
163
+
164
+ Specify allowed values:
165
+
166
+ ```json
167
+ {
168
+ "status": "<one of: active/inactive/pending>"
169
+ }
170
+ ```
171
+
172
+ ### Optional Fields
173
+
174
+ Mark optional fields clearly:
175
+
176
+ ```json
177
+ {
178
+ "required_field": "<string>",
179
+ "optional_field?": "<string or null>"
180
+ }
181
+ ```
182
+
183
+ ## Validation Flow
184
+
185
+ ### Step 1: Infer Schema from First Output
186
+
187
+ ```python
188
+ # Get first output
189
+ first_result = jsonExtract(file_path="./outputs/batch001.md")
190
+
191
+ # Infer schema
192
+ schema_result = jsonInfer(
193
+ data=json.dumps(first_result.data),
194
+ strict=true
195
+ )
196
+
197
+ # Store schema for validation
198
+ expected_schema = json.dumps(schema_result.data)
199
+ ```
200
+
201
+ ### Step 2: Validate All Outputs
202
+
203
+ ```python
204
+ for file_path in output_files:
205
+ # Extract
206
+ result = jsonExtract(file_path=file_path)
207
+ if not result.success:
208
+ log_error(f"Extraction failed: {file_path}")
209
+ continue
210
+
211
+ # Validate
212
+ validation = jsonValidate(
213
+ data=json.dumps(result.data),
214
+ schema=expected_schema
215
+ )
216
+
217
+ if not validation.valid:
218
+ log_error(f"Validation failed: {file_path}")
219
+ log_error(validation.errors)
220
+ continue
221
+
222
+ # Collect valid data
223
+ valid_outputs.append(result.data)
224
+ ```
225
+
226
+ ## Error Handling
227
+
228
+ ### Error Structures
229
+
230
+ #### jsonExtract Error Response
231
+ ```json
232
+ {
233
+ "success": false,
234
+ "data": null,
235
+ "metadata": {
236
+ "error": {
237
+ "code": "NO_JSON_FOUND",
238
+ "message": "No valid JSON found in file"
239
+ }
240
+ }
241
+ }
242
+ ```
243
+
244
+ #### Error Codes
245
+ | Code | Description |
246
+ |------|-------------|
247
+ | `FILE_NOT_FOUND` | File does not exist |
248
+ | `FILE_TOO_LARGE` | File exceeds 200MB limit |
249
+ | `BINARY_FILE` | File is binary format |
250
+ | `EMPTY_FILE` | File has no content |
251
+ | `NO_JSON_FOUND` | No valid JSON found |
252
+
253
+ #### jsonValidate Error Response
254
+ ```json
255
+ {
256
+ "success": true,
257
+ "valid": false,
258
+ "errors": [
259
+ {
260
+ "path": "summaries.0.row_number",
261
+ "message": "Expected number, received string",
262
+ "code": "invalid_type",
263
+ "expected": "number",
264
+ "received": "string"
265
+ }
266
+ ]
267
+ }
268
+ ```
269
+
270
+ ### Extraction Failures
271
+
272
+ ```python
273
+ if not result.success:
274
+ error_code = result.metadata.get("error", {}).get("code", "UNKNOWN")
275
+ if error_code == "NO_JSON_FOUND":
276
+ log_error("Subagent did not output valid JSON")
277
+ log_error("Check subagent output for errors")
278
+ retry_or_skip()
279
+ ```
280
+
281
+ ### Validation Failures
282
+
283
+ ```python
284
+ if not validation.valid:
285
+ for error in validation.errors:
286
+ log_error(f"Field {error['path']}: {error['message']}")
287
+ if error['code'] == "invalid_type":
288
+ log_error(f" Expected: {error['expected']}")
289
+ log_error(f" Received: {error['received']}")
290
+ ```
291
+
292
+ ### Subagent Execution Failures
293
+
294
+ Beyond output validation, subagents may fail during execution:
295
+
296
+ | Failure Type | Detection | Recovery |
297
+ |--------------|-----------|----------|
298
+ | Timeout | Task exceeds time limit | Retry with smaller batch |
299
+ | Crash | No output file created | Retry or skip |
300
+ | Partial output | Incomplete JSON | Retry or use partial data |
301
+ | Wrong format | JSON doesn't match schema | Re-prompt with clearer instructions |
302
+
303
+ ### Failure Handling Pattern
304
+
305
+ ```python
306
+ # After launching subagent wave
307
+ failed_batches = []
308
+
309
+ for batch_file in expected_outputs:
310
+ if not file_exists(batch_file):
311
+ log_error(f"Subagent failed to create output: {batch_file}")
312
+ failed_batches.append(batch_file)
313
+ continue
314
+
315
+ result = jsonExtract(file_path=batch_file)
316
+ if not result.success:
317
+ log_error(f"Failed to extract JSON: {batch_file}")
318
+ failed_batches.append(batch_file)
319
+ continue
320
+
321
+ validation = jsonValidate(data=json.dumps(result.data), schema=expected_schema)
322
+ if not validation.valid:
323
+ log_error(f"Validation failed: {batch_file}")
324
+ failed_batches.append(batch_file)
325
+ continue
326
+
327
+ valid_outputs.append(result.data)
328
+
329
+ # Retry failed batches using retry.md pattern
330
+ if failed_batches:
331
+ for batch in failed_batches:
332
+ retry_subagent(batch, max_attempts=3, delay=5)
333
+ ```
334
+
335
+ > **Note:** Reference `patterns/retry.md` for implementing retry logic with exponential backoff.
336
+
337
+ ## Complete Example
338
+
339
+ ### Main Agent: Create Prompt
340
+
341
+ ```markdown
342
+ # Gene Classification Task
343
+
344
+ ## Input
345
+ - File: ./data/genes.xlsx
346
+ - Sheet: Sheet1
347
+ - Rows: 2-31
348
+
349
+ ## Instructions
350
+ For each row, classify the gene by species and function.
351
+
352
+ ## Output Format
353
+ Write JSON to: ./outputs/batch001.md
354
+
355
+ ```json
356
+ {
357
+ "batch_number": 1,
358
+ "row_count": 30,
359
+ "summaries": [
360
+ {
361
+ "row_number": <integer>,
362
+ "gene_name": "<string>",
363
+ "species": "<one of: human/mouse/other>",
364
+ "function": "<string>"
365
+ }
366
+ ]
367
+ }
368
+ ```
369
+ ```
370
+
371
+ ### Subagent: Write Output
372
+
373
+ ```json
374
+ {
375
+ "batch_number": 1,
376
+ "row_count": 30,
377
+ "summaries": [
378
+ {"row_number": 2, "gene_name": "BRAF", "species": "human", "function": "Kinase"},
379
+ {"row_number": 3, "gene_name": "TP53", "species": "human", "function": "Tumor suppressor"}
380
+ ]
381
+ }
382
+ ```
383
+
384
+ ### Main Agent: Validate
385
+
386
+ ```python
387
+ # Extract
388
+ result = jsonExtract(file_path="./outputs/batch001.md")
389
+
390
+ # Validate
391
+ validation = jsonValidate(
392
+ data=json.dumps(result.data),
393
+ schema='{"type":"object","properties":{"batch_number":{"type":"integer"},"summaries":{"type":"array"}}}'
394
+ )
395
+
396
+ if validation.valid:
397
+ process(result.data)
398
+ ```
399
+
400
+ ## Best Practices
401
+
402
+ 1. **Embed schema in prompt**: Don't rely on external schema files
403
+ 2. **Use strict typing**: Specify exact types and allowed values
404
+ 3. **Validate every output**: Never skip validation
405
+ 4. **Handle errors gracefully**: Log and continue with other outputs
406
+ 5. **Keep schemas simple**: Avoid complex nested structures