@fungi.computer/shiitake 0.5.0 → 0.7.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.
Files changed (88) hide show
  1. package/README.md +59 -21
  2. package/dist/agent-control.d.ts +94 -2
  3. package/dist/agent-control.js +147 -26
  4. package/dist/client-entry.d.ts +20 -0
  5. package/dist/client-entry.js +5 -0
  6. package/dist/client-visitor.d.ts +33 -0
  7. package/dist/client-visitor.js +231 -0
  8. package/dist/client-wire.d.ts +9 -0
  9. package/dist/client-wire.js +24 -3
  10. package/dist/client.d.ts +27 -6
  11. package/dist/client.js +23 -0
  12. package/dist/cloudflare.d.ts +20 -0
  13. package/dist/cloudflare.js +4 -1
  14. package/dist/delegation.d.ts +79 -53
  15. package/dist/delegation.js +26 -21
  16. package/dist/effect.d.ts +26 -1
  17. package/dist/effect.js +14 -1
  18. package/dist/errors.d.ts +2 -2
  19. package/dist/errors.js +2 -0
  20. package/dist/extensions.d.ts +22 -3
  21. package/dist/extensions.js +1 -1
  22. package/dist/fleet.d.ts +25 -2
  23. package/dist/fleet.js +108 -24
  24. package/dist/hosted.js +3 -0
  25. package/dist/http-routes.d.ts +23 -9
  26. package/dist/http.d.ts +1 -0
  27. package/dist/http.js +1 -0
  28. package/dist/index.d.ts +1 -1
  29. package/dist/internal/accepted-run-executor.js +2 -1
  30. package/dist/internal/admission-door.d.ts +6 -1
  31. package/dist/internal/admission-door.js +33 -3
  32. package/dist/internal/contracts.d.ts +19 -1
  33. package/dist/internal/coordinator.js +115 -52
  34. package/dist/internal/effect-client.js +1 -1
  35. package/dist/internal/effect-contracts.d.ts +9 -2
  36. package/dist/internal/extension-command-registry.d.ts +2 -1
  37. package/dist/internal/extension-command-registry.js +3 -1
  38. package/dist/internal/extension-runtime.d.ts +3 -1
  39. package/dist/internal/extension-runtime.js +18 -8
  40. package/dist/internal/model-acquisition.js +2 -0
  41. package/dist/internal/observation-kernel.d.ts +2 -0
  42. package/dist/internal/observation-kernel.js +17 -6
  43. package/dist/internal/promise-facade.js +2 -0
  44. package/dist/internal/run-scope.d.ts +14 -0
  45. package/dist/internal/run-scope.js +58 -15
  46. package/dist/internal/runtime-coordinator.d.ts +14 -0
  47. package/dist/internal/runtime-coordinator.js +60 -11
  48. package/dist/internal/runtime-core.d.ts +3 -0
  49. package/dist/internal/runtime-core.js +1 -0
  50. package/dist/internal/runtime-reconciliation.js +123 -25
  51. package/dist/internal/session-context.d.ts +5 -5
  52. package/dist/internal/session-context.js +80 -83
  53. package/dist/internal/session-status.d.ts +2 -2
  54. package/dist/internal/session-status.js +5 -3
  55. package/dist/internal/woodstock/agent-reply.d.ts +5 -0
  56. package/dist/internal/woodstock/agent-reply.js +3 -0
  57. package/dist/internal/woodstock/client-projection.js +13 -11
  58. package/dist/internal/woodstock/fleet-store.d.ts +3 -2
  59. package/dist/internal/woodstock/fleet-store.js +24 -4
  60. package/dist/internal/woodstock/index.d.ts +7 -3
  61. package/dist/internal/woodstock/index.js +23 -6
  62. package/dist/internal/woodstock/progress.d.ts +11 -1
  63. package/dist/internal/woodstock/progress.js +126 -25
  64. package/dist/internal/woodstock/session-delegator.d.ts +13 -0
  65. package/dist/internal/woodstock/session-delegator.js +44 -0
  66. package/dist/internal/woodstock/session-entry.d.ts +12 -2
  67. package/dist/internal/woodstock/session-store.d.ts +16 -2
  68. package/dist/internal/woodstock/session-store.js +349 -66
  69. package/dist/internal/woodstock/work-senders.d.ts +32 -0
  70. package/dist/internal/woodstock/work-senders.js +70 -0
  71. package/dist/node.js +11 -2
  72. package/dist/remote-client.js +7 -2
  73. package/dist/server-visitor-stream.d.ts +13 -0
  74. package/dist/server-visitor-stream.js +124 -0
  75. package/dist/session-attention.d.ts +30 -0
  76. package/dist/session-attention.js +14 -0
  77. package/docs/api/agent-control.md +212 -15
  78. package/docs/api/client-entry.md +3 -0
  79. package/docs/api/client.md +209 -5
  80. package/docs/api/cloudflare.md +23 -1
  81. package/docs/api/delegation.md +284 -77
  82. package/docs/api/effect.md +100 -12
  83. package/docs/api/extensions.md +73 -12
  84. package/docs/api/fleet.md +138 -25
  85. package/docs/api/http.md +28 -0
  86. package/docs/api/index.md +43 -17
  87. package/docs/api/testing.md +9 -7
  88. package/package.json +10 -6
@@ -31,10 +31,15 @@ export declare class AgentDelegation {
31
31
  }>);
32
32
  private fleetOwner;
33
33
  private fleet;
34
+ /** Best-effort remote refresh before an owner-local archive transaction.
35
+ * Confirmed settlements are recorded by Shiitake; unreadable targets leave
36
+ * their local accepted receipt outstanding for busySync to refuse.
37
+ */
38
+ refreshOutstanding(readSettlement: (agentId: string, sessionId: string, commandId: string) => Promise<CommandSettlement | undefined>): Promise<void>;
34
39
  private scope;
35
40
  /** Recipient-local disclosure through the public host, never another Agent's RPC. */
36
41
  settlement(sender: DelegationIdentity, sessionId: string, commandId: string, host: Pick<ShiitakeHost, "readSettlement">): Promise<CommandSettlement | undefined>;
37
- /** Delegate work to an in-scope Agent: steer its Session, or start fleet correspondence. */
42
+ /** Delegate work to an in-scope Agent through fleet correspondence; a steer rides the mail. */
38
43
  send(input: AgentDelegationInput, sourceSessionId: string, signal: AbortSignal, invocation?: AgentDelegationInvocation): Promise<DelegationReceipt>;
39
44
  /** Resolve this sender's exact request, then let the recipient guard pending work. */
40
45
  recall(input: AgentRecallInput, sourceSessionId: string, signal: AbortSignal): Promise<CancelResult>;
@@ -63,15 +68,9 @@ export type AgentReplySettlement = (mail: BirdDogMail) => Promise<CommandSettlem
63
68
  export declare function agentMailRoute(namespace: PostRoute<never, never>["namespace"], replySettlement: AgentReplySettlement): PostRoute<import("@fungi.computer/seam/machine-link-protocol").AgentMailAddress, {
64
69
  readonly key: string;
65
70
  readonly content: string;
66
- readonly createdAt: number;
67
- readonly from: {
68
- readonly kind: "agent";
69
- readonly agentId: string;
70
- readonly sessionId: string;
71
- };
72
71
  readonly to: {
73
- readonly kind: "agent";
74
72
  readonly agentId: string;
73
+ readonly kind: "agent";
75
74
  readonly sessionId?: string;
76
75
  };
77
76
  readonly replyTo: readonly {
@@ -79,11 +78,22 @@ export declare function agentMailRoute(namespace: PostRoute<never, never>["names
79
78
  readonly agentId: string;
80
79
  readonly sessionId: string;
81
80
  }[];
81
+ readonly createdAt: number;
82
+ readonly from: {
83
+ readonly kind: "agent";
84
+ readonly agentId: string;
85
+ readonly sessionId: string;
86
+ };
82
87
  readonly meta?: Schema.Json;
83
88
  readonly reply?: {
84
89
  readonly commandId: string;
85
90
  readonly outcome: "completed" | "failed" | "cancelled" | "interrupted" | "outcome_unknown";
86
91
  readonly diagnostic?: string;
92
+ readonly waitingOnYou?: readonly {
93
+ readonly itemId: string;
94
+ readonly kind: string;
95
+ readonly summary: string;
96
+ }[];
87
97
  } | {
88
98
  readonly outcome: "accepted";
89
99
  readonly commandId: string;
@@ -98,14 +108,9 @@ export declare function agentMailRoute(namespace: PostRoute<never, never>["names
98
108
  readonly reason: "recipient_offline";
99
109
  };
100
110
  readonly content: string;
101
- readonly createdAt: number;
102
- readonly from: {
103
- readonly kind: "system";
104
- readonly systemId: "hub";
105
- };
106
111
  readonly to: {
107
- readonly kind: "agent";
108
112
  readonly agentId: string;
113
+ readonly kind: "agent";
109
114
  readonly sessionId?: string;
110
115
  };
111
116
  readonly replyTo: readonly {
@@ -113,19 +118,18 @@ export declare function agentMailRoute(namespace: PostRoute<never, never>["names
113
118
  readonly agentId: string;
114
119
  readonly sessionId: string;
115
120
  }[];
121
+ readonly createdAt: number;
122
+ readonly from: {
123
+ readonly kind: "system";
124
+ readonly systemId: "hub";
125
+ };
116
126
  readonly meta?: Schema.Json;
117
127
  }, {
118
128
  readonly key: string;
119
129
  readonly content: string;
120
- readonly createdAt: number;
121
- readonly from: {
122
- readonly kind: "agent";
123
- readonly agentId: string;
124
- readonly sessionId: string;
125
- };
126
130
  readonly to: {
127
- readonly kind: "agent";
128
131
  readonly agentId: string;
132
+ readonly kind: "agent";
129
133
  readonly sessionId?: string;
130
134
  };
131
135
  readonly replyTo: readonly {
@@ -133,11 +137,22 @@ export declare function agentMailRoute(namespace: PostRoute<never, never>["names
133
137
  readonly agentId: string;
134
138
  readonly sessionId: string;
135
139
  }[];
140
+ readonly createdAt: number;
141
+ readonly from: {
142
+ readonly kind: "agent";
143
+ readonly agentId: string;
144
+ readonly sessionId: string;
145
+ };
136
146
  readonly meta?: Schema.Json;
137
147
  readonly reply?: {
138
148
  readonly commandId: string;
139
149
  readonly outcome: "completed" | "failed" | "cancelled" | "interrupted" | "outcome_unknown";
140
150
  readonly diagnostic?: string;
151
+ readonly waitingOnYou?: readonly {
152
+ readonly itemId: string;
153
+ readonly kind: string;
154
+ readonly summary: string;
155
+ }[];
141
156
  } | {
142
157
  readonly outcome: "accepted";
143
158
  readonly commandId: string;
@@ -152,14 +167,9 @@ export declare function agentMailRoute(namespace: PostRoute<never, never>["names
152
167
  readonly reason: "recipient_offline";
153
168
  };
154
169
  readonly content: string;
155
- readonly createdAt: number;
156
- readonly from: {
157
- readonly kind: "system";
158
- readonly systemId: "hub";
159
- };
160
170
  readonly to: {
161
- readonly kind: "agent";
162
171
  readonly agentId: string;
172
+ readonly kind: "agent";
163
173
  readonly sessionId?: string;
164
174
  };
165
175
  readonly replyTo: readonly {
@@ -167,19 +177,18 @@ export declare function agentMailRoute(namespace: PostRoute<never, never>["names
167
177
  readonly agentId: string;
168
178
  readonly sessionId: string;
169
179
  }[];
180
+ readonly createdAt: number;
181
+ readonly from: {
182
+ readonly kind: "system";
183
+ readonly systemId: "hub";
184
+ };
170
185
  readonly meta?: Schema.Json;
171
186
  }, import("@fungi.computer/seam/machine-link-protocol").AgentMailAddress, {
172
187
  readonly key: string;
173
188
  readonly content: string;
174
- readonly createdAt: number;
175
- readonly from: {
176
- readonly kind: "agent";
177
- readonly agentId: string;
178
- readonly sessionId: string;
179
- };
180
189
  readonly to: {
181
- readonly kind: "agent";
182
190
  readonly agentId: string;
191
+ readonly kind: "agent";
183
192
  readonly sessionId?: string;
184
193
  };
185
194
  readonly replyTo: readonly {
@@ -187,11 +196,22 @@ export declare function agentMailRoute(namespace: PostRoute<never, never>["names
187
196
  readonly agentId: string;
188
197
  readonly sessionId: string;
189
198
  }[];
199
+ readonly createdAt: number;
200
+ readonly from: {
201
+ readonly kind: "agent";
202
+ readonly agentId: string;
203
+ readonly sessionId: string;
204
+ };
190
205
  readonly meta?: Schema.Json;
191
206
  readonly reply?: {
192
207
  readonly commandId: string;
193
208
  readonly outcome: "completed" | "failed" | "cancelled" | "interrupted" | "outcome_unknown";
194
209
  readonly diagnostic?: string;
210
+ readonly waitingOnYou?: readonly {
211
+ readonly itemId: string;
212
+ readonly kind: string;
213
+ readonly summary: string;
214
+ }[];
195
215
  } | {
196
216
  readonly outcome: "accepted";
197
217
  readonly commandId: string;
@@ -206,14 +226,9 @@ export declare function agentMailRoute(namespace: PostRoute<never, never>["names
206
226
  readonly reason: "recipient_offline";
207
227
  };
208
228
  readonly content: string;
209
- readonly createdAt: number;
210
- readonly from: {
211
- readonly kind: "system";
212
- readonly systemId: "hub";
213
- };
214
229
  readonly to: {
215
- readonly kind: "agent";
216
230
  readonly agentId: string;
231
+ readonly kind: "agent";
217
232
  readonly sessionId?: string;
218
233
  };
219
234
  readonly replyTo: readonly {
@@ -221,19 +236,18 @@ export declare function agentMailRoute(namespace: PostRoute<never, never>["names
221
236
  readonly agentId: string;
222
237
  readonly sessionId: string;
223
238
  }[];
239
+ readonly createdAt: number;
240
+ readonly from: {
241
+ readonly kind: "system";
242
+ readonly systemId: "hub";
243
+ };
224
244
  readonly meta?: Schema.Json;
225
245
  }, {
226
246
  readonly key: string;
227
247
  readonly content: string;
228
- readonly createdAt: number;
229
- readonly from: {
230
- readonly kind: "agent";
231
- readonly agentId: string;
232
- readonly sessionId: string;
233
- };
234
248
  readonly to: {
235
- readonly kind: "agent";
236
249
  readonly agentId: string;
250
+ readonly kind: "agent";
237
251
  readonly sessionId?: string;
238
252
  };
239
253
  readonly replyTo: readonly {
@@ -241,11 +255,22 @@ export declare function agentMailRoute(namespace: PostRoute<never, never>["names
241
255
  readonly agentId: string;
242
256
  readonly sessionId: string;
243
257
  }[];
258
+ readonly createdAt: number;
259
+ readonly from: {
260
+ readonly kind: "agent";
261
+ readonly agentId: string;
262
+ readonly sessionId: string;
263
+ };
244
264
  readonly meta?: Schema.Json;
245
265
  readonly reply?: {
246
266
  readonly commandId: string;
247
267
  readonly outcome: "completed" | "failed" | "cancelled" | "interrupted" | "outcome_unknown";
248
268
  readonly diagnostic?: string;
269
+ readonly waitingOnYou?: readonly {
270
+ readonly itemId: string;
271
+ readonly kind: string;
272
+ readonly summary: string;
273
+ }[];
249
274
  } | {
250
275
  readonly outcome: "accepted";
251
276
  readonly commandId: string;
@@ -260,14 +285,9 @@ export declare function agentMailRoute(namespace: PostRoute<never, never>["names
260
285
  readonly reason: "recipient_offline";
261
286
  };
262
287
  readonly content: string;
263
- readonly createdAt: number;
264
- readonly from: {
265
- readonly kind: "system";
266
- readonly systemId: "hub";
267
- };
268
288
  readonly to: {
269
- readonly kind: "agent";
270
289
  readonly agentId: string;
290
+ readonly kind: "agent";
271
291
  readonly sessionId?: string;
272
292
  };
273
293
  readonly replyTo: readonly {
@@ -275,6 +295,11 @@ export declare function agentMailRoute(namespace: PostRoute<never, never>["names
275
295
  readonly agentId: string;
276
296
  readonly sessionId: string;
277
297
  }[];
298
+ readonly createdAt: number;
299
+ readonly from: {
300
+ readonly kind: "system";
301
+ readonly systemId: "hub";
302
+ };
278
303
  readonly meta?: Schema.Json;
279
304
  }> & Omit<Readonly<{
280
305
  addressKind: string;
@@ -317,6 +342,7 @@ export declare class AgentMail {
317
342
  stageAcceptedNotice(mail: BirdDogMail, scopeId: string): void;
318
343
  /** BirdDog's mail room: disclosed settlement replies fan out over Post. */
319
344
  mailRoom(): BirdDogEffect & {
345
+ /** Stage acceptance through this Post owner within the caller's transaction. */
320
346
  stageAcceptedNotice: (mail: BirdDogMail, scopeId: string) => void;
321
347
  };
322
348
  }
@@ -3,7 +3,7 @@
3
3
  * addressed Agent mail over Carrier Post, and the Agent grammar a host hands
4
4
  * to Oyster's machine link as ports. Oyster core never imports this engine.
5
5
  */
6
- import { commandSettlementSchema, createAgentDirectory, createFleetCorrespondence, agentDelegationRequestKey, delegationProvenance, delegationReplyMeta, delegationSendMeta, } from "./fleet.js";
6
+ import { commandSettlementSchema, createAgentDirectory, createFleetCorrespondence, createFleetDelegation, agentDelegationRequestKey, delegationProvenance, delegationReplyMeta, delegationSendMeta, settlementReadableBy, } from "./fleet.js";
7
7
  import * as Schema from "effect/Schema";
8
8
  import { agentMailAddressSchema } from "@fungi.computer/seam/machine-link-protocol";
9
9
  import { BirdDogMailSchema, BirdDogError, settlementReplies, } from "@fungi.computer/bird-dog/effect";
@@ -27,6 +27,19 @@ export class AgentDelegation {
27
27
  deliver: this.deps.deliver,
28
28
  }));
29
29
  }
30
+ /** Best-effort remote refresh before an owner-local archive transaction.
31
+ * Confirmed settlements are recorded by Shiitake; unreadable targets leave
32
+ * their local accepted receipt outstanding for busySync to refuse.
33
+ */
34
+ async refreshOutstanding(readSettlement) {
35
+ const fleet = createFleetDelegation({
36
+ storage: this.deps.storage,
37
+ deliver: this.deps.deliver,
38
+ open: (agentId) => this.deps.directory().open(agentId, new AbortController().signal),
39
+ readSettlement,
40
+ });
41
+ await fleet.outstanding();
42
+ }
30
43
  async scope(signal) {
31
44
  const agents = await this.deps.directory().list(signal);
32
45
  const identity = await this.deps.identity();
@@ -44,11 +57,11 @@ export class AgentDelegation {
44
57
  !scope.agents.some(({ agentId }) => agentId === sender.agentId))
45
58
  throw new AgentDisclosureRefused();
46
59
  const facts = await host.readSettlement(sessionId, commandId);
47
- if (facts !== undefined && facts.acceptedSender !== sender.agentId)
60
+ if (facts !== undefined && !settlementReadableBy(facts, sender.agentId))
48
61
  throw new AgentDisclosureRefused();
49
62
  return facts;
50
63
  }
51
- /** Delegate work to an in-scope Agent: steer its Session, or start fleet correspondence. */
64
+ /** Delegate work to an in-scope Agent through fleet correspondence; a steer rides the mail. */
52
65
  async send(input, sourceSessionId, signal, invocation) {
53
66
  if (invocation === undefined)
54
67
  throw new Error("Delegation requires a tool invocation");
@@ -66,36 +79,28 @@ export class AgentDelegation {
66
79
  requestId: input.requestId,
67
80
  });
68
81
  signal.throwIfAborted();
69
- if (input.delivery === "steer") {
70
- const opened = await this.deps.directory().open(input.agentId, signal);
71
- try {
72
- return await opened.agent.session(input.sessionId).send(input.text, {
73
- requestId,
74
- delivery: "steer",
75
- });
76
- }
77
- finally {
78
- await opened.release();
79
- }
80
- }
81
82
  const provenance = await delegationProvenance({
82
83
  agentId: scope.agentId,
83
84
  sessionId: sourceSessionId,
84
85
  });
85
86
  const meta = delegationSendMeta({ id: scope.agentId, name: scope.source.name }, invocation.meta);
86
87
  signal.throwIfAborted();
88
+ let task = {
89
+ agentId: input.agentId,
90
+ sessionId: input.sessionId,
91
+ delivery: input.delivery,
92
+ text: input.text,
93
+ requestId,
94
+ };
95
+ if (input.delivery === "followUp" && input.goal !== undefined)
96
+ task = { ...task, goal: input.goal };
87
97
  const accepted = await this.fleet().start({
88
98
  agents: scope.agents.map(({ agentId }) => agentId),
89
99
  actions: ["delegate"],
90
100
  expiresAt: this.deps.expiresAt(),
91
101
  provenance,
92
102
  meta,
93
- }, {
94
- agentId: input.agentId,
95
- sessionId: input.sessionId,
96
- text: input.text,
97
- requestId,
98
- });
103
+ }, task);
99
104
  return accepted;
100
105
  }
101
106
  /** Resolve this sender's exact request, then let the recipient guard pending work. */
package/dist/effect.d.ts CHANGED
@@ -8,7 +8,7 @@ import type { Accepted } from "./client.js";
8
8
  import type { ShiitakeError } from "./errors.js";
9
9
  import type { ShiitakeEffectOptions, ShiitakeEffectOwner } from "./internal/effect-contracts.js";
10
10
  import type { SqliteOwner } from "./internal/contracts.js";
11
- export type { AbortCommand, BranchCommand, CompactCommand, CancelCommand, CancelResult, Accepted, ForkCommand, ForkedSession, PromptCommand, PromptDelivery, ReadOptions, SessionCommand, SessionCommandHandler, SessionFrame, SessionMessage, SessionProgress, SessionToolOutput, SessionSnapshot, SessionActivity, AgentRunningWork, SubscribeOptions, TooLate, WatchOptions, } from "./client.js";
11
+ export type { AbortCommand, BranchCommand, CompactCommand, CancelCommand, CancelResult, Accepted, ForkCommand, ForkedSession, PromptCommand, PromptDelivery, ReadOptions, SessionCommand, SessionCommandHandler, SessionFrame, SessionMessage, SessionProgress, SessionProgressDelta, SessionToolOutput, SessionSnapshot, SessionActivity, AgentRunningWork, SubscribeOptions, TooLate, WatchOptions, } from "./client.js";
12
12
  export type { InstructionSnapshot, InstructionSource, ModelAcquisition, ModelDescription, ModelSource, RuntimeHost, RuntimePendingWork, SqliteCursor, SqliteOwner, SqliteValue, SqliteRow, GrantsDelivery, GrantsDeliveryResult, ShiitakeOptions, ToolAccess, HostMetaOptions, StandardHostMetaResult, StandardHostMetaSchema, ToolSource, } from "./internal/contracts.js";
13
13
  export type { InstructionSourceEffect, ModelAcquisitionEffect, ModelSourceEffect, RuntimeHostEffect, ShiitakeEffectAgent, ShiitakeEffectAgentExtensions, ShiitakeEffectCommandHandler, ShiitakeEffectOptions, ShiitakeEffectOwner, ShiitakeEffectSession, ShiitakeEffectSessionExtension, ShiitakeEffectSendOptions, ShiitakeEffectWatch, ToolSourceEffect, } from "./internal/effect-contracts.js";
14
14
  export type { SessionSummary } from "./client.js";
@@ -38,5 +38,30 @@ export declare function readSessionSummaries(owner: SqliteOwner, after?: string)
38
38
  sessions: readonly import("./internal/woodstock/session-store.js").StoredSessionSummaryRow[];
39
39
  next: string | undefined;
40
40
  }>, ShiitakeError, never>;
41
+ /**
42
+ * One page of saved conversations with their stored run state (needs_you,
43
+ * running, errored, done), in tier then newest-activity order, read from the
44
+ * store alone: no Agent runtime starts. The state is as the runtime last wrote
45
+ * it, so it can lag work a stopped runtime left behind.
46
+ */
47
+ export declare function readStoredSessionStates(owner: SqliteOwner, after?: string): Effect.Effect<Readonly<{
48
+ sessions: readonly import("./client.js").SessionSummaryRow[];
49
+ next: string | undefined;
50
+ }>, ShiitakeError, never>;
51
+ /** One saved conversation's open attention items, read from the store alone. */
52
+ export declare function readStoredAttention(owner: SqliteOwner, sessionId: string): Effect.Effect<readonly {
53
+ readonly id: string;
54
+ readonly kind: string;
55
+ readonly summary: string;
56
+ readonly since: number;
57
+ readonly extensionId: string;
58
+ readonly expiresAt?: number | undefined;
59
+ readonly inbox?: false | undefined;
60
+ readonly waitingOn?: {
61
+ readonly agentId: string;
62
+ readonly sessionId: string;
63
+ readonly name: string;
64
+ } | undefined;
65
+ }[], ShiitakeError, never>;
41
66
  export { sqliteRowSchema } from "./internal/contracts.js";
42
67
  export type { CommandSettlement } from "./internal/contracts.js";
package/dist/effect.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import * as Effect from "effect/Effect";
2
- import { readSessionFactPage } from "./internal/woodstock/index.js";
2
+ import { readSessionFactPage, readSessionInbox, readStoredSessionAttention, } from "./internal/woodstock/index.js";
3
3
  export { ShiitakeError } from "./errors.js";
4
4
  /** Construct the canonical Effect-native Shiitake scaffold. */
5
5
  export function make(options) {
@@ -17,4 +17,17 @@ export function openHost(options, mailRoom) {
17
17
  export function readSessionSummaries(owner, after) {
18
18
  return readSessionFactPage(owner, after);
19
19
  }
20
+ /**
21
+ * One page of saved conversations with their stored run state (needs_you,
22
+ * running, errored, done), in tier then newest-activity order, read from the
23
+ * store alone: no Agent runtime starts. The state is as the runtime last wrote
24
+ * it, so it can lag work a stopped runtime left behind.
25
+ */
26
+ export function readStoredSessionStates(owner, after) {
27
+ return readSessionInbox(owner, after);
28
+ }
29
+ /** One saved conversation's open attention items, read from the store alone. */
30
+ export function readStoredAttention(owner, sessionId) {
31
+ return readStoredSessionAttention(owner, sessionId);
32
+ }
20
33
  export { sqliteRowSchema } from "./internal/contracts.js";
package/dist/errors.d.ts CHANGED
@@ -4,14 +4,14 @@ declare const ShiitakeErrorBoundarySchema: Schema.Literals<readonly ["contract",
4
4
  /** Stable boundary that rejected a Shiitake operation. */
5
5
  export type ShiitakeErrorBoundary = Schema.Schema.Type<typeof ShiitakeErrorBoundarySchema>;
6
6
  /** Safe failure category exposed by both Shiitake facades. */
7
- declare const ShiitakeErrorCauseSchema: Schema.Literals<readonly ["closed", "conflict", "incompatible", "invalid", "rejected", "unavailable", "state_reset_required", "storage_pressure"]>;
7
+ declare const ShiitakeErrorCauseSchema: Schema.Literals<readonly ["closed", "conflict", "incompatible", "invalid", "rejected", "unavailable", "state_reset_required", "storage_pressure", "archived"]>;
8
8
  /** Safe failure category exposed by both Shiitake facades. */
9
9
  export type ShiitakeErrorCause = Schema.Schema.Type<typeof ShiitakeErrorCauseSchema>;
10
10
  /** Canonical serialized Shiitake failure. */
11
11
  export declare const ShiitakeErrorWireSchema: Schema.Struct<{
12
12
  readonly _tag: Schema.Literal<"ShiitakeError">;
13
13
  readonly boundary: Schema.Literals<readonly ["contract", "extensions", "instructions", "model", "runtime", "store", "tools"]>;
14
- readonly cause: Schema.Literals<readonly ["closed", "conflict", "incompatible", "invalid", "rejected", "unavailable", "state_reset_required", "storage_pressure"]>;
14
+ readonly cause: Schema.Literals<readonly ["closed", "conflict", "incompatible", "invalid", "rejected", "unavailable", "state_reset_required", "storage_pressure", "archived"]>;
15
15
  readonly message: Schema.String;
16
16
  readonly requestId: Schema.optionalKey<Schema.String>;
17
17
  }>;
package/dist/errors.js CHANGED
@@ -21,6 +21,8 @@ const ShiitakeErrorCauseSchema = Schema.Literals([
21
21
  "state_reset_required",
22
22
  /** Owner storage is near its budget; new Sessions and prompts wait. */
23
23
  "storage_pressure",
24
+ /** This Agent is archived; new Sessions and prompts require restoration. */
25
+ "archived",
24
26
  ]);
25
27
  const requestIdSchema = Schema.String.pipe(Schema.check(Schema.isMinLength(1)), Schema.check(Schema.isMaxLength(256)));
26
28
  /** Canonical serialized Shiitake failure. */
@@ -1,6 +1,6 @@
1
1
  import type { FileTool } from "@fungi.computer/knapsack";
2
- import type { AttentionItem } from "./session-attention.js";
3
- export { AttentionItemSchema, type AttentionItem, type SessionAttention, } from "./session-attention.js";
2
+ import type { AttentionItem, AttentionRecipient } from "./session-attention.js";
3
+ export { AttentionItemSchema, AttentionRecipientSchema, type AttentionItem, type AttentionRecipient, type SessionAttention, } from "./session-attention.js";
4
4
  import type { Message, Usage } from "@fungi.computer/mule/effect";
5
5
  import type { ModuleRegistration } from "@fungi.computer/mycelium";
6
6
  import * as Brand from "effect/Brand";
@@ -77,7 +77,7 @@ declare const AdmissionError_base: new <A extends Record<string, any> = {}>(args
77
77
  } & Readonly<A>;
78
78
  /** The door refused an extension admission. */
79
79
  export declare class AdmissionError extends AdmissionError_base<{
80
- reason: "invalid" | "conflict" | "closed";
80
+ reason: "invalid" | "conflict" | "closed" | "archived";
81
81
  message: string;
82
82
  }> {
83
83
  }
@@ -261,6 +261,8 @@ export type SendInputV0 = Readonly<{
261
261
  when: "now" | "idle";
262
262
  /** Stored with the admission and returned on `SettledRunV0.origin`. */
263
263
  correlation?: string;
264
+ /** This work continues earlier work of the Session and keeps its sender. */
265
+ continuesWorkId?: string;
264
266
  }>;
265
267
  /** Door outcome for one extension admission. */
266
268
  export type SendResultV0 = Readonly<{
@@ -290,17 +292,26 @@ export type CommandSessionIdsV0 = {
290
292
  agent: null;
291
293
  session: string;
292
294
  };
295
+ /** Host-authenticated caller context; never decoded from command JSON or HTTP. */
296
+ export type ExtensionCommandCallerV0 = Readonly<{
297
+ agentId: string;
298
+ sessionId: string;
299
+ }>;
293
300
  /** Handlers for every declared command, run in one core transaction. */
294
301
  export type CommandHandlersV0<C extends CommandsV0> = {
295
302
  readonly [K in keyof C]: (call: Readonly<{
296
303
  sessionId: CommandSessionIdsV0[C[K]["scope"]];
297
304
  input: C[K]["input"]["Type"];
305
+ /** Present only when the owning in-process host authenticates a caller. */
306
+ caller?: ExtensionCommandCallerV0;
298
307
  }>) => C[K]["output"]["Type"] | Effect.Effect<C[K]["output"]["Type"], ExtensionCommandError | ExtensionStateError | AdmissionError, ExtensionTx | ExtensionRead>;
299
308
  };
300
309
  /** Transaction-scoped, extension-owned attention on an existing Session. */
301
310
  export type AttentionV0 = Readonly<{
302
311
  /** Upsert this extension’s item and publish the committed Session change. */
303
312
  set: (sessionId: string, item: AttentionItem) => Effect.Effect<void, ExtensionStateError, ExtensionTx>;
313
+ /** Whether any extension holds an inbox item asking a person to act (a question or approval). */
314
+ awaitsPerson: (sessionId: string) => Effect.Effect<boolean, ExtensionStateError, ExtensionRead>;
304
315
  /** Clear this extension’s item; other owners cannot be changed. */
305
316
  clear: (sessionId: string, id: string) => Effect.Effect<void, ExtensionStateError, ExtensionTx>;
306
317
  }>;
@@ -322,10 +333,18 @@ export type ExtensionContextV0<S extends CollectionsV0, Config extends Json, D e
322
333
  sessionPosition: (sessionId: string) => Effect.Effect<number, ExtensionStateError, ExtensionRead>;
323
334
  /** Observe accepted steering without consuming Mule's next control delivery. Requires run_tools. */
324
335
  hasPendingSteer: (run: Pick<RunIdentityV0, "sessionId" | "workId">) => Effect.Effect<boolean, ExtensionStateError, ExtensionRead>;
336
+ /**
337
+ * The Agent Session that sent this run, or null when a person (or the host)
338
+ * did. Attention an extension raises for the run waits on it first.
339
+ * Requires run_tools.
340
+ */
341
+ workSender: (run: Pick<RunIdentityV0, "sessionId" | "workId">) => Effect.Effect<AttentionRecipient | null, ExtensionStateError, ExtensionRead>;
325
342
  /** Whether this run durably recorded a successful tool outcome. Requires run_tools. */
326
343
  hasSuccessfulToolResult: (run: Pick<RunIdentityV0, "sessionId" | "workId">, toolCallId: string) => Effect.Effect<boolean, ExtensionStateError, ExtensionRead>;
327
344
  /** Publish a Session observation after this transaction commits. */
328
345
  observe: (sessionId: string) => Effect.Effect<void, never, ExtensionTx>;
346
+ /** Process-local live-view demand, excluding exact-command settlement waiters. */
347
+ isObserved: (sessionId: string) => boolean;
329
348
  /**
330
349
  * Run one write transaction from outside a hook (for example a Mycelium
331
350
  * tool execute). Core commits, publishes, and requests a wake when it
@@ -1,4 +1,4 @@
1
- export { AttentionItemSchema, } from "./session-attention.js";
1
+ export { AttentionItemSchema, AttentionRecipientSchema, } from "./session-attention.js";
2
2
  import * as Brand from "effect/Brand";
3
3
  import * as Context from "effect/Context";
4
4
  import * as Data from "effect/Data";
package/dist/fleet.d.ts CHANGED
@@ -82,8 +82,8 @@ export type AgentLifecycleFact = Readonly<{
82
82
  }>;
83
83
  /** Refusal of supplied authority; no host policy lookup is performed. */
84
84
  export declare class AgentGrantError extends Error {
85
- readonly reason: "agent" | "action" | "expired" | "delegation_loop" | "delegation_depth";
86
- constructor(reason: "agent" | "action" | "expired" | "delegation_loop" | "delegation_depth");
85
+ readonly reason: "agent" | "action" | "expired" | "delegation_loop" | "delegation_depth" | "delegator_missing";
86
+ constructor(reason: "agent" | "action" | "expired" | "delegation_loop" | "delegation_depth" | "delegator_missing");
87
87
  }
88
88
  /** Check every operation against its explicit authority. */
89
89
  export declare function assertAgentGrant(grant: AgentGrant, action: AgentAction, agentId?: string): void;
@@ -180,11 +180,23 @@ export declare function createAgentDirectory(sql: WatchdogSqliteOwner["sql"]): {
180
180
  /** Whether the retained erasure roster covers this store. */
181
181
  erasureRosterComplete: () => boolean;
182
182
  };
183
+ /**
184
+ * Whether an Agent may read one command's settlement: the Agent whose mail the
185
+ * command answered, or the Session's delegator of record for work no Agent's
186
+ * mail admitted (goal, loop and person turns, the work its reports carry).
187
+ * Another Agent's correspondence stays with that Agent.
188
+ */
189
+ export declare function settlementReadableBy(facts: Pick<CommandSettlement, "acceptedSender" | "delegator">, agentId: string): boolean;
183
190
  /** Replay identity and work, with the parent supplied exclusively by the grant. */
184
191
  export declare const agentDelegationTaskSchema: z.ZodLazy<z.ZodObject<{
185
192
  requestId: z.ZodString;
186
193
  agentId: z.ZodString;
187
194
  sessionId: z.ZodOptional<z.ZodString>;
195
+ delivery: z.ZodOptional<z.ZodEnum<{
196
+ followUp: "followUp";
197
+ steer: "steer";
198
+ }>>;
199
+ goal: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodLiteral<false>]>>;
188
200
  text: z.ZodString;
189
201
  }, z.core.$strict>>;
190
202
  /** A caller reuses this task unchanged while polling Pending. */
@@ -260,6 +272,8 @@ export declare function delegationSendMeta(sender: Readonly<{
260
272
  * while the verified reply retains the failed recipient's identity.
261
273
  */
262
274
  export declare function delegationReplyMeta(delegation: AuthenticatedDelegationReply, replierName: string): DelegationReplyMeta;
275
+ /** An original one-way report can only name an ancestor of its Agent sender. */
276
+ export declare function isOneWayAncestorNotice(mail: BirdDogMail): boolean;
263
277
  /**
264
278
  * Delegated work an owner still waits on; `unreadable` says why its state
265
279
  * could not be read, when it could not.
@@ -270,6 +284,11 @@ export type OutstandingDelegation = Readonly<{
270
284
  commandId: string;
271
285
  unreadable?: string;
272
286
  }>;
287
+ /** Read confirmed sender receipts that have no locally observed settlement.
288
+ * Call inside the Agent owner's transaction that also changes archived state.
289
+ * Remote reads happen separately; an unobserved settlement remains busy.
290
+ */
291
+ export declare function readOutstandingDelegationSync(storage: WatchdogSqliteOwner): OutstandingDelegation | undefined;
273
292
  /**
274
293
  * BirdDog submission and reply authentication. The durable row freezes
275
294
  * correspondence before transport; an ambiguous delivery reuses that exact mail.
@@ -280,7 +299,9 @@ export declare function createFleetCorrespondence(options: Omit<FleetDelegationO
280
299
  start: (grant: AgentGrant, raw: AgentDelegationTask) => Promise<DelegationReceipt>;
281
300
  /** Match a reply to frozen mail and restore the caller's delegation path. */
282
301
  authenticateReply: (mail: BirdDogMail) => AuthenticatedDelegationReply | undefined;
302
+ /** Bind exhausted local delivery to its frozen sender correspondence. */
283
303
  recordLocalUndeliverable: (original: BirdDogMail, reply: BirdDogMail) => boolean;
304
+ /** Prevent replay after a system undeliverable reply is admitted. */
284
305
  recordUndeliverableReply: (mailKey: string) => boolean;
285
306
  /** Read an existing acceptance receipt without reserving or delivering mail. */
286
307
  receipt: (requestId: string) => Accepted | undefined;
@@ -295,7 +316,9 @@ export declare function createFleetDelegation(options: FleetDelegationOptions):
295
316
  start: (grant: AgentGrant, raw: AgentDelegationTask) => Promise<DelegationReceipt>;
296
317
  /** Match a reply to frozen mail and restore the caller's delegation path. */
297
318
  authenticateReply: (mail: BirdDogMail) => AuthenticatedDelegationReply | undefined;
319
+ /** Bind exhausted local delivery to its frozen sender correspondence. */
298
320
  recordLocalUndeliverable: (original: BirdDogMail, reply: BirdDogMail) => boolean;
321
+ /** Prevent replay after a system undeliverable reply is admitted. */
299
322
  recordUndeliverableReply: (mailKey: string) => boolean;
300
323
  /** Read an existing acceptance receipt without reserving or delivering mail. */
301
324
  receipt: (requestId: string) => Accepted | undefined;