sneakoscope 6.1.2 → 6.2.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/README.md +11 -4
- package/crates/sks-core/Cargo.lock +1 -1
- package/crates/sks-core/Cargo.toml +1 -1
- package/dist/cli/install-helpers.js +8 -3
- package/dist/config/skills-manifest.json +58 -58
- package/dist/core/agents/agent-effort-policy.js +28 -17
- package/dist/core/agents/agent-schema.js +1 -1
- package/dist/core/codex/codex-config-guard.js +178 -7
- package/dist/core/codex/codex-config-readability.js +21 -8
- package/dist/core/codex/codex-config-toml.js +14 -11
- package/dist/core/codex-app/mcp-manager.js +679 -0
- package/dist/core/codex-app/sks-menubar.js +405 -6
- package/dist/core/codex-control/codex-lb-launch-recovery.js +15 -0
- package/dist/core/codex-native/core-skill-manifest.js +1 -1
- package/dist/core/commands/mad-sks-command.js +44 -3
- package/dist/core/commands/menubar-command.js +94 -0
- package/dist/core/commands/naruto-command.js +3 -1
- package/dist/core/commands/wiki-command.js +11 -5
- package/dist/core/fsx.js +1 -0
- package/dist/core/hooks-runtime/code-pack-freshness-preflight.js +14 -8
- package/dist/core/hooks-runtime/naruto-decision-gate.js +184 -0
- package/dist/core/hooks-runtime/stop-repeat-guard.js +89 -0
- package/dist/core/hooks-runtime.js +36 -105
- package/dist/core/init/skills.js +4 -4
- package/dist/core/init.js +1 -1
- package/dist/core/managed-assets/managed-assets-manifest.js +178 -29
- package/dist/core/preflight/parallel-preflight-engine.js +16 -3
- package/dist/core/proof/route-adapter.js +1 -1
- package/dist/core/proof/selftest-proof-fixtures.js +3 -5
- package/dist/core/provider/model-router.js +15 -6
- package/dist/core/release/package-size-budget.js +4 -6
- package/dist/core/research/research-plan-markdown.js +123 -0
- package/dist/core/research/research-super-search.js +8 -4
- package/dist/core/research.js +4 -119
- package/dist/core/retention.js +70 -2
- package/dist/core/routes/dollar-manifest-lite.js +1 -1
- package/dist/core/routes.js +75 -22
- package/dist/core/subagents/agent-catalog.js +87 -15
- package/dist/core/subagents/model-policy.js +189 -48
- package/dist/core/subagents/naruto-help-contract.js +11 -4
- package/dist/core/subagents/official-subagent-preparation.js +55 -9
- package/dist/core/subagents/official-subagent-prompt.js +45 -23
- package/dist/core/subagents/thread-budget.js +1 -1
- package/dist/core/subagents/triwiki-attention.js +117 -14
- package/dist/core/triwiki/code-pack-head-freshness.js +291 -0
- package/dist/core/version.js +1 -1
- package/dist/core/zellij/zellij-launcher.js +12 -2
- package/dist/core/zellij/zellij-pane-proof.js +9 -1
- package/dist/core/zellij/zellij-update.js +14 -1
- package/dist/scripts/canonical-test-runner.js +7 -1
- package/dist/scripts/codex-lb-fast-mode-truth-check.js +11 -1
- package/dist/scripts/codex-lb-fast-ui-preservation-check.js +9 -2
- package/dist/scripts/codex-lb-gpt56-fast-profile-check.js +13 -2
- package/dist/scripts/codex-native-agent-role-content-check.js +13 -1
- package/dist/scripts/codex-sdk-backend-router-check.js +2 -0
- package/dist/scripts/lib/codex-sdk-gate-lib.js +4 -0
- package/dist/scripts/official-subagent-workflow-check.js +1 -1
- package/dist/scripts/packlist-performance-check.js +1 -18
- package/dist/scripts/python-codex-sdk-all-pipelines-check.js +8 -0
- package/dist/scripts/sks-menubar-install-check.js +6 -1
- package/dist/scripts/super-search-provider-interface-check.js +31 -18
- package/package.json +3 -1
- package/dist/scripts/codex-0139-feature-probes-check.js +0 -30
- package/dist/scripts/codex-0139-marketplace-source-check.js +0 -13
|
@@ -1,29 +1,58 @@
|
|
|
1
1
|
export const NARUTO_PARENT_MODEL = 'gpt-5.6-sol';
|
|
2
2
|
export const NARUTO_PARENT_EFFORT = 'max';
|
|
3
|
-
export const
|
|
4
|
-
export const
|
|
5
|
-
export const
|
|
6
|
-
const
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
3
|
+
export const LUNA_SUBAGENT_MODEL = 'gpt-5.6-luna';
|
|
4
|
+
export const TERRA_SUBAGENT_MODEL = 'gpt-5.6-terra';
|
|
5
|
+
export const SOL_SUBAGENT_MODEL = 'gpt-5.6-sol';
|
|
6
|
+
export const LUNA_SUBAGENT_EFFORT = 'max';
|
|
7
|
+
export const TERRA_SUBAGENT_EFFORT = 'medium';
|
|
8
|
+
export const DEFAULT_SUBAGENT_EFFORT = 'high';
|
|
9
|
+
export const SOL_MAX_SUBAGENT_EFFORT = 'max';
|
|
10
|
+
// Compatibility exports retained for research and older callers. New code
|
|
11
|
+
// should select a policy profile instead of combining model/effort constants.
|
|
12
|
+
export const DEFAULT_SUBAGENT_MODEL = SOL_SUBAGENT_MODEL;
|
|
13
|
+
export const THINKING_SUBAGENT_MODEL = SOL_SUBAGENT_MODEL;
|
|
14
|
+
export const SUBAGENT_EFFORT = SOL_MAX_SUBAGENT_EFFORT;
|
|
15
|
+
export const SUBAGENT_MODEL_POLICIES = Object.freeze({
|
|
16
|
+
luna_max_mechanical: Object.freeze({
|
|
17
|
+
policy: 'luna_max_mechanical',
|
|
18
|
+
kind: 'worker',
|
|
19
|
+
model: LUNA_SUBAGENT_MODEL,
|
|
20
|
+
modelReasoningEffort: LUNA_SUBAGENT_EFFORT
|
|
21
|
+
}),
|
|
22
|
+
sol_high_implementation: Object.freeze({
|
|
23
|
+
policy: 'sol_high_implementation',
|
|
24
|
+
kind: 'worker',
|
|
25
|
+
model: SOL_SUBAGENT_MODEL,
|
|
26
|
+
modelReasoningEffort: DEFAULT_SUBAGENT_EFFORT
|
|
27
|
+
}),
|
|
28
|
+
sol_max_judgment: Object.freeze({
|
|
29
|
+
policy: 'sol_max_judgment',
|
|
30
|
+
kind: 'expert',
|
|
31
|
+
model: SOL_SUBAGENT_MODEL,
|
|
32
|
+
modelReasoningEffort: SOL_MAX_SUBAGENT_EFFORT
|
|
33
|
+
}),
|
|
34
|
+
terra_medium_context_tools: Object.freeze({
|
|
35
|
+
policy: 'terra_medium_context_tools',
|
|
36
|
+
kind: 'worker',
|
|
37
|
+
model: TERRA_SUBAGENT_MODEL,
|
|
38
|
+
modelReasoningEffort: TERRA_SUBAGENT_EFFORT
|
|
39
|
+
})
|
|
40
|
+
});
|
|
41
|
+
const JUDGMENT_TASK_RE = new RegExp([
|
|
42
|
+
'\\breview(?:er|ing)?\\b',
|
|
43
|
+
'\\baudit(?:or|ing)?\\b',
|
|
44
|
+
'\\bdebug(?:ger|ging)?\\b',
|
|
15
45
|
'diagnos',
|
|
16
46
|
'investigat',
|
|
17
47
|
'\\bwhy\\b',
|
|
18
48
|
'\\bfail(?:ed|ure|ing)?\\b',
|
|
19
49
|
'root[- ]?cause',
|
|
20
50
|
'strategy',
|
|
21
|
-
'\\bplan
|
|
22
|
-
'planning',
|
|
51
|
+
'\\bplan(?:ning)?\\b',
|
|
23
52
|
'product',
|
|
24
53
|
'architecture',
|
|
25
54
|
'architect',
|
|
26
|
-
'
|
|
55
|
+
'\\bdesign(?:ing)?\\b',
|
|
27
56
|
'refactor',
|
|
28
57
|
'integrat',
|
|
29
58
|
'conflict',
|
|
@@ -36,8 +65,12 @@ const SOL_TASK_RE = new RegExp([
|
|
|
36
65
|
'release',
|
|
37
66
|
'publish',
|
|
38
67
|
'deploy',
|
|
39
|
-
'
|
|
40
|
-
'
|
|
68
|
+
'research',
|
|
69
|
+
'hypothesis',
|
|
70
|
+
'falsif',
|
|
71
|
+
'novelty',
|
|
72
|
+
'test[-_ ]?(?:design|strategy|coverage|gap|review)',
|
|
73
|
+
'regression',
|
|
41
74
|
'flaky',
|
|
42
75
|
'ambiguous',
|
|
43
76
|
'ambiguity',
|
|
@@ -47,15 +80,12 @@ const SOL_TASK_RE = new RegExp([
|
|
|
47
80
|
'assessment',
|
|
48
81
|
'\\bexpert\\b',
|
|
49
82
|
'\\brisk\\b',
|
|
50
|
-
'사용성',
|
|
51
|
-
'화면',
|
|
52
|
-
'유아이',
|
|
53
|
-
'유엑스',
|
|
54
|
-
'프론트엔드',
|
|
55
83
|
'리뷰',
|
|
56
84
|
'검토',
|
|
85
|
+
'감사',
|
|
57
86
|
'디버깅',
|
|
58
87
|
'진단',
|
|
88
|
+
'조사',
|
|
59
89
|
'원인',
|
|
60
90
|
'전략',
|
|
61
91
|
'기획',
|
|
@@ -66,27 +96,123 @@ const SOL_TASK_RE = new RegExp([
|
|
|
66
96
|
'통합',
|
|
67
97
|
'충돌',
|
|
68
98
|
'보안',
|
|
99
|
+
'인증',
|
|
69
100
|
'안전',
|
|
70
101
|
'데이터베이스',
|
|
71
102
|
'마이그레이션',
|
|
72
103
|
'배포',
|
|
73
104
|
'릴리즈',
|
|
74
105
|
'출시',
|
|
106
|
+
'연구',
|
|
107
|
+
'가설',
|
|
108
|
+
'반증',
|
|
109
|
+
'회귀',
|
|
75
110
|
'모호',
|
|
76
111
|
'트레이드오프',
|
|
77
112
|
'품질',
|
|
78
113
|
'판정',
|
|
79
114
|
'위험'
|
|
80
115
|
].join('|'), 'i');
|
|
81
|
-
const
|
|
82
|
-
'
|
|
83
|
-
'\\
|
|
84
|
-
'\\
|
|
85
|
-
'
|
|
86
|
-
'
|
|
87
|
-
'
|
|
88
|
-
'
|
|
116
|
+
const CONTEXT_TOOL_TASK_RE = new RegExp([
|
|
117
|
+
'computer[- ]?use',
|
|
118
|
+
'\\bbrowser(?:[- ]?use)?\\b',
|
|
119
|
+
'\\bchrome\\b',
|
|
120
|
+
'\\bplaywright\\b',
|
|
121
|
+
'\\bselenium\\b',
|
|
122
|
+
'\\bpuppeteer\\b',
|
|
123
|
+
'image[- ]?(?:gen|generation)',
|
|
124
|
+
'\\bimagegen\\b',
|
|
125
|
+
'gpt[- ]?image',
|
|
126
|
+
'\\bscreenshot(?:ting)?\\b',
|
|
127
|
+
'long[- ]?context',
|
|
128
|
+
'large[- ]?(?:file|document|codebase|repository|context)',
|
|
129
|
+
'(?:repository|repo)[- ]?wide',
|
|
130
|
+
'read[- ]?heavy',
|
|
131
|
+
'supporting[- ]?documents?',
|
|
132
|
+
'multi[- ]?(?:document|file) scan',
|
|
133
|
+
'\\bexplor(?:e|er|ation)\\b',
|
|
134
|
+
'\\bscan(?:ning)?\\b',
|
|
135
|
+
'\\bextract(?:ion)?\\b',
|
|
136
|
+
'\\binventory\\b',
|
|
137
|
+
'extensive[- ]?logs?',
|
|
138
|
+
'컴퓨터\\s*유즈',
|
|
139
|
+
'브라우저',
|
|
140
|
+
'크롬',
|
|
141
|
+
'이미지\\s*생성',
|
|
142
|
+
'스크린샷',
|
|
143
|
+
'롱\\s*컨텍스트',
|
|
144
|
+
'긴\\s*컨텍스트',
|
|
145
|
+
'장문',
|
|
146
|
+
'대규모',
|
|
147
|
+
'저장소\\s*전체',
|
|
148
|
+
'여러\\s*(?:문서|파일)',
|
|
149
|
+
'탐색',
|
|
150
|
+
'스캔',
|
|
151
|
+
'추출',
|
|
152
|
+
'인벤토리'
|
|
153
|
+
].join('|'), 'i');
|
|
154
|
+
const SIMPLE_MECHANICAL_TASK_RE = new RegExp([
|
|
155
|
+
'\\bone[- ]?line\\b',
|
|
156
|
+
'\\bsingle[- ]?file\\b',
|
|
157
|
+
'\\btiny\\b',
|
|
158
|
+
'\\btrivial\\b',
|
|
159
|
+
'\\bmechanical\\b',
|
|
160
|
+
'\\brepeatable\\b',
|
|
161
|
+
'\\bexact(?:ly)?\\b[^\\n]{0,36}\\b(?:rename|copy|replace|format|fixture|change)\\b',
|
|
162
|
+
'\\b(?:typo|spacing|label|copy|format)[-_ ]?(?:only|fix|change)?\\b',
|
|
163
|
+
'\\brename\\b[^\\n]{0,24}\\b(?:symbol|file|label|key|field)\\b',
|
|
164
|
+
'한\\s*줄',
|
|
165
|
+
'단일\\s*파일',
|
|
166
|
+
'아주\\s*(?:작은|단순한?)',
|
|
167
|
+
'극단적으로\\s*단순',
|
|
168
|
+
'기계적',
|
|
169
|
+
'반복적',
|
|
170
|
+
'정확한?[^\\n]{0,24}(?:이름\\s*변경|복사|치환|포맷|수정)',
|
|
171
|
+
'오타',
|
|
172
|
+
'문구',
|
|
173
|
+
'라벨',
|
|
174
|
+
'간격',
|
|
175
|
+
'이름\\s*변경'
|
|
176
|
+
].join('|'), 'i');
|
|
177
|
+
const IMPLEMENTATION_TASK_RE = new RegExp([
|
|
178
|
+
'\\bimplement(?:ation|er|ing)?\\b',
|
|
179
|
+
'\\bbuild(?:ing)?\\b',
|
|
180
|
+
'\\bcreate\\b',
|
|
181
|
+
'\\badd\\b[^\\n]{0,40}\\b(?:feature|endpoint|component|modal|button|handler|parser)\\b',
|
|
182
|
+
'\\bmodify\\b',
|
|
183
|
+
'\\bfix\\b',
|
|
184
|
+
'\\bcod(?:e|ing)\\b',
|
|
185
|
+
'\\bui\\b',
|
|
186
|
+
'\\bux\\b',
|
|
187
|
+
'\\bgui\\b',
|
|
188
|
+
'frontend',
|
|
189
|
+
'backend',
|
|
190
|
+
'\\blogic\\b',
|
|
191
|
+
'\\bparser\\b',
|
|
192
|
+
'\\bcomponent\\b',
|
|
193
|
+
'\\bmodal\\b',
|
|
194
|
+
'\\bappkit\\b',
|
|
195
|
+
'\\bswift\\b',
|
|
196
|
+
'\\bfeature\\b',
|
|
197
|
+
'구현',
|
|
198
|
+
'기능\\s*추가',
|
|
199
|
+
'코딩',
|
|
200
|
+
'코드',
|
|
201
|
+
'로직',
|
|
202
|
+
'화면',
|
|
203
|
+
'유아이',
|
|
204
|
+
'유엑스',
|
|
205
|
+
'프론트엔드',
|
|
206
|
+
'백엔드',
|
|
207
|
+
'컴포넌트',
|
|
208
|
+
'모달',
|
|
209
|
+
'버튼',
|
|
210
|
+
'앱킷',
|
|
211
|
+
'스위프트'
|
|
89
212
|
].join('|'), 'i');
|
|
213
|
+
export function subagentModelProfile(policy) {
|
|
214
|
+
return SUBAGENT_MODEL_POLICIES[policy];
|
|
215
|
+
}
|
|
90
216
|
export function decideSubagentModel(input = {}) {
|
|
91
217
|
const text = [
|
|
92
218
|
input.title,
|
|
@@ -94,25 +220,40 @@ export function decideSubagentModel(input = {}) {
|
|
|
94
220
|
input.role,
|
|
95
221
|
input.expectedOutput
|
|
96
222
|
].filter(Boolean).join(' ');
|
|
97
|
-
const
|
|
98
|
-
||
|
|
99
|
-
||
|
|
100
|
-
if (
|
|
101
|
-
return
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
223
|
+
const judgment = input.requiresJudgment === true
|
|
224
|
+
|| input.taskClass === 'judgment'
|
|
225
|
+
|| JUDGMENT_TASK_RE.test(text);
|
|
226
|
+
if (judgment)
|
|
227
|
+
return decision('sol_max_judgment');
|
|
228
|
+
const contextOrTools = input.longContext === true
|
|
229
|
+
|| input.toolHeavy === true
|
|
230
|
+
|| input.taskClass === 'context_tools'
|
|
231
|
+
|| input.contextMode === 'long'
|
|
232
|
+
|| (input.toolSurface !== undefined && input.toolSurface !== 'none')
|
|
233
|
+
|| input.scopeSize === 'large'
|
|
234
|
+
|| CONTEXT_TOOL_TASK_RE.test(text);
|
|
235
|
+
if (contextOrTools)
|
|
236
|
+
return decision('terra_medium_context_tools');
|
|
237
|
+
const simpleMechanical = input.simpleMechanical === true
|
|
238
|
+
|| input.taskClass === 'mechanical'
|
|
239
|
+
|| input.scopeSize === 'tiny'
|
|
240
|
+
|| SIMPLE_MECHANICAL_TASK_RE.test(text);
|
|
241
|
+
if (simpleMechanical)
|
|
242
|
+
return decision('luna_max_mechanical');
|
|
243
|
+
const implementation = input.taskClass === 'implementation' || IMPLEMENTATION_TASK_RE.test(text);
|
|
244
|
+
if (implementation)
|
|
245
|
+
return decision('sol_high_implementation');
|
|
246
|
+
// Ambiguous work defaults to the trust-first lane. Sol High is reserved for
|
|
247
|
+
// clearly identified implementation, not for underspecified judgment.
|
|
248
|
+
return decision('sol_max_judgment');
|
|
114
249
|
}
|
|
115
250
|
export function isReasoningSensitiveSubagentTask(input = {}) {
|
|
116
|
-
return decideSubagentModel(input).
|
|
251
|
+
return decideSubagentModel(input).policy === 'sol_max_judgment';
|
|
252
|
+
}
|
|
253
|
+
function decision(policy) {
|
|
254
|
+
return {
|
|
255
|
+
...subagentModelProfile(policy),
|
|
256
|
+
reason: policy
|
|
257
|
+
};
|
|
117
258
|
}
|
|
118
259
|
//# sourceMappingURL=model-policy.js.map
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { NARUTO_PARENT_EFFORT, NARUTO_PARENT_MODEL } from './model-policy.js';
|
|
2
|
-
import {
|
|
3
|
-
import { MAX_AUTOMATIC_REVIEWER_COUNT, MAX_AUTOMATIC_SUBAGENT_COUNT, officialSubagentRolePlan } from './agent-catalog.js';
|
|
2
|
+
import { DEFAULT_AUTOMATIC_SUBAGENT_COUNT, MAX_AUTOMATIC_REVIEWER_COUNT, MAX_AUTOMATIC_SUBAGENT_COUNT, officialSubagentRolePlan } from './agent-catalog.js';
|
|
4
3
|
export const NARUTO_HELP_SCHEMA = 'sks.naruto-subagent-workflow.v1';
|
|
5
4
|
export function buildNarutoHelpResult() {
|
|
6
5
|
return {
|
|
@@ -16,13 +15,20 @@ export function buildNarutoHelpResult() {
|
|
|
16
15
|
'sks naruto proof [latest|M-...] [--json]'
|
|
17
16
|
],
|
|
18
17
|
commands: ['help', 'status', 'subagents', 'proof', 'run'],
|
|
19
|
-
default_requested_subagents:
|
|
20
|
-
scaling_policy: '
|
|
18
|
+
default_requested_subagents: DEFAULT_AUTOMATIC_SUBAGENT_COUNT,
|
|
19
|
+
scaling_policy: 'two_independent_children_for_non_trivial_work_parent_owned_risk_based_expansion',
|
|
21
20
|
automatic_subagent_ceiling: MAX_AUTOMATIC_SUBAGENT_COUNT,
|
|
22
21
|
automatic_reviewer_ceiling: MAX_AUTOMATIC_REVIEWER_COUNT,
|
|
23
22
|
critical_multi_domain_reviewer_ceiling: MAX_AUTOMATIC_SUBAGENT_COUNT,
|
|
24
23
|
max_depth: 1,
|
|
25
24
|
triwiki_context: 'bounded_attention_use_first_with_on_demand_hydration',
|
|
25
|
+
model_routing_policy: {
|
|
26
|
+
luna_max: 'tiny_short_context_mechanical_only',
|
|
27
|
+
sol_high: 'ordinary_ui_logic_backend_and_native_implementation',
|
|
28
|
+
sol_max: 'review_debug_planning_architecture_security_database_research_release_and_judgment',
|
|
29
|
+
terra_medium: 'long_context_computer_use_browser_chrome_and_image_generation_execution',
|
|
30
|
+
mixed_slice_rule: 'split_execution_from_judgment_when_possible_otherwise_sol_max_wins'
|
|
31
|
+
},
|
|
26
32
|
completion_evidence: {
|
|
27
33
|
lifecycle_events: ['SubagentStart', 'SubagentStop'],
|
|
28
34
|
stop_is_success_evidence: false,
|
|
@@ -34,6 +40,7 @@ export function buildNarutoHelpResult() {
|
|
|
34
40
|
},
|
|
35
41
|
legacy_process_runtime_available: false,
|
|
36
42
|
parent: { model: NARUTO_PARENT_MODEL, model_reasoning_effort: NARUTO_PARENT_EFFORT },
|
|
43
|
+
agent_catalog_mode: 'full_catalog_only_on_explicit_help',
|
|
37
44
|
agents: officialSubagentRolePlan()
|
|
38
45
|
};
|
|
39
46
|
}
|
|
@@ -6,7 +6,7 @@ import { chooseVerificationBudget } from '../runtime/verification-budget.js';
|
|
|
6
6
|
import { buildOfficialSubagentPrompt } from './official-subagent-prompt.js';
|
|
7
7
|
import { readOfficialSubagentConfig } from './official-subagent-config.js';
|
|
8
8
|
import { NARUTO_PARENT_EFFORT, NARUTO_PARENT_MODEL } from './model-policy.js';
|
|
9
|
-
import { officialSubagentFanoutPolicy,
|
|
9
|
+
import { MAX_ON_DEMAND_SUBAGENT_ROLE_COUNT, officialSubagentFanoutPolicy, officialSubagentOnDemandRolePlan, officialSubagentRoleCatalog, recommendOfficialSubagentRoles } from './agent-catalog.js';
|
|
10
10
|
import { resolveSubagentThreadBudget } from './thread-budget.js';
|
|
11
11
|
import { readBoundedTriwikiAttention } from './triwiki-attention.js';
|
|
12
12
|
import { SUBAGENT_EVIDENCE_FILENAME, SUBAGENT_EVENT_LOG_FILENAME, SUBAGENT_PARENT_SUMMARY_FILENAME, normalizeSubagentParentSummary, writeSubagentEvidence } from './subagent-evidence.js';
|
|
@@ -24,11 +24,21 @@ export async function prepareOfficialSubagentMission(input) {
|
|
|
24
24
|
requiresWrite: input.readOnly !== true
|
|
25
25
|
});
|
|
26
26
|
const officialConfig = await readOfficialSubagentConfig(input.root);
|
|
27
|
-
const triwikiAttention = await readBoundedTriwikiAttention(input.root);
|
|
28
|
-
const
|
|
27
|
+
const triwikiAttention = await readBoundedTriwikiAttention(input.root, triwikiAttentionLimit(taskProfile), goal);
|
|
28
|
+
const operatorRequested = input.requestedSubagentsExplicit ?? input.requestedSubagents !== undefined;
|
|
29
|
+
const routeContract = mode === 'generic' && !operatorRequested
|
|
30
|
+
? routeOwnedSubagentContract(input.route)
|
|
31
|
+
: null;
|
|
32
|
+
const requestedSubagents = input.requestedSubagents ?? routeContract?.count;
|
|
33
|
+
const requestedSource = operatorRequested
|
|
34
|
+
? 'operator'
|
|
35
|
+
: routeContract
|
|
36
|
+
? 'route_contract'
|
|
37
|
+
: 'automatic';
|
|
29
38
|
const selectedFanoutPolicy = officialSubagentFanoutPolicy({
|
|
30
|
-
...(
|
|
31
|
-
requestedExplicit,
|
|
39
|
+
...(requestedSubagents === undefined ? {} : { requestedSubagents }),
|
|
40
|
+
requestedExplicit: requestedSource !== 'automatic',
|
|
41
|
+
requestedSource,
|
|
32
42
|
taskProfile,
|
|
33
43
|
suggestedRoles: suggestedAgents,
|
|
34
44
|
goal
|
|
@@ -53,12 +63,15 @@ export async function prepareOfficialSubagentMission(input) {
|
|
|
53
63
|
goal: delegationGoal,
|
|
54
64
|
slices: [],
|
|
55
65
|
requestedSubagents: budget.requestedSubagents,
|
|
56
|
-
requestedSubagentsExplicit:
|
|
66
|
+
requestedSubagentsExplicit: requestedSource === 'operator',
|
|
67
|
+
requestedSubagentsSource: requestedSource,
|
|
57
68
|
maxThreads: budget.maxThreads,
|
|
58
69
|
decompositionStatus: 'parent_required',
|
|
59
70
|
triwikiAttention,
|
|
60
71
|
recommendedAgents: suggestedAgents
|
|
61
72
|
});
|
|
73
|
+
const selectedAgentPlan = officialSubagentOnDemandRolePlan(suggestedAgents);
|
|
74
|
+
const agentCatalog = onDemandAgentCatalogMetadata(selectedAgentPlan);
|
|
62
75
|
const configBlockers = officialConfig.blockers.map((blocker) => `official_subagent_config:${blocker}`);
|
|
63
76
|
const plan = {
|
|
64
77
|
schema: 'sks.subagent-plan.v1',
|
|
@@ -73,7 +86,9 @@ export async function prepareOfficialSubagentMission(input) {
|
|
|
73
86
|
decomposition_status: 'parent_required',
|
|
74
87
|
delegation_prompt: delegationPrompt,
|
|
75
88
|
requested_subagents: budget.requestedSubagents,
|
|
76
|
-
requested_subagents_explicit:
|
|
89
|
+
requested_subagents_explicit: requestedSource === 'operator',
|
|
90
|
+
requested_subagents_source: requestedSource,
|
|
91
|
+
route_owned_count_contract: routeContract,
|
|
77
92
|
max_threads: budget.maxThreads,
|
|
78
93
|
first_wave: budget.firstWave,
|
|
79
94
|
wave_count: budget.waveCount,
|
|
@@ -92,7 +107,8 @@ export async function prepareOfficialSubagentMission(input) {
|
|
|
92
107
|
model: NARUTO_PARENT_MODEL,
|
|
93
108
|
model_reasoning_effort: NARUTO_PARENT_EFFORT
|
|
94
109
|
},
|
|
95
|
-
|
|
110
|
+
agent_catalog: agentCatalog,
|
|
111
|
+
agents: selectedAgentPlan,
|
|
96
112
|
verification_budget: verification,
|
|
97
113
|
verification_checks: [],
|
|
98
114
|
verification: { budget: verification },
|
|
@@ -134,6 +150,7 @@ export async function prepareOfficialSubagentMission(input) {
|
|
|
134
150
|
ok: false,
|
|
135
151
|
blockers,
|
|
136
152
|
sessionKey: input.sessionScope || null,
|
|
153
|
+
suggestedAgents,
|
|
137
154
|
observedParentModel,
|
|
138
155
|
parentModelMatch
|
|
139
156
|
}));
|
|
@@ -165,8 +182,25 @@ export async function prepareOfficialSubagentMission(input) {
|
|
|
165
182
|
parentModelMatch
|
|
166
183
|
};
|
|
167
184
|
}
|
|
185
|
+
function triwikiAttentionLimit(taskProfile) {
|
|
186
|
+
return ['parallel-read', 'parallel-write', 'high-risk'].includes(taskProfile) ? 6 : 4;
|
|
187
|
+
}
|
|
188
|
+
function routeOwnedSubagentContract(route) {
|
|
189
|
+
const normalized = String(route || '').replace(/^\$/, '').trim().toLowerCase();
|
|
190
|
+
if (normalized === 'research') {
|
|
191
|
+
return { count: 3, reason: 'research_exact_three_independent_reviewers' };
|
|
192
|
+
}
|
|
193
|
+
if (normalized === 'autoresearch') {
|
|
194
|
+
return { count: 3, reason: 'autoresearch_exact_three_independent_reviewers' };
|
|
195
|
+
}
|
|
196
|
+
return null;
|
|
197
|
+
}
|
|
168
198
|
export function buildNarutoSummary(input) {
|
|
169
199
|
const parentSummary = normalizeSubagentParentSummary(input.parentSummary);
|
|
200
|
+
const suggestedAgents = Array.isArray(input.suggestedAgents)
|
|
201
|
+
? uniqueStrings(input.suggestedAgents)
|
|
202
|
+
: [];
|
|
203
|
+
const selectedAgentPlan = officialSubagentOnDemandRolePlan(suggestedAgents);
|
|
170
204
|
return {
|
|
171
205
|
schema: NARUTO_RESULT_SCHEMA,
|
|
172
206
|
ok: input.ok === true,
|
|
@@ -188,7 +222,8 @@ export function buildNarutoSummary(input) {
|
|
|
188
222
|
started_subagents: Number(input.evidence?.started_threads || 0),
|
|
189
223
|
completed_subagents: Number(input.evidence?.completed_threads || 0),
|
|
190
224
|
failed_subagents: Number(input.evidence?.failed_threads || 0),
|
|
191
|
-
|
|
225
|
+
agent_catalog: onDemandAgentCatalogMetadata(selectedAgentPlan),
|
|
226
|
+
agents: selectedAgentPlan,
|
|
192
227
|
verification: {
|
|
193
228
|
budget: input.verification,
|
|
194
229
|
checks: []
|
|
@@ -203,6 +238,17 @@ export function buildNarutoSummary(input) {
|
|
|
203
238
|
updated_at: nowIso()
|
|
204
239
|
};
|
|
205
240
|
}
|
|
241
|
+
function onDemandAgentCatalogMetadata(selectedAgentPlan) {
|
|
242
|
+
const selectedAgents = Object.keys(selectedAgentPlan);
|
|
243
|
+
return {
|
|
244
|
+
mode: 'on_demand',
|
|
245
|
+
total_available: officialSubagentRoleCatalog().length,
|
|
246
|
+
selected_count: selectedAgents.length,
|
|
247
|
+
selected_agents: selectedAgents,
|
|
248
|
+
max_injected: MAX_ON_DEMAND_SUBAGENT_ROLE_COUNT,
|
|
249
|
+
full_catalog_injected: false
|
|
250
|
+
};
|
|
251
|
+
}
|
|
206
252
|
export async function writeNarutoGate(dir, input) {
|
|
207
253
|
await writeJsonAtomic(path.join(dir, NARUTO_GATE_FILENAME), buildNarutoGateResult(input));
|
|
208
254
|
}
|
|
@@ -1,30 +1,45 @@
|
|
|
1
1
|
import { HARD_NARUTO_MAX_THREADS } from './thread-budget.js';
|
|
2
|
-
import { MAX_AUTOMATIC_REVIEWER_COUNT, MAX_AUTOMATIC_SUBAGENT_COUNT, officialSubagentRoleCatalog, selectOfficialSubagentRole } from './agent-catalog.js';
|
|
2
|
+
import { MAX_AUTOMATIC_REVIEWER_COUNT, MAX_AUTOMATIC_SUBAGENT_COUNT, officialSubagentOnDemandRoleCatalog, officialSubagentRoleCatalog, selectOfficialSubagentRole } from './agent-catalog.js';
|
|
3
3
|
export function buildOfficialSubagentPrompt(input) {
|
|
4
4
|
const maxThreads = clampThreads(input.maxThreads);
|
|
5
5
|
const requestedSubagents = normalizeRequestedSubagents(input.requestedSubagents, input.slices.length);
|
|
6
6
|
const waveCount = requestedSubagents === 0 ? 0 : Math.ceil(requestedSubagents / maxThreads);
|
|
7
7
|
const parentDecompositionRequired = input.decompositionStatus === 'parent_required';
|
|
8
|
-
const
|
|
8
|
+
const requestedSource = input.requestedSubagentsSource === 'route_contract'
|
|
9
|
+
? 'route_contract'
|
|
10
|
+
: input.requestedSubagentsExplicit === true || input.requestedSubagentsSource === 'operator'
|
|
11
|
+
? 'operator'
|
|
12
|
+
: 'automatic';
|
|
13
|
+
const requestedPolicy = requestedSource === 'operator'
|
|
9
14
|
? `${requestedSubagents} (explicit operator request)`
|
|
10
|
-
:
|
|
15
|
+
: requestedSource === 'route_contract'
|
|
16
|
+
? `${requestedSubagents} (route-owned exact orchestration contract)`
|
|
17
|
+
: `${requestedSubagents} (risk-based automatic count; two independent children are the non-trivial default; keep the plan and evidence count exact)`;
|
|
11
18
|
const triwiki = renderBoundedTriwikiAttention(input.triwikiAttention);
|
|
12
|
-
const
|
|
13
|
-
|
|
14
|
-
|
|
19
|
+
const resolvedSlices = input.slices.map((slice) => ({
|
|
20
|
+
slice,
|
|
21
|
+
agentName: slice.agent || selectOfficialSubagentRole({
|
|
15
22
|
title: slice.title,
|
|
16
23
|
description: slice.description,
|
|
17
24
|
role: slice.kind,
|
|
18
25
|
...(slice.paths === undefined ? {} : { paths: slice.paths }),
|
|
19
26
|
readOnly: slice.readOnly === true,
|
|
20
27
|
requiresWrite: slice.readOnly !== true
|
|
21
|
-
})
|
|
28
|
+
})
|
|
29
|
+
}));
|
|
30
|
+
const catalog = renderAgentCatalog([
|
|
31
|
+
...resolvedSlices.map((row) => row.agentName),
|
|
32
|
+
...(input.recommendedAgents || [])
|
|
33
|
+
]);
|
|
34
|
+
const rows = resolvedSlices.map(({ slice, agentName }, index) => {
|
|
22
35
|
const mode = slice.readOnly ? 'read-only' : 'use the parent permission mode';
|
|
23
36
|
const paths = (slice.paths || []).map((entry) => String(entry).trim()).filter(Boolean);
|
|
37
|
+
const role = officialSubagentOnDemandRoleCatalog([agentName])[0];
|
|
24
38
|
return [
|
|
25
39
|
`${index + 1}. [${slice.id}] use custom agent \`${agentName}\``,
|
|
26
40
|
` title: ${slice.title}`,
|
|
27
41
|
` task: ${slice.description}`,
|
|
42
|
+
` model policy: ${role ? `${role.model_policy} (${role.model}/${role.model_reasoning_effort})` : 'resolve from installed custom agent'}`,
|
|
28
43
|
` mode: ${mode}`,
|
|
29
44
|
` paths: ${paths.join(', ') || 'assigned by parent'}`
|
|
30
45
|
].join('\n');
|
|
@@ -40,10 +55,14 @@ Parent agent:
|
|
|
40
55
|
Subagent rules:
|
|
41
56
|
- use only Codex official subagent threads; do not launch shell workers, a custom scheduler, a worker pool, or model fanout
|
|
42
57
|
- select the narrowest matching project custom agent by its description; the custom agent name is the spawn type
|
|
43
|
-
- use \`worker\` with gpt-5.6-luna and max reasoning only for
|
|
44
|
-
- use
|
|
45
|
-
-
|
|
46
|
-
|
|
58
|
+
- use \`worker\` with gpt-5.6-luna and max reasoning only for tiny, short-context, mechanical work with no exploration or judgment
|
|
59
|
+
- use gpt-5.6-sol with high reasoning for ordinary UI, logic, backend, and native implementation
|
|
60
|
+
- use gpt-5.6-sol with max reasoning for review, debugging, planning, architecture, security, database, research, release, ambiguity, and every judgment-bearing slice
|
|
61
|
+
- use gpt-5.6-terra with medium reasoning for long-context analysis and direct Computer Use, Browser/Chrome, or image-generation execution
|
|
62
|
+
- split mixed work when possible: Terra gathers or operates, Sol High implements, and Sol Max judges; when one slice cannot be split safely, judgment takes priority
|
|
63
|
+
- never assign Luna to long-context, exploration, review, debugging, planning, or tool-heavy work
|
|
64
|
+
- automatic fan-out is selected before execution: two independent children for non-trivial work,
|
|
65
|
+
and at most ${MAX_AUTOMATIC_SUBAGENT_COUNT} only for critical multi-domain risk; trivial Answer/DFix work is filtered before this route
|
|
47
66
|
- automatic reviewer-only fan-out is capped at ${MAX_AUTOMATIC_REVIEWER_COUNT} for ordinary work; critical multi-domain review may use the overall cap of ${MAX_AUTOMATIC_SUBAGENT_COUNT}
|
|
48
67
|
- requested subagents: ${requestedPolicy}
|
|
49
68
|
- max open agent threads: ${maxThreads}
|
|
@@ -57,9 +76,11 @@ Subagent rules:
|
|
|
57
76
|
${parentDecompositionRequired ? `- decomposition status: parent_required
|
|
58
77
|
- before spawning, decompose the goal into independent, non-overlapping slices
|
|
59
78
|
- do not invent write scopes merely to reach the requested count
|
|
60
|
-
${
|
|
79
|
+
${requestedSource === 'operator'
|
|
61
80
|
? '- the explicit operator count is authoritative; if it cannot be defended safely, block and report instead of silently changing it'
|
|
62
|
-
:
|
|
81
|
+
: requestedSource === 'route_contract'
|
|
82
|
+
? '- the route-owned exact count is authoritative; preserve it and follow the route-specific orchestration contract'
|
|
83
|
+
: '- if fewer defensible slices exist, reduce the delegation plan and requested count before execution; never increase automatically beyond the selected count'}` : '- decomposition status: ready'}
|
|
63
84
|
|
|
64
85
|
Central TriWiki context:
|
|
65
86
|
${triwiki}
|
|
@@ -111,16 +132,17 @@ function renderBoundedTriwikiAttention(value) {
|
|
|
111
132
|
`- bounded anchors: ${JSON.stringify(anchors)}`
|
|
112
133
|
].join('\n');
|
|
113
134
|
}
|
|
114
|
-
function renderAgentCatalog(
|
|
115
|
-
const
|
|
116
|
-
const
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
.
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
135
|
+
function renderAgentCatalog(requested) {
|
|
136
|
+
const names = [...new Set(requested.map(String).map((name) => name.trim()).filter(Boolean))];
|
|
137
|
+
const selected = officialSubagentOnDemandRoleCatalog(names.length ? names : ['expert']);
|
|
138
|
+
const preferred = new Set(names);
|
|
139
|
+
return [
|
|
140
|
+
`- metadata mode: on-demand (${selected.length}/${officialSubagentRoleCatalog().length} roles included; full catalog is not injected)`,
|
|
141
|
+
...selected.map((role) => {
|
|
142
|
+
const marker = preferred.has(role.name) ? ' [suggested for this goal]' : '';
|
|
143
|
+
return `- \`${role.name}\`${marker}: ${role.model_policy}, ${role.model}/${role.model_reasoning_effort}, ${role.sandbox_mode}; ${role.description}`;
|
|
144
|
+
})
|
|
145
|
+
].join('\n');
|
|
124
146
|
}
|
|
125
147
|
function clampThreads(value) {
|
|
126
148
|
const parsed = Number(value);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export const DEFAULT_NARUTO_MAX_THREADS = 12;
|
|
2
2
|
export const HARD_NARUTO_MAX_THREADS = 32;
|
|
3
|
-
export const DEFAULT_NARUTO_REQUESTED_SUBAGENTS =
|
|
3
|
+
export const DEFAULT_NARUTO_REQUESTED_SUBAGENTS = 2;
|
|
4
4
|
export function resolveSubagentThreadBudget(input = {}) {
|
|
5
5
|
const requested = clamp(input.requested ?? input.independentSliceCount ?? DEFAULT_NARUTO_REQUESTED_SUBAGENTS, 1, HARD_NARUTO_MAX_THREADS);
|
|
6
6
|
const configured = clamp(input.configuredMaxThreads ?? DEFAULT_NARUTO_MAX_THREADS, 1, HARD_NARUTO_MAX_THREADS);
|