@cronicorn/mcp-server 1.4.5 → 1.5.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.
- package/dist/docs/README.md +133 -0
- package/dist/docs/core-concepts.md +233 -0
- package/dist/docs/introduction.md +152 -0
- package/dist/docs/quick-start.md +232 -0
- package/dist/docs/technical/_category.yml +8 -0
- package/dist/docs/technical/configuration-and-constraints.md +415 -0
- package/dist/docs/technical/coordinating-multiple-endpoints.md +457 -0
- package/dist/docs/technical/how-ai-adaptation-works.md +453 -0
- package/dist/docs/technical/how-scheduling-works.md +268 -0
- package/dist/docs/technical/reference.md +404 -0
- package/dist/docs/technical/system-architecture.md +306 -0
- package/dist/index.js +123 -8
- package/dist/index.js.map +1 -1
- package/package.json +3 -2
|
@@ -0,0 +1,457 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: coordinating-endpoints
|
|
3
|
+
title: Coordinating Multiple Endpoints
|
|
4
|
+
description: Orchestration patterns and multi-endpoint examples
|
|
5
|
+
tags: [assistant, technical, orchestration]
|
|
6
|
+
sidebar_position: 4
|
|
7
|
+
mcp:
|
|
8
|
+
uri: file:///docs/technical/coordinating-multiple-endpoints.md
|
|
9
|
+
mimeType: text/markdown
|
|
10
|
+
priority: 0.80
|
|
11
|
+
lastModified: 2025-11-02T00:00:00Z
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
# Coordinating Multiple Endpoints
|
|
15
|
+
|
|
16
|
+
This document shows practical patterns for orchestrating workflows across multiple endpoints. Instead of abstract concepts, you'll find concrete examples you can copy and adapt.
|
|
17
|
+
|
|
18
|
+
## Core Concept: Coordination via Response Bodies
|
|
19
|
+
|
|
20
|
+
Cronicorn doesn't have built-in workflow orchestration or explicit dependencies. Instead, endpoints coordinate by:
|
|
21
|
+
|
|
22
|
+
1. Writing signals to their response bodies
|
|
23
|
+
2. Other endpoints reading those signals via `get_sibling_latest_responses`
|
|
24
|
+
3. AI acting on the signals (pause, run immediately, adjust intervals)
|
|
25
|
+
|
|
26
|
+
This approach is flexible—you define the coordination protocol in your response data.
|
|
27
|
+
|
|
28
|
+
## Pattern 1: Flash Sale Load Management
|
|
29
|
+
|
|
30
|
+
**Scenario**: E-commerce site with flash sale. Need to prioritize critical endpoints and pause low-priority work during traffic spikes.
|
|
31
|
+
|
|
32
|
+
### Endpoints
|
|
33
|
+
|
|
34
|
+
**Job**: "Flash Sale Management"
|
|
35
|
+
|
|
36
|
+
**Endpoint 1: Traffic Monitor** (1-minute interval)
|
|
37
|
+
- Checks current traffic load
|
|
38
|
+
- Returns: `{ "visitors_per_min": 5000, "load_status": "high", "flash_sale_active": true }`
|
|
39
|
+
|
|
40
|
+
**Endpoint 2: Order Processor** (30-second interval)
|
|
41
|
+
- Critical: processes orders
|
|
42
|
+
- Priority: Must keep running
|
|
43
|
+
|
|
44
|
+
**Endpoint 3: Inventory Sync** (5-minute interval)
|
|
45
|
+
- Normal priority: syncs inventory to warehouse
|
|
46
|
+
- Can pause during spikes
|
|
47
|
+
|
|
48
|
+
**Endpoint 4: Analytics Updater** (10-minute interval)
|
|
49
|
+
- Low priority: updates dashboards
|
|
50
|
+
- Should pause during spikes
|
|
51
|
+
|
|
52
|
+
### Response Body Structure
|
|
53
|
+
|
|
54
|
+
**Traffic Monitor**:
|
|
55
|
+
```json
|
|
56
|
+
{
|
|
57
|
+
"visitors_per_min": 5000,
|
|
58
|
+
"load_status": "high",
|
|
59
|
+
"flash_sale_active": true,
|
|
60
|
+
"recommendations": {
|
|
61
|
+
"pause_low_priority": true,
|
|
62
|
+
"pause_until": "2025-11-02T15:00:00Z"
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
**Analytics Updater**:
|
|
68
|
+
```json
|
|
69
|
+
{
|
|
70
|
+
"last_update_at": "2025-11-02T14:30:00Z",
|
|
71
|
+
"records_processed": 1500,
|
|
72
|
+
"status": "active"
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### AI Coordination Logic
|
|
77
|
+
|
|
78
|
+
When AI analyzes **Analytics Updater**:
|
|
79
|
+
|
|
80
|
+
1. Calls `get_sibling_latest_responses()`
|
|
81
|
+
2. Finds Traffic Monitor response: `{ "load_status": "high", "recommendations": { "pause_low_priority": true } }`
|
|
82
|
+
3. Checks Analytics Updater's priority (low)
|
|
83
|
+
4. Calls `pause_until("2025-11-02T15:00:00Z", reason="Flash sale traffic spike - pausing low-priority work")`
|
|
84
|
+
|
|
85
|
+
When AI analyzes **Order Processor**:
|
|
86
|
+
|
|
87
|
+
1. Calls `get_sibling_latest_responses()`
|
|
88
|
+
2. Finds Traffic Monitor response: `{ "load_status": "high" }`
|
|
89
|
+
3. Checks Order Processor's priority (critical)
|
|
90
|
+
4. Takes no action (critical endpoints keep running)
|
|
91
|
+
|
|
92
|
+
When load drops (Traffic Monitor returns `"load_status": "normal"`):
|
|
93
|
+
|
|
94
|
+
1. AI analyzes Analytics Updater
|
|
95
|
+
2. Sees normal load status
|
|
96
|
+
3. Calls `pause_until(null, reason="Load normalized - resuming")`
|
|
97
|
+
|
|
98
|
+
### Key Points
|
|
99
|
+
|
|
100
|
+
- Traffic Monitor acts as coordinator (writes signals)
|
|
101
|
+
- Other endpoints react to signals (via AI reading sibling responses)
|
|
102
|
+
- Priority is encoded in endpoint names/descriptions, not the system
|
|
103
|
+
- Coordination is eventual (within 5 minutes of AI analysis cycle)
|
|
104
|
+
|
|
105
|
+
## Pattern 2: ETL Pipeline with Dependencies
|
|
106
|
+
|
|
107
|
+
**Scenario**: Extract-Transform-Load pipeline where each stage depends on the previous stage completing.
|
|
108
|
+
|
|
109
|
+
### Endpoints
|
|
110
|
+
|
|
111
|
+
**Job**: "Customer Data Pipeline"
|
|
112
|
+
|
|
113
|
+
**Endpoint 1: Extract Customer Data** (cron: `0 2 * * *` - 2 AM daily)
|
|
114
|
+
- Pulls data from external API
|
|
115
|
+
- Returns: `{ "extracted_count": 5000, "batch_id": "2025-11-02", "completed_at": "2025-11-02T02:15:00Z" }`
|
|
116
|
+
|
|
117
|
+
**Endpoint 2: Transform Customer Data** (1-minute interval, waits for extract)
|
|
118
|
+
- Transforms raw data to normalized format
|
|
119
|
+
- Returns: `{ "transformed_count": 5000, "batch_id": "2025-11-02", "ready_for_load": true }`
|
|
120
|
+
|
|
121
|
+
**Endpoint 3: Load to Database** (1-minute interval, waits for transform)
|
|
122
|
+
- Loads normalized data to production database
|
|
123
|
+
- Returns: `{ "loaded_count": 5000, "batch_id": "2025-11-02", "pipeline_complete": true }`
|
|
124
|
+
|
|
125
|
+
### Response Body Structure
|
|
126
|
+
|
|
127
|
+
**Extract**:
|
|
128
|
+
```json
|
|
129
|
+
{
|
|
130
|
+
"stage": "extract",
|
|
131
|
+
"batch_id": "2025-11-02",
|
|
132
|
+
"extracted_count": 5000,
|
|
133
|
+
"completed_at": "2025-11-02T02:15:00Z",
|
|
134
|
+
"ready_for_transform": true,
|
|
135
|
+
"status": "success"
|
|
136
|
+
}
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
**Transform** (before ready):
|
|
140
|
+
```json
|
|
141
|
+
{
|
|
142
|
+
"stage": "transform",
|
|
143
|
+
"batch_id": "2025-11-01",
|
|
144
|
+
"status": "waiting",
|
|
145
|
+
"waiting_for": "extract_2025-11-02"
|
|
146
|
+
}
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
**Transform** (after ready):
|
|
150
|
+
```json
|
|
151
|
+
{
|
|
152
|
+
"stage": "transform",
|
|
153
|
+
"batch_id": "2025-11-02",
|
|
154
|
+
"transformed_count": 5000,
|
|
155
|
+
"completed_at": "2025-11-02T02:30:00Z",
|
|
156
|
+
"ready_for_load": true,
|
|
157
|
+
"status": "success"
|
|
158
|
+
}
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
### AI Coordination Logic
|
|
162
|
+
|
|
163
|
+
When AI analyzes **Transform**:
|
|
164
|
+
|
|
165
|
+
1. Calls `get_sibling_latest_responses()`
|
|
166
|
+
2. Finds Extract response: `{ "batch_id": "2025-11-02", "ready_for_transform": true }`
|
|
167
|
+
3. Checks Transform's last response: `{ "batch_id": "2025-11-01", "status": "waiting" }`
|
|
168
|
+
4. Sees new batch available (batch IDs don't match)
|
|
169
|
+
5. Calls `propose_next_time(now, reason="New batch 2025-11-02 ready for transform")`
|
|
170
|
+
|
|
171
|
+
When AI analyzes **Load**:
|
|
172
|
+
|
|
173
|
+
1. Calls `get_sibling_latest_responses()`
|
|
174
|
+
2. Finds Transform response: `{ "batch_id": "2025-11-02", "ready_for_load": true }`
|
|
175
|
+
3. Checks Load's last response: `{ "batch_id": "2025-11-01" }`
|
|
176
|
+
4. Sees new batch available
|
|
177
|
+
5. Calls `propose_next_time(now, reason="Transformed batch 2025-11-02 ready to load")`
|
|
178
|
+
|
|
179
|
+
### Key Points
|
|
180
|
+
|
|
181
|
+
- Batch IDs enable idempotency (endpoints know what they've processed)
|
|
182
|
+
- `ready_for_*` flags signal downstream readiness
|
|
183
|
+
- Transform and Load run frequently (1-minute interval) but only process when data is ready
|
|
184
|
+
- Coordination happens within minutes of upstream completion
|
|
185
|
+
|
|
186
|
+
## Pattern 3: Cooldown-Based Actions
|
|
187
|
+
|
|
188
|
+
**Scenario**: Cache warming endpoint that should run immediately when cache hit rate drops, but not more than once per hour.
|
|
189
|
+
|
|
190
|
+
### Endpoint
|
|
191
|
+
|
|
192
|
+
**Job**: "Cache Management"
|
|
193
|
+
|
|
194
|
+
**Endpoint: Cache Monitor** (5-minute interval)
|
|
195
|
+
- Monitors cache hit rate
|
|
196
|
+
- Warms cache if hit rate drops below threshold
|
|
197
|
+
- Includes cooldown tracking to prevent duplicate warming
|
|
198
|
+
|
|
199
|
+
### Response Body Structure
|
|
200
|
+
|
|
201
|
+
**Normal operation**:
|
|
202
|
+
```json
|
|
203
|
+
{
|
|
204
|
+
"cache_hit_rate_pct": 95.5,
|
|
205
|
+
"cache_size_mb": 512,
|
|
206
|
+
"status": "healthy",
|
|
207
|
+
"last_warm_at": "2025-11-02T12:00:00Z"
|
|
208
|
+
}
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
**Low hit rate detected**:
|
|
212
|
+
```json
|
|
213
|
+
{
|
|
214
|
+
"cache_hit_rate_pct": 65.2,
|
|
215
|
+
"cache_size_mb": 512,
|
|
216
|
+
"status": "degraded",
|
|
217
|
+
"last_warm_at": "2025-11-02T12:00:00Z",
|
|
218
|
+
"warm_cache_needed": true,
|
|
219
|
+
"cooldown_minutes": 60
|
|
220
|
+
}
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
**After warming**:
|
|
224
|
+
```json
|
|
225
|
+
{
|
|
226
|
+
"cache_hit_rate_pct": 94.8,
|
|
227
|
+
"cache_size_mb": 512,
|
|
228
|
+
"status": "healthy",
|
|
229
|
+
"last_warm_at": "2025-11-02T13:15:00Z",
|
|
230
|
+
"cache_warmed": true
|
|
231
|
+
}
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
### AI Coordination Logic
|
|
235
|
+
|
|
236
|
+
When AI analyzes Cache Monitor:
|
|
237
|
+
|
|
238
|
+
1. Calls `get_latest_response()`
|
|
239
|
+
2. Sees: `{ "cache_hit_rate_pct": 65.2, "warm_cache_needed": true, "last_warm_at": "2025-11-02T12:00:00Z" }`
|
|
240
|
+
3. Calls `get_response_history(limit=5)` to check recent warmings
|
|
241
|
+
4. Calculates time since last warm: `now - last_warm_at = 75 minutes`
|
|
242
|
+
5. Compares to cooldown: `75 min > 60 min cooldown`
|
|
243
|
+
6. Calls `propose_next_time(now, reason="Cache hit rate dropped to 65%, cooldown elapsed")`
|
|
244
|
+
|
|
245
|
+
If cooldown not elapsed:
|
|
246
|
+
|
|
247
|
+
1. AI sees `last_warm_at` was 30 minutes ago
|
|
248
|
+
2. Cooldown is 60 minutes
|
|
249
|
+
3. Takes no action (reasoning: "Cache warming needed but cooldown active - 30 min elapsed of 60 min required")
|
|
250
|
+
|
|
251
|
+
### Key Points
|
|
252
|
+
|
|
253
|
+
- Cooldown prevents duplicate expensive actions
|
|
254
|
+
- `last_warm_at` timestamp enables cooldown calculation
|
|
255
|
+
- AI checks response history to verify pattern
|
|
256
|
+
- Endpoint's response body drives action (not external state)
|
|
257
|
+
|
|
258
|
+
## Pattern 4: Tiered Priority System
|
|
259
|
+
|
|
260
|
+
**Scenario**: Multiple monitoring endpoints with different priorities. Under load, pause lower tiers.
|
|
261
|
+
|
|
262
|
+
### Endpoint Naming Convention
|
|
263
|
+
|
|
264
|
+
Use names/descriptions to encode priority:
|
|
265
|
+
|
|
266
|
+
- `[CRITICAL] Payment Processor`
|
|
267
|
+
- `[NORMAL] Inventory Sync`
|
|
268
|
+
- `[LOW] Analytics Updater`
|
|
269
|
+
|
|
270
|
+
Or use description field:
|
|
271
|
+
|
|
272
|
+
```json
|
|
273
|
+
{
|
|
274
|
+
"name": "Payment Processor",
|
|
275
|
+
"description": "Priority: CRITICAL. Processes customer payments."
|
|
276
|
+
}
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
### Coordination Endpoint
|
|
280
|
+
|
|
281
|
+
**System Health Monitor** (1-minute interval)
|
|
282
|
+
- Checks overall system load (CPU, memory, queue depths)
|
|
283
|
+
- Returns recommendations for priority levels to pause
|
|
284
|
+
|
|
285
|
+
**Response Body**:
|
|
286
|
+
```json
|
|
287
|
+
{
|
|
288
|
+
"system_load_pct": 85,
|
|
289
|
+
"recommendations": {
|
|
290
|
+
"active_priority_levels": ["CRITICAL", "NORMAL"],
|
|
291
|
+
"paused_priority_levels": ["LOW"],
|
|
292
|
+
"reason": "System load at 85% - pausing low-priority work"
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
### AI Logic for Each Endpoint
|
|
298
|
+
|
|
299
|
+
When AI analyzes any endpoint:
|
|
300
|
+
|
|
301
|
+
1. Calls `get_sibling_latest_responses()`
|
|
302
|
+
2. Finds System Health Monitor response
|
|
303
|
+
3. Extracts endpoint's priority from name/description
|
|
304
|
+
4. Checks if priority in `paused_priority_levels`
|
|
305
|
+
5. If yes: `pause_until(calculated_time, reason="System load high")`
|
|
306
|
+
6. If no: No action (or resume if paused)
|
|
307
|
+
|
|
308
|
+
### Key Points
|
|
309
|
+
|
|
310
|
+
- Single health monitor coordinates entire tier
|
|
311
|
+
- Priority encoded in metadata (names/descriptions)
|
|
312
|
+
- AI interprets recommendations and applies to individual endpoints
|
|
313
|
+
- Centralized policy (health monitor) with distributed execution (AI per endpoint)
|
|
314
|
+
|
|
315
|
+
## Pattern 5: Cross-Job Coordination
|
|
316
|
+
|
|
317
|
+
**Scenario**: Endpoints in different jobs need to coordinate (e.g., upstream service health affects downstream consumers).
|
|
318
|
+
|
|
319
|
+
### Challenge
|
|
320
|
+
|
|
321
|
+
`get_sibling_latest_responses()` only works within the same job. Cross-job coordination requires a different approach.
|
|
322
|
+
|
|
323
|
+
### Solution: Shared State Endpoint
|
|
324
|
+
|
|
325
|
+
**Job 1**: "Upstream Service"
|
|
326
|
+
- **Endpoint**: Health Check (1-minute interval)
|
|
327
|
+
- Returns: `{ "service_status": "healthy", "last_check": "..." }`
|
|
328
|
+
|
|
329
|
+
**Job 2**: "Downstream Consumers"
|
|
330
|
+
- **Endpoint 1**: Data Processor
|
|
331
|
+
- **Endpoint 2**: Analytics Pipeline
|
|
332
|
+
|
|
333
|
+
Configure Downstream endpoints to call Upstream Service's health endpoint and include the result in their response body:
|
|
334
|
+
|
|
335
|
+
**Data Processor Response**:
|
|
336
|
+
```json
|
|
337
|
+
{
|
|
338
|
+
"processed_count": 100,
|
|
339
|
+
"upstream_health": {
|
|
340
|
+
"status": "healthy",
|
|
341
|
+
"checked_at": "2025-11-02T14:30:00Z"
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
When upstream goes down:
|
|
347
|
+
```json
|
|
348
|
+
{
|
|
349
|
+
"processed_count": 0,
|
|
350
|
+
"error": "Upstream service unavailable",
|
|
351
|
+
"upstream_health": {
|
|
352
|
+
"status": "unavailable",
|
|
353
|
+
"checked_at": "2025-11-02T14:35:00Z"
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
### AI Logic
|
|
359
|
+
|
|
360
|
+
When AI analyzes Data Processor:
|
|
361
|
+
|
|
362
|
+
1. Calls `get_latest_response()`
|
|
363
|
+
2. Sees: `{ "upstream_health": { "status": "unavailable" } }`
|
|
364
|
+
3. Calls `pause_until(now + 15_minutes, reason="Upstream service unavailable")`
|
|
365
|
+
|
|
366
|
+
### Key Points
|
|
367
|
+
|
|
368
|
+
- Endpoints embed external dependency status in their response bodies
|
|
369
|
+
- AI reacts to dependency signals
|
|
370
|
+
- Works across jobs (no sibling query needed)
|
|
371
|
+
- Endpoint is responsible for checking upstream status
|
|
372
|
+
|
|
373
|
+
## Common Coordination Signals
|
|
374
|
+
|
|
375
|
+
Here are standard signal patterns you can reuse:
|
|
376
|
+
|
|
377
|
+
### Readiness Signals
|
|
378
|
+
```json
|
|
379
|
+
{
|
|
380
|
+
"ready_for_processing": true,
|
|
381
|
+
"data_available": true,
|
|
382
|
+
"batch_ready": true
|
|
383
|
+
}
|
|
384
|
+
```
|
|
385
|
+
|
|
386
|
+
### Dependency Status
|
|
387
|
+
```json
|
|
388
|
+
{
|
|
389
|
+
"dependency_status": "healthy" | "degraded" | "unavailable",
|
|
390
|
+
"upstream_healthy": true
|
|
391
|
+
}
|
|
392
|
+
```
|
|
393
|
+
|
|
394
|
+
### Action Requests
|
|
395
|
+
```json
|
|
396
|
+
{
|
|
397
|
+
"warm_cache_needed": true,
|
|
398
|
+
"scale_up_needed": true,
|
|
399
|
+
"send_alert": true
|
|
400
|
+
}
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
### Cooldown Tracking
|
|
404
|
+
```json
|
|
405
|
+
{
|
|
406
|
+
"last_action_at": "2025-11-02T14:30:00Z",
|
|
407
|
+
"cooldown_minutes": 60,
|
|
408
|
+
"action_type": "cache_warm" | "alert_sent" | "scaled"
|
|
409
|
+
}
|
|
410
|
+
```
|
|
411
|
+
|
|
412
|
+
### Load/Priority Signals
|
|
413
|
+
```json
|
|
414
|
+
{
|
|
415
|
+
"load_status": "normal" | "elevated" | "high" | "critical",
|
|
416
|
+
"pause_priorities": ["LOW", "NORMAL"],
|
|
417
|
+
"active_priorities": ["CRITICAL"]
|
|
418
|
+
}
|
|
419
|
+
```
|
|
420
|
+
|
|
421
|
+
## Best Practices
|
|
422
|
+
|
|
423
|
+
1. **Be explicit**: Use clear signal names (`ready_for_load` not `ready`)
|
|
424
|
+
2. **Include timestamps**: Enable cooldown calculations and staleness checks
|
|
425
|
+
3. **Provide context**: Add `reason` fields explaining state
|
|
426
|
+
4. **Use batch IDs**: Enable idempotency in pipelines
|
|
427
|
+
5. **Keep signals simple**: AI reads truncated bodies (1000 chars)
|
|
428
|
+
6. **Document protocols**: Comment what signals mean in endpoint descriptions
|
|
429
|
+
7. **Test coordination**: Verify AI picks up signals by checking analysis sessions
|
|
430
|
+
|
|
431
|
+
## Debugging Coordination
|
|
432
|
+
|
|
433
|
+
When coordination isn't working:
|
|
434
|
+
|
|
435
|
+
1. **Check sibling responses**: Does `get_sibling_latest_responses()` return expected data?
|
|
436
|
+
2. **Review AI sessions**: What did AI see? What reasoning did it provide?
|
|
437
|
+
3. **Verify signal format**: Are field names consistent?
|
|
438
|
+
4. **Check timing**: AI analyzes every 5 minutes—coordination isn't instant
|
|
439
|
+
5. **Look for errors**: Did endpoint fail to write expected signal?
|
|
440
|
+
|
|
441
|
+
## Key Takeaways
|
|
442
|
+
|
|
443
|
+
1. **Coordination via response bodies**: Write signals, other endpoints read them
|
|
444
|
+
2. **AI interprets signals**: Uses `get_sibling_latest_responses()` and `get_latest_response()`
|
|
445
|
+
3. **Eventual consistency**: Coordination happens within minutes (AI analysis cycle)
|
|
446
|
+
4. **Flexible protocols**: You define what signals mean
|
|
447
|
+
5. **Priority systems**: Use names/descriptions to encode metadata
|
|
448
|
+
6. **Cooldowns prevent duplicates**: Track `last_action_at` in response bodies
|
|
449
|
+
7. **Cross-job coordination**: Embed external status checks in responses
|
|
450
|
+
|
|
451
|
+
These patterns give you the building blocks for complex workflows. Mix and match based on your needs.
|
|
452
|
+
|
|
453
|
+
## Next Steps
|
|
454
|
+
|
|
455
|
+
- **[Configuration and Constraints](./configuration-and-constraints.md)** - Set up endpoints for optimal coordination
|
|
456
|
+
- **[How AI Adaptation Works](./how-ai-adaptation-works.md)** - Understand how AI reads and acts on signals
|
|
457
|
+
- **[Reference](./reference.md)** - Quick lookup for tools and response body patterns
|