helloagents 3.0.32 → 3.0.33
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/.claude-plugin/plugin.json +1 -1
- package/.codex-plugin/plugin.json +1 -1
- package/README.md +3 -3
- package/README_CN.md +3 -3
- package/bootstrap-lite.md +1 -1
- package/bootstrap.md +1 -1
- package/gemini-extension.json +1 -1
- package/package.json +1 -1
- package/scripts/notify-context.mjs +1 -1
- package/scripts/notify-payload.mjs +8 -0
- package/scripts/notify-ui.mjs +14 -1
- package/scripts/notify.mjs +78 -2
- package/scripts/ralph-loop.mjs +54 -1
- package/skills/helloagents/SKILL.md +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "helloagents",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.33",
|
|
4
4
|
"description": "HelloAGENTS — The orchestration kernel that makes any AI CLI smarter. Adds intelligent routing, quality verification (Ralph Loop), safety guards, and notifications.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "HelloWind",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "helloagents",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.33",
|
|
4
4
|
"description": "HelloAGENTS — Quality-driven orchestration kernel for AI CLIs with intelligent routing, quality verification (Ralph Loop), safety guards, and notifications.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "HelloWind",
|
package/README.md
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
**A workflow layer for AI coding CLIs: skills, project knowledge, delivery checks, safer config writes, and resumable execution.**
|
|
10
10
|
|
|
11
|
-
[](./package.json)
|
|
12
12
|
[](https://www.npmjs.com/package/helloagents)
|
|
13
13
|
[](./package.json)
|
|
14
14
|
[](./skills)
|
|
@@ -657,7 +657,7 @@ Codex is rules-file driven by default.
|
|
|
657
657
|
- global mode installs the native local-plugin chain, but keeps `~/.helloagents/helloagents` as the single managed runtime source by linking plugin roots, plugin cache, and `~/.codex/helloagents` back to it
|
|
658
658
|
- cleanup removes only the HelloAGENTS-managed hook trust entries and legacy managed notify residues, while keeping user-owned hook state untouched
|
|
659
659
|
- Codex hooks only synchronize runtime state and enforce Stop gates; they do not inject HelloAGENTS rules or route text through hook output
|
|
660
|
-
- Codex closeout de-duplicates Stop hooks and native `codex-notify`, so one turn does not notify twice
|
|
660
|
+
- Codex closeout de-duplicates Stop hooks and native `codex-notify`, so one turn does not notify twice, and clientless delegated child-completion events stay silent when the managed Stop hook is active
|
|
661
661
|
- `/goal` remains Codex-native. Enable it explicitly with `helloagents codex goals enable` when long-running plan execution is needed
|
|
662
662
|
- Goal-aware commands resume from `tasks.md`, `contract.json`, and `state_path`; they do not create goals automatically or mark them complete before HelloAGENTS verification and closeout
|
|
663
663
|
|
|
@@ -680,7 +680,7 @@ The current suite covers:
|
|
|
680
680
|
- `helloagents doctor`
|
|
681
681
|
- project storage and `repo-shared` behavior
|
|
682
682
|
- session-scoped `state_path`, runtime signals, and evidence
|
|
683
|
-
- runtime injection, routing, guard, verification, visual evidence, delivery gates, closeout de-duplication, and successful-mode tracking after native install failures
|
|
683
|
+
- runtime injection, routing, guard, verification, visual evidence, delivery gates, closeout de-duplication, sub-agent wrapper and notification suppression, and successful-mode tracking after native install failures
|
|
684
684
|
- README and skill contract alignment
|
|
685
685
|
|
|
686
686
|
## FAQ
|
package/README_CN.md
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
**面向 AI 编码 CLI 的工作流层:技能、知识库、交付检查、更安全的配置写入,以及可恢复的执行流程。**
|
|
10
10
|
|
|
11
|
-
[](./package.json)
|
|
12
12
|
[](https://www.npmjs.com/package/helloagents)
|
|
13
13
|
[](./package.json)
|
|
14
14
|
[](./skills)
|
|
@@ -661,7 +661,7 @@ Codex 默认走规则文件驱动。
|
|
|
661
661
|
- 全局模式安装原生本地插件流程,但仍把 `~/.helloagents/helloagents` 作为唯一受管运行时源;插件根目录、插件缓存和 `~/.codex/helloagents` 都会回链到它
|
|
662
662
|
- 清理时只删除 HelloAGENTS 自己写入的 hook trust 条目和旧式受管 notify 残留,不影响用户已有的 hook 状态
|
|
663
663
|
- Codex hooks 只做静默运行态同步和 Stop 门禁,不通过 hook 注入 HelloAGENTS 规则或路由说明
|
|
664
|
-
- Codex 收尾会对 Stop hook 和原生 `codex-notify`
|
|
664
|
+
- Codex 收尾会对 Stop hook 和原生 `codex-notify` 去重,避免同一轮重复通知;受管 Stop hook 生效时,client 为空的委派子任务完成事件也会保持静默
|
|
665
665
|
- `/goal` 保持 Codex 原生能力;需要长程执行时,用 `helloagents codex goals enable` 显式启用
|
|
666
666
|
- 感知 goal 的命令从 `tasks.md`、`contract.json` 和 `state_path` 恢复;不会自动创建 goal,也不会在 HelloAGENTS 验证和收尾前标记完成
|
|
667
667
|
|
|
@@ -684,7 +684,7 @@ npm test
|
|
|
684
684
|
- `helloagents doctor`
|
|
685
685
|
- 项目存储和 `repo-shared`
|
|
686
686
|
- 会话级 `state_path`、运行态信号和证据
|
|
687
|
-
- 运行时注入、选路、Guard
|
|
687
|
+
- 运行时注入、选路、Guard、验证、视觉证据、交付门控、收尾去重、子代理外层格式与通知静默保护,以及原生安装失败后的模式记录
|
|
688
688
|
- README 与 skill 契约一致性
|
|
689
689
|
|
|
690
690
|
## FAQ
|
package/bootstrap-lite.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# HelloAGENTS
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
当当前任务属于上级代理分派的局部任务、由宿主协作/委派机制创建(包括 spawn_agent、worker / explorer、并行代理、Codex agent/delegate/wait 等)、当前输出会交回上级代理或控制器继续汇总/决策/复述,或当前回复并非直接面向最终用户的终局交付时,一律按子代理处理:仅跳过输出格式、交互确认与停顿、统一执行流程、任务分层、完成判定、命令路由和流程状态,直接执行并返回结果。只返回结果、证据或阻塞项;禁止输出 `【HelloAGENTS】` 外层格式、`🔄 下一步:`、面向最终用户的收尾或 turn-state;其余规则持续生效。
|
|
4
4
|
|
|
5
5
|
## 配置
|
|
6
6
|
配置文件: ~/.helloagents/helloagents.json
|
package/bootstrap.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# HelloAGENTS
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
当当前任务属于上级代理分派的局部任务、由宿主协作/委派机制创建(包括 spawn_agent、worker / explorer、并行代理、Codex agent/delegate/wait 等)、当前输出会交回上级代理或控制器继续汇总/决策/复述,或当前回复并非直接面向最终用户的终局交付时,一律按子代理处理:仅跳过输出格式、交互确认与停顿、统一执行流程、任务分层、完成判定、命令路由和流程状态,直接执行并返回结果。只返回结果、证据或阻塞项;禁止输出 `【HelloAGENTS】` 外层格式、`🔄 下一步:`、面向最终用户的收尾或 turn-state;其余规则持续生效。
|
|
4
4
|
|
|
5
5
|
## 配置
|
|
6
6
|
配置文件: ~/.helloagents/helloagents.json
|
package/gemini-extension.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "helloagents",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.33",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "HelloAGENTS — The orchestration kernel that makes any AI CLI smarter. Adds intelligent routing, quality verification (Ralph Loop), safety guards, and notifications.",
|
|
6
6
|
"author": "HelloWind",
|
|
@@ -55,7 +55,7 @@ function buildAliasRouteNote(skillName) {
|
|
|
55
55
|
}
|
|
56
56
|
|
|
57
57
|
function buildDelegatedTaskHint() {
|
|
58
|
-
return '
|
|
58
|
+
return '若当前任务由上级代理、控制器或宿主协作/委派机制创建,或本次输出会交回上级代理继续汇总、决策或复述,而不是直接交付给最终用户,则一律按子代理处理:直接完成局部任务并返回结果、证据或阻塞项;禁止输出 HelloAGENTS 外层格式、`🔄 下一步:`、turn-state 或面向最终用户的收尾。'
|
|
59
59
|
}
|
|
60
60
|
|
|
61
61
|
export function buildCompactionContext({ payload, pkgRoot, settings, bootstrapFile, host }) {
|
|
@@ -14,6 +14,14 @@ const PAYLOAD_KEY_ALIASES = {
|
|
|
14
14
|
stop_hook_active: 'stopHookActive',
|
|
15
15
|
'goal-id': 'goalId',
|
|
16
16
|
goal_id: 'goalId',
|
|
17
|
+
is_subagent: 'isSubagent',
|
|
18
|
+
sub_agent: 'subagent',
|
|
19
|
+
parent_agent_id: 'parentAgentId',
|
|
20
|
+
parent_turn_id: 'parentTurnId',
|
|
21
|
+
delegated_by_agent_id: 'delegatedByAgentId',
|
|
22
|
+
agent_id: 'agentId',
|
|
23
|
+
agent_role: 'agentRole',
|
|
24
|
+
agent_kind: 'agentKind',
|
|
17
25
|
}
|
|
18
26
|
|
|
19
27
|
function assignAlias(target, source, sourceKey, targetKey) {
|
package/scripts/notify-ui.mjs
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import { platform } from 'node:os';
|
|
6
6
|
import { join } from 'node:path';
|
|
7
|
-
import { existsSync } from 'node:fs';
|
|
7
|
+
import { appendFileSync, existsSync } from 'node:fs';
|
|
8
8
|
import { execFileSync, spawn } from 'node:child_process';
|
|
9
9
|
|
|
10
10
|
const PLAT = platform();
|
|
@@ -19,6 +19,17 @@ const NOTIFY_MESSAGES = {
|
|
|
19
19
|
|
|
20
20
|
const WIN_APPID = 'HelloAgents.Notification';
|
|
21
21
|
const DISABLE_OS_NOTIFICATIONS = process.env.HELLOAGENTS_DISABLE_OS_NOTIFICATIONS === '1';
|
|
22
|
+
const TEST_NOTIFY_LOG = String(process.env.HELLOAGENTS_NOTIFY_TEST_LOG || '').trim();
|
|
23
|
+
|
|
24
|
+
function recordTestTransport(kind, event) {
|
|
25
|
+
if (!TEST_NOTIFY_LOG) return false;
|
|
26
|
+
try {
|
|
27
|
+
appendFileSync(TEST_NOTIFY_LOG, `${kind} ${String(event || '')}\n`, 'utf-8');
|
|
28
|
+
return true;
|
|
29
|
+
} catch {
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
22
33
|
|
|
23
34
|
function escapeToastText(value = '') {
|
|
24
35
|
return String(value)
|
|
@@ -100,6 +111,7 @@ function runSoundHelper(pkgRoot, event, mode = 'background') {
|
|
|
100
111
|
|
|
101
112
|
export function playSound(pkgRoot, event, options = {}) {
|
|
102
113
|
if (DISABLE_OS_NOTIFICATIONS) return;
|
|
114
|
+
if (recordTestTransport('sound', event)) return;
|
|
103
115
|
const wav = resolveWav(pkgRoot, event);
|
|
104
116
|
if (!wav) { process.stderr.write('\x07'); return; }
|
|
105
117
|
if (runSoundHelper(pkgRoot, event, options.mode === 'blocking' ? 'blocking' : 'background')) return;
|
|
@@ -152,6 +164,7 @@ $toast = [Windows.UI.Notifications.ToastNotification]::new($doc)
|
|
|
152
164
|
|
|
153
165
|
export function desktopNotify(pkgRoot, event, extra) {
|
|
154
166
|
if (DISABLE_OS_NOTIFICATIONS) return;
|
|
167
|
+
if (recordTestTransport('desktop', event)) return;
|
|
155
168
|
const notification = buildDesktopNotificationContent(event, extra);
|
|
156
169
|
try {
|
|
157
170
|
if (PLAT === 'win32') {
|
package/scripts/notify.mjs
CHANGED
|
@@ -88,6 +88,59 @@ function getSettings() {
|
|
|
88
88
|
return readSettings(CONFIG_FILE);
|
|
89
89
|
}
|
|
90
90
|
|
|
91
|
+
function hasTruthyAgentFlag(value) {
|
|
92
|
+
if (typeof value === 'boolean') return value;
|
|
93
|
+
const normalized = String(value || '').trim().toLowerCase();
|
|
94
|
+
return ['1', 'true', 'yes', 'subagent'].includes(normalized);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function hasNonEmptyValue(value) {
|
|
98
|
+
return String(value || '').trim().length > 0;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function looksLikeCodexDelegatedTurn(payload = {}) {
|
|
102
|
+
if (!IS_CODEX || !payload || typeof payload !== 'object') return false;
|
|
103
|
+
const client = String(payload.client || '').trim();
|
|
104
|
+
const inputMessages = Array.isArray(payload.inputMessages) ? payload.inputMessages : [];
|
|
105
|
+
return !client && inputMessages.length > 1;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
function isSubagentPayload(payload = {}) {
|
|
109
|
+
if (!payload || typeof payload !== 'object') return false;
|
|
110
|
+
|
|
111
|
+
if ([payload.isSubagent, payload.subagent].some(hasTruthyAgentFlag)) {
|
|
112
|
+
return true;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
const roleLike = [
|
|
116
|
+
payload.role,
|
|
117
|
+
payload.agentRole,
|
|
118
|
+
payload.agent_role,
|
|
119
|
+
payload.agentKind,
|
|
120
|
+
payload.agent_kind,
|
|
121
|
+
payload.kind,
|
|
122
|
+
]
|
|
123
|
+
.map((value) => String(value || '').trim().toLowerCase())
|
|
124
|
+
.filter(Boolean);
|
|
125
|
+
|
|
126
|
+
if (roleLike.some((value) => ['subagent', 'delegate', 'delegated', 'worker', 'explorer'].includes(value))) {
|
|
127
|
+
return true;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
if ([
|
|
131
|
+
payload.parentAgentId,
|
|
132
|
+
payload.parent_agent_id,
|
|
133
|
+
payload.parentTurnId,
|
|
134
|
+
payload.parent_turn_id,
|
|
135
|
+
payload.delegatedByAgentId,
|
|
136
|
+
payload.delegated_by_agent_id,
|
|
137
|
+
].some(hasNonEmptyValue)) {
|
|
138
|
+
return true;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
return looksLikeCodexDelegatedTurn(payload);
|
|
142
|
+
}
|
|
143
|
+
|
|
91
144
|
function shouldRunRalphLoop(cwd, turnState, payload = {}) {
|
|
92
145
|
if (!turnState || turnState.kind !== 'complete') return false;
|
|
93
146
|
if (turnState.requiresDeliveryGate) return true;
|
|
@@ -230,13 +283,28 @@ async function runRalphLoop(payload, { turnState } = {}) {
|
|
|
230
283
|
blockEvent: 'verify_gate_blocked',
|
|
231
284
|
exportName: 'evaluateRalphLoop',
|
|
232
285
|
evaluateArgs: [payload, {
|
|
233
|
-
isSubagent:
|
|
286
|
+
isSubagent: isSubagentPayload(payload),
|
|
234
287
|
isGemini: IS_GEMINI,
|
|
235
288
|
hookEventName: HOST === 'codex' ? 'Stop' : (IS_GEMINI ? 'SessionEnd' : 'Stop'),
|
|
236
289
|
}],
|
|
237
290
|
});
|
|
238
291
|
}
|
|
239
292
|
|
|
293
|
+
async function runCodexSubagentGate(payload) {
|
|
294
|
+
if (!IS_CODEX || !isSubagentPayload(payload)) return false;
|
|
295
|
+
return await runInlineGate({
|
|
296
|
+
payload,
|
|
297
|
+
source: 'ralph-loop',
|
|
298
|
+
blockEvent: 'verify_gate_blocked',
|
|
299
|
+
exportName: 'evaluateRalphLoop',
|
|
300
|
+
evaluateArgs: [payload, {
|
|
301
|
+
isSubagent: true,
|
|
302
|
+
isGemini: false,
|
|
303
|
+
hookEventName: 'Stop',
|
|
304
|
+
}],
|
|
305
|
+
});
|
|
306
|
+
}
|
|
307
|
+
|
|
240
308
|
async function runDeliveryGate(payload) {
|
|
241
309
|
return await runInlineGate({
|
|
242
310
|
payload,
|
|
@@ -447,6 +515,11 @@ async function cmdStop() {
|
|
|
447
515
|
const payload = readPayloadFromStdin();
|
|
448
516
|
const cwd = payload.cwd || process.cwd();
|
|
449
517
|
const turnPayload = attachTurnSession(payload, cwd);
|
|
518
|
+
if (await runCodexSubagentGate(turnPayload)) return;
|
|
519
|
+
if (IS_CODEX && isSubagentPayload(turnPayload)) {
|
|
520
|
+
emptySuppress();
|
|
521
|
+
return;
|
|
522
|
+
}
|
|
450
523
|
const turnState = readMainTurnState(cwd, turnPayload);
|
|
451
524
|
const managedCodexStopHook = IS_CODEX && hasManagedCodexStopHook();
|
|
452
525
|
const skipCompleteNotify = managedCodexStopHook && hasCodexQuickNotifyEvidence(cwd, {
|
|
@@ -504,7 +577,10 @@ async function cmdCodexNotify() {
|
|
|
504
577
|
return;
|
|
505
578
|
}
|
|
506
579
|
if (type !== 'agent-turn-complete') return;
|
|
507
|
-
|
|
580
|
+
const managedCodexStopHook = hasManagedCodexStopHook();
|
|
581
|
+
if (managedCodexStopHook && !String(turnPayload.client || '').trim()) return;
|
|
582
|
+
if (isSubagentPayload(turnPayload)) return;
|
|
583
|
+
if (managedCodexStopHook) {
|
|
508
584
|
const turnState = readMainTurnState(cwd, turnPayload);
|
|
509
585
|
if (shouldEmitManagedCodexCompleteNotify(cwd, turnState, turnPayload)) {
|
|
510
586
|
notifyByLevel('complete', buildNotifyExtra(data), getSettings(), { mode: 'blocking' });
|
package/scripts/ralph-loop.mjs
CHANGED
|
@@ -98,6 +98,59 @@ function getLastAssistantMessage(data = {}) {
|
|
|
98
98
|
).trim();
|
|
99
99
|
}
|
|
100
100
|
|
|
101
|
+
function hasTruthyAgentFlag(value) {
|
|
102
|
+
if (typeof value === 'boolean') return value;
|
|
103
|
+
const normalized = String(value || '').trim().toLowerCase();
|
|
104
|
+
return ['1', 'true', 'yes', 'subagent'].includes(normalized);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
function hasNonEmptyValue(value) {
|
|
108
|
+
return String(value || '').trim().length > 0;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
function looksLikeCodexDelegatedTurn(data = {}) {
|
|
112
|
+
if (!data || typeof data !== 'object') return false;
|
|
113
|
+
const client = String(data.client || '').trim();
|
|
114
|
+
const inputMessages = Array.isArray(data.inputMessages) ? data.inputMessages : [];
|
|
115
|
+
return !client && inputMessages.length > 1;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
function inferSubagentFromPayload(data = {}) {
|
|
119
|
+
if (!data || typeof data !== 'object') return false;
|
|
120
|
+
|
|
121
|
+
if ([data.isSubagent, data.subagent].some(hasTruthyAgentFlag)) {
|
|
122
|
+
return true;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
const roleLike = [
|
|
126
|
+
data.role,
|
|
127
|
+
data.agentRole,
|
|
128
|
+
data.agent_role,
|
|
129
|
+
data.agentKind,
|
|
130
|
+
data.agent_kind,
|
|
131
|
+
data.kind,
|
|
132
|
+
]
|
|
133
|
+
.map((value) => String(value || '').trim().toLowerCase())
|
|
134
|
+
.filter(Boolean);
|
|
135
|
+
|
|
136
|
+
if (roleLike.some((value) => ['subagent', 'delegate', 'delegated', 'worker', 'explorer'].includes(value))) {
|
|
137
|
+
return true;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
if ([
|
|
141
|
+
data.parentAgentId,
|
|
142
|
+
data.parent_agent_id,
|
|
143
|
+
data.parentTurnId,
|
|
144
|
+
data.parent_turn_id,
|
|
145
|
+
data.delegatedByAgentId,
|
|
146
|
+
data.delegated_by_agent_id,
|
|
147
|
+
].some(hasNonEmptyValue)) {
|
|
148
|
+
return true;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
return looksLikeCodexDelegatedTurn(data);
|
|
152
|
+
}
|
|
153
|
+
|
|
101
154
|
function hasHelloagentsWrapper(message = '') {
|
|
102
155
|
if (!message.includes('【HelloAGENTS】')) return false;
|
|
103
156
|
const firstNonEmptyLine = message
|
|
@@ -138,7 +191,7 @@ export function evaluateRalphLoop(data = {}, runtime = {}) {
|
|
|
138
191
|
|
|
139
192
|
const cwd = data.cwd || process.cwd();
|
|
140
193
|
const runtimeOptions = { payload: data };
|
|
141
|
-
const isSubagent = runtime.isSubagent
|
|
194
|
+
const isSubagent = runtime.isSubagent === true || inferSubagentFromPayload(data) || IS_SUBAGENT;
|
|
142
195
|
const hookEventName = runtime.hookEventName || HOOK_EVENT;
|
|
143
196
|
|
|
144
197
|
if (isSubagent) {
|
|
@@ -6,7 +6,7 @@ description: 按任务类型适用 — 建立质量驱动工作流,通过技
|
|
|
6
6
|
# HelloAGENTS
|
|
7
7
|
|
|
8
8
|
主代理触发或读取任意 skill 时,只有直接面向最终用户、且当前对话已经结束的终局交付,才按通用输出格式包装;流式内容、进度或状态汇报、中间文本,以及任何仍将继续执行或会交回上级代理继续消费的文本,都保持自然输出。最终回复中的 `🔄 下一步` 写真实动作,不写当前状态;等待用户授权时使用等待输入态收尾,已获授权且可继续执行时不得收尾。同一条最终回复只包装一次;若需要分段,在同一个外层块内展开,不在正文里再次输出 `【HelloAGENTS】` 或第二个 `🔄 下一步`。
|
|
9
|
-
|
|
9
|
+
若当前输出会交回上级代理、控制器或其他代理继续汇总、决策、复述或等待后续动作,或当前任务由宿主协作/委派机制创建(包括 spawn_agent、worker / explorer、并行代理、Codex agent/delegate/wait 等),则一律按子代理处理:只豁免输出格式、交互确认与停顿、统一执行流程、任务分层、完成判定、命令路由和流程状态,直接执行任务;安全、质量、验证和失败处理规则仍持续生效。子代理只返回结果、证据或阻塞项;不得包装 HelloAGENTS 外层输出格式,不写 `🔄 下一步:`,不做面向最终用户的收尾。
|
|
10
10
|
只有运行时必须识别当前对话“完成 / 等待输入 / 阻塞”时,主代理才写 turn-state;普通问候、普通问答、T0 只读分析和一次性解释不调用。必须调用场景:显式 `~auto` / `~loop`、非只读任务完成验证并进入收尾、需要让运行时识别当前对话已完成、等待输入或已阻塞时、已进入项目连续流程或方案包闭环。首选 `helloagents-turn-state write --kind complete --role main`;等待或阻塞时写 `kind=waiting` / `kind=blocked`,并同时写 `reasonCategory` 与 `reason`。显式 `~auto` / `~loop` 下,还必须写入 `blocker.target`、`blocker.evidence`、`blocker.requiredAction`。不要查找、读取或拼接 `turn-state.mjs` 源码路径。子代理不得写 turn-state。
|
|
11
11
|
普通问答、解释、分析、改写、邮件回复和其他一次性交付虽然不进入完整实现、验证或收尾流程,但仍属于交付:默认只交付与当前请求直接对应的一版最终结果;请求已满足时直接结束,不主动追加无执行价值的延伸、派生版本、不同写法、第二版或邀约式收尾,除非用户明确要求。
|
|
12
12
|
|