@fungi.computer/shiitake 0.4.0 → 0.6.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.
- package/README.md +1 -10
- package/dist/agent-control.d.ts +98 -5
- package/dist/agent-control.js +111 -8
- package/dist/client-entry.d.ts +20 -0
- package/dist/client-entry.js +5 -0
- package/dist/client-visitor.d.ts +31 -0
- package/dist/client-visitor.js +226 -0
- package/dist/client-wire.d.ts +5 -0
- package/dist/client-wire.js +6 -0
- package/dist/client.d.ts +4 -3
- package/dist/client.js +1 -0
- package/dist/delegation.d.ts +100 -77
- package/dist/delegation.js +73 -23
- package/dist/effect.d.ts +25 -0
- package/dist/effect.js +14 -1
- package/dist/extensions.d.ts +21 -2
- package/dist/extensions.js +1 -1
- package/dist/fleet.d.ts +22 -2
- package/dist/fleet.js +127 -36
- package/dist/hosted.js +3 -0
- package/dist/http-routes.d.ts +11 -0
- package/dist/internal/accepted-run-executor.js +2 -1
- package/dist/internal/admission-door.d.ts +5 -0
- package/dist/internal/admission-door.js +34 -3
- package/dist/internal/contracts.d.ts +14 -1
- package/dist/internal/coordinator.js +8 -2
- package/dist/internal/effect-client.js +1 -1
- package/dist/internal/effect-contracts.d.ts +4 -2
- package/dist/internal/extension-command-registry.d.ts +2 -1
- package/dist/internal/extension-command-registry.js +3 -1
- package/dist/internal/extension-runtime.d.ts +3 -1
- package/dist/internal/extension-runtime.js +13 -5
- package/dist/internal/model-acquisition.js +2 -0
- package/dist/internal/observation-kernel.d.ts +2 -0
- package/dist/internal/observation-kernel.js +17 -6
- package/dist/internal/run-scope.d.ts +14 -0
- package/dist/internal/run-scope.js +32 -9
- package/dist/internal/runtime-coordinator.js +8 -1
- package/dist/internal/runtime-reconciliation.js +119 -24
- package/dist/internal/woodstock/agent-reply.d.ts +5 -0
- package/dist/internal/woodstock/agent-reply.js +3 -0
- package/dist/internal/woodstock/client-projection.js +9 -1
- package/dist/internal/woodstock/fleet-store.d.ts +1 -0
- package/dist/internal/woodstock/fleet-store.js +28 -1
- package/dist/internal/woodstock/index.d.ts +4 -0
- package/dist/internal/woodstock/index.js +7 -0
- package/dist/internal/woodstock/session-delegator.d.ts +12 -0
- package/dist/internal/woodstock/session-delegator.js +44 -0
- package/dist/internal/woodstock/session-entry.d.ts +12 -2
- package/dist/internal/woodstock/session-store.d.ts +2 -0
- package/dist/internal/woodstock/session-store.js +20 -0
- package/dist/internal/woodstock/work-senders.d.ts +32 -0
- package/dist/internal/woodstock/work-senders.js +70 -0
- package/dist/remote-client.js +7 -2
- package/dist/server-visitor-stream.d.ts +13 -0
- package/dist/server-visitor-stream.js +115 -0
- package/dist/session-attention.d.ts +30 -0
- package/dist/session-attention.js +14 -0
- package/docs/api/agent-control.md +209 -13
- package/docs/api/client-entry.md +3 -0
- package/docs/api/client.md +136 -1
- package/docs/api/cloudflare.md +7 -1
- package/docs/api/delegation.md +234 -61
- package/docs/api/effect.md +16 -6
- package/docs/api/extensions.md +65 -4
- package/docs/api/fleet.md +69 -16
- package/docs/api/index.md +6 -4
- package/package.json +10 -6
package/dist/client-wire.js
CHANGED
|
@@ -282,10 +282,16 @@ export function parseForkedSession(value) {
|
|
|
282
282
|
/** Exact command facts shared by Session clients and host fleet transports. */
|
|
283
283
|
export const commandSettlementSchema = Schema.Struct({
|
|
284
284
|
acceptedSender: Schema.NullOr(Schema.String),
|
|
285
|
+
delegator: Schema.NullOr(Schema.String),
|
|
285
286
|
terminal: SessionTerminalSchema,
|
|
286
287
|
content: Schema.String,
|
|
287
288
|
usage: Schema.Array(Schema.Struct({ provider: Schema.String, model: Schema.String, usage })),
|
|
288
289
|
toolCalls: Schema.Int.check(Schema.isGreaterThanOrEqualTo(0)),
|
|
290
|
+
waitingOnYou: Schema.Array(Schema.Struct({
|
|
291
|
+
itemId: Schema.String,
|
|
292
|
+
kind: Schema.String,
|
|
293
|
+
summary: Schema.String,
|
|
294
|
+
})).check(Schema.isMaxLength(8)),
|
|
289
295
|
});
|
|
290
296
|
/** A timeout is null on the JSON wire and undefined at the client boundary. */
|
|
291
297
|
export function parseCommandSettlement(value) {
|
package/dist/client.d.ts
CHANGED
|
@@ -5,12 +5,13 @@ export { type SessionAttention } from "./session-attention.js";
|
|
|
5
5
|
import type { SandboxFailureEvent } from "@fungi.computer/mycelium";
|
|
6
6
|
import type { ModelPreference } from "./internal/model-preference.js";
|
|
7
7
|
import type { Message } from "@fungi.computer/mule/effect";
|
|
8
|
-
import type { ExtensionSlotV0, ExtensionStatusV0, Json } from "./extensions.js";
|
|
8
|
+
import type { ExtensionCommandCallerV0, ExtensionSlotV0, ExtensionStatusV0, Json } from "./extensions.js";
|
|
9
9
|
import type { AbortCommand, BranchCommand, CompactCommand, OperatorCommand, TitleCommand, CancelCommand, ForkCommand, PromptCommand, PromptDelivery, SessionCommand } from "./internal/client-boundary.js";
|
|
10
10
|
export { createShiitakeClient, type ShiitakeClientOptions, } from "./remote-client.js";
|
|
11
11
|
export { bindAgentExtension, bindSessionExtension, type BoundAgentExtensionV0, type BoundCallV0, type BoundSessionExtensionV0, type ExtensionViewV0, type ScopedCommandsV0, } from "./extension-client.js";
|
|
12
12
|
export { AcceptedSchema, DelegationReceiptSchema, HeldSchema, parseAccepted, parseDelegationReceipt, parseCancelResult, parseLatestPendingPrompt, parseWithdrawResult, parseForkedSession, parseSessionFrame, parseSessionSnapshot, parseSessionSummaryPage, parseShiitakeError, } from "./client-wire.js";
|
|
13
13
|
export type { AbortCommand, BranchCommand, CompactCommand, CancelCommand, ForkCommand, OperatorCommand, PromptCommand, PromptDelivery, SessionCommand, TitleCommand, } from "./internal/client-boundary.js";
|
|
14
|
+
export { participantSnapshot, visitorPendingPrompt, visitorSnapshot, visitorView, type ParticipantPolicy, type VisitorPendingPrompt, type VisitorView, } from "./client-visitor.js";
|
|
14
15
|
/** Semantic acknowledgement returned after one durable acceptance commit. */
|
|
15
16
|
export type Accepted = Readonly<{
|
|
16
17
|
/** Indicates that the owner transaction committed. */
|
|
@@ -185,8 +186,8 @@ export type SessionActivity = Readonly<{
|
|
|
185
186
|
export type SessionExtensionSlots = Readonly<Record<string, ExtensionSlotV0>>;
|
|
186
187
|
/** Generic Session-scope extension commands. */
|
|
187
188
|
export type SessionExtensionControls = Readonly<{
|
|
188
|
-
/** Call one Session-scope command with its encoded input
|
|
189
|
-
call: (command: string, input: Json) => Promise<Json>;
|
|
189
|
+
/** Call one Session-scope command with its encoded input and optional host caller. */
|
|
190
|
+
call: (command: string, input: Json, caller?: ExtensionCommandCallerV0) => Promise<Json>;
|
|
190
191
|
}>;
|
|
191
192
|
/** Generic Agent-scope extension controls. */
|
|
192
193
|
export type AgentExtensionControls = Readonly<{
|
package/dist/client.js
CHANGED
|
@@ -2,3 +2,4 @@ export {} from "./session-attention.js";
|
|
|
2
2
|
export { createShiitakeClient, } from "./remote-client.js";
|
|
3
3
|
export { bindAgentExtension, bindSessionExtension, } from "./extension-client.js";
|
|
4
4
|
export { AcceptedSchema, DelegationReceiptSchema, HeldSchema, parseAccepted, parseDelegationReceipt, parseCancelResult, parseLatestPendingPrompt, parseWithdrawResult, parseForkedSession, parseSessionFrame, parseSessionSnapshot, parseSessionSummaryPage, parseShiitakeError, } from "./client-wire.js";
|
|
5
|
+
export { participantSnapshot, visitorPendingPrompt, visitorSnapshot, visitorView, } from "./client-visitor.js";
|
package/dist/delegation.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { WatchdogSqliteOwner } from "@fungi.computer/watchdog";
|
|
2
2
|
import * as Schema from "effect/Schema";
|
|
3
3
|
import { type BirdDogEffect } from "@fungi.computer/bird-dog/effect";
|
|
4
|
-
import type
|
|
4
|
+
import { type BirdDogMail } from "@fungi.computer/bird-dog";
|
|
5
5
|
import { type PostRoute, type PostRuntime, type PostEnvelope, type PostDeliveryResult } from "@fungi.computer/carrier/post";
|
|
6
6
|
import { type Accepted, type DelegationReceipt, type CancelResult } from "./client.js";
|
|
7
7
|
import type { CommandSettlement, ShiitakeHost, VerifiedAgentReply } from "./index.js";
|
|
@@ -34,15 +34,15 @@ export declare class AgentDelegation {
|
|
|
34
34
|
private scope;
|
|
35
35
|
/** Recipient-local disclosure through the public host, never another Agent's RPC. */
|
|
36
36
|
settlement(sender: DelegationIdentity, sessionId: string, commandId: string, host: Pick<ShiitakeHost, "readSettlement">): Promise<CommandSettlement | undefined>;
|
|
37
|
-
/** Delegate work to an in-scope Agent
|
|
37
|
+
/** Delegate work to an in-scope Agent through fleet correspondence; a steer rides the mail. */
|
|
38
38
|
send(input: AgentDelegationInput, sourceSessionId: string, signal: AbortSignal, invocation?: AgentDelegationInvocation): Promise<DelegationReceipt>;
|
|
39
39
|
/** Resolve this sender's exact request, then let the recipient guard pending work. */
|
|
40
40
|
recall(input: AgentRecallInput, sourceSessionId: string, signal: AbortSignal): Promise<CancelResult>;
|
|
41
41
|
/**
|
|
42
42
|
* A reply-less envelope is only ever BirdDog's reply to work this Agent
|
|
43
43
|
* sent. Admit it only after the fleet authenticates it against that frozen
|
|
44
|
-
* mail
|
|
45
|
-
*
|
|
44
|
+
* mail. A recipient-left reply remains Agent-authored; a recipient-offline
|
|
45
|
+
* reply is Hub-authored. Its meta carries only the authenticated reply.
|
|
46
46
|
*/
|
|
47
47
|
private authenticatedReply;
|
|
48
48
|
private parseAddressedMail;
|
|
@@ -50,6 +50,8 @@ export declare class AgentDelegation {
|
|
|
50
50
|
receive(raw: PostEnvelope): Promise<PostDeliveryResult>;
|
|
51
51
|
private recordAcceptedNotice;
|
|
52
52
|
private acceptAdmitted;
|
|
53
|
+
/** Admit local outbox exhaustion through the same Fleet/system reply gate. */
|
|
54
|
+
localUndeliverable(original: BirdDogMail): Promise<PostDeliveryResult>;
|
|
53
55
|
}
|
|
54
56
|
/** A current correspondent no longer has disclosure authority. */
|
|
55
57
|
export declare class AgentDisclosureRefused extends Error {
|
|
@@ -61,15 +63,9 @@ export type AgentReplySettlement = (mail: BirdDogMail) => Promise<CommandSettlem
|
|
|
61
63
|
export declare function agentMailRoute(namespace: PostRoute<never, never>["namespace"], replySettlement: AgentReplySettlement): PostRoute<import("@fungi.computer/seam/machine-link-protocol").AgentMailAddress, {
|
|
62
64
|
readonly key: string;
|
|
63
65
|
readonly content: string;
|
|
64
|
-
readonly createdAt: number;
|
|
65
|
-
readonly from: {
|
|
66
|
-
readonly kind: "agent";
|
|
67
|
-
readonly agentId: string;
|
|
68
|
-
readonly sessionId: string;
|
|
69
|
-
};
|
|
70
66
|
readonly to: {
|
|
71
|
-
readonly kind: "agent";
|
|
72
67
|
readonly agentId: string;
|
|
68
|
+
readonly kind: "agent";
|
|
73
69
|
readonly sessionId?: string;
|
|
74
70
|
};
|
|
75
71
|
readonly replyTo: readonly {
|
|
@@ -77,34 +73,39 @@ export declare function agentMailRoute(namespace: PostRoute<never, never>["names
|
|
|
77
73
|
readonly agentId: string;
|
|
78
74
|
readonly sessionId: string;
|
|
79
75
|
}[];
|
|
76
|
+
readonly createdAt: number;
|
|
77
|
+
readonly from: {
|
|
78
|
+
readonly kind: "agent";
|
|
79
|
+
readonly agentId: string;
|
|
80
|
+
readonly sessionId: string;
|
|
81
|
+
};
|
|
80
82
|
readonly meta?: Schema.Json;
|
|
81
83
|
readonly reply?: {
|
|
82
84
|
readonly commandId: string;
|
|
83
85
|
readonly outcome: "completed" | "failed" | "cancelled" | "interrupted" | "outcome_unknown";
|
|
84
86
|
readonly diagnostic?: string;
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
87
|
+
readonly waitingOnYou?: readonly {
|
|
88
|
+
readonly itemId: string;
|
|
89
|
+
readonly kind: string;
|
|
90
|
+
readonly summary: string;
|
|
91
|
+
}[];
|
|
88
92
|
} | {
|
|
89
93
|
readonly outcome: "accepted";
|
|
90
94
|
readonly commandId: string;
|
|
95
|
+
} | {
|
|
96
|
+
readonly outcome: "undeliverable";
|
|
97
|
+
readonly reason: "recipient_left";
|
|
91
98
|
};
|
|
92
99
|
} | {
|
|
93
100
|
readonly key: string;
|
|
94
101
|
readonly reply: {
|
|
95
102
|
readonly outcome: "undeliverable";
|
|
96
|
-
readonly reason: "recipient_offline"
|
|
103
|
+
readonly reason: "recipient_offline";
|
|
97
104
|
};
|
|
98
105
|
readonly content: string;
|
|
99
|
-
readonly createdAt: number;
|
|
100
|
-
readonly from: {
|
|
101
|
-
readonly kind: "agent";
|
|
102
|
-
readonly agentId: string;
|
|
103
|
-
readonly sessionId?: string;
|
|
104
|
-
};
|
|
105
106
|
readonly to: {
|
|
106
|
-
readonly kind: "agent";
|
|
107
107
|
readonly agentId: string;
|
|
108
|
+
readonly kind: "agent";
|
|
108
109
|
readonly sessionId?: string;
|
|
109
110
|
};
|
|
110
111
|
readonly replyTo: readonly {
|
|
@@ -112,19 +113,18 @@ export declare function agentMailRoute(namespace: PostRoute<never, never>["names
|
|
|
112
113
|
readonly agentId: string;
|
|
113
114
|
readonly sessionId: string;
|
|
114
115
|
}[];
|
|
116
|
+
readonly createdAt: number;
|
|
117
|
+
readonly from: {
|
|
118
|
+
readonly kind: "system";
|
|
119
|
+
readonly systemId: "hub";
|
|
120
|
+
};
|
|
115
121
|
readonly meta?: Schema.Json;
|
|
116
122
|
}, {
|
|
117
123
|
readonly key: string;
|
|
118
124
|
readonly content: string;
|
|
119
|
-
readonly createdAt: number;
|
|
120
|
-
readonly from: {
|
|
121
|
-
readonly kind: "agent";
|
|
122
|
-
readonly agentId: string;
|
|
123
|
-
readonly sessionId: string;
|
|
124
|
-
};
|
|
125
125
|
readonly to: {
|
|
126
|
-
readonly kind: "agent";
|
|
127
126
|
readonly agentId: string;
|
|
127
|
+
readonly kind: "agent";
|
|
128
128
|
readonly sessionId?: string;
|
|
129
129
|
};
|
|
130
130
|
readonly replyTo: readonly {
|
|
@@ -132,34 +132,39 @@ export declare function agentMailRoute(namespace: PostRoute<never, never>["names
|
|
|
132
132
|
readonly agentId: string;
|
|
133
133
|
readonly sessionId: string;
|
|
134
134
|
}[];
|
|
135
|
+
readonly createdAt: number;
|
|
136
|
+
readonly from: {
|
|
137
|
+
readonly kind: "agent";
|
|
138
|
+
readonly agentId: string;
|
|
139
|
+
readonly sessionId: string;
|
|
140
|
+
};
|
|
135
141
|
readonly meta?: Schema.Json;
|
|
136
142
|
readonly reply?: {
|
|
137
143
|
readonly commandId: string;
|
|
138
144
|
readonly outcome: "completed" | "failed" | "cancelled" | "interrupted" | "outcome_unknown";
|
|
139
145
|
readonly diagnostic?: string;
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
146
|
+
readonly waitingOnYou?: readonly {
|
|
147
|
+
readonly itemId: string;
|
|
148
|
+
readonly kind: string;
|
|
149
|
+
readonly summary: string;
|
|
150
|
+
}[];
|
|
143
151
|
} | {
|
|
144
152
|
readonly outcome: "accepted";
|
|
145
153
|
readonly commandId: string;
|
|
154
|
+
} | {
|
|
155
|
+
readonly outcome: "undeliverable";
|
|
156
|
+
readonly reason: "recipient_left";
|
|
146
157
|
};
|
|
147
158
|
} | {
|
|
148
159
|
readonly key: string;
|
|
149
160
|
readonly reply: {
|
|
150
161
|
readonly outcome: "undeliverable";
|
|
151
|
-
readonly reason: "recipient_offline"
|
|
162
|
+
readonly reason: "recipient_offline";
|
|
152
163
|
};
|
|
153
164
|
readonly content: string;
|
|
154
|
-
readonly createdAt: number;
|
|
155
|
-
readonly from: {
|
|
156
|
-
readonly kind: "agent";
|
|
157
|
-
readonly agentId: string;
|
|
158
|
-
readonly sessionId?: string;
|
|
159
|
-
};
|
|
160
165
|
readonly to: {
|
|
161
|
-
readonly kind: "agent";
|
|
162
166
|
readonly agentId: string;
|
|
167
|
+
readonly kind: "agent";
|
|
163
168
|
readonly sessionId?: string;
|
|
164
169
|
};
|
|
165
170
|
readonly replyTo: readonly {
|
|
@@ -167,19 +172,18 @@ export declare function agentMailRoute(namespace: PostRoute<never, never>["names
|
|
|
167
172
|
readonly agentId: string;
|
|
168
173
|
readonly sessionId: string;
|
|
169
174
|
}[];
|
|
175
|
+
readonly createdAt: number;
|
|
176
|
+
readonly from: {
|
|
177
|
+
readonly kind: "system";
|
|
178
|
+
readonly systemId: "hub";
|
|
179
|
+
};
|
|
170
180
|
readonly meta?: Schema.Json;
|
|
171
181
|
}, import("@fungi.computer/seam/machine-link-protocol").AgentMailAddress, {
|
|
172
182
|
readonly key: string;
|
|
173
183
|
readonly content: string;
|
|
174
|
-
readonly createdAt: number;
|
|
175
|
-
readonly from: {
|
|
176
|
-
readonly kind: "agent";
|
|
177
|
-
readonly agentId: string;
|
|
178
|
-
readonly sessionId: string;
|
|
179
|
-
};
|
|
180
184
|
readonly to: {
|
|
181
|
-
readonly kind: "agent";
|
|
182
185
|
readonly agentId: string;
|
|
186
|
+
readonly kind: "agent";
|
|
183
187
|
readonly sessionId?: string;
|
|
184
188
|
};
|
|
185
189
|
readonly replyTo: readonly {
|
|
@@ -187,34 +191,39 @@ export declare function agentMailRoute(namespace: PostRoute<never, never>["names
|
|
|
187
191
|
readonly agentId: string;
|
|
188
192
|
readonly sessionId: string;
|
|
189
193
|
}[];
|
|
194
|
+
readonly createdAt: number;
|
|
195
|
+
readonly from: {
|
|
196
|
+
readonly kind: "agent";
|
|
197
|
+
readonly agentId: string;
|
|
198
|
+
readonly sessionId: string;
|
|
199
|
+
};
|
|
190
200
|
readonly meta?: Schema.Json;
|
|
191
201
|
readonly reply?: {
|
|
192
202
|
readonly commandId: string;
|
|
193
203
|
readonly outcome: "completed" | "failed" | "cancelled" | "interrupted" | "outcome_unknown";
|
|
194
204
|
readonly diagnostic?: string;
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
205
|
+
readonly waitingOnYou?: readonly {
|
|
206
|
+
readonly itemId: string;
|
|
207
|
+
readonly kind: string;
|
|
208
|
+
readonly summary: string;
|
|
209
|
+
}[];
|
|
198
210
|
} | {
|
|
199
211
|
readonly outcome: "accepted";
|
|
200
212
|
readonly commandId: string;
|
|
213
|
+
} | {
|
|
214
|
+
readonly outcome: "undeliverable";
|
|
215
|
+
readonly reason: "recipient_left";
|
|
201
216
|
};
|
|
202
217
|
} | {
|
|
203
218
|
readonly key: string;
|
|
204
219
|
readonly reply: {
|
|
205
220
|
readonly outcome: "undeliverable";
|
|
206
|
-
readonly reason: "recipient_offline"
|
|
221
|
+
readonly reason: "recipient_offline";
|
|
207
222
|
};
|
|
208
223
|
readonly content: string;
|
|
209
|
-
readonly createdAt: number;
|
|
210
|
-
readonly from: {
|
|
211
|
-
readonly kind: "agent";
|
|
212
|
-
readonly agentId: string;
|
|
213
|
-
readonly sessionId?: string;
|
|
214
|
-
};
|
|
215
224
|
readonly to: {
|
|
216
|
-
readonly kind: "agent";
|
|
217
225
|
readonly agentId: string;
|
|
226
|
+
readonly kind: "agent";
|
|
218
227
|
readonly sessionId?: string;
|
|
219
228
|
};
|
|
220
229
|
readonly replyTo: readonly {
|
|
@@ -222,19 +231,18 @@ export declare function agentMailRoute(namespace: PostRoute<never, never>["names
|
|
|
222
231
|
readonly agentId: string;
|
|
223
232
|
readonly sessionId: string;
|
|
224
233
|
}[];
|
|
234
|
+
readonly createdAt: number;
|
|
235
|
+
readonly from: {
|
|
236
|
+
readonly kind: "system";
|
|
237
|
+
readonly systemId: "hub";
|
|
238
|
+
};
|
|
225
239
|
readonly meta?: Schema.Json;
|
|
226
240
|
}, {
|
|
227
241
|
readonly key: string;
|
|
228
242
|
readonly content: string;
|
|
229
|
-
readonly createdAt: number;
|
|
230
|
-
readonly from: {
|
|
231
|
-
readonly kind: "agent";
|
|
232
|
-
readonly agentId: string;
|
|
233
|
-
readonly sessionId: string;
|
|
234
|
-
};
|
|
235
243
|
readonly to: {
|
|
236
|
-
readonly kind: "agent";
|
|
237
244
|
readonly agentId: string;
|
|
245
|
+
readonly kind: "agent";
|
|
238
246
|
readonly sessionId?: string;
|
|
239
247
|
};
|
|
240
248
|
readonly replyTo: readonly {
|
|
@@ -242,34 +250,39 @@ export declare function agentMailRoute(namespace: PostRoute<never, never>["names
|
|
|
242
250
|
readonly agentId: string;
|
|
243
251
|
readonly sessionId: string;
|
|
244
252
|
}[];
|
|
253
|
+
readonly createdAt: number;
|
|
254
|
+
readonly from: {
|
|
255
|
+
readonly kind: "agent";
|
|
256
|
+
readonly agentId: string;
|
|
257
|
+
readonly sessionId: string;
|
|
258
|
+
};
|
|
245
259
|
readonly meta?: Schema.Json;
|
|
246
260
|
readonly reply?: {
|
|
247
261
|
readonly commandId: string;
|
|
248
262
|
readonly outcome: "completed" | "failed" | "cancelled" | "interrupted" | "outcome_unknown";
|
|
249
263
|
readonly diagnostic?: string;
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
264
|
+
readonly waitingOnYou?: readonly {
|
|
265
|
+
readonly itemId: string;
|
|
266
|
+
readonly kind: string;
|
|
267
|
+
readonly summary: string;
|
|
268
|
+
}[];
|
|
253
269
|
} | {
|
|
254
270
|
readonly outcome: "accepted";
|
|
255
271
|
readonly commandId: string;
|
|
272
|
+
} | {
|
|
273
|
+
readonly outcome: "undeliverable";
|
|
274
|
+
readonly reason: "recipient_left";
|
|
256
275
|
};
|
|
257
276
|
} | {
|
|
258
277
|
readonly key: string;
|
|
259
278
|
readonly reply: {
|
|
260
279
|
readonly outcome: "undeliverable";
|
|
261
|
-
readonly reason: "recipient_offline"
|
|
280
|
+
readonly reason: "recipient_offline";
|
|
262
281
|
};
|
|
263
282
|
readonly content: string;
|
|
264
|
-
readonly createdAt: number;
|
|
265
|
-
readonly from: {
|
|
266
|
-
readonly kind: "agent";
|
|
267
|
-
readonly agentId: string;
|
|
268
|
-
readonly sessionId?: string;
|
|
269
|
-
};
|
|
270
283
|
readonly to: {
|
|
271
|
-
readonly kind: "agent";
|
|
272
284
|
readonly agentId: string;
|
|
285
|
+
readonly kind: "agent";
|
|
273
286
|
readonly sessionId?: string;
|
|
274
287
|
};
|
|
275
288
|
readonly replyTo: readonly {
|
|
@@ -277,6 +290,11 @@ export declare function agentMailRoute(namespace: PostRoute<never, never>["names
|
|
|
277
290
|
readonly agentId: string;
|
|
278
291
|
readonly sessionId: string;
|
|
279
292
|
}[];
|
|
293
|
+
readonly createdAt: number;
|
|
294
|
+
readonly from: {
|
|
295
|
+
readonly kind: "system";
|
|
296
|
+
readonly systemId: "hub";
|
|
297
|
+
};
|
|
280
298
|
readonly meta?: Schema.Json;
|
|
281
299
|
}> & Omit<Readonly<{
|
|
282
300
|
addressKind: string;
|
|
@@ -295,7 +313,7 @@ export declare function agentMailRoute(namespace: PostRoute<never, never>["names
|
|
|
295
313
|
/** The host's one Post lane, as Agent mail borrows it. */
|
|
296
314
|
export type AgentMailPost = Pick<PostRuntime<{
|
|
297
315
|
agentMail: ReturnType<typeof agentMailRoute>;
|
|
298
|
-
}>, "send" | "read" | "nextWake">;
|
|
316
|
+
}>, "send" | "read" | "nextWake" | "deadLetters">;
|
|
299
317
|
/** Recipient-owned replies and receipt-bearing submissions over the host's one Post lane. */
|
|
300
318
|
export declare class AgentMail {
|
|
301
319
|
private readonly deps;
|
|
@@ -305,16 +323,21 @@ export declare class AgentMail {
|
|
|
305
323
|
identity: () => DelegationIdentity | null | Promise<DelegationIdentity | null>;
|
|
306
324
|
/** Only a typed disclosure refusal becomes undefined; missing settled facts must fail. */
|
|
307
325
|
replySettlement: AgentReplySettlement;
|
|
326
|
+
/** Route a terminal reply for this sender through its Fleet admission. */
|
|
327
|
+
onUndeliverable: (original: BirdDogMail, reply: BirdDogMail) => Promise<PostDeliveryResult>;
|
|
308
328
|
drain: () => Promise<void>;
|
|
309
329
|
wake: () => Promise<void>;
|
|
310
330
|
}>);
|
|
311
331
|
private envelope;
|
|
312
332
|
/** Submit one mail and return recipient acceptance or relay-held custody. */
|
|
313
333
|
send(mail: BirdDogMail): Promise<DelegationReceipt>;
|
|
334
|
+
/** Reconcile exhausted original outbox mail into one local system reply. */
|
|
335
|
+
stageUndeliverableReplies(): Promise<void>;
|
|
314
336
|
/** Stage the acceptance reply through this Post owner without leaving the transaction. */
|
|
315
337
|
stageAcceptedNotice(mail: BirdDogMail, scopeId: string): void;
|
|
316
338
|
/** BirdDog's mail room: disclosed settlement replies fan out over Post. */
|
|
317
339
|
mailRoom(): BirdDogEffect & {
|
|
340
|
+
/** Stage acceptance through this Post owner within the caller's transaction. */
|
|
318
341
|
stageAcceptedNotice: (mail: BirdDogMail, scopeId: string) => void;
|
|
319
342
|
};
|
|
320
343
|
}
|
package/dist/delegation.js
CHANGED
|
@@ -3,12 +3,13 @@
|
|
|
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, 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";
|
|
10
10
|
import * as Effect from "effect/Effect";
|
|
11
11
|
import { messageAuthor } from "@fungi.computer/agar/agents";
|
|
12
|
+
import { undeliverableReply } from "@fungi.computer/bird-dog";
|
|
12
13
|
import { PostEnvelopeSchema, definePostRoute, } from "@fungi.computer/carrier/post";
|
|
13
14
|
import { parseDelegationReceipt, } from "./client.js";
|
|
14
15
|
import { decodeClientSessionCreationRequest } from "./internal/client-boundary.js";
|
|
@@ -43,11 +44,11 @@ export class AgentDelegation {
|
|
|
43
44
|
!scope.agents.some(({ agentId }) => agentId === sender.agentId))
|
|
44
45
|
throw new AgentDisclosureRefused();
|
|
45
46
|
const facts = await host.readSettlement(sessionId, commandId);
|
|
46
|
-
if (facts !== undefined && facts
|
|
47
|
+
if (facts !== undefined && !settlementReadableBy(facts, sender.agentId))
|
|
47
48
|
throw new AgentDisclosureRefused();
|
|
48
49
|
return facts;
|
|
49
50
|
}
|
|
50
|
-
/** Delegate work to an in-scope Agent
|
|
51
|
+
/** Delegate work to an in-scope Agent through fleet correspondence; a steer rides the mail. */
|
|
51
52
|
async send(input, sourceSessionId, signal, invocation) {
|
|
52
53
|
if (invocation === undefined)
|
|
53
54
|
throw new Error("Delegation requires a tool invocation");
|
|
@@ -65,18 +66,6 @@ export class AgentDelegation {
|
|
|
65
66
|
requestId: input.requestId,
|
|
66
67
|
});
|
|
67
68
|
signal.throwIfAborted();
|
|
68
|
-
if (input.delivery === "steer") {
|
|
69
|
-
const opened = await this.deps.directory().open(input.agentId, signal);
|
|
70
|
-
try {
|
|
71
|
-
return await opened.agent.session(input.sessionId).send(input.text, {
|
|
72
|
-
requestId,
|
|
73
|
-
delivery: "steer",
|
|
74
|
-
});
|
|
75
|
-
}
|
|
76
|
-
finally {
|
|
77
|
-
await opened.release();
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
69
|
const provenance = await delegationProvenance({
|
|
81
70
|
agentId: scope.agentId,
|
|
82
71
|
sessionId: sourceSessionId,
|
|
@@ -92,6 +81,7 @@ export class AgentDelegation {
|
|
|
92
81
|
}, {
|
|
93
82
|
agentId: input.agentId,
|
|
94
83
|
sessionId: input.sessionId,
|
|
84
|
+
delivery: input.delivery,
|
|
95
85
|
text: input.text,
|
|
96
86
|
requestId,
|
|
97
87
|
});
|
|
@@ -135,8 +125,8 @@ export class AgentDelegation {
|
|
|
135
125
|
/**
|
|
136
126
|
* A reply-less envelope is only ever BirdDog's reply to work this Agent
|
|
137
127
|
* sent. Admit it only after the fleet authenticates it against that frozen
|
|
138
|
-
* mail
|
|
139
|
-
*
|
|
128
|
+
* mail. A recipient-left reply remains Agent-authored; a recipient-offline
|
|
129
|
+
* reply is Hub-authored. Its meta carries only the authenticated reply.
|
|
140
130
|
*/
|
|
141
131
|
async authenticatedReply(mail) {
|
|
142
132
|
const delegation = this.fleet().authenticateReply(mail);
|
|
@@ -173,19 +163,21 @@ export class AgentDelegation {
|
|
|
173
163
|
let authenticated;
|
|
174
164
|
const valid = async () => {
|
|
175
165
|
const scope = await this.scope(new AbortController().signal);
|
|
176
|
-
const
|
|
177
|
-
|
|
166
|
+
const sender = mail.from;
|
|
167
|
+
const authenticatedUndeliverable = authenticated?.reply.outcome === "undeliverable";
|
|
178
168
|
return (address.scopeId === scope.scopeId &&
|
|
179
169
|
address.agentId === scope.agentId &&
|
|
180
170
|
mail.to.agentId === scope.agentId &&
|
|
181
171
|
envelope.key === mail.key &&
|
|
182
|
-
(
|
|
183
|
-
|
|
172
|
+
(authenticatedUndeliverable ||
|
|
173
|
+
(sender.kind === "agent" &&
|
|
174
|
+
scope.agents.some(({ agentId }) => agentId === sender.agentId))) &&
|
|
184
175
|
mail.replyTo.every(({ agentId }) => scope.agents.some((agent) => agent.agentId === agentId)) &&
|
|
185
176
|
(mail.replyTo.length === 0 ||
|
|
186
177
|
(mail.replyTo.length === 1 &&
|
|
187
|
-
|
|
188
|
-
mail.replyTo[0]
|
|
178
|
+
sender.kind === "agent" &&
|
|
179
|
+
mail.replyTo[0]?.agentId === sender.agentId &&
|
|
180
|
+
mail.replyTo[0].sessionId === sender.sessionId)));
|
|
189
181
|
};
|
|
190
182
|
if (mail.replyTo.length === 0)
|
|
191
183
|
authenticated = await this.authenticatedReply(mail);
|
|
@@ -215,12 +207,37 @@ export class AgentDelegation {
|
|
|
215
207
|
this.deps.stageAcceptedNotice(notice, scopeId);
|
|
216
208
|
};
|
|
217
209
|
const receipt = await this.deps.accept(admitted.mail, admitted.reply, stageAcceptedNotice);
|
|
210
|
+
if (admitted.reply?.outcome === "undeliverable" &&
|
|
211
|
+
admitted.mail.from.kind === "system") {
|
|
212
|
+
this.fleet().recordUndeliverableReply(admitted.mail.key.slice(0, -":reply:0".length));
|
|
213
|
+
}
|
|
218
214
|
const sessionId = admitted.mail.to.sessionId ?? receipt.sessionId;
|
|
219
215
|
return {
|
|
220
216
|
status: "accepted",
|
|
221
217
|
receipt: sessionId === undefined ? receipt : { ...receipt, sessionId },
|
|
222
218
|
};
|
|
223
219
|
}
|
|
220
|
+
/** Admit local outbox exhaustion through the same Fleet/system reply gate. */
|
|
221
|
+
async localUndeliverable(original) {
|
|
222
|
+
const identity = await this.deps.identity();
|
|
223
|
+
if (identity === null)
|
|
224
|
+
return "refused";
|
|
225
|
+
let reply;
|
|
226
|
+
try {
|
|
227
|
+
reply = undeliverableReply(original, Date.now());
|
|
228
|
+
}
|
|
229
|
+
catch {
|
|
230
|
+
return "refused";
|
|
231
|
+
}
|
|
232
|
+
if (!this.fleet().recordLocalUndeliverable(original, reply))
|
|
233
|
+
return "refused";
|
|
234
|
+
return await this.receive({
|
|
235
|
+
key: reply.key,
|
|
236
|
+
kind: "agentMail",
|
|
237
|
+
address: { scopeId: identity.scopeId, agentId: identity.agentId },
|
|
238
|
+
event: reply,
|
|
239
|
+
});
|
|
240
|
+
}
|
|
224
241
|
}
|
|
225
242
|
/** A current correspondent no longer has disclosure authority. */
|
|
226
243
|
export class AgentDisclosureRefused extends Error {
|
|
@@ -284,6 +301,39 @@ export class AgentMail {
|
|
|
284
301
|
throw new Error(`Agent delivery ${row.reason}`);
|
|
285
302
|
throw new Error("Agent did not return a delegated work receipt");
|
|
286
303
|
}
|
|
304
|
+
/** Reconcile exhausted original outbox mail into one local system reply. */
|
|
305
|
+
async stageUndeliverableReplies() {
|
|
306
|
+
const identity = await this.deps.identity();
|
|
307
|
+
if (identity === null)
|
|
308
|
+
return;
|
|
309
|
+
const post = this.deps.post();
|
|
310
|
+
let cursor;
|
|
311
|
+
do {
|
|
312
|
+
const page = post.deadLetters(64, cursor);
|
|
313
|
+
for (const letter of page.letters) {
|
|
314
|
+
if (letter.reason !== "exhausted" ||
|
|
315
|
+
letter.envelope.kind !== "agentMail")
|
|
316
|
+
continue;
|
|
317
|
+
const envelope = Schema.decodeUnknownOption(PostEnvelopeSchema)(letter.envelope);
|
|
318
|
+
if (envelope._tag === "None" || envelope.value.kind !== "agentMail")
|
|
319
|
+
continue;
|
|
320
|
+
const original = Schema.decodeUnknownOption(BirdDogMailSchema)(envelope.value.event);
|
|
321
|
+
const address = Schema.decodeUnknownOption(agentMailAddressSchema)(envelope.value.address);
|
|
322
|
+
if (original._tag === "None" ||
|
|
323
|
+
address._tag === "None" ||
|
|
324
|
+
original.value.key !== envelope.value.key ||
|
|
325
|
+
original.value.reply !== undefined ||
|
|
326
|
+
original.value.from.kind !== "agent" ||
|
|
327
|
+
original.value.from.agentId !== identity.agentId ||
|
|
328
|
+
address.value.scopeId !== identity.scopeId ||
|
|
329
|
+
address.value.agentId !== original.value.to.agentId)
|
|
330
|
+
continue;
|
|
331
|
+
const reply = undeliverableReply(original.value, Date.now());
|
|
332
|
+
await this.deps.onUndeliverable(original.value, reply);
|
|
333
|
+
}
|
|
334
|
+
cursor = page.nextCursor;
|
|
335
|
+
} while (cursor !== undefined);
|
|
336
|
+
}
|
|
287
337
|
/** Stage the acceptance reply through this Post owner without leaving the transaction. */
|
|
288
338
|
stageAcceptedNotice(mail, scopeId) {
|
|
289
339
|
this.deps.post().send({
|
package/dist/effect.d.ts
CHANGED
|
@@ -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";
|