@miller-tech/uap 1.20.33 → 1.20.35
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/config/model-profiles/qwen35.json +6 -5
- package/dist/.tsbuildinfo +1 -1
- package/dist/bin/cli.js +6 -1
- package/dist/bin/cli.js.map +1 -1
- package/dist/cli/hooks.js +30 -7
- package/dist/cli/hooks.js.map +1 -1
- package/dist/cli/policy.d.ts.map +1 -1
- package/dist/cli/policy.js +26 -0
- package/dist/cli/policy.js.map +1 -1
- package/dist/index.d.ts +15 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +14 -0
- package/dist/index.js.map +1 -1
- package/dist/types/index.d.ts +20 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +20 -0
- package/dist/types/index.js.map +1 -1
- package/docs/AGENTS.md +423 -0
- package/docs/AGENTS.md</path>CLAUDE.md</path>/home/cogtek/dev/miller-tech/universal-agent-protocol/docs/INDEX.md</path>/home/cogtek/dev/miller-tech/universal-agent-protocol/docs/reference/API_REFERENCE.md</path>/home/cogtek/dev/miller-tech/universal-agent-protocol/docs/reference/UAP_CLI_REFERENCE.md</path>src/index.ts</path>/src/cli/worktree.ts</path>/src/coordination/deploy-batcher.ts</path>/src/policies/policy-gate.ts</path>/src/memory/model-router.ts</path>/src/memory/embeddings.ts</path>/src/models/types.ts</path>/src/types/coordination.ts</path>/src/utils/logger.ts</path>/src/utils/config-loader.ts</path>/src/utils/performance-monitor.ts</path>/src/utils/concurrency.ts</path>/src/utils/concurrency-pool.ts</path>/src/utils/string-similarity.ts</path>/src/utils/rate-limiter.ts</path>/src/utils/system-resources.ts</path>/src/utils/adaptive-cache.ts</path>/src/utils/lazy-imports.ts</path>/src/utils/merge-claude-md.ts</path>/src/utils/stopwords.ts</path>/src/utils/config-loader.ts</path>/src/utils/performance-monitor.ts</path>/src/utils/concurrency.ts</path>/src/utils/concurrency-pool.ts</path>/src/utils/string-similarity.ts</path>/src/utils/rate-limiter.ts</path>/src/utils/system-resources.ts</path>/src/utils/adaptive-cache.ts</path>/src/utils/lazy-imports.ts</path>/src/utils/merge-claude-md.ts</path>/src/utils/stopwords.ts</path> +433 -0
- package/docs/DOCUMENTATION_AUDIT_REPORT.md +131 -0
- package/docs/GETTING_STARTED.md +288 -0
- package/docs/INDEX.md +272 -42
- package/docs/PROJECT_ANALYSIS_REPORT.md +510 -0
- package/docs/architecture/SYSTEM_ANALYSIS.md +220 -1003
- package/docs/blog/local-coding-agents.md +266 -0
- package/docs/blog/x-thread.md +254 -0
- package/docs/deployment/DEPLOY_BATCHER_ANALYSIS.md +15 -647
- package/docs/getting-started/OVERVIEW.md +10 -30
- package/docs/getting-started/SETUP.md +183 -9
- package/docs/pr/UPSTREAM_PRS.md +424 -0
- package/docs/reference/CONFIGURATION.md +208 -0
- package/docs/reference/DATABASE_SCHEMA.md +344 -0
- package/docs/reference/PATTERN_LIBRARY.md +636 -0
- package/package.json +1 -1
- package/templates/hooks/uap-policy-gate.sh +36 -0
- package/tools/agents/claude_local_agent.py +92 -0
- package/tools/agents/config/qwen3.5-enhanced.jinja +187 -0
- package/tools/agents/opencode_uap_agent.py +3 -0
- package/tools/agents/scripts/anthropic_proxy.py +1748 -76
- package/tools/agents/tests/test_anthropic_proxy_streaming.py +64 -8
- package/tools/agents/uap_agent.py +1 -1
|
@@ -1,30 +1,16 @@
|
|
|
1
|
-
# DeployBatcher
|
|
1
|
+
# DeployBatcher Analysis
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
## Table of Contents
|
|
6
|
-
|
|
7
|
-
1. [Overview](#overview)
|
|
8
|
-
2. [Architecture](#architecture)
|
|
9
|
-
3. [Type System](#type-system)
|
|
10
|
-
4. [Class Diagram](#class-diagram)
|
|
11
|
-
5. [Core Features](#core-features)
|
|
12
|
-
6. [Data Flow](#data-flow)
|
|
13
|
-
7. [State Management](#state-management)
|
|
14
|
-
8. [CI/CD Optimization Strategies](#cicd-optimization-strategies)
|
|
15
|
-
9. [CLI Integration](#cli-integration)
|
|
16
|
-
10. [Usage Examples](#usage-examples)
|
|
17
|
-
11. [Performance Characteristics](#performance-characteristics)
|
|
3
|
+
Intelligent batching and deduplication for multi-agent deployment scenarios.
|
|
18
4
|
|
|
19
5
|
---
|
|
20
6
|
|
|
21
7
|
## Overview
|
|
22
8
|
|
|
23
|
-
The `DeployBatcher`
|
|
9
|
+
The `DeployBatcher` optimizes CI/CD pipeline usage in multi-agent environments through SQLite-backed coordination. Multiple agents queue actions that batch into single CI runs, reducing pipeline minutes by 50-80%.
|
|
24
10
|
|
|
25
|
-
###
|
|
11
|
+
### Problem Solved
|
|
26
12
|
|
|
27
|
-
```
|
|
13
|
+
```text
|
|
28
14
|
Without DeployBatcher:
|
|
29
15
|
Agent A commits → CI Run 1 (5 min)
|
|
30
16
|
Agent B commits → CI Run 2 (5 min)
|
|
@@ -34,7 +20,6 @@ Without DeployBatcher:
|
|
|
34
20
|
|
|
35
21
|
With DeployBatcher:
|
|
36
22
|
Agent A, B, C queue commits → Batched → Single squashed commit
|
|
37
|
-
Single push → CI Run 1 (5 min)
|
|
38
23
|
Total: 1 run × 5 min = 5 CI minutes (75% reduction)
|
|
39
24
|
```
|
|
40
25
|
|
|
@@ -43,7 +28,7 @@ With DeployBatcher:
|
|
|
43
28
|
## Architecture
|
|
44
29
|
|
|
45
30
|
```mermaid
|
|
46
|
-
|
|
31
|
+
flowchart TB
|
|
47
32
|
subgraph "Multi-Agent Environment"
|
|
48
33
|
A1[Agent 1]
|
|
49
34
|
A2[Agent 2]
|
|
@@ -85,616 +70,9 @@ graph TB
|
|
|
85
70
|
E --> GH
|
|
86
71
|
E --> DEPLOY
|
|
87
72
|
|
|
88
|
-
style Q fill:#
|
|
89
|
-
style B fill:#fff3e0
|
|
90
|
-
style S fill:#
|
|
91
|
-
style E fill:#e8f5e9
|
|
92
|
-
```
|
|
93
|
-
|
|
94
|
-
---
|
|
95
|
-
|
|
96
|
-
## Type System
|
|
97
|
-
|
|
98
|
-
### Core Types (from `types/coordination.ts`)
|
|
99
|
-
|
|
100
|
-
```typescript
|
|
101
|
-
// Action types that can be batched
|
|
102
|
-
type DeployActionType = 'commit' | 'push' | 'merge' | 'deploy' | 'workflow';
|
|
103
|
-
|
|
104
|
-
// Status lifecycle
|
|
105
|
-
type DeployStatus = 'pending' | 'batched' | 'executing' | 'completed' | 'failed';
|
|
106
|
-
|
|
107
|
-
// Single deploy action
|
|
108
|
-
interface DeployAction {
|
|
109
|
-
id: number;
|
|
110
|
-
agentId: string;
|
|
111
|
-
actionType: DeployActionType;
|
|
112
|
-
target: string;
|
|
113
|
-
payload?: Record<string, unknown>;
|
|
114
|
-
status: DeployStatus;
|
|
115
|
-
batchId?: string;
|
|
116
|
-
queuedAt: string;
|
|
117
|
-
executeAfter?: string;
|
|
118
|
-
priority: number;
|
|
119
|
-
dependencies?: string[];
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
// Grouped batch
|
|
123
|
-
interface DeployBatch {
|
|
124
|
-
id: string; // UUID
|
|
125
|
-
actions: DeployAction[];
|
|
126
|
-
createdAt: string;
|
|
127
|
-
status: DeployStatus;
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
// Execution result
|
|
131
|
-
interface BatchResult {
|
|
132
|
-
batchId: string;
|
|
133
|
-
success: boolean;
|
|
134
|
-
executedActions: number;
|
|
135
|
-
failedActions: number;
|
|
136
|
-
errors?: string[];
|
|
137
|
-
duration: number; // milliseconds
|
|
138
|
-
}
|
|
139
|
-
```
|
|
140
|
-
|
|
141
|
-
### Configuration Interfaces
|
|
142
|
-
|
|
143
|
-
```typescript
|
|
144
|
-
// Dynamic window configuration (per action type)
|
|
145
|
-
interface DynamicBatchWindows {
|
|
146
|
-
commit: number; // Default: 30000ms (30s)
|
|
147
|
-
push: number; // Default: 5000ms (5s)
|
|
148
|
-
merge: number; // Default: 10000ms (10s)
|
|
149
|
-
workflow: number; // Default: 5000ms (5s)
|
|
150
|
-
deploy: number; // Default: 60000ms (60s)
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
// Batcher configuration
|
|
154
|
-
interface DeployBatcherConfig {
|
|
155
|
-
dbPath?: string;
|
|
156
|
-
batchWindowMs?: number; // Legacy single window
|
|
157
|
-
dynamicWindows?: Partial<DynamicBatchWindows>;
|
|
158
|
-
maxBatchSize?: number; // Default: 20
|
|
159
|
-
dryRun?: boolean;
|
|
160
|
-
parallelExecution?: boolean; // Default: true
|
|
161
|
-
maxParallelActions?: number; // Default: 5
|
|
162
|
-
}
|
|
163
|
-
```
|
|
164
|
-
|
|
165
|
-
---
|
|
166
|
-
|
|
167
|
-
## Class Diagram
|
|
168
|
-
|
|
169
|
-
```mermaid
|
|
170
|
-
classDiagram
|
|
171
|
-
class DeployBatcher {
|
|
172
|
-
-db: Database
|
|
173
|
-
-dynamicWindows: DynamicBatchWindows
|
|
174
|
-
-maxBatchSize: number
|
|
175
|
-
-dryRun: boolean
|
|
176
|
-
-parallelExecution: boolean
|
|
177
|
-
-maxParallelActions: number
|
|
178
|
-
|
|
179
|
-
+constructor(config?: DeployBatcherConfig)
|
|
180
|
-
+getBatchWindow(actionType): number
|
|
181
|
-
+setUrgentMode(urgent: boolean): void
|
|
182
|
-
+queue(agentId, actionType, target, payload?, options?): Promise~number~
|
|
183
|
-
+queueBulk(agentId, actions): Promise~number[]~
|
|
184
|
-
+createBatch(): Promise~DeployBatch|null~
|
|
185
|
-
+executeBatch(batchId): Promise~BatchResult~
|
|
186
|
-
+getBatch(batchId): DeployBatch|null
|
|
187
|
-
+getPendingBatches(): DeployBatch[]
|
|
188
|
-
+flushAll(): Promise~BatchResult[]~
|
|
189
|
-
+getWindowConfig(): DynamicBatchWindows
|
|
190
|
-
|
|
191
|
-
-queueSync(agentId, actionType, target, payload?, options?): number
|
|
192
|
-
-findSimilarAction(actionType, target): DeployAction|null
|
|
193
|
-
-canMerge(existing, incoming): boolean
|
|
194
|
-
-mergeActions(existingId, newPayload?): Promise~void~
|
|
195
|
-
-mergePayloads(existing, incoming): Record
|
|
196
|
-
-groupByTarget(actions): Map
|
|
197
|
-
-squashActions(grouped): DeployAction[]
|
|
198
|
-
-squashCommits(commits): DeployAction
|
|
199
|
-
-categorizeActions(actions): {sequential, parallel}
|
|
200
|
-
-executeParallel(actions): Promise~Array~
|
|
201
|
-
-executeAction(action): Promise~void~
|
|
202
|
-
-executeCommit(target, payload): Promise~void~
|
|
203
|
-
-executePush(target, payload): Promise~void~
|
|
204
|
-
-executeMerge(target, payload): Promise~void~
|
|
205
|
-
-executeWorkflow(target, payload): Promise~void~
|
|
206
|
-
-executeDeploy(target, payload): Promise~void~
|
|
207
|
-
-updateActionStatus(actionId, status): void
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
class CoordinationDatabase {
|
|
211
|
-
-db: Database
|
|
212
|
-
-instance: CoordinationDatabase$
|
|
213
|
-
|
|
214
|
-
+getInstance(dbPath): CoordinationDatabase$
|
|
215
|
-
+resetInstance(): void$
|
|
216
|
-
+getDatabase(): Database
|
|
217
|
-
+close(): void
|
|
218
|
-
-initSchema(): void
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
class DeployAction {
|
|
222
|
-
<<interface>>
|
|
223
|
-
+id: number
|
|
224
|
-
+agentId: string
|
|
225
|
-
+actionType: DeployActionType
|
|
226
|
-
+target: string
|
|
227
|
-
+payload?: Record
|
|
228
|
-
+status: DeployStatus
|
|
229
|
-
+batchId?: string
|
|
230
|
-
+queuedAt: string
|
|
231
|
-
+executeAfter?: string
|
|
232
|
-
+priority: number
|
|
233
|
-
+dependencies?: string[]
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
class DeployBatch {
|
|
237
|
-
<<interface>>
|
|
238
|
-
+id: string
|
|
239
|
-
+actions: DeployAction[]
|
|
240
|
-
+createdAt: string
|
|
241
|
-
+status: DeployStatus
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
class BatchResult {
|
|
245
|
-
<<interface>>
|
|
246
|
-
+batchId: string
|
|
247
|
-
+success: boolean
|
|
248
|
-
+executedActions: number
|
|
249
|
-
+failedActions: number
|
|
250
|
-
+errors?: string[]
|
|
251
|
-
+duration: number
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
class DynamicBatchWindows {
|
|
255
|
-
<<interface>>
|
|
256
|
-
+commit: number
|
|
257
|
-
+push: number
|
|
258
|
-
+merge: number
|
|
259
|
-
+workflow: number
|
|
260
|
-
+deploy: number
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
DeployBatcher --> CoordinationDatabase : uses
|
|
264
|
-
DeployBatcher --> DeployAction : manages
|
|
265
|
-
DeployBatcher --> DeployBatch : creates
|
|
266
|
-
DeployBatcher --> BatchResult : returns
|
|
267
|
-
DeployBatcher --> DynamicBatchWindows : configures
|
|
268
|
-
DeployBatch --> DeployAction : contains
|
|
269
|
-
```
|
|
270
|
-
|
|
271
|
-
---
|
|
272
|
-
|
|
273
|
-
## Core Features
|
|
274
|
-
|
|
275
|
-
### 1. Dynamic Batch Windows
|
|
276
|
-
|
|
277
|
-
Different action types have different time-sensitivity requirements:
|
|
278
|
-
|
|
279
|
-
| Action Type | Window | Rationale |
|
|
280
|
-
|-------------|--------|-----------|
|
|
281
|
-
| `push` | 5s | PRs need fast feedback |
|
|
282
|
-
| `workflow` | 5s | CI triggers should be responsive |
|
|
283
|
-
| `merge` | 10s | Moderate safety buffer |
|
|
284
|
-
| `commit` | 30s | Allows squashing multiple commits |
|
|
285
|
-
| `deploy` | 60s | Safety buffer for production |
|
|
286
|
-
|
|
287
|
-
```mermaid
|
|
288
|
-
gantt
|
|
289
|
-
title Batch Window Timeline
|
|
290
|
-
dateFormat X
|
|
291
|
-
axisFormat %s
|
|
292
|
-
|
|
293
|
-
section Push Actions
|
|
294
|
-
Window (5s) :0, 5
|
|
295
|
-
|
|
296
|
-
section Workflow Actions
|
|
297
|
-
Window (5s) :0, 5
|
|
298
|
-
|
|
299
|
-
section Merge Actions
|
|
300
|
-
Window (10s) :0, 10
|
|
301
|
-
|
|
302
|
-
section Commit Actions
|
|
303
|
-
Window (30s) :0, 30
|
|
304
|
-
|
|
305
|
-
section Deploy Actions
|
|
306
|
-
Window (60s) :0, 60
|
|
307
|
-
```
|
|
308
|
-
|
|
309
|
-
### 2. Action Merging & Deduplication
|
|
310
|
-
|
|
311
|
-
The batcher intelligently merges similar pending actions:
|
|
312
|
-
|
|
313
|
-
```mermaid
|
|
314
|
-
flowchart LR
|
|
315
|
-
subgraph "Incoming Actions"
|
|
316
|
-
C1[Commit: file1.ts]
|
|
317
|
-
C2[Commit: file2.ts]
|
|
318
|
-
C3[Commit: file3.ts]
|
|
319
|
-
P1[Push: main]
|
|
320
|
-
P2[Push: main]
|
|
321
|
-
W1[Workflow: test.yml]
|
|
322
|
-
W2[Workflow: test.yml]
|
|
323
|
-
end
|
|
324
|
-
|
|
325
|
-
subgraph "Merge Logic"
|
|
326
|
-
MC[canMerge]
|
|
327
|
-
MP[mergePayloads]
|
|
328
|
-
end
|
|
329
|
-
|
|
330
|
-
subgraph "Result"
|
|
331
|
-
SC[Squashed Commit:\nfile1, file2, file3]
|
|
332
|
-
SP[Single Push: main]
|
|
333
|
-
SW[Single Workflow: test.yml]
|
|
334
|
-
end
|
|
335
|
-
|
|
336
|
-
C1 --> MC
|
|
337
|
-
C2 --> MC
|
|
338
|
-
C3 --> MC
|
|
339
|
-
MC --> MP
|
|
340
|
-
MP --> SC
|
|
341
|
-
|
|
342
|
-
P1 --> MC
|
|
343
|
-
P2 --> MC
|
|
344
|
-
MC --> SP
|
|
345
|
-
|
|
346
|
-
W1 --> MC
|
|
347
|
-
W2 --> MC
|
|
348
|
-
MC --> SW
|
|
349
|
-
```
|
|
350
|
-
|
|
351
|
-
### 3. Commit Squashing
|
|
352
|
-
|
|
353
|
-
Multiple commits to the same target are squashed into one:
|
|
354
|
-
|
|
355
|
-
```typescript
|
|
356
|
-
// Input: 3 separate commits
|
|
357
|
-
[
|
|
358
|
-
{ message: "fix: typo in auth", files: ["src/auth.ts"] },
|
|
359
|
-
{ message: "feat: add logging", files: ["src/logger.ts"] },
|
|
360
|
-
{ message: "test: add auth tests", files: ["test/auth.test.ts"] }
|
|
361
|
-
]
|
|
362
|
-
|
|
363
|
-
// Output: Single squashed commit
|
|
364
|
-
{
|
|
365
|
-
message: "Squashed 3 commits:\n\n1. fix: typo in auth\n2. feat: add logging\n3. test: add auth tests",
|
|
366
|
-
files: ["src/auth.ts", "src/logger.ts", "test/auth.test.ts"],
|
|
367
|
-
squashedFrom: [1, 2, 3]
|
|
368
|
-
}
|
|
369
|
-
```
|
|
370
|
-
|
|
371
|
-
### 4. Parallel Execution
|
|
372
|
-
|
|
373
|
-
Actions are categorized for parallel vs sequential execution:
|
|
374
|
-
|
|
375
|
-
```mermaid
|
|
376
|
-
flowchart TB
|
|
377
|
-
subgraph "Action Pool"
|
|
378
|
-
A1[Commit]
|
|
379
|
-
A2[Push]
|
|
380
|
-
A3[Workflow 1]
|
|
381
|
-
A4[Workflow 2]
|
|
382
|
-
A5[Workflow 3]
|
|
383
|
-
A6[Deploy]
|
|
384
|
-
end
|
|
385
|
-
|
|
386
|
-
subgraph "Categorization"
|
|
387
|
-
CAT{categorizeActions}
|
|
388
|
-
end
|
|
389
|
-
|
|
390
|
-
subgraph "Sequential Queue"
|
|
391
|
-
S1[Commit]
|
|
392
|
-
S2[Push]
|
|
393
|
-
S3[Deploy]
|
|
394
|
-
end
|
|
395
|
-
|
|
396
|
-
subgraph "Parallel Pool"
|
|
397
|
-
P1[Workflow 1]
|
|
398
|
-
P2[Workflow 2]
|
|
399
|
-
P3[Workflow 3]
|
|
400
|
-
end
|
|
401
|
-
|
|
402
|
-
A1 --> CAT
|
|
403
|
-
A2 --> CAT
|
|
404
|
-
A3 --> CAT
|
|
405
|
-
A4 --> CAT
|
|
406
|
-
A5 --> CAT
|
|
407
|
-
A6 --> CAT
|
|
408
|
-
|
|
409
|
-
CAT --> S1
|
|
410
|
-
CAT --> S2
|
|
411
|
-
CAT --> S3
|
|
412
|
-
CAT --> P1
|
|
413
|
-
CAT --> P2
|
|
414
|
-
CAT --> P3
|
|
415
|
-
|
|
416
|
-
S1 --> |"order matters"| S2
|
|
417
|
-
S2 --> S3
|
|
418
|
-
|
|
419
|
-
P1 --> |"concurrent"| DONE[Complete]
|
|
420
|
-
P2 --> |"concurrent"| DONE
|
|
421
|
-
P3 --> |"concurrent"| DONE
|
|
422
|
-
```
|
|
423
|
-
|
|
424
|
-
**Parallel-safe types**: `workflow` (no state dependencies)
|
|
425
|
-
**Sequential types**: `commit`, `push`, `merge`, `deploy` (state-dependent)
|
|
426
|
-
|
|
427
|
-
### 5. Urgent Mode
|
|
428
|
-
|
|
429
|
-
For time-critical operations, urgent mode reduces all windows:
|
|
430
|
-
|
|
431
|
-
```typescript
|
|
432
|
-
// Normal mode
|
|
433
|
-
{ commit: 30000, push: 5000, merge: 10000, workflow: 5000, deploy: 60000 }
|
|
434
|
-
|
|
435
|
-
// Urgent mode
|
|
436
|
-
{ commit: 2000, push: 1000, merge: 2000, workflow: 1000, deploy: 5000 }
|
|
437
|
-
```
|
|
438
|
-
|
|
439
|
-
---
|
|
440
|
-
|
|
441
|
-
## Data Flow
|
|
442
|
-
|
|
443
|
-
### Queue → Batch → Execute Flow
|
|
444
|
-
|
|
445
|
-
```mermaid
|
|
446
|
-
sequenceDiagram
|
|
447
|
-
participant A1 as Agent 1
|
|
448
|
-
participant A2 as Agent 2
|
|
449
|
-
participant Q as queue()
|
|
450
|
-
participant DB as SQLite
|
|
451
|
-
participant CB as createBatch()
|
|
452
|
-
participant EB as executeBatch()
|
|
453
|
-
participant GIT as Git/GitHub
|
|
454
|
-
|
|
455
|
-
Note over A1,A2: Multiple agents queue actions
|
|
456
|
-
|
|
457
|
-
A1->>Q: queue(commit, main, {files})
|
|
458
|
-
Q->>DB: INSERT INTO deploy_queue
|
|
459
|
-
Q-->>A1: action_id: 1
|
|
460
|
-
|
|
461
|
-
A2->>Q: queue(commit, main, {files})
|
|
462
|
-
Q->>DB: findSimilarAction()
|
|
463
|
-
DB-->>Q: existing action found
|
|
464
|
-
Q->>DB: mergeActions()
|
|
465
|
-
Q-->>A2: action_id: 1 (merged)
|
|
466
|
-
|
|
467
|
-
A1->>Q: queue(push, main)
|
|
468
|
-
Q->>DB: INSERT INTO deploy_queue
|
|
469
|
-
Q-->>A1: action_id: 2
|
|
470
|
-
|
|
471
|
-
Note over CB: Time window expires
|
|
472
|
-
|
|
473
|
-
rect rgb(255, 243, 224)
|
|
474
|
-
CB->>DB: SELECT pending WHERE execute_after <= now
|
|
475
|
-
DB-->>CB: [action 1, action 2]
|
|
476
|
-
CB->>CB: groupByTarget()
|
|
477
|
-
CB->>CB: squashActions()
|
|
478
|
-
CB->>DB: UPDATE status='batched', INSERT batch
|
|
479
|
-
CB-->>EB: DeployBatch
|
|
480
|
-
end
|
|
481
|
-
|
|
482
|
-
rect rgb(232, 245, 233)
|
|
483
|
-
EB->>EB: categorizeActions()
|
|
484
|
-
EB->>DB: UPDATE status='executing'
|
|
485
|
-
|
|
486
|
-
par Parallel Execution
|
|
487
|
-
EB->>GIT: executeAction(workflow)
|
|
488
|
-
and
|
|
489
|
-
EB->>GIT: executeAction(workflow)
|
|
490
|
-
end
|
|
491
|
-
|
|
492
|
-
loop Sequential Execution
|
|
493
|
-
EB->>GIT: executeCommit()
|
|
494
|
-
EB->>GIT: executePush()
|
|
495
|
-
end
|
|
496
|
-
|
|
497
|
-
EB->>DB: UPDATE status='completed'
|
|
498
|
-
EB-->>A1: BatchResult
|
|
499
|
-
end
|
|
500
|
-
```
|
|
501
|
-
|
|
502
|
-
---
|
|
503
|
-
|
|
504
|
-
## State Management
|
|
505
|
-
|
|
506
|
-
### Action Status Lifecycle
|
|
507
|
-
|
|
508
|
-
```mermaid
|
|
509
|
-
stateDiagram-v2
|
|
510
|
-
[*] --> pending: queue()
|
|
511
|
-
|
|
512
|
-
pending --> pending: mergeActions()
|
|
513
|
-
pending --> batched: createBatch()
|
|
514
|
-
|
|
515
|
-
batched --> executing: executeBatch()
|
|
516
|
-
|
|
517
|
-
executing --> completed: success
|
|
518
|
-
executing --> failed: error
|
|
519
|
-
|
|
520
|
-
completed --> [*]
|
|
521
|
-
failed --> [*]
|
|
522
|
-
|
|
523
|
-
note right of pending
|
|
524
|
-
Actions wait in queue
|
|
525
|
-
until executeAfter time
|
|
526
|
-
end note
|
|
527
|
-
|
|
528
|
-
note right of batched
|
|
529
|
-
Actions grouped into
|
|
530
|
-
batch, ready for execution
|
|
531
|
-
end note
|
|
532
|
-
|
|
533
|
-
note right of executing
|
|
534
|
-
Parallel/sequential
|
|
535
|
-
execution in progress
|
|
536
|
-
end note
|
|
537
|
-
```
|
|
538
|
-
|
|
539
|
-
### Batch Status Lifecycle
|
|
540
|
-
|
|
541
|
-
```mermaid
|
|
542
|
-
stateDiagram-v2
|
|
543
|
-
[*] --> pending: createBatch()
|
|
544
|
-
|
|
545
|
-
pending --> executing: executeBatch() starts
|
|
546
|
-
|
|
547
|
-
executing --> completed: all actions succeed
|
|
548
|
-
executing --> completed: partial success (some failed)
|
|
549
|
-
executing --> failed: all actions failed
|
|
550
|
-
|
|
551
|
-
completed --> [*]
|
|
552
|
-
failed --> [*]
|
|
553
|
-
```
|
|
554
|
-
|
|
555
|
-
---
|
|
556
|
-
|
|
557
|
-
## CI/CD Optimization Strategies
|
|
558
|
-
|
|
559
|
-
### Strategy 1: Commit Squashing
|
|
560
|
-
|
|
561
|
-
**Problem**: N commits = N CI runs
|
|
562
|
-
**Solution**: Squash commits within window into single commit
|
|
563
|
-
|
|
564
|
-
```mermaid
|
|
565
|
-
flowchart LR
|
|
566
|
-
subgraph "Without Squashing"
|
|
567
|
-
C1A[Commit 1] --> CI1[CI Run 1]
|
|
568
|
-
C2A[Commit 2] --> CI2[CI Run 2]
|
|
569
|
-
C3A[Commit 3] --> CI3[CI Run 3]
|
|
570
|
-
end
|
|
571
|
-
|
|
572
|
-
subgraph "With Squashing"
|
|
573
|
-
C1B[Commit 1] --> SQ[Squash]
|
|
574
|
-
C2B[Commit 2] --> SQ
|
|
575
|
-
C3B[Commit 3] --> SQ
|
|
576
|
-
SQ --> CIS[CI Run 1]
|
|
577
|
-
end
|
|
578
|
-
|
|
579
|
-
style CI1 fill:#ffcdd2
|
|
580
|
-
style CI2 fill:#ffcdd2
|
|
581
|
-
style CI3 fill:#ffcdd2
|
|
582
|
-
style CIS fill:#c8e6c9
|
|
583
|
-
```
|
|
584
|
-
|
|
585
|
-
**Savings**: ~67% reduction (3 runs → 1 run)
|
|
586
|
-
|
|
587
|
-
### Strategy 2: Push Deduplication
|
|
588
|
-
|
|
589
|
-
**Problem**: Multiple agents push to same branch
|
|
590
|
-
**Solution**: Merge push requests, execute once
|
|
591
|
-
|
|
592
|
-
```mermaid
|
|
593
|
-
flowchart LR
|
|
594
|
-
subgraph "Without Dedup"
|
|
595
|
-
P1A[Push Agent 1] --> CI1[CI Run 1]
|
|
596
|
-
P2A[Push Agent 2] --> CI2[CI Run 2]
|
|
597
|
-
end
|
|
598
|
-
|
|
599
|
-
subgraph "With Dedup"
|
|
600
|
-
P1B[Push Agent 1] --> MERGE[Merge]
|
|
601
|
-
P2B[Push Agent 2] --> MERGE
|
|
602
|
-
MERGE --> CIS[CI Run 1]
|
|
603
|
-
end
|
|
604
|
-
|
|
605
|
-
style CI1 fill:#ffcdd2
|
|
606
|
-
style CI2 fill:#ffcdd2
|
|
607
|
-
style CIS fill:#c8e6c9
|
|
608
|
-
```
|
|
609
|
-
|
|
610
|
-
### Strategy 3: Workflow Trigger Batching
|
|
611
|
-
|
|
612
|
-
**Problem**: Redundant workflow dispatches
|
|
613
|
-
**Solution**: Deduplicate identical workflow triggers
|
|
614
|
-
|
|
615
|
-
### Strategy 4: Time-Window Batching
|
|
616
|
-
|
|
617
|
-
**Problem**: Rapid-fire actions trigger multiple pipelines
|
|
618
|
-
**Solution**: Delay execution to collect related actions
|
|
619
|
-
|
|
620
|
-
```mermaid
|
|
621
|
-
gantt
|
|
622
|
-
title Action Batching Timeline
|
|
623
|
-
dateFormat X
|
|
624
|
-
axisFormat %s
|
|
625
|
-
|
|
626
|
-
section Without Batching
|
|
627
|
-
Action 1 :a1, 0, 1
|
|
628
|
-
CI Run 1 :crit, ci1, 1, 6
|
|
629
|
-
Action 2 :a2, 3, 1
|
|
630
|
-
CI Run 2 :crit, ci2, 4, 9
|
|
631
|
-
Action 3 :a3, 5, 1
|
|
632
|
-
CI Run 3 :crit, ci3, 6, 11
|
|
633
|
-
|
|
634
|
-
section With Batching (30s window)
|
|
635
|
-
Action 1 :a1b, 0, 1
|
|
636
|
-
Action 2 :a2b, 3, 1
|
|
637
|
-
Action 3 :a3b, 5, 1
|
|
638
|
-
Window :active, w, 0, 30
|
|
639
|
-
Batch CI :done, bci, 30, 35
|
|
640
|
-
```
|
|
641
|
-
|
|
642
|
-
---
|
|
643
|
-
|
|
644
|
-
## CLI Integration
|
|
645
|
-
|
|
646
|
-
The `DeployBatcher` is exposed through the CLI:
|
|
647
|
-
|
|
648
|
-
```bash
|
|
649
|
-
# Queue a commit
|
|
650
|
-
uam deploy queue --agent-id <id> --action-type commit --target main \
|
|
651
|
-
--message "feat: new feature" --files "src/feature.ts"
|
|
652
|
-
|
|
653
|
-
# Queue a push
|
|
654
|
-
uam deploy queue --agent-id <id> --action-type push --target main
|
|
655
|
-
|
|
656
|
-
# Queue a workflow trigger
|
|
657
|
-
uam deploy queue --agent-id <id> --action-type workflow --target test.yml \
|
|
658
|
-
--ref main --inputs '{"env":"staging"}'
|
|
659
|
-
|
|
660
|
-
# View status
|
|
661
|
-
uam deploy status
|
|
662
|
-
|
|
663
|
-
# Create batch manually
|
|
664
|
-
uam deploy batch
|
|
665
|
-
|
|
666
|
-
# Execute specific batch
|
|
667
|
-
uam deploy execute --batch-id <uuid>
|
|
668
|
-
|
|
669
|
-
# Flush all pending
|
|
670
|
-
uam deploy flush
|
|
671
|
-
```
|
|
672
|
-
|
|
673
|
-
### CLI Command Flow
|
|
674
|
-
|
|
675
|
-
```mermaid
|
|
676
|
-
flowchart TB
|
|
677
|
-
subgraph "CLI Commands"
|
|
678
|
-
QC[uam deploy queue]
|
|
679
|
-
BC[uam deploy batch]
|
|
680
|
-
EC[uam deploy execute]
|
|
681
|
-
SC[uam deploy status]
|
|
682
|
-
FC[uam deploy flush]
|
|
683
|
-
end
|
|
684
|
-
|
|
685
|
-
subgraph "DeployBatcher Methods"
|
|
686
|
-
Q[queue]
|
|
687
|
-
CB[createBatch]
|
|
688
|
-
EB[executeBatch]
|
|
689
|
-
GB[getBatch/getPendingBatches]
|
|
690
|
-
FA[flushAll]
|
|
691
|
-
end
|
|
692
|
-
|
|
693
|
-
QC --> Q
|
|
694
|
-
BC --> CB
|
|
695
|
-
EC --> EB
|
|
696
|
-
SC --> GB
|
|
697
|
-
FC --> FA
|
|
73
|
+
style Q fill:#e3f2fd,stroke:#1976d2
|
|
74
|
+
style B fill:#fff3e0,stroke:#f57c00
|
|
75
|
+
style S fill:#c8e6c9,stroke:#388e3c
|
|
698
76
|
```
|
|
699
77
|
|
|
700
78
|
---
|
|
@@ -706,14 +84,7 @@ flowchart TB
|
|
|
706
84
|
```typescript
|
|
707
85
|
import { DeployBatcher } from './coordination/deploy-batcher.js';
|
|
708
86
|
|
|
709
|
-
const batcher = new DeployBatcher({
|
|
710
|
-
dynamicWindows: { commit: 30000 }, // 30s window
|
|
711
|
-
parallelExecution: true,
|
|
712
|
-
});
|
|
713
|
-
|
|
714
|
-
// Agent 1 commits
|
|
715
|
-
await batcher.queue('agent-1', 'commit', 'main', {
|
|
716
|
-
message: 'feat: add user auth',
|
|
87
|
+
const batcher = new DeployBatcher({ message: 'feat: add user auth',
|
|
717
88
|
files: ['src/auth.ts', 'src/user.ts']
|
|
718
89
|
});
|
|
719
90
|
|
|
@@ -763,15 +134,9 @@ batcher.setUrgentMode(false);
|
|
|
763
134
|
### Example 3: Bulk Queue with Transaction
|
|
764
135
|
|
|
765
136
|
```typescript
|
|
766
|
-
|
|
137
|
+
import { DeployBatcher } from './coordination/deploy-batcher.js';
|
|
767
138
|
|
|
768
|
-
|
|
769
|
-
const ids = await batcher.queueBulk('agent-1', [
|
|
770
|
-
{ actionType: 'commit', target: 'main', payload: { message: 'feat: A' } },
|
|
771
|
-
{ actionType: 'commit', target: 'main', payload: { message: 'feat: B' } },
|
|
772
|
-
{ actionType: 'push', target: 'main' },
|
|
773
|
-
{ actionType: 'workflow', target: 'deploy.yml', payload: { ref: 'main' } },
|
|
774
|
-
]);
|
|
139
|
+
const batcher = new DeployBatcher();
|
|
775
140
|
|
|
776
141
|
console.log(`Queued ${ids.length} actions`);
|
|
777
142
|
```
|
|
@@ -835,6 +200,9 @@ erDiagram
|
|
|
835
200
|
}
|
|
836
201
|
|
|
837
202
|
deploy_queue }o--|| deploy_batches : "belongs to"
|
|
203
|
+
|
|
204
|
+
style deploy_queue fill:#e3f2fd,stroke:#1976d2
|
|
205
|
+
style deploy_batches fill:#fff3e0,stroke:#f57c00
|
|
838
206
|
```
|
|
839
207
|
|
|
840
208
|
---
|