agent-conveyor 0.1.10 → 0.1.11
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
CHANGED
|
@@ -372,9 +372,13 @@ tmux attach -t codex-live-test
|
|
|
372
372
|
`heartbeat_recommendations` with role-specific poll prompts; Dispatch can
|
|
373
373
|
deliver into those inboxes, but a heartbeat or operator wake-up is still
|
|
374
374
|
required to make an idle app thread poll autonomously. Those recommendations
|
|
375
|
-
include
|
|
376
|
-
|
|
377
|
-
|
|
375
|
+
also include `wakeup_dispatch_command` and `delivery_receipt_commands` for
|
|
376
|
+
app-thread wake recovery. Use them to record sent, skipped, and blocked wake
|
|
377
|
+
outcomes after `app-wakeup-dispatch`; an app-thread send is not task
|
|
378
|
+
completion. The recommendations include a `teardown_policy`: an idle poll is
|
|
379
|
+
only a quiet interval, not a reason to delete or pause heartbeat automation;
|
|
380
|
+
heartbeat teardown belongs to the manager/operator after terminal closeout or
|
|
381
|
+
explicit operator instruction.
|
|
378
382
|
The optional
|
|
379
383
|
Codex app thread metadata is normally supplied after a Codex app manager has
|
|
380
384
|
used `create_thread` and `set_thread_title`; terminal-only users can omit it
|
|
@@ -1045,10 +1049,12 @@ Current dispatch state:
|
|
|
1045
1049
|
reaches `max_iterations`. For no-tmux Codex app sessions, treat
|
|
1046
1050
|
`communication.requires_polling=true` as requiring a heartbeat/wake layer:
|
|
1047
1051
|
a delivered pull inbox item does not by itself wake an idle app thread. Do
|
|
1048
|
-
not delete or pause heartbeats because an inbox poll is idle.
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
+
not delete or pause heartbeats because an inbox poll is idle. Use generated
|
|
1053
|
+
`heartbeat_recommendations.wakeup_dispatch_command` and
|
|
1054
|
+
`heartbeat_recommendations.delivery_receipt_commands` for stale-thread wake
|
|
1055
|
+
recovery receipts. A terminal manager decision should be followed by
|
|
1056
|
+
`finish-task --require-criteria-audit` or by an explicit blocker explaining
|
|
1057
|
+
why the task/binding still appears active.
|
|
1052
1058
|
- `register-worker`, `register-manager`, `sessions`, `discover`, and
|
|
1053
1059
|
`create-disposable-binding --json` expose a `communication` block per
|
|
1054
1060
|
session. Treat `session_kind='tmux'` plus `receive_style='push'` as direct
|
|
@@ -17114,6 +17114,8 @@ function renderDisposableBindingText(result) {
|
|
|
17114
17114
|
lines.push(` worker: ${result.heartbeat_recommendations.worker.poll_command}`);
|
|
17115
17115
|
lines.push(` status: ${result.heartbeat_recommendations.status_command}`);
|
|
17116
17116
|
lines.push(` wakeup plan: ${result.heartbeat_recommendations.wakeup_plan_command}`);
|
|
17117
|
+
lines.push(` wakeup dispatch: ${result.heartbeat_recommendations.wakeup_dispatch_command}`);
|
|
17118
|
+
lines.push(` delivery sent: ${result.heartbeat_recommendations.delivery_receipt_commands.sent}`);
|
|
17117
17119
|
lines.push(` teardown: ${result.heartbeat_recommendations.teardown_policy.idle_poll}`);
|
|
17118
17120
|
lines.push(` closeout: ${result.heartbeat_recommendations.teardown_policy.terminal_closeout_command}`);
|
|
17119
17121
|
}
|
|
@@ -17127,6 +17129,8 @@ function disposableHeartbeatRecommendations(taskName, dbPath) {
|
|
|
17127
17129
|
const workerHeartbeatCommand = disposableAppHeartbeatCommand("worker", taskName, dbPath);
|
|
17128
17130
|
const managerInboxCommand = sessionPollCommand("manager", taskName, dbPath);
|
|
17129
17131
|
const workerInboxCommand = sessionPollCommand("worker", taskName, dbPath);
|
|
17132
|
+
const wakeupDispatchCommand = `${conveyorPollInvocation()} app-wakeup-dispatch ${shellQuote(taskName)} --path ${shellQuote(dbPath)} --json`;
|
|
17133
|
+
const deliveryReceiptCommands = disposableDeliveryReceiptCommands(taskName, dbPath);
|
|
17130
17134
|
return {
|
|
17131
17135
|
applies_when: {
|
|
17132
17136
|
can_receive_push: false,
|
|
@@ -17134,6 +17138,7 @@ function disposableHeartbeatRecommendations(taskName, dbPath) {
|
|
|
17134
17138
|
receive_style: "pull",
|
|
17135
17139
|
session_kind: "codex_app",
|
|
17136
17140
|
},
|
|
17141
|
+
delivery_receipt_commands: deliveryReceiptCommands,
|
|
17137
17142
|
interval_minutes: 2,
|
|
17138
17143
|
note: "Dispatch can deliver pull-required inbox items, but Codex app/no-tmux sessions still need a heartbeat or operator wake-up to poll while idle.",
|
|
17139
17144
|
status_command: `${conveyorPollInvocation()} app-loop-status ${shellQuote(taskName)} --path ${shellQuote(dbPath)} --json`,
|
|
@@ -17144,6 +17149,7 @@ function disposableHeartbeatRecommendations(taskName, dbPath) {
|
|
|
17144
17149
|
terminal_closeout_command: terminalCloseoutCommand,
|
|
17145
17150
|
worker_rule: "The worker must not own loop teardown and must not remove heartbeat automation based on idle polling.",
|
|
17146
17151
|
},
|
|
17152
|
+
wakeup_dispatch_command: wakeupDispatchCommand,
|
|
17147
17153
|
wakeup_plan_command: `${conveyorPollInvocation()} app-wakeup-plan ${shellQuote(taskName)} --path ${shellQuote(dbPath)} --json`,
|
|
17148
17154
|
manager: {
|
|
17149
17155
|
direct_inbox_command: managerInboxCommand,
|
|
@@ -17154,6 +17160,11 @@ function disposableHeartbeatRecommendations(taskName, dbPath) {
|
|
|
17154
17160
|
`Run the manager app heartbeat for task ${taskName}.`,
|
|
17155
17161
|
`Run: ${managerHeartbeatCommand}`,
|
|
17156
17162
|
`If the heartbeat output asks for direct inbox polling, run: ${managerInboxCommand}`,
|
|
17163
|
+
`For stale app-thread recovery with an auditable receipt, run: ${wakeupDispatchCommand}`,
|
|
17164
|
+
"Send app-thread wake prompts only for actions where `send_ready=true`; direct app-thread delivery is not task completion.",
|
|
17165
|
+
`After a successful app-thread send, record it with: ${deliveryReceiptCommands.sent}`,
|
|
17166
|
+
`For healthy skipped actions, record: ${deliveryReceiptCommands.skipped}`,
|
|
17167
|
+
`For missing-thread blocked actions, record: ${deliveryReceiptCommands.blocked}`,
|
|
17157
17168
|
"If an item is consumed, execute only that manager instruction, verify worker claims before recording conclusions, update Conveyor state as appropriate, and produce exactly one next worker task.",
|
|
17158
17169
|
"If no item is consumed, stop after a one-line idle receipt.",
|
|
17159
17170
|
"Do not delete, pause, or disable manager or worker heartbeat automation after an idle poll; an idle poll is only a quiet interval.",
|
|
@@ -17170,13 +17181,23 @@ function disposableHeartbeatRecommendations(taskName, dbPath) {
|
|
|
17170
17181
|
`Run the worker app heartbeat for task ${taskName}.`,
|
|
17171
17182
|
`Run: ${workerHeartbeatCommand}`,
|
|
17172
17183
|
`If the heartbeat output asks for direct inbox polling, run: ${workerInboxCommand}`,
|
|
17173
|
-
"If an item is consumed, execute only that single worker instruction and return exact commands, compact evidence, blockers/residual risk, and exactly one next recommended worker task.",
|
|
17184
|
+
"If an item is consumed, execute only that single worker instruction and return exact commands, compact evidence for any completion claim, blockers/residual risk, and exactly one next recommended worker task.",
|
|
17174
17185
|
"If no item is consumed, stop after a one-line idle receipt.",
|
|
17175
17186
|
"Do not delete, pause, or disable worker heartbeat automation after an idle poll; the manager or operator owns terminal loop teardown.",
|
|
17176
17187
|
].join("\n"),
|
|
17177
17188
|
},
|
|
17178
17189
|
};
|
|
17179
17190
|
}
|
|
17191
|
+
function disposableDeliveryReceiptCommands(taskName, dbPath) {
|
|
17192
|
+
const base = `${conveyorPollInvocation()} app-wakeup-record-delivery ${shellQuote(taskName)} --role <role> --dispatch-receipt <receipt.event_id>`;
|
|
17193
|
+
const pathAndJson = ` --path ${shellQuote(dbPath)} --json`;
|
|
17194
|
+
return {
|
|
17195
|
+
blocked: `${base} --delivery-status blocked${pathAndJson}`,
|
|
17196
|
+
note: "Run these only after app-wakeup-dispatch. Replace <role>, <receipt.event_id>, and <action.thread.id> from the dispatch JSON; sent is valid only for send_ready=true actions.",
|
|
17197
|
+
sent: `${base} --delivery-status sent --thread-id <action.thread.id>${pathAndJson}`,
|
|
17198
|
+
skipped: `${base} --delivery-status skipped${pathAndJson}`,
|
|
17199
|
+
};
|
|
17200
|
+
}
|
|
17180
17201
|
function disposableAppHeartbeatCommand(role, taskName, dbPath) {
|
|
17181
17202
|
return `${conveyorPollInvocation()} app-heartbeat ${shellQuote(taskName)} --role ${role} --path ${shellQuote(dbPath)} --json`;
|
|
17182
17203
|
}
|