agent-dag 1.34.5 → 1.34.6
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/dist/web/index.html
CHANGED
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
document.documentElement.setAttribute("data-theme", stored === "light" ? "light" : "dark");
|
|
41
41
|
})();
|
|
42
42
|
</script>
|
|
43
|
-
<script type="module" crossorigin src="/assets/index-
|
|
43
|
+
<script type="module" crossorigin src="/assets/index-G1Xt6iC6.js"></script>
|
|
44
44
|
<link rel="stylesheet" crossorigin href="/assets/index-CRPobBZf.css">
|
|
45
45
|
</head>
|
|
46
46
|
<body>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agent-dag",
|
|
3
|
-
"version": "1.34.
|
|
3
|
+
"version": "1.34.6",
|
|
4
4
|
"description": "Live deck of Claude Code and Codex agents — watch parallel subagents fork, call tools, and return on one calm canvas. Also available as npx ccdeck and npx agent-dag.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
package/src/server/index.mjs
CHANGED
|
@@ -785,12 +785,17 @@ function maybeResolveCodex(payload) {
|
|
|
785
785
|
// object {timestamp, type, payload}; we map the relevant ones to the same
|
|
786
786
|
// synthetic hook payloads the reducer already understands:
|
|
787
787
|
// session_meta → SessionStart
|
|
788
|
-
// event_msg/user_message → UserPromptSubmit
|
|
788
|
+
// event_msg/user_message → UserPromptSubmit (Codex ≤ 0.144)
|
|
789
|
+
// event_msg/item_completed/UserMessage → UserPromptSubmit (Codex ≥ 0.147)
|
|
789
790
|
// response_item/function_call → PreToolUse
|
|
790
791
|
// response_item/function_call_output → PostToolUse
|
|
791
792
|
// event_msg/token_count → UsageObserved
|
|
792
793
|
// event_msg/task_started (+window) → ModelObserved (context window)
|
|
794
|
+
// event_msg/task_complete → Stop (the turn finished)
|
|
795
|
+
// event_msg/turn_aborted → Stop (the turn was interrupted)
|
|
793
796
|
// turn_context / response_item.model → model snapshot (ModelObserved on change)
|
|
797
|
+
// There is deliberately no SessionEnd here: Codex writes no session-close
|
|
798
|
+
// record, so the end of a SESSION is still inferred by sweepStaleSessions.
|
|
794
799
|
// Events are emitted with source "codex" so pushEvent skips the Claude-only
|
|
795
800
|
// transcript enrichment (which needs transcript_path / hook events) but still
|
|
796
801
|
// broadcasts them exactly like a hook event, and persists them when this deck is
|
|
@@ -890,10 +895,27 @@ async function readCodexHeader(path) {
|
|
|
890
895
|
return null;
|
|
891
896
|
}
|
|
892
897
|
|
|
898
|
+
/**
|
|
899
|
+
* The human's prompt out of a 0.147-era `item_completed` item.
|
|
900
|
+
*
|
|
901
|
+
* `item.content` is an array of parts — every UserMessage observed carries a
|
|
902
|
+
* single `{ type: "text", text, text_elements }` — so the parts are joined
|
|
903
|
+
* rather than indexed, and a part with no string `text` contributes nothing
|
|
904
|
+
* instead of printing "undefined" into the prompt the card shows.
|
|
905
|
+
*/
|
|
906
|
+
function codexItemText(item) {
|
|
907
|
+
const parts = Array.isArray(item && item.content) ? item.content : [];
|
|
908
|
+
return parts.map(p => (p && typeof p.text === "string" ? p.text : "")).join("");
|
|
909
|
+
}
|
|
910
|
+
|
|
893
911
|
// Map one parsed rollout object to a synthetic hook payload (or null to skip).
|
|
894
912
|
// Mutates codexSessionModel and returns { payload, modelEvent } where
|
|
895
913
|
// modelEvent is an optional ModelObserved to emit first when the model changed.
|
|
896
|
-
|
|
914
|
+
//
|
|
915
|
+
// Exported for the tests: this is the whole of the Codex translation, and the
|
|
916
|
+
// lifecycle it produces is worth pinning against the real reducer without
|
|
917
|
+
// standing up a watcher, a temp home and a 1.5s poll to get at it.
|
|
918
|
+
export function codexObjToPayload(obj, sid, cwd) {
|
|
897
919
|
const type = obj && obj.type;
|
|
898
920
|
const pl = (obj && obj.payload) || {};
|
|
899
921
|
const base = { session_id: sid, cwd, provider: "codex" };
|
|
@@ -913,12 +935,49 @@ function codexObjToPayload(obj, sid, cwd) {
|
|
|
913
935
|
const prompt = typeof pl.message === "string" ? pl.message : "";
|
|
914
936
|
return { ...base, hook_event_name: "UserPromptSubmit", prompt, model };
|
|
915
937
|
}
|
|
938
|
+
// Codex 0.147 stopped writing `user_message` and writes the same submission
|
|
939
|
+
// as an `item_completed` carrying a `UserMessage` item instead. The two are
|
|
940
|
+
// mutually exclusive per CLI version — across the rollouts sampled here the
|
|
941
|
+
// 0.144 files have `user_message` and no `item_completed` at all, and the
|
|
942
|
+
// 0.147 files have exactly one `UserMessage` item per turn and no
|
|
943
|
+
// `user_message` — so handling both names emits one prompt per turn either
|
|
944
|
+
// way rather than two on either version. The item is the human's typed text
|
|
945
|
+
// only: the AGENTS.md preamble Codex prepends is written as a bare
|
|
946
|
+
// `response_item` with role "user" and never gets an item of its own.
|
|
947
|
+
//
|
|
948
|
+
// This matters far beyond the prompt text. `UserPromptSubmit` is what puts
|
|
949
|
+
// a settled root back to `active` (reducer.ts), so on 0.147 it is the ONLY
|
|
950
|
+
// thing that reopens a session for its second turn — without it the `Stop`
|
|
951
|
+
// below would trade "live forever" for "done forever", which is not better.
|
|
952
|
+
if (pl.type === "item_completed" && pl.item && pl.item.type === "UserMessage") {
|
|
953
|
+
return { ...base, hook_event_name: "UserPromptSubmit", prompt: codexItemText(pl.item), model };
|
|
954
|
+
}
|
|
916
955
|
if (pl.type === "token_count" && pl.info && pl.info.total_token_usage) {
|
|
917
956
|
return { ...base, hook_event_name: "UsageObserved", usage: pl.info.total_token_usage, model };
|
|
918
957
|
}
|
|
919
958
|
if (pl.type === "task_started" && typeof pl.model_context_window === "number") {
|
|
920
959
|
return { ...base, hook_event_name: "ModelObserved", model, model_context_window: pl.model_context_window };
|
|
921
960
|
}
|
|
961
|
+
// The end of a turn, which is the only end Codex ever announces. Both names
|
|
962
|
+
// are one outcome as far as the deck is concerned — the turn is over and
|
|
963
|
+
// nothing is running — so both settle the root the way Claude's own Stop
|
|
964
|
+
// hook does. They are also exhaustive: across the rollouts sampled here
|
|
965
|
+
// every `task_started` is answered by exactly one of the two (54 completes
|
|
966
|
+
// + 1 abort for 55 starts), so no turn is left open by this mapping and
|
|
967
|
+
// none is closed twice. `turn_aborted` is the Esc key, and it is the case
|
|
968
|
+
// that matters most on the deck: pressing Esc is precisely when the user is
|
|
969
|
+
// watching to confirm the thing stopped.
|
|
970
|
+
//
|
|
971
|
+
// Per TURN, not per session, and that is correct: Codex writes no
|
|
972
|
+
// session-close record at all — a rollout simply stops growing when the
|
|
973
|
+
// terminal goes away — so `sweepStaleSessions` remains the only thing that
|
|
974
|
+
// ends a Codex *session*, and it must. What changes is that it now only
|
|
975
|
+
// ever sees the sessions it was written for: the ones that died without
|
|
976
|
+
// finishing. A turn that really ended is settled here, at the moment it
|
|
977
|
+
// ended, with no `reaped` flag, because it was a finish and not a guess.
|
|
978
|
+
if (pl.type === "task_complete" || pl.type === "turn_aborted") {
|
|
979
|
+
return { ...base, hook_event_name: "Stop", model };
|
|
980
|
+
}
|
|
922
981
|
return null;
|
|
923
982
|
}
|
|
924
983
|
if (type === "response_item") {
|