@hyperdrive.bot/paseo-protocol 0.3.73 → 0.3.74

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.
@@ -3,6 +3,8 @@ export declare const WORKFLOW_ID_LABEL = "paseo.workflow-id";
3
3
  export declare const WORKFLOW_TASK_ID_LABEL = "paseo.workflow-task-id";
4
4
  export declare const LOOP_NAME_LABEL = "loop";
5
5
  export declare const LOOP_RUN_LABEL = "run";
6
+ export declare const SCHEDULE_ID_LABEL = "paseo.schedule-id";
7
+ export declare const SCHEDULE_RUN_LABEL = "paseo.schedule-run";
6
8
  export interface AgentLabelSource {
7
9
  labels?: Record<string, unknown> | null;
8
10
  }
@@ -23,4 +25,31 @@ export declare function isLoopAgent(agent: AgentLabelSource): boolean;
23
25
  * whole HITL story dies. See docs/loops.md.
24
26
  */
25
27
  export declare function isLoopExecutionAgent(agent: AgentLabelSource): boolean;
28
+ export declare function getScheduleIdFromLabels(labels: Record<string, unknown> | null | undefined): string | null;
29
+ export declare function getScheduleRunFromLabels(labels: Record<string, unknown> | null | undefined): string | null;
30
+ /** Any agent a schedule fired. */
31
+ export declare function isScheduleAgent(agent: AgentLabelSource): boolean;
32
+ /**
33
+ * A scheduled execution, the set the general session surfaces hide.
34
+ *
35
+ * KNOWN LIMIT, stated rather than papered over: schedules have NO adoption escape hatch,
36
+ * so a scheduled run a human takes over stays hidden. A second adoption mechanism was
37
+ * deliberately not built, because the loop one (LOOP_ADOPTED_AT_LABEL) is defined and read
38
+ * but written NOWHERE - shipping a second unwritten escape hatch would double the dead
39
+ * code, not halve the problem. Wire one adoption path for both, then use it here.
40
+ */
41
+ export declare function isScheduleExecutionAgent(agent: AgentLabelSource): boolean;
42
+ /**
43
+ * Anything the machine spawned on its own and no human is waiting inside: a loop tick or
44
+ * a scheduled firing. This is what the general session surfaces hide.
45
+ *
46
+ * Prefer this over `isLoopExecutionAgent` in any LIST filter. Keying on loops alone is the
47
+ * exact bug this replaced: a new kind of machine agent silently reads as human work, and
48
+ * the failure is invisible because "more sessions" looks like activity, not a defect.
49
+ *
50
+ * Hiding remains a LIST concern only. Attention surfaces (favicon, background activity,
51
+ * push) must keep counting these, or an automated run blocked on a permission goes silent.
52
+ * See docs/loops.md.
53
+ */
54
+ export declare function isMachineExecutionAgent(agent: AgentLabelSource): boolean;
26
55
  //# sourceMappingURL=agent-labels.d.ts.map
@@ -17,6 +17,20 @@ export const WORKFLOW_TASK_ID_LABEL = "paseo.workflow-task-id";
17
17
  // tooling/loops/lib/run-agent.sh (`paseo agent run --label loop=<name> --label run=<ts>`).
18
18
  export const LOOP_NAME_LABEL = "loop";
19
19
  export const LOOP_RUN_LABEL = "run";
20
+ // Scheduled runs (paseo schedules: cron/interval prompts the daemon fires on its own).
21
+ // A scheduled execution carries paseo.schedule-id for the owning schedule and
22
+ // paseo.schedule-run for the individual firing. Producer: the daemon's scheduler, not a
23
+ // human and not a loop.
24
+ //
25
+ // These were invisible to every list filter until 2026-08-29, because the filters keyed
26
+ // on `loop` alone and a scheduled run carries no `loop` label. Measured on one box over
27
+ // two days: 882 scheduled runs (517 Sentry incident-responder, 222 fleet watcher, 128 a
28
+ // WhatsApp poller) sat in Sessions indistinguishable from human work, against 125 loop
29
+ // runs correctly hidden. The gap was predicted in docs when the loop filter shipped -
30
+ // "any count keyed on `loop` alone will silently fold them into human work" - and it was
31
+ // 9 rows then, 517 now.
32
+ export const SCHEDULE_ID_LABEL = "paseo.schedule-id";
33
+ export const SCHEDULE_RUN_LABEL = "paseo.schedule-run";
20
34
  export function getParentAgentIdFromLabels(labels) {
21
35
  const parentAgentId = labels?.[PARENT_AGENT_ID_LABEL];
22
36
  return typeof parentAgentId === "string" && parentAgentId.trim().length > 0
@@ -62,4 +76,43 @@ export function isLoopAgent(agent) {
62
76
  export function isLoopExecutionAgent(agent) {
63
77
  return isLoopAgent(agent) && getLoopAdoptedAtFromLabels(agent.labels) === null;
64
78
  }
79
+ export function getScheduleIdFromLabels(labels) {
80
+ const scheduleId = labels?.[SCHEDULE_ID_LABEL];
81
+ return typeof scheduleId === "string" && scheduleId.trim().length > 0 ? scheduleId.trim() : null;
82
+ }
83
+ export function getScheduleRunFromLabels(labels) {
84
+ const run = labels?.[SCHEDULE_RUN_LABEL];
85
+ return typeof run === "string" && run.trim().length > 0 ? run.trim() : null;
86
+ }
87
+ /** Any agent a schedule fired. */
88
+ export function isScheduleAgent(agent) {
89
+ return getScheduleIdFromLabels(agent.labels) !== null;
90
+ }
91
+ /**
92
+ * A scheduled execution, the set the general session surfaces hide.
93
+ *
94
+ * KNOWN LIMIT, stated rather than papered over: schedules have NO adoption escape hatch,
95
+ * so a scheduled run a human takes over stays hidden. A second adoption mechanism was
96
+ * deliberately not built, because the loop one (LOOP_ADOPTED_AT_LABEL) is defined and read
97
+ * but written NOWHERE - shipping a second unwritten escape hatch would double the dead
98
+ * code, not halve the problem. Wire one adoption path for both, then use it here.
99
+ */
100
+ export function isScheduleExecutionAgent(agent) {
101
+ return isScheduleAgent(agent);
102
+ }
103
+ /**
104
+ * Anything the machine spawned on its own and no human is waiting inside: a loop tick or
105
+ * a scheduled firing. This is what the general session surfaces hide.
106
+ *
107
+ * Prefer this over `isLoopExecutionAgent` in any LIST filter. Keying on loops alone is the
108
+ * exact bug this replaced: a new kind of machine agent silently reads as human work, and
109
+ * the failure is invisible because "more sessions" looks like activity, not a defect.
110
+ *
111
+ * Hiding remains a LIST concern only. Attention surfaces (favicon, background activity,
112
+ * push) must keep counting these, or an automated run blocked on a permission goes silent.
113
+ * See docs/loops.md.
114
+ */
115
+ export function isMachineExecutionAgent(agent) {
116
+ return isLoopExecutionAgent(agent) || isScheduleExecutionAgent(agent);
117
+ }
65
118
  //# sourceMappingURL=agent-labels.js.map
@@ -53073,6 +53073,11 @@ export const WSOutboundMessageSchema = /* @__PURE__ */ (() => {
53073
53073
  }
53074
53074
  }
53075
53075
  }
53076
+ if (__o_3505["adopted"] !== undefined) {
53077
+ if (typeof __o_3505["adopted"] !== "boolean") {
53078
+ _e.push({ code: "invalid_type", expected: "boolean", input: __o_3505["adopted"], path: ["message"].concat("payload").concat("adopted") });
53079
+ }
53080
+ }
53076
53081
  if (__o_3505["error"] !== undefined) {
53077
53082
  if (typeof __o_3505["error"] !== "string") {
53078
53083
  _e.push({ code: "invalid_type", expected: "string", input: __o_3505["error"], path: ["message"].concat("payload").concat("error") });
@@ -3659,6 +3659,7 @@ export declare const EditMessageResponseMessageSchema: z.ZodObject<{
3659
3659
  agentId: z.ZodString;
3660
3660
  newSessionId: z.ZodOptional<z.ZodString>;
3661
3661
  linesCopied: z.ZodOptional<z.ZodNumber>;
3662
+ adopted: z.ZodOptional<z.ZodBoolean>;
3662
3663
  error: z.ZodOptional<z.ZodString>;
3663
3664
  errorCode: z.ZodOptional<z.ZodString>;
3664
3665
  }, z.core.$strip>;
@@ -21919,6 +21920,7 @@ export declare const SessionOutboundMessageSchema: z.ZodDiscriminatedUnion<[z.Zo
21919
21920
  agentId: z.ZodString;
21920
21921
  newSessionId: z.ZodOptional<z.ZodString>;
21921
21922
  linesCopied: z.ZodOptional<z.ZodNumber>;
21923
+ adopted: z.ZodOptional<z.ZodBoolean>;
21922
21924
  error: z.ZodOptional<z.ZodString>;
21923
21925
  errorCode: z.ZodOptional<z.ZodString>;
21924
21926
  }, z.core.$strip>;
@@ -32441,6 +32443,7 @@ export declare const WSSessionOutboundSchema: z.ZodObject<{
32441
32443
  agentId: z.ZodString;
32442
32444
  newSessionId: z.ZodOptional<z.ZodString>;
32443
32445
  linesCopied: z.ZodOptional<z.ZodNumber>;
32446
+ adopted: z.ZodOptional<z.ZodBoolean>;
32444
32447
  error: z.ZodOptional<z.ZodString>;
32445
32448
  errorCode: z.ZodOptional<z.ZodString>;
32446
32449
  }, z.core.$strip>;
@@ -42621,6 +42624,7 @@ export declare const WSOutboundMessageSchema: z.ZodDiscriminatedUnion<[z.ZodObje
42621
42624
  agentId: z.ZodString;
42622
42625
  newSessionId: z.ZodOptional<z.ZodString>;
42623
42626
  linesCopied: z.ZodOptional<z.ZodNumber>;
42627
+ adopted: z.ZodOptional<z.ZodBoolean>;
42624
42628
  error: z.ZodOptional<z.ZodString>;
42625
42629
  errorCode: z.ZodOptional<z.ZodString>;
42626
42630
  }, z.core.$strip>;
package/dist/messages.js CHANGED
@@ -2536,6 +2536,12 @@ export const EditMessageResponseMessageSchema = z.object({
2536
2536
  agentId: z.string(),
2537
2537
  newSessionId: z.string().optional(),
2538
2538
  linesCopied: z.number().int().nonnegative().optional(),
2539
+ /**
2540
+ * True when the daemon repointed THIS agent at the forked transcript, so the client
2541
+ * should rewind in place. False means the fork exists but the agent still runs the old
2542
+ * session, and the client must not pretend the conversation moved.
2543
+ */
2544
+ adopted: z.boolean().optional(),
2539
2545
  error: z.string().optional(),
2540
2546
  errorCode: z.string().optional(),
2541
2547
  }),
@@ -8019,6 +8019,7 @@ export declare const WSOutboundMessageSchema: {
8019
8019
  agentId: import("zod").ZodString;
8020
8020
  newSessionId: import("zod").ZodOptional<import("zod").ZodString>;
8021
8021
  linesCopied: import("zod").ZodOptional<import("zod").ZodNumber>;
8022
+ adopted: import("zod").ZodOptional<import("zod").ZodBoolean>;
8022
8023
  error: import("zod").ZodOptional<import("zod").ZodString>;
8023
8024
  errorCode: import("zod").ZodOptional<import("zod").ZodString>;
8024
8025
  }, import("zod/v4/core").$strip>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hyperdrive.bot/paseo-protocol",
3
- "version": "0.3.73",
3
+ "version": "0.3.74",
4
4
  "description": "Paseo shared protocol schemas and wire types",
5
5
  "files": [
6
6
  "dist",