odai-dsh-agent 0.2.0 → 0.2.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.
- package/LICENSE +21 -21
- package/README.md +138 -134
- package/bin/odai-dsh-agent.mjs +108 -108
- package/package.json +69 -69
- package/preset/odai/agent.cordis.yml +260 -260
- package/preset/odai/preset.yml +3 -3
- package/preset/odai/runtime/compaction-config.mjs +388 -388
- package/preset/odai/runtime/context-activation.mjs +71 -0
- package/preset/odai/runtime/context-capability.mjs +86 -0
- package/preset/odai/runtime/governance.mjs +128 -121
- package/preset/odai/runtime/human-care.mjs +45 -0
- package/preset/odai/runtime/human-safety-continuity.mjs +2 -2
- package/preset/odai/runtime/human-safety.mjs +3 -3
- package/preset/odai/runtime/index.mjs +2461 -1977
- package/preset/odai/runtime/output-config.mjs +360 -304
- package/preset/odai/runtime/research-packet.mjs +150 -150
- package/preset/odai/runtime/responsibility-gap.mjs +8 -10
- package/preset/odai/runtime/responsibility-scope.mjs +199 -0
- package/preset/odai/runtime/role-overlays.mjs +27 -27
- package/preset/odai/runtime/route-card.mjs +168 -152
- package/preset/odai/runtime/router.mjs +683 -651
- package/preset/odai/runtime/routing-config.mjs +480 -436
- package/preset/odai/runtime/routing-context.mjs +321 -321
- package/preset/odai/runtime/semantic-memory-store.mjs +452 -452
- package/preset/odai/runtime/semantic-memory.mjs +842 -842
- package/preset/odai/runtime/session-compat.mjs +389 -389
- package/preset/odai/runtime/skill-bundle.mjs +318 -318
- package/preset/odai/runtime/skill-evolution.mjs +1413 -1413
- package/preset/odai/skills/odai/SKILL.md +69 -68
- package/preset/odai/skills/odai/agents/openai.yaml +4 -4
- package/preset/odai/skills/odai/assets/claude-agents/agent.md +11 -11
- package/preset/odai/skills/odai/assets/codex-agents/config.toml +11 -11
- package/preset/odai/skills/odai/assets/codex-agents/role.toml +5 -5
- package/preset/odai/skills/odai/assets/copilot-agents/agent.md +13 -13
- package/preset/odai/skills/odai/assets/hooks-policy.example.json +24 -24
- package/preset/odai/skills/odai/assets/routing-roles/controller.md +15 -15
- package/preset/odai/skills/odai/assets/routing-roles/executor.md +11 -11
- package/preset/odai/skills/odai/assets/routing-roles/frontend.md +7 -7
- package/preset/odai/skills/odai/assets/routing-roles/planner.md +29 -29
- package/preset/odai/skills/odai/assets/routing-roles/researcher.md +6 -6
- package/preset/odai/skills/odai/assets/routing-roles/reviewer.md +11 -11
- package/preset/odai/skills/odai/assets/task-state.md +14 -14
- package/preset/odai/skills/odai/manifest.json +37 -36
- package/preset/odai/skills/odai/references/care.md +26 -0
- package/preset/odai/skills/odai/references/craft.md +54 -54
- package/preset/odai/skills/odai/references/dao.md +30 -30
- package/preset/odai/skills/odai/references/human-safety.md +33 -54
- package/preset/odai/skills/odai/references/leverage.md +53 -53
- package/preset/odai/skills/odai/references/planning.md +82 -82
- package/preset/odai/skills/odai/references/support.md +36 -36
- package/preset/odai/skills/odai/references/verification.md +23 -23
- package/preset/odai/skills/odai/scripts/build-hooks.mjs +273 -273
- package/preset/odai/skills/odai/scripts/build-routing.mjs +274 -274
- package/preset/odai/skills/odai/scripts/install-routing.mjs +397 -397
- package/preset/odai/skills/odai/scripts/odai-hook.mjs +457 -457
- package/preset/odai/skills/odai/scripts/run-role.mjs +336 -336
- package/preset/odai/skills/odai/scripts/run-routing.mjs +1154 -1154
- package/preset/odai/skills/odai/scripts/verify-routing.mjs +103 -103
- package/scripts/verify-agent-load.mjs +257 -257
- package/src/dsh-version.mjs +6 -2
- package/src/installer.mjs +382 -382
|
@@ -1,651 +1,683 @@
|
|
|
1
|
-
export const HIGH_IMPACT_PLANNER_REASON = "PLANNER_UNVERIFIED_HIGH_IMPACT_CHANGE";
|
|
2
|
-
export const RESEARCHER_EVIDENCE_REASON = "RESEARCHER_MULTI_SOURCE_DECISION_EVIDENCE";
|
|
3
|
-
export const FRONTEND_SPECIALIST_REASON = "FRONTEND_SUBSTANTIAL_INTERFACE_WORK";
|
|
4
|
-
export const EXECUTOR_ROUTE_CARD_REASON = "EXECUTOR_FROZEN_ROUTE_NET_BENEFIT";
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
/
|
|
21
|
-
/
|
|
22
|
-
/
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
/(
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
/
|
|
34
|
-
/
|
|
35
|
-
/
|
|
36
|
-
/
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
/(
|
|
42
|
-
/(
|
|
43
|
-
/(?:
|
|
44
|
-
]
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
/(
|
|
49
|
-
|
|
50
|
-
/\b(?:
|
|
51
|
-
]
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
]
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
]
|
|
82
|
-
|
|
83
|
-
const
|
|
84
|
-
/(
|
|
85
|
-
|
|
86
|
-
]
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
];
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
/(
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
]
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
/\
|
|
110
|
-
/\
|
|
111
|
-
]
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
/\b(?:do
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
]
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
]
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
/(
|
|
167
|
-
/\b(?:
|
|
168
|
-
];
|
|
169
|
-
const
|
|
170
|
-
/(
|
|
171
|
-
/\b(?:
|
|
172
|
-
];
|
|
173
|
-
const
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
if (
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
if (matchesAny(
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
&& matchesAny(
|
|
235
|
-
&&
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
return
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
.
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
...(
|
|
296
|
-
...(
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
const
|
|
347
|
-
const
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
const
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
"
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
);
|
|
396
|
-
}
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
}
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
"
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
"
|
|
468
|
-
"
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
}
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
}
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
}
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
}
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
`
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
1
|
+
export const HIGH_IMPACT_PLANNER_REASON = "PLANNER_UNVERIFIED_HIGH_IMPACT_CHANGE";
|
|
2
|
+
export const RESEARCHER_EVIDENCE_REASON = "RESEARCHER_MULTI_SOURCE_DECISION_EVIDENCE";
|
|
3
|
+
export const FRONTEND_SPECIALIST_REASON = "FRONTEND_SUBSTANTIAL_INTERFACE_WORK";
|
|
4
|
+
export const EXECUTOR_ROUTE_CARD_REASON = "EXECUTOR_FROZEN_ROUTE_NET_BENEFIT";
|
|
5
|
+
export const OUTPUT_LIMIT_CONTINUATION_REASON = "RESPONSIBILITY_OUTPUT_LIMIT_CONTINUATION";
|
|
6
|
+
|
|
7
|
+
const RESPONSIBILITY_LABELS = Object.freeze({
|
|
8
|
+
researcher: "多源事实调查",
|
|
9
|
+
planner: "规划",
|
|
10
|
+
executor: "执行",
|
|
11
|
+
reviewer: "验收",
|
|
12
|
+
frontend: "前端设计与制作",
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
const PLANNER_PATTERNS = [
|
|
16
|
+
/独立(?:判断|规划|分析|决定|决策)/iu,
|
|
17
|
+
/比较(?:一下)?(?:方案|路线|架构)/iu,
|
|
18
|
+
/架构选型/iu,
|
|
19
|
+
/先(?:判断|规划)(?:路线|方案)/iu,
|
|
20
|
+
/second opinion (?:on|for) (?:the )?(?:plan|approach|architecture)/iu,
|
|
21
|
+
/compare (?:the )?(?:approaches|options|architectures)/iu,
|
|
22
|
+
/architecture decision/iu,
|
|
23
|
+
/(?:independently decide|independent decision)/iu,
|
|
24
|
+
];
|
|
25
|
+
|
|
26
|
+
const PLANNER_META_PATTERNS = [
|
|
27
|
+
/(?:你|是否|有没有|有没).{0,12}(?:规划|计划)(?:了|过|吗|没有)/iu,
|
|
28
|
+
/(?:did you|have you).{0,24}\bplan(?:ned|ning)?\b/iu,
|
|
29
|
+
];
|
|
30
|
+
|
|
31
|
+
const REVIEWER_PATTERNS = [
|
|
32
|
+
/独立(?:审查|复核|评审)/iu,
|
|
33
|
+
/(?:代码|安全|变更)(?:审查|复核|评审)/iu,
|
|
34
|
+
/code review/iu,
|
|
35
|
+
/security review/iu,
|
|
36
|
+
/independent review/iu,
|
|
37
|
+
/challenge (?:the )?(?:plan|implementation|result)/iu,
|
|
38
|
+
];
|
|
39
|
+
|
|
40
|
+
const RISK_PATTERNS = [
|
|
41
|
+
/(?:高风险|安全|权限|删除|迁移|发布|生产环境)/iu,
|
|
42
|
+
/(?:支付|付款|结算|扣款|退款|订单)[^。!?\n]{0,60}(?:提供方|服务|接口|请求|结果|状态|超时|重试|金额|交易|配置|回调|不稳定)/iu,
|
|
43
|
+
/(?:high[- ]risk|security|permission|delete|migration|production)/iu,
|
|
44
|
+
/(?:checkout|payment|billing|charge|refund)[^.!?\n]{0,80}(?:provider|service|request|result|status|timeout|retry|transaction|configuration|unstable|fail|超时|重试|不稳定)/iu,
|
|
45
|
+
];
|
|
46
|
+
|
|
47
|
+
const UNVERIFIED_CAUSAL_PATTERNS = [
|
|
48
|
+
/(?:我看|看起来|看来|估计|大概|八成|明显|肯定)(?:就)?是/iu,
|
|
49
|
+
/(?:问题|原因|根因)(?:应该|可能|大概|估计)(?:就)?在/iu,
|
|
50
|
+
/\b(?:it\s+)?(?:looks?|seems)\s+like\b/iu,
|
|
51
|
+
/\b(?:i think|probably|apparently|clearly|obviously)\b[^.!?\n]{0,80}\b(?:is|are|because|caused by|comes from)\b/iu,
|
|
52
|
+
];
|
|
53
|
+
|
|
54
|
+
const CONCRETE_CHANGE_PATTERNS = [
|
|
55
|
+
/把[^。!?\n]{1,120}(?:降到|提到|提高到|改成|设为|设置为|切到|换成|开启|关闭|删除|清空|迁移到|发布到|上线)/iu,
|
|
56
|
+
/(?:降低|提高|增加|减少|修改|设置|开启|关闭|删除|清空|迁移|发布|上线)[^。!?\n]{0,80}(?:\d|配置|超时|重试|权限|数据|服务)/iu,
|
|
57
|
+
/\b(?:set|change|reduce|lower|increase|raise|disable|enable|delete|drop|clear|migrate|deploy|release)\b[^.!?\n]{0,100}\b(?:to|from|timeout|retries|permission|data|service|production)\b/iu,
|
|
58
|
+
];
|
|
59
|
+
|
|
60
|
+
const SPECIFIC_PARAMETER_PATTERNS = [
|
|
61
|
+
/\d+(?:\.\d+)?\s*(?:毫秒|秒|分钟|小时|次|%|%|ms|sec(?:ond)?s?|min(?:ute)?s?|hours?|retries?|mb|gb)/iu,
|
|
62
|
+
];
|
|
63
|
+
|
|
64
|
+
const URGENCY_PATTERNS = [
|
|
65
|
+
/(?:先止血|立即|马上|赶紧|紧急|热修)/iu,
|
|
66
|
+
/\b(?:hotfix|immediately|right away|stop the bleeding)\b/iu,
|
|
67
|
+
];
|
|
68
|
+
|
|
69
|
+
const IRREVERSIBLE_ACTION_PATTERNS = [
|
|
70
|
+
/(?:删除|清空|迁移|发布|上线|关闭)/iu,
|
|
71
|
+
/\b(?:delete|drop|clear|migrate|deploy|release|disable)\b/iu,
|
|
72
|
+
];
|
|
73
|
+
|
|
74
|
+
const CONTINUATION_PATTERNS = [
|
|
75
|
+
/(?:继续|接着|进一步|深入|再(?:判断|分析|评估|检查|处理)|按(?:照)?(?:刚才|上面|上述|前面|这个|该)|那就|就按|能做不|能不能做|可以做不|可以做吗)/iu,
|
|
76
|
+
/\b(?:continue|proceed|go ahead|follow up|dig deeper|based on (?:that|the previous|the above)|can you (?:do|handle|implement) (?:it|that))\b/iu,
|
|
77
|
+
];
|
|
78
|
+
|
|
79
|
+
const PURE_RESPONSIBILITY_CONTINUATION_PATTERNS = [
|
|
80
|
+
/^\s*(?:请)?(?:继续|接着|接下去|续上|恢复)(?:(?:执行|完成|处理|做|推进|设计|分析|规划))?(?:(?:刚才|之前|上次|这个|该|原来)的?)?(?:任务|工作|实现|方案|设计|分析|规划)?(?:下去|完成|吧)?[。!!]?\s*$/iu,
|
|
81
|
+
/^\s*(?:please\s+)?(?:continue|go on|resume|carry on|keep going)(?:\s+(?:the\s+)?(?:previous|interrupted|same)?\s*(?:task|work|implementation|plan|design|analysis))?[.!]?\s*$/iu,
|
|
82
|
+
];
|
|
83
|
+
const OUTPUT_LIMIT_DIAGNOSTIC_PATTERNS = [
|
|
84
|
+
/(?:截断|断掉|中断|输出[^。!?\n]{0,12}(?:上限|预算)|(?:上限|预算)[^。!?\n]{0,12}输出|max\s*[_-]?\s*tokens?)/iu,
|
|
85
|
+
/(?:token|令牌)[^。!?\n]{0,16}(?:limit|budget|上限|预算|截断)/iu,
|
|
86
|
+
/(?:为什么|为何|怎么)[^。!?\n]{0,20}(?:停|断|中断|没继续|不继续)/iu,
|
|
87
|
+
];
|
|
88
|
+
|
|
89
|
+
const LOW_RISK_TRANSFORM_PATTERNS = [
|
|
90
|
+
/(?:重述|总结|概括|压缩|翻译|改写|润色|格式化|解释(?:一下)?)/iu,
|
|
91
|
+
/\b(?:restate|summari[sz]e|translate|shorten|rewrite|format|explain)\b/iu,
|
|
92
|
+
];
|
|
93
|
+
|
|
94
|
+
const EXPLICIT_EXECUTION_CONTINUATION_PATTERNS = [
|
|
95
|
+
/(?:继续|接着|就按|按(?:照)?(?:(?:这个|该|上述|上面|前面|刚才)的?)?(?:方案|计划|卡片))/iu,
|
|
96
|
+
/\b(?:continue|proceed|go ahead|follow the plan)\b/iu,
|
|
97
|
+
];
|
|
98
|
+
const IMPLEMENTATION_AUTHORIZATION_PATTERNS = [
|
|
99
|
+
/(?:做(?:完|好|掉|这个|这项|这次|一个)|实现|修复|完成|落地|开发|添加|新增|替换|删除|执行|全都做好)/iu,
|
|
100
|
+
/(?:请|麻烦|直接|开始|继续)(?:帮我)?(?:处理|修改|更新)|帮我(?:处理|修改|更新)|需要(?:处理|修改|更新)|可以(?:帮我)?(?:处理|修改|更新)|^(?:处理|修改|更新)(?:一下|这个|该|文件|代码|配置|依赖|问题|功能|实现|文档|测试)/iu,
|
|
101
|
+
/\b(?:do it|implement|fix|complete|build|add|replace|remove|execute|ship)\b/iu,
|
|
102
|
+
/^(?:please\s+)?(?:(?:change|modify)\b|update\b(?!\s+(?:me|us|them|everyone|the team)\b))|\b(?:please|can you|could you|would you|go ahead and|start to|continue to)\s+(?:(?:change|modify)\b|update\b(?!\s+(?:me|us|them|everyone|the team)\b))|\bi (?:need|want) you to\s+(?:(?:change|modify)\b|update\b(?!\s+(?:me|us|them|everyone|the team)\b))/iu,
|
|
103
|
+
];
|
|
104
|
+
const PLAN_ONLY_PATTERNS = [
|
|
105
|
+
/(?:只|仅).{0,16}(?:规划|计划|分析|评估|建议|方案|审查|复核|评审|检查)/iu,
|
|
106
|
+
/(?:先|帮我)(?:规划|计划|分析|评估)(?:一下)?[^。!?\n]{0,40}(?:$|[。!?])/iu,
|
|
107
|
+
/^\s*(?:请)?(?:规划|计划|分析|评估|建议|审查|复核|评审|检查)/iu,
|
|
108
|
+
/^\s*(?:请)?(?:列一下|列出|整理(?:一份)?|给我(?:一份)?)[^。!?\n]{0,64}(?:地方|清单|列表|说明|建议|方案|示例|影响|步骤)(?:$|[。!?])/iu,
|
|
109
|
+
/\b(?:review|audit|inspect)\s+only\b/iu,
|
|
110
|
+
/\b(?:just|only)\s+(?:plan|analy[sz]e|assess|evaluate|review|audit|inspect|recommend|explain|describe|outline|list)\b/iu,
|
|
111
|
+
/^\s*(?:please\s+)?(?:plan|analy[sz]e|assess|evaluate|review|audit|inspect|recommend|explain|describe|outline|list)\b/iu,
|
|
112
|
+
];
|
|
113
|
+
const PLAN_THEN_IMPLEMENT_PATTERNS = [
|
|
114
|
+
/(?:规划|计划|分析|评估|建议|审查|复核|评审|检查)[^。!?\n]{0,48}(?:然后|再|之后|接着|并(?:且)?)[^。!?\n]{0,24}(?:实现|修复|完成|落地|开发|添加|新增|修改|更新(?![^。!?\n]{0,8}(?:我|我们|团队|进展|结果|情况|发现|消息|状态))|替换|删除|执行)/iu,
|
|
115
|
+
/(?:列一下|列出|整理(?:一份)?|给我(?:一份)?)[^。!?\n]{0,64}(?:然后|再|之后|接着|并(?:且)?)[^。!?\n]{0,24}(?:实现|修复|完成|落地|开发|添加|新增|修改|更新|替换|删除|执行)/iu,
|
|
116
|
+
/\b(?:plan|analy[sz]e|assess|evaluate|review|audit|inspect|recommend|explain|describe|outline|list)\b[^.!?\n]{0,64}\b(?:then|and(?: then)?|after that)\b[^.!?\n]{0,24}\b(?:implement|fix|complete|build|add|change|update(?!\s+(?:me|us|them|everyone|the team)\b)|modify|replace|remove|execute|ship)\b/iu,
|
|
117
|
+
];
|
|
118
|
+
const STATUS_UPDATE_PATTERNS = [
|
|
119
|
+
/(?:更新|同步)[^。!?\n]{0,24}(?:进展|结果|情况|发现|消息|状态)/iu,
|
|
120
|
+
/\bupdate\b[^.!?\n]{1,48}\b(?:on|about|regarding)\b/iu,
|
|
121
|
+
/\bupdate\b[^.!?\n]{1,48}\bwith\s+(?:the\s+)?(?:findings|progress|results|status|details|news|outcome)\b/iu,
|
|
122
|
+
];
|
|
123
|
+
const UNAMBIGUOUS_DELIVERY_PATTERNS = [
|
|
124
|
+
/(?:^|[,;。]|然后|再|之后|接着|并(?:且)?|请|帮我)(?:做(?:完|好|掉)|实现|修复|完成|落地|开发|添加|新增|修改|替换|删除|执行)/iu,
|
|
125
|
+
/更新(?:代码|项目|依赖|包|清单|文档|测试|配置|文件|运行时|服务|应用|界面|数据库|架构)/iu,
|
|
126
|
+
/\b(?:do it|implement|execute|ship)\b/iu,
|
|
127
|
+
/(?:^|\b(?:then|and|to|please)\s+)\b(?:fix|complete|build|add|change|modify|replace|remove)\b/iu,
|
|
128
|
+
/\bupdate\s+(?:the\s+)?(?:code|project|dependencies?|packages?|manifest|docs?|documentation|tests?|config(?:uration)?|files?|runtime|services?|app(?:lication)?|ui|interface|schema|database|architecture)\b/iu,
|
|
129
|
+
];
|
|
130
|
+
const NON_IMPLEMENTATION_QUERY_PATTERNS = [
|
|
131
|
+
/(?:有什么|有何|哪些|是什么|为何|为什么|怎么样|怎么看|发生了什么|有变化吗|影响(?:是|有)?什么)[^。!?\n]*[??]?$/iu,
|
|
132
|
+
/^\s*(?:what|why|how)\b[^.!?\n]*[?]\s*$/iu,
|
|
133
|
+
/\b(?:what changed|what changes|what impact|which changes|difference between)\b[^.!?\n]*[?]?$/iu,
|
|
134
|
+
];
|
|
135
|
+
const NO_IMPLEMENTATION_PATTERNS = [
|
|
136
|
+
/(?:不要|别|请勿|禁止|无需|不用|不需要|不能)[^。!?\n]{0,28}(?:改|修改|编辑|写入|实现|执行|落地|动文件|动代码)/iu,
|
|
137
|
+
/\b(?:do not|don't|never|without)\b[^.!?\n]{0,48}\b(?:implement|modify|edit|change|write|execute|apply|make changes?)\b/iu,
|
|
138
|
+
/\b(?:plan|analyze|assess|evaluate|recommend)(?: only)?\b[^.!?]{0,30}\b(?:do not|don't|without) (?:implementing|changes?)\b/iu,
|
|
139
|
+
];
|
|
140
|
+
const GLOBAL_NO_EDIT_PATTERNS = [
|
|
141
|
+
/(?:不要|别|请勿|禁止)[^,;。!?\n]{0,12}(?:改|修改|编辑|写入)[^,;。!?\n]{0,12}(?:任何|全部|所有|整个)[^,;。!?\n]{0,12}(?:文件|代码|内容|实现|东西)/iu,
|
|
142
|
+
/\b(?:do not|don't|never)\b[^,;.!?\n]{0,12}\b(?:modify|edit|change|write)\b[^,;.!?\n]{0,16}\b(?:anything|any (?:files?|code|changes?)|all (?:files?|code|changes?)|the (?:whole|entire) codebase)\b/iu,
|
|
143
|
+
];
|
|
144
|
+
const SCOPED_NO_EDIT_WITH_EXECUTION_PATTERNS = [
|
|
145
|
+
/(?:不要|别|请勿)[^,;。!?\n]{0,12}(?:改|修改|编辑|写入)(?![^,;。!?\n]{0,12}(?:任何|全部|所有|整个))[^,;。!?\n]{1,28}[,;。](?![^,;。!?\n]{0,20}(?:不要|别|请勿|禁止|无需|不用|不需要|不能))[ \t]*[^,;。!?\n]{0,20}(?:实现|修复|修改|更新|执行|落地)/iu,
|
|
146
|
+
/\b(?:do not|don't|never)\b[^,;.!?\n]{0,12}\b(?:modify|edit|change|write)\b(?![^,;.!?\n]{0,16}\b(?:anything|any (?:files?|code|changes?)|all (?:files?|code|changes?)|the (?:whole|entire) codebase)\b)[^,;.!?\n]{1,36}[,;.](?![^,;.!?\n]{0,24}\b(?:do not|don't|never|no need to|without|skip)\b)\s*[^,;.!?\n]{0,24}\b(?:implement|fix|change|update|execute|apply)\b/iu,
|
|
147
|
+
];
|
|
148
|
+
const EXECUTION_ACTION_PATTERNS = [
|
|
149
|
+
/(?:开始|执行|实施|落实|动手)/iu,
|
|
150
|
+
/\b(?:start|execute|implement|apply)\b/iu,
|
|
151
|
+
];
|
|
152
|
+
const ROUTE_CARD_REFERENCE_PATTERNS = [
|
|
153
|
+
/(?:(?:这个|该|上述|上面|前面|刚才)的?(?:方案|计划|卡片|实现|改动|工作))/iu,
|
|
154
|
+
/\b(?:(?:this|that|the|above|previous)\s+(?:plan|proposal|route card|implementation|change)|(?:it|that))\b/iu,
|
|
155
|
+
];
|
|
156
|
+
const NEW_TASK_PATTERNS = [
|
|
157
|
+
/(?:另一个|另一项|另一件|另外(?:一个|一项|一件)|新(?:的)?(?:问题|任务|需求|工作))/iu,
|
|
158
|
+
/\b(?:another|(?:a )?new|different|separate)\s+(?:task|issue|problem|request|change|project)\b/iu,
|
|
159
|
+
];
|
|
160
|
+
|
|
161
|
+
const FRONTEND_SCOPE_PATTERNS = [
|
|
162
|
+
/(?:前端|界面|页面|网页|网站|着陆页|应用界面|仪表盘|控制台|组件|交互界面|移动端|桌面端|游戏界面|3D场景)/iu,
|
|
163
|
+
/\b(?:front[- ]?end|ui|ux|interface|web(?:site| app)?|landing page|page|dashboard|component|mobile|desktop|game ui|3d scene)\b/iu,
|
|
164
|
+
];
|
|
165
|
+
const FRONTEND_DELIVERY_PATTERNS = [
|
|
166
|
+
/(?:设计|制作|实现|开发|构建|创建|搭建|改版|重做|重构|优化|美化|修复)/iu,
|
|
167
|
+
/\b(?:design|build|implement|develop|create|craft|redesign|revamp|rework|optimi[sz]e|fix)\b/iu,
|
|
168
|
+
];
|
|
169
|
+
const FRONTEND_STRONG_WORK_PATTERNS = [
|
|
170
|
+
/(?:从零|新建|新做|整页|整站|整体改版|完整界面|设计并实现|重新设计|重做|改版|搭建)/iu,
|
|
171
|
+
/\b(?:build|create|design and implement|redesign|revamp|rebuild)\b[^.!?\n]{0,60}\b(?:ui|interface|page|website|web app|dashboard|component|game)\b/iu,
|
|
172
|
+
];
|
|
173
|
+
const FRONTEND_SURFACE_PATTERNS = [
|
|
174
|
+
/登录(?:页|页面)/iu,
|
|
175
|
+
/(?:登录后)?首页/iu,
|
|
176
|
+
/(?:个人空间|个人中心|用户中心|个人主页)/iu,
|
|
177
|
+
/(?:注册|设置|搜索|列表|详情|结算|支付)(?:页|页面)/iu,
|
|
178
|
+
/\b(?:login page|home page|profile|personal space|settings page|search page|list page|detail page|checkout page)\b/iu,
|
|
179
|
+
];
|
|
180
|
+
const FRONTEND_NON_UI_PATTERNS = [
|
|
181
|
+
/(?:API|接口)(?:调用|请求|响应|超时|缓存|鉴权|数据|字段|契约)/iu,
|
|
182
|
+
/\b(?:api|endpoint|backend|server-side)\b/iu,
|
|
183
|
+
];
|
|
184
|
+
const FRONTEND_UI_PRODUCTION_PATTERNS = [
|
|
185
|
+
/(?:UI|UX|用户界面|界面介绍|布局|样式|排版|配色|交互|视觉|响应式|移动端|桌面端|截图|浏览器验收)/iu,
|
|
186
|
+
/\b(?:ui|ux|interface|layout|styling|typography|interaction|visual|responsive|mobile|desktop|screenshot|browser acceptance)\b/iu,
|
|
187
|
+
];
|
|
188
|
+
const FRONTEND_EXPLICIT_SPECIALIST_PATTERNS = [
|
|
189
|
+
/(?:交给|使用|用)[^。!?\n]{0,30}(?:前端|UI|UX)(?:专长|专家|模型)/iu,
|
|
190
|
+
/\b(?:use|with|via)\b[^.!?\n]{0,30}\b(?:front[- ]?end|ui|ux) (?:specialist|expert|model)\b/iu,
|
|
191
|
+
];
|
|
192
|
+
const FRONTEND_AXIS_PATTERNS = Object.freeze({
|
|
193
|
+
responsive: [/(?:响应式|移动端|桌面端|多端|窄屏|宽屏|视口)/iu, /\b(?:responsive|mobile|desktop|viewport|breakpoint)\b/iu],
|
|
194
|
+
interaction: [/(?:交互|动效|动画|拖拽|手势|状态流转|多状态)/iu, /\b(?:interaction|animation|motion|drag|gesture|state flow|multiple states)\b/iu],
|
|
195
|
+
visual: [/(?:视觉|品牌|排版|配色|设计系统|素材|图片|图标|3D|游戏界面)/iu, /\b(?:visual|brand|typography|palette|design system|asset|image|icon|3d|game ui)\b/iu],
|
|
196
|
+
comprehension: [/(?:一眼(?:就)?(?:看懂|明白|理解)|做什么|首屏认知|价值表达|信息架构|界面介绍)/iu, /\b(?:understand at a glance|first-screen comprehension|value proposition|information architecture|what (?:it|the product) does)\b/iu],
|
|
197
|
+
acceptance: [/(?:截图|浏览器验收|视觉验收|无障碍|Playwright|真机)/iu, /\b(?:screenshot|browser acceptance|visual acceptance|accessibility|playwright|device testing)\b/iu],
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
function matchesAny(text, patterns) {
|
|
201
|
+
return patterns.some((pattern) => pattern.test(text));
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
function stripQuotedMaterial(text) {
|
|
205
|
+
return text
|
|
206
|
+
.replace(/```[\s\S]*?```/gu, " ")
|
|
207
|
+
.replace(/^\s*>.*$/gmu, " ")
|
|
208
|
+
.replace(/`[^`\n]*`/gu, " ")
|
|
209
|
+
.replace(/“[^”\n]*”|‘[^’\n]*’|「[^」\n]*」|『[^』\n]*』|《[^》\n]*》|"[^"\n]*"/gu, " ");
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
export function classifyResponsibilityInterruptionText(text) {
|
|
213
|
+
const explicit = stripQuotedMaterial(String(text ?? "")).trim();
|
|
214
|
+
if (!explicit) return "clear";
|
|
215
|
+
if (matchesAny(explicit, PURE_RESPONSIBILITY_CONTINUATION_PATTERNS)) return "continue";
|
|
216
|
+
if (matchesAny(explicit, OUTPUT_LIMIT_DIAGNOSTIC_PATTERNS)) return "preserve";
|
|
217
|
+
return "clear";
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
function isExecutionContinuation(text) {
|
|
221
|
+
if (matchesAny(text, NEW_TASK_PATTERNS)) return false;
|
|
222
|
+
if (matchesAny(text, EXPLICIT_EXECUTION_CONTINUATION_PATTERNS)) return true;
|
|
223
|
+
return matchesAny(text, EXECUTION_ACTION_PATTERNS)
|
|
224
|
+
&& matchesAny(text, ROUTE_CARD_REFERENCE_PATTERNS);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
export function classifyImplementationAuthorization(text) {
|
|
228
|
+
const explicit = stripQuotedMaterial(String(text ?? "")).trim();
|
|
229
|
+
if (!explicit) return Object.freeze({ status: "unknown" });
|
|
230
|
+
if (matchesAny(explicit, GLOBAL_NO_EDIT_PATTERNS)) return Object.freeze({ status: "plan-only" });
|
|
231
|
+
if (matchesAny(explicit, SCOPED_NO_EDIT_WITH_EXECUTION_PATTERNS)) return Object.freeze({ status: "authorized" });
|
|
232
|
+
if (matchesAny(explicit, NO_IMPLEMENTATION_PATTERNS)) return Object.freeze({ status: "plan-only" });
|
|
233
|
+
if (matchesAny(explicit, STATUS_UPDATE_PATTERNS)
|
|
234
|
+
&& !matchesAny(explicit, UNAMBIGUOUS_DELIVERY_PATTERNS)
|
|
235
|
+
&& !matchesAny(explicit, CONCRETE_CHANGE_PATTERNS)) {
|
|
236
|
+
return Object.freeze({ status: matchesAny(explicit, PLAN_ONLY_PATTERNS) ? "plan-only" : "unknown" });
|
|
237
|
+
}
|
|
238
|
+
if (isExecutionContinuation(explicit) || matchesAny(explicit, PLAN_THEN_IMPLEMENT_PATTERNS)) {
|
|
239
|
+
return Object.freeze({ status: "authorized" });
|
|
240
|
+
}
|
|
241
|
+
if (matchesAny(explicit, PLAN_ONLY_PATTERNS)) return Object.freeze({ status: "plan-only" });
|
|
242
|
+
if (matchesAny(explicit, NON_IMPLEMENTATION_QUERY_PATTERNS)) return Object.freeze({ status: "unknown" });
|
|
243
|
+
if (matchesAny(explicit, IMPLEMENTATION_AUTHORIZATION_PATTERNS)
|
|
244
|
+
|| matchesAny(explicit, CONCRETE_CHANGE_PATTERNS)) {
|
|
245
|
+
return Object.freeze({ status: "authorized" });
|
|
246
|
+
}
|
|
247
|
+
return Object.freeze({ status: "unknown" });
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
function hasContextualPlannerGap(text) {
|
|
251
|
+
return matchesAny(text, RISK_PATTERNS)
|
|
252
|
+
&& matchesAny(text, UNVERIFIED_CAUSAL_PATTERNS)
|
|
253
|
+
&& matchesAny(text, CONCRETE_CHANGE_PATTERNS)
|
|
254
|
+
&& (matchesAny(text, SPECIFIC_PARAMETER_PATTERNS)
|
|
255
|
+
|| matchesAny(text, URGENCY_PATTERNS)
|
|
256
|
+
|| matchesAny(text, IRREVERSIBLE_ACTION_PATTERNS));
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
function isLowRiskTransform(text) {
|
|
260
|
+
return matchesAny(stripQuotedMaterial(text), LOW_RISK_TRANSFORM_PATTERNS);
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
function frontendSpecializationSignals(text) {
|
|
264
|
+
const explicit = matchesAny(text, FRONTEND_EXPLICIT_SPECIALIST_PATTERNS);
|
|
265
|
+
const surfaceCount = FRONTEND_SURFACE_PATTERNS.filter((pattern) => pattern.test(text)).length;
|
|
266
|
+
const explicitScope = matchesAny(text, FRONTEND_SCOPE_PATTERNS);
|
|
267
|
+
const scope = surfaceCount > 0 || explicitScope;
|
|
268
|
+
const delivery = matchesAny(text, FRONTEND_DELIVERY_PATTERNS);
|
|
269
|
+
const strongWork = matchesAny(text, FRONTEND_STRONG_WORK_PATTERNS);
|
|
270
|
+
const axes = Object.entries(FRONTEND_AXIS_PATTERNS)
|
|
271
|
+
.filter(([, patterns]) => matchesAny(text, patterns))
|
|
272
|
+
.map(([axis]) => axis);
|
|
273
|
+
const nonUiRequest = matchesAny(text, FRONTEND_NON_UI_PATTERNS)
|
|
274
|
+
&& !matchesAny(text, FRONTEND_UI_PRODUCTION_PATTERNS);
|
|
275
|
+
const specialistDepth = explicit
|
|
276
|
+
|| strongWork
|
|
277
|
+
|| axes.length >= 2
|
|
278
|
+
|| (surfaceCount >= 2 && (explicitScope || axes.length >= 1));
|
|
279
|
+
return Object.freeze({
|
|
280
|
+
explicit,
|
|
281
|
+
scope,
|
|
282
|
+
delivery,
|
|
283
|
+
strongWork,
|
|
284
|
+
nonUiRequest,
|
|
285
|
+
specialistDepth,
|
|
286
|
+
surfaceCount,
|
|
287
|
+
axes: Object.freeze(axes),
|
|
288
|
+
substantial: scope && delivery && specialistDepth && !nonUiRequest,
|
|
289
|
+
});
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
function frontendRouteSignals(frontend) {
|
|
293
|
+
return [
|
|
294
|
+
...(frontend.scope ? ["frontend-interface-scope"] : []),
|
|
295
|
+
...(frontend.delivery ? ["frontend-delivery-request"] : []),
|
|
296
|
+
...(frontend.explicit ? ["explicit-frontend-specialist"] : []),
|
|
297
|
+
...(frontend.strongWork ? ["substantial-frontend-work"] : []),
|
|
298
|
+
...(frontend.surfaceCount >= 2 ? ["frontend-multi-surface"] : []),
|
|
299
|
+
...frontend.axes.map((axis) => `frontend-${axis}`),
|
|
300
|
+
];
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
function genuineUserText(message) {
|
|
304
|
+
if (message?.role !== "user" || message?.source?.kind !== "user" || !Array.isArray(message.content)) return "";
|
|
305
|
+
return message.content
|
|
306
|
+
.filter((block) => block?.type === "text" && typeof block.text === "string")
|
|
307
|
+
.map((block) => block.text)
|
|
308
|
+
.join("\n")
|
|
309
|
+
.trim();
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
function genuineUserTexts(messages, sessionEvents = []) {
|
|
313
|
+
const candidates = [
|
|
314
|
+
...(Array.isArray(messages) ? [...messages].reverse() : []),
|
|
315
|
+
...(Array.isArray(sessionEvents)
|
|
316
|
+
? [...sessionEvents].reverse()
|
|
317
|
+
.filter((event) => event?.type === "user/message")
|
|
318
|
+
.map((event) => event.data)
|
|
319
|
+
: []),
|
|
320
|
+
];
|
|
321
|
+
const seen = new Set();
|
|
322
|
+
const texts = [];
|
|
323
|
+
for (const message of candidates) {
|
|
324
|
+
const text = genuineUserText(message);
|
|
325
|
+
if (!text || seen.has(text)) continue;
|
|
326
|
+
seen.add(text);
|
|
327
|
+
texts.push(text);
|
|
328
|
+
}
|
|
329
|
+
return texts;
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
function route(role, reasonCode, reason, signals, action = role === "controller" ? "direct" : "delegate", targetRole) {
|
|
333
|
+
return Object.freeze({
|
|
334
|
+
role,
|
|
335
|
+
mode: action,
|
|
336
|
+
action,
|
|
337
|
+
...(targetRole === undefined ? {} : { targetRole }),
|
|
338
|
+
reasonCode,
|
|
339
|
+
reason,
|
|
340
|
+
signals: Object.freeze([...new Set(signals)]),
|
|
341
|
+
});
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
export function decideResearchPrefetch(input = {}) {
|
|
345
|
+
const text = typeof input.text === "string" ? input.text.trim() : "";
|
|
346
|
+
const explicitIntentText = stripQuotedMaterial(text);
|
|
347
|
+
const proposal = input.proposal?.responsibility === "researcher" ? input.proposal : undefined;
|
|
348
|
+
if (!proposal || !explicitIntentText || isLowRiskTransform(explicitIntentText)) {
|
|
349
|
+
return route("controller", "RESEARCHER_PREFETCH_NOT_NEEDED", "No evidence-grounded multi-source compression gap was proposed.", ["no-research-prefetch"]);
|
|
350
|
+
}
|
|
351
|
+
return route(
|
|
352
|
+
"researcher",
|
|
353
|
+
RESEARCHER_EVIDENCE_REASON,
|
|
354
|
+
proposal.gap,
|
|
355
|
+
["evidence-grounded-responsibility-gap", `state:${proposal.stateDigest}`],
|
|
356
|
+
);
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
/**
|
|
360
|
+
* Choose the smallest useful odai role. Risk alone never creates another role.
|
|
361
|
+
* Executor routing requires a frozen route card and observable net benefit;
|
|
362
|
+
* those facts cannot be inferred from task prose.
|
|
363
|
+
*/
|
|
364
|
+
export function decideRoute(input = {}) {
|
|
365
|
+
const text = typeof input.text === "string" ? input.text.trim() : "";
|
|
366
|
+
const explicitIntentText = stripQuotedMaterial(text);
|
|
367
|
+
const proposal = input.proposal;
|
|
368
|
+
const signals = [];
|
|
369
|
+
const considerations = [];
|
|
370
|
+
const riskPresent = matchesAny(text, RISK_PATTERNS);
|
|
371
|
+
const unverifiedCausalClaim = matchesAny(text, UNVERIFIED_CAUSAL_PATTERNS);
|
|
372
|
+
const concreteChangeRequest = matchesAny(text, CONCRETE_CHANGE_PATTERNS);
|
|
373
|
+
const specificOperationalParameter = matchesAny(text, SPECIFIC_PARAMETER_PATTERNS);
|
|
374
|
+
const urgencyPressure = matchesAny(text, URGENCY_PATTERNS);
|
|
375
|
+
const irreversibleAction = matchesAny(text, IRREVERSIBLE_ACTION_PATTERNS);
|
|
376
|
+
const frontend = frontendSpecializationSignals(explicitIntentText);
|
|
377
|
+
|
|
378
|
+
if (riskPresent) signals.push("risk-present");
|
|
379
|
+
if (unverifiedCausalClaim) signals.push("unverified-causal-claim");
|
|
380
|
+
if (concreteChangeRequest) signals.push("concrete-change-request");
|
|
381
|
+
if (specificOperationalParameter) signals.push("specific-operational-parameter");
|
|
382
|
+
if (urgencyPressure) signals.push("urgency-pressure");
|
|
383
|
+
if (irreversibleAction) signals.push("irreversible-action");
|
|
384
|
+
|
|
385
|
+
const interruption = input.interruption;
|
|
386
|
+
if (["planner", "executor", "frontend"].includes(interruption?.responsibility)
|
|
387
|
+
&& classifyResponsibilityInterruptionText(interruption?.continuationText) === "continue") {
|
|
388
|
+
return route(
|
|
389
|
+
"controller",
|
|
390
|
+
OUTPUT_LIMIT_CONTINUATION_REASON,
|
|
391
|
+
`The verified ${interruption.responsibility} responsibility was interrupted by the provider output limit and the user explicitly continued it.`,
|
|
392
|
+
["verified-output-limit-interruption", "explicit-continuation"],
|
|
393
|
+
"upgrade",
|
|
394
|
+
interruption.responsibility,
|
|
395
|
+
);
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
const executionAuthorizedByState = proposal?.responsibility === "executor"
|
|
399
|
+
&& input.routeCard?.authorization?.status === "authorized";
|
|
400
|
+
if (input.routeCard?.frozen === true
|
|
401
|
+
&& input.routeCard?.observableBenefit === true
|
|
402
|
+
&& (isExecutionContinuation(explicitIntentText) || executionAuthorizedByState)) {
|
|
403
|
+
signals.push(
|
|
404
|
+
"route-card-frozen",
|
|
405
|
+
"observable-net-benefit",
|
|
406
|
+
...(executionAuthorizedByState ? ["evidence-grounded-responsibility-gap", `state:${proposal.stateDigest}`] : ["explicit-execution-continuation"]),
|
|
407
|
+
);
|
|
408
|
+
return route(
|
|
409
|
+
"controller",
|
|
410
|
+
EXECUTOR_ROUTE_CARD_REASON,
|
|
411
|
+
executionAuthorizedByState
|
|
412
|
+
? proposal.gap
|
|
413
|
+
: "A frozen route card exists, executor separation has an observable net benefit, and the user explicitly continued implementation.",
|
|
414
|
+
signals,
|
|
415
|
+
"upgrade",
|
|
416
|
+
"executor",
|
|
417
|
+
);
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
if (proposal?.responsibility === "user") {
|
|
421
|
+
signals.push("user-decision-gap", `state:${proposal.stateDigest}`);
|
|
422
|
+
return route(
|
|
423
|
+
"controller",
|
|
424
|
+
"USER_DECISION_REQUIRED",
|
|
425
|
+
proposal.gap,
|
|
426
|
+
signals,
|
|
427
|
+
);
|
|
428
|
+
}
|
|
429
|
+
if (proposal?.responsibility === "reviewer") {
|
|
430
|
+
signals.push("evidence-grounded-responsibility-gap", `state:${proposal.stateDigest}`);
|
|
431
|
+
return route("reviewer", "REVIEWER_EVIDENCE_STATE_GAP", proposal.gap, signals);
|
|
432
|
+
}
|
|
433
|
+
if (proposal?.responsibility === "planner") {
|
|
434
|
+
signals.push("evidence-grounded-responsibility-gap", `state:${proposal.stateDigest}`);
|
|
435
|
+
return route("controller", "PLANNER_EVIDENCE_STATE_GAP", proposal.gap, signals, "upgrade", "planner");
|
|
436
|
+
}
|
|
437
|
+
if (proposal?.responsibility === "frontend") {
|
|
438
|
+
signals.push("evidence-grounded-responsibility-gap", `state:${proposal.stateDigest}`);
|
|
439
|
+
return route("controller", "FRONTEND_EVIDENCE_STATE_GAP", proposal.gap, signals, "upgrade", "frontend");
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
if (matchesAny(explicitIntentText, REVIEWER_PATTERNS)) {
|
|
443
|
+
signals.push("review-language-present");
|
|
444
|
+
considerations.push(Object.freeze({
|
|
445
|
+
role: "reviewer",
|
|
446
|
+
match: "lexical",
|
|
447
|
+
action: "skip",
|
|
448
|
+
reasonCode: "REVIEWER_GAP_NOT_PROVEN",
|
|
449
|
+
signals: Object.freeze(["review-language-present"]),
|
|
450
|
+
unmet: Object.freeze(["current-evidence-package", "acceptance-impact"]),
|
|
451
|
+
}));
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
if (matchesAny(explicitIntentText, PLANNER_PATTERNS)) {
|
|
455
|
+
signals.push("planning-language-present");
|
|
456
|
+
considerations.push(Object.freeze({
|
|
457
|
+
role: "planner",
|
|
458
|
+
match: "lexical",
|
|
459
|
+
action: "skip",
|
|
460
|
+
reasonCode: "PLANNER_GAP_NOT_PROVEN",
|
|
461
|
+
signals: Object.freeze(["planning-language-present"]),
|
|
462
|
+
unmet: Object.freeze(["evidence-grounded-decision-branch", "observable-capability-benefit"]),
|
|
463
|
+
}));
|
|
464
|
+
} else if (matchesAny(explicitIntentText, PLANNER_META_PATTERNS)) {
|
|
465
|
+
signals.push("planner-meta-question");
|
|
466
|
+
considerations.push(Object.freeze({
|
|
467
|
+
role: "planner",
|
|
468
|
+
match: "meta-question",
|
|
469
|
+
action: "skip",
|
|
470
|
+
reasonCode: "PLANNER_META_QUERY_NO_INDEPENDENT_GAP",
|
|
471
|
+
signals: Object.freeze(["planner-meta-question"]),
|
|
472
|
+
unmet: Object.freeze(["prior-task-state-with-unresolved-decision-branch"]),
|
|
473
|
+
}));
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
const contextualPlannerGap = riskPresent
|
|
477
|
+
&& unverifiedCausalClaim
|
|
478
|
+
&& concreteChangeRequest
|
|
479
|
+
&& (specificOperationalParameter || urgencyPressure || irreversibleAction);
|
|
480
|
+
if (contextualPlannerGap) {
|
|
481
|
+
return route(
|
|
482
|
+
"controller",
|
|
483
|
+
HIGH_IMPACT_PLANNER_REASON,
|
|
484
|
+
"An unverified causal claim is being used to justify a concrete high-impact change, so the controller needs a stronger decision route.",
|
|
485
|
+
signals,
|
|
486
|
+
"upgrade",
|
|
487
|
+
"planner",
|
|
488
|
+
);
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
const frontendSignals = frontend.scope || frontend.explicit ? frontendRouteSignals(frontend) : [];
|
|
492
|
+
if (frontend.substantial && !isLowRiskTransform(explicitIntentText)) {
|
|
493
|
+
signals.push(...frontendSignals);
|
|
494
|
+
return route(
|
|
495
|
+
"controller",
|
|
496
|
+
FRONTEND_SPECIALIST_REASON,
|
|
497
|
+
"Substantial user-facing interface work can benefit from a configured frontend specialist without a child handoff.",
|
|
498
|
+
signals,
|
|
499
|
+
"upgrade",
|
|
500
|
+
"frontend",
|
|
501
|
+
);
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
signals.push(...frontendSignals, "no-independent-gap");
|
|
505
|
+
const direct = route(
|
|
506
|
+
"controller",
|
|
507
|
+
"DIRECT_DEFAULT_NO_INDEPENDENT_GAP",
|
|
508
|
+
"No evidence-grounded independent decision, execution, or acceptance gap was found.",
|
|
509
|
+
signals,
|
|
510
|
+
);
|
|
511
|
+
if (frontendSignals.length > 0) {
|
|
512
|
+
const lowRiskTransform = isLowRiskTransform(explicitIntentText);
|
|
513
|
+
considerations.push(Object.freeze({
|
|
514
|
+
role: "frontend",
|
|
515
|
+
match: "partial",
|
|
516
|
+
action: "skip",
|
|
517
|
+
reasonCode: frontend.nonUiRequest
|
|
518
|
+
? "FRONTEND_API_REQUEST"
|
|
519
|
+
: lowRiskTransform
|
|
520
|
+
? "FRONTEND_LOW_RISK_TRANSFORM"
|
|
521
|
+
: "FRONTEND_BELOW_SPECIALIST_THRESHOLD",
|
|
522
|
+
signals: Object.freeze(frontendSignals),
|
|
523
|
+
unmet: Object.freeze(frontend.nonUiRequest
|
|
524
|
+
? ["ui-production-request"]
|
|
525
|
+
: [
|
|
526
|
+
...(frontend.scope ? [] : ["interface-scope"]),
|
|
527
|
+
...(frontend.delivery ? [] : ["delivery-request"]),
|
|
528
|
+
...(frontend.specialistDepth ? [] : ["specialist-or-substantial-scope"]),
|
|
529
|
+
]),
|
|
530
|
+
}));
|
|
531
|
+
}
|
|
532
|
+
return considerations.length === 0
|
|
533
|
+
? direct
|
|
534
|
+
: Object.freeze({ ...direct, considerations: Object.freeze(considerations) });
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
export function extractLatestUserText(messages) {
|
|
538
|
+
return genuineUserTexts(messages)[0] ?? "";
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
export function extractRoutingText(messages, sessionEvents) {
|
|
542
|
+
const texts = genuineUserTexts(messages, sessionEvents);
|
|
543
|
+
const latest = texts[0] ?? "";
|
|
544
|
+
if (!latest
|
|
545
|
+
|| hasContextualPlannerGap(latest)
|
|
546
|
+
|| !matchesAny(stripQuotedMaterial(latest), CONTINUATION_PATTERNS)
|
|
547
|
+
|| isLowRiskTransform(latest)) {
|
|
548
|
+
return latest;
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
let referencedHighImpact;
|
|
552
|
+
let referencedFrontend;
|
|
553
|
+
for (const text of texts.slice(1)) {
|
|
554
|
+
if (hasContextualPlannerGap(text)) {
|
|
555
|
+
referencedHighImpact = text;
|
|
556
|
+
break;
|
|
557
|
+
}
|
|
558
|
+
const frontend = frontendSpecializationSignals(stripQuotedMaterial(text));
|
|
559
|
+
if (frontend.scope && frontend.delivery) {
|
|
560
|
+
referencedFrontend = text;
|
|
561
|
+
break;
|
|
562
|
+
}
|
|
563
|
+
if (!isLowRiskTransform(text)) break;
|
|
564
|
+
}
|
|
565
|
+
if (referencedHighImpact) {
|
|
566
|
+
return `${latest}\n\nReferenced earlier high-impact user context:\n${referencedHighImpact}`;
|
|
567
|
+
}
|
|
568
|
+
if (referencedFrontend) {
|
|
569
|
+
return `${latest}\n\nReferenced earlier frontend user context:\n${referencedFrontend}`;
|
|
570
|
+
}
|
|
571
|
+
return latest;
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
export function requiresFailClosedProtection(decision) {
|
|
575
|
+
if (decision?.reasonCode === HIGH_IMPACT_PLANNER_REASON) return true;
|
|
576
|
+
|
|
577
|
+
const decisionRole = decision?.targetRole ?? decision?.role;
|
|
578
|
+
if (!["planner", "executor", "reviewer"].includes(decisionRole)) return false;
|
|
579
|
+
|
|
580
|
+
const signals = new Set(Array.isArray(decision.signals) ? decision.signals : []);
|
|
581
|
+
if (!signals.has("risk-present")) return false;
|
|
582
|
+
return signals.has("irreversible-action")
|
|
583
|
+
|| (signals.has("concrete-change-request")
|
|
584
|
+
&& (signals.has("specific-operational-parameter") || signals.has("urgency-pressure")));
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
function observeProtocol(decision) {
|
|
588
|
+
const shared = [
|
|
589
|
+
"Observe-mode controller protocol:",
|
|
590
|
+
"- No independent role was run. Do not claim independent planning or review.",
|
|
591
|
+
"- Perform the missing responsibility locally: separate facts from assumptions, inspect decisive project evidence, and state what remains unverified.",
|
|
592
|
+
"- Ground the path in capabilities and evidence that actually exist. Treat unavailable environments, tools, owners, thresholds, and protections as missing conditions, not facts.",
|
|
593
|
+
"- End with concrete evidence-gathering steps and explicit decision criteria that let the user safely continue; objection alone is not a complete delivery.",
|
|
594
|
+
];
|
|
595
|
+
if (!requiresFailClosedProtection(decision)) return shared;
|
|
596
|
+
|
|
597
|
+
return [
|
|
598
|
+
...shared,
|
|
599
|
+
"- High-impact fail-closed boundary: do not implement, persist, or publish the requested change in this turn. Use read-only evidence only.",
|
|
600
|
+
"- Explain the protection-chain gap and keep the current state unchanged until the decision basis and end-to-end safety dependency are verified.",
|
|
601
|
+
];
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
export function renderRouteNotice(decision, runtimeMode, actualRoute) {
|
|
605
|
+
const routeRole = decision.targetRole ?? decision.role;
|
|
606
|
+
const isUpgrade = decision.action === "upgrade"
|
|
607
|
+
&& (runtimeMode === "auto" || ["executor", "frontend"].includes(routeRole));
|
|
608
|
+
const action = isUpgrade
|
|
609
|
+
? "The current controller turn requested an in-place upgrade; no child was started."
|
|
610
|
+
: runtimeMode === "observe"
|
|
611
|
+
? `The ${routeRole} gap was selected in observe mode; do not start a child automatically.`
|
|
612
|
+
: `The ${routeRole} route was selected and executed as an independent child.`;
|
|
613
|
+
const routeIdentity = actualRoute
|
|
614
|
+
? [`${isUpgrade ? "requested controller route" : "verified child route"}: ${actualRoute.provider}/${actualRoute.model} (reasoning: ${actualRoute.reasoningEffort ?? "unspecified"}, maxTokens: ${actualRoute.maxTokens ?? (isUpgrade ? "inherited from Controller policy" : "provider default")})`]
|
|
615
|
+
: [];
|
|
616
|
+
|
|
617
|
+
return [
|
|
618
|
+
"odai automatic routing decision",
|
|
619
|
+
`role: ${decision.role}`,
|
|
620
|
+
`action: ${isUpgrade ? "upgrade" : decision.action}`,
|
|
621
|
+
...(decision.targetRole ? [`target responsibility: ${decision.targetRole}`] : []),
|
|
622
|
+
`reason: ${decision.reasonCode}`,
|
|
623
|
+
`runtime: ${runtimeMode}`,
|
|
624
|
+
action,
|
|
625
|
+
...routeIdentity,
|
|
626
|
+
...(runtimeMode === "observe" ? ["", ...observeProtocol(decision)] : []),
|
|
627
|
+
].join("\n");
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
export function renderMissingRouteConfigNotice(decision, runtimeMode, configFailure) {
|
|
631
|
+
const routeRole = decision.targetRole ?? decision.role;
|
|
632
|
+
const naturalRole = RESPONSIBILITY_LABELS[routeRole] ?? routeRole;
|
|
633
|
+
const invalidConfig = typeof configFailure === "string" && configFailure !== "";
|
|
634
|
+
return [
|
|
635
|
+
`odai routing capability is ${invalidConfig ? "invalid" : "not configured"}`,
|
|
636
|
+
`required responsibility: ${routeRole}`,
|
|
637
|
+
`runtime: ${runtimeMode}`,
|
|
638
|
+
`${invalidConfig ? "untrusted" : "missing"} responsibility mapping: ${routeRole}`,
|
|
639
|
+
...(invalidConfig ? [`configuration error: ${configFailure}`] : []),
|
|
640
|
+
`No ${routeRole} model was called. Do not claim that this responsibility ran or that the controller was upgraded.`,
|
|
641
|
+
`Tell the user that the required ${routeRole} model is ${invalidConfig ? "unavailable because its saved configuration is invalid" : "not configured"}. Ask them to name the provider, model, and optional reasoning effort in natural language.`,
|
|
642
|
+
`Example: “把${naturalRole}模型设为 <provider>/<model>,推理档设为 <effort>。”`,
|
|
643
|
+
`When the user specifies that mapping, call the odai_routing_config tool to ${invalidConfig ? "repair and " : ""}persist it. Do not ask the user to edit YAML or JSON, run a command, or add routing terminology to future task prompts.`,
|
|
644
|
+
|
|
645
|
+
...(requiresFailClosedProtection(decision) ? [
|
|
646
|
+
"High-impact fail-closed protection is active for this turn.",
|
|
647
|
+
"Do not implement, persist, or publish the requested change. Use read-only evidence only until the missing responsibility is configured or the decision gap is otherwise resolved.",
|
|
648
|
+
] : [
|
|
649
|
+
"Continue only with parts that do not depend on the missing independent responsibility.",
|
|
650
|
+
]),
|
|
651
|
+
].join("\n");
|
|
652
|
+
}
|
|
653
|
+
|
|
654
|
+
export function renderRouteFailureNotice(decision, failure) {
|
|
655
|
+
const routeRole = decision.targetRole ?? decision.role;
|
|
656
|
+
if (!requiresFailClosedProtection(decision)) {
|
|
657
|
+
return `odai ${routeRole} route failed (${failure}); continue directly as controller and do not claim delegated evidence.`;
|
|
658
|
+
}
|
|
659
|
+
|
|
660
|
+
return [
|
|
661
|
+
`odai ${routeRole} route failed (${failure}); no independent evidence was obtained.`,
|
|
662
|
+
"High-impact fail-closed protection is active for this turn.",
|
|
663
|
+
"Do not implement, persist, or publish the requested change. Use read-only evidence only.",
|
|
664
|
+
"Ground the path in capabilities and evidence that actually exist. Treat unavailable environments, tools, owners, thresholds, and protections as missing conditions, not facts.",
|
|
665
|
+
"Explain the unresolved decision-evidence and protection-chain gaps, then provide concrete evidence-gathering steps and explicit decision criteria. Objection alone is not a complete delivery.",
|
|
666
|
+
].join("\n");
|
|
667
|
+
}
|
|
668
|
+
|
|
669
|
+
export function renderDelegationPrompt(decision, taskText, roleContract) {
|
|
670
|
+
if (typeof roleContract !== "string" || roleContract.trim() === "") {
|
|
671
|
+
throw new TypeError(`canonical ${decision.role} role contract must be a non-empty string`);
|
|
672
|
+
}
|
|
673
|
+
|
|
674
|
+
return [
|
|
675
|
+
`You are the odai ${decision.role}.`,
|
|
676
|
+
roleContract.trim(),
|
|
677
|
+
"Runtime boundary: do not edit files, run shell commands, ask the user, or delegate further. The controller owns all final decisions and delivery.",
|
|
678
|
+
"Context boundary: this is a bounded task and evidence packet, not an inherited controller transcript. Use only the supplied contract, task, evidence, and source pointers; do not request or reconstruct the controller's full history.",
|
|
679
|
+
"",
|
|
680
|
+
"Task:",
|
|
681
|
+
taskText,
|
|
682
|
+
].join("\n");
|
|
683
|
+
}
|