@fungi.computer/shiitake 0.6.0 → 0.8.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 +59 -21
- package/dist/agent-control.d.ts +1 -1
- package/dist/agent-control.js +40 -21
- package/dist/client-visitor.d.ts +2 -0
- package/dist/client-visitor.js +6 -1
- package/dist/client-wire.d.ts +4 -0
- package/dist/client-wire.js +26 -15
- package/dist/client.d.ts +23 -11
- package/dist/client.js +22 -0
- package/dist/cloudflare.d.ts +20 -0
- package/dist/cloudflare.js +4 -1
- package/dist/delegation.d.ts +5 -0
- package/dist/delegation.js +24 -8
- package/dist/effect.d.ts +1 -1
- package/dist/errors.d.ts +2 -2
- package/dist/errors.js +2 -0
- package/dist/extensions.d.ts +1 -1
- package/dist/fleet.d.ts +14 -2
- package/dist/fleet.js +81 -19
- package/dist/http-routes.d.ts +12 -16
- package/dist/http.d.ts +1 -0
- package/dist/http.js +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/internal/admission-door.d.ts +1 -1
- package/dist/internal/admission-door.js +8 -4
- package/dist/internal/contracts.d.ts +5 -0
- package/dist/internal/coordinator.js +107 -50
- package/dist/internal/effect-contracts.d.ts +5 -0
- package/dist/internal/extension-runtime.js +5 -3
- package/dist/internal/observation-kernel.js +12 -3
- package/dist/internal/promise-facade.js +2 -0
- package/dist/internal/run-scope.d.ts +1 -0
- package/dist/internal/run-scope.js +29 -7
- package/dist/internal/runtime-coordinator.d.ts +14 -0
- package/dist/internal/runtime-coordinator.js +57 -10
- package/dist/internal/runtime-core.d.ts +3 -0
- package/dist/internal/runtime-core.js +1 -0
- package/dist/internal/runtime-reconciliation.js +4 -1
- package/dist/internal/session-context.d.ts +5 -5
- package/dist/internal/session-context.js +80 -83
- package/dist/internal/session-status.d.ts +4 -2
- package/dist/internal/session-status.js +22 -4
- package/dist/internal/woodstock/client-projection.js +5 -11
- package/dist/internal/woodstock/fleet-store.d.ts +3 -2
- package/dist/internal/woodstock/fleet-store.js +24 -4
- package/dist/internal/woodstock/index.d.ts +3 -3
- package/dist/internal/woodstock/index.js +18 -7
- package/dist/internal/woodstock/progress.d.ts +13 -1
- package/dist/internal/woodstock/progress.js +130 -24
- package/dist/internal/woodstock/session-delegator.d.ts +2 -1
- package/dist/internal/woodstock/session-store.d.ts +14 -2
- package/dist/internal/woodstock/session-store.js +329 -66
- package/dist/node.js +11 -2
- package/dist/server-visitor-stream.js +33 -24
- package/dist/testing.d.ts +2 -0
- package/dist/testing.js +2 -0
- package/docs/api/agent-control.md +3 -2
- package/docs/api/client.md +79 -19
- package/docs/api/cloudflare.md +16 -0
- package/docs/api/delegation.md +84 -50
- package/docs/api/effect.md +85 -7
- package/docs/api/extensions.md +8 -8
- package/docs/api/fleet.md +118 -29
- package/docs/api/http.md +28 -0
- package/docs/api/index.md +39 -15
- package/docs/api/testing.md +20 -7
- package/package.json +5 -5
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. */
|
package/dist/extensions.d.ts
CHANGED
|
@@ -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
|
}
|
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;
|
|
@@ -196,6 +196,7 @@ export declare const agentDelegationTaskSchema: z.ZodLazy<z.ZodObject<{
|
|
|
196
196
|
followUp: "followUp";
|
|
197
197
|
steer: "steer";
|
|
198
198
|
}>>;
|
|
199
|
+
goal: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodLiteral<false>]>>;
|
|
199
200
|
text: z.ZodString;
|
|
200
201
|
}, z.core.$strict>>;
|
|
201
202
|
/** A caller reuses this task unchanged while polling Pending. */
|
|
@@ -271,6 +272,12 @@ export declare function delegationSendMeta(sender: Readonly<{
|
|
|
271
272
|
* while the verified reply retains the failed recipient's identity.
|
|
272
273
|
*/
|
|
273
274
|
export declare function delegationReplyMeta(delegation: AuthenticatedDelegationReply, replierName: string): DelegationReplyMeta;
|
|
275
|
+
/**
|
|
276
|
+
* Shape check for a one-way ancestor notice, not sender provenance. The Local
|
|
277
|
+
* mail receiver checks mesh membership before calling it. This addressed mail
|
|
278
|
+
* is still work and may steer the parent's running turn when admitted.
|
|
279
|
+
*/
|
|
280
|
+
export declare function isOneWayAncestorNotice(mail: BirdDogMail): boolean;
|
|
274
281
|
/**
|
|
275
282
|
* Delegated work an owner still waits on; `unreadable` says why its state
|
|
276
283
|
* could not be read, when it could not.
|
|
@@ -281,6 +288,11 @@ export type OutstandingDelegation = Readonly<{
|
|
|
281
288
|
commandId: string;
|
|
282
289
|
unreadable?: string;
|
|
283
290
|
}>;
|
|
291
|
+
/** Read confirmed sender receipts that have no locally observed settlement.
|
|
292
|
+
* Call inside the Agent owner's transaction that also changes archived state.
|
|
293
|
+
* Remote reads happen separately; an unobserved settlement remains busy.
|
|
294
|
+
*/
|
|
295
|
+
export declare function readOutstandingDelegationSync(storage: WatchdogSqliteOwner): OutstandingDelegation | undefined;
|
|
284
296
|
/**
|
|
285
297
|
* BirdDog submission and reply authentication. The durable row freezes
|
|
286
298
|
* correspondence before transport; an ambiguous delivery reuses that exact mail.
|
package/dist/fleet.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { commandSettlementSchema } from "./client-wire.js";
|
|
2
|
-
import { createFleetDirectoryStore, createFleetDelegationStore, } from "./internal/woodstock/index.js";
|
|
2
|
+
import { createFleetDirectoryStore, createFleetDelegationStore, readSessionDelegator, } from "./internal/woodstock/index.js";
|
|
3
3
|
import { pending } from "@fungi.computer/agar";
|
|
4
4
|
import { BirdDogMailSchema } from "@fungi.computer/bird-dog/effect";
|
|
5
5
|
import * as Schema from "effect/Schema";
|
|
@@ -280,17 +280,23 @@ export function settlementReadableBy(facts, agentId) {
|
|
|
280
280
|
(facts.acceptedSender === null && facts.delegator === agentId));
|
|
281
281
|
}
|
|
282
282
|
/** Replay identity and work, with the parent supplied exclusively by the grant. */
|
|
283
|
-
export const agentDelegationTaskSchema = z.lazy(() => z
|
|
283
|
+
export const agentDelegationTaskSchema = z.lazy(() => z
|
|
284
|
+
.strictObject({
|
|
284
285
|
requestId: identity,
|
|
285
286
|
agentId: identity,
|
|
286
287
|
sessionId: identity.optional(),
|
|
287
288
|
/** A live steer into the recipient's running turn; queued follow-up when omitted. */
|
|
288
289
|
delivery: z.enum(["followUp", "steer"]).optional(),
|
|
290
|
+
/** Only a new-Session follow-up carries goal intent. */
|
|
291
|
+
goal: z
|
|
292
|
+
.union([z.string().min(1).max(4_000), z.literal(false)])
|
|
293
|
+
.optional(),
|
|
289
294
|
text: z
|
|
290
295
|
.string()
|
|
291
296
|
.min(1)
|
|
292
297
|
.max(256 * 1024),
|
|
293
|
-
})
|
|
298
|
+
})
|
|
299
|
+
.refine(({ goal, sessionId, delivery }) => goal === undefined || (sessionId === undefined && delivery !== "steer"), { path: ["goal"], error: "goal requires a new-Session follow-up" }));
|
|
294
300
|
/**
|
|
295
301
|
* Provenance for one delegated send from the invoking Agent's Session. The
|
|
296
302
|
* model program's digest is frozen with the replay input, so a retried tool
|
|
@@ -355,6 +361,23 @@ export function delegationReplyMeta(delegation, replierName) {
|
|
|
355
361
|
const delegationMetadata = z.object({
|
|
356
362
|
delegation: FungiMessageMetaSchema.shape.delegation,
|
|
357
363
|
});
|
|
364
|
+
/**
|
|
365
|
+
* Shape check for a one-way ancestor notice, not sender provenance. The Local
|
|
366
|
+
* mail receiver checks mesh membership before calling it. This addressed mail
|
|
367
|
+
* is still work and may steer the parent's running turn when admitted.
|
|
368
|
+
*/
|
|
369
|
+
export function isOneWayAncestorNotice(mail) {
|
|
370
|
+
if (mail.reply !== undefined ||
|
|
371
|
+
mail.replyTo.length !== 0 ||
|
|
372
|
+
mail.from.kind !== "agent" ||
|
|
373
|
+
mail.to.sessionId === undefined)
|
|
374
|
+
return false;
|
|
375
|
+
const parsed = delegationMetadata.safeParse(mail.meta);
|
|
376
|
+
return (parsed.success &&
|
|
377
|
+
parsed.data.delegation !== undefined &&
|
|
378
|
+
parsed.data.delegation.ancestors.includes(mail.to.agentId) &&
|
|
379
|
+
parsed.data.delegation.ancestors.at(-1) === mail.from.agentId);
|
|
380
|
+
}
|
|
358
381
|
const delegationRowSchema = z.lazy(() => z.strictObject({
|
|
359
382
|
input: z.string(),
|
|
360
383
|
mail: z.string(),
|
|
@@ -375,6 +398,25 @@ function bindRecipientSession(mail, sessionId) {
|
|
|
375
398
|
to: { ...mail.to, sessionId },
|
|
376
399
|
};
|
|
377
400
|
}
|
|
401
|
+
/** Read confirmed sender receipts that have no locally observed settlement.
|
|
402
|
+
* Call inside the Agent owner's transaction that also changes archived state.
|
|
403
|
+
* Remote reads happen separately; an unobserved settlement remains busy.
|
|
404
|
+
*/
|
|
405
|
+
export function readOutstandingDelegationSync(storage) {
|
|
406
|
+
const raw = createFleetDelegationStore(storage).unsettled()[0];
|
|
407
|
+
if (raw === undefined)
|
|
408
|
+
return undefined;
|
|
409
|
+
const row = delegationRowSchema.parse(raw);
|
|
410
|
+
const mail = decodeMail(row.mail);
|
|
411
|
+
const sessionId = mail.to.sessionId;
|
|
412
|
+
if (sessionId === undefined)
|
|
413
|
+
throw new DirectoryError(503, "partial_init");
|
|
414
|
+
return {
|
|
415
|
+
agentId: mail.to.agentId,
|
|
416
|
+
sessionId,
|
|
417
|
+
commandId: parseAccepted(z.string().parse(row.receipt)).commandId,
|
|
418
|
+
};
|
|
419
|
+
}
|
|
378
420
|
/**
|
|
379
421
|
* BirdDog submission and reply authentication. The durable row freezes
|
|
380
422
|
* correspondence before transport; an ambiguous delivery reuses that exact mail.
|
|
@@ -402,13 +444,18 @@ export function createFleetCorrespondence(options) {
|
|
|
402
444
|
: undefined;
|
|
403
445
|
const ancestors = inherited?.ancestors ?? [];
|
|
404
446
|
const maxDepth = Math.min(grant.maxDepth ?? 8, inherited?.maxDepth ?? 8);
|
|
405
|
-
//
|
|
447
|
+
// A report to an ancestor is one-way: the parent handles the work but
|
|
448
|
+
// must not send its settlement back as a new prompt to the worker.
|
|
406
449
|
if (parent.agentId === task.agentId)
|
|
407
450
|
throw new AgentGrantError("delegation_loop");
|
|
408
451
|
if (ancestors.length >= maxDepth)
|
|
409
452
|
throw new AgentGrantError("delegation_depth");
|
|
410
453
|
const path = { ancestors: [...ancestors, parent.agentId], maxDepth };
|
|
411
|
-
const delegation =
|
|
454
|
+
const delegation = {
|
|
455
|
+
...path,
|
|
456
|
+
...(task.delivery === "steer" && { steer: true }),
|
|
457
|
+
...(task.goal !== undefined && { goal: task.goal }),
|
|
458
|
+
};
|
|
412
459
|
const outgoingMeta = {
|
|
413
460
|
...(objectMeta.success
|
|
414
461
|
? objectMeta.data
|
|
@@ -427,10 +474,20 @@ export function createFleetCorrespondence(options) {
|
|
|
427
474
|
let row = read(task.requestId);
|
|
428
475
|
if (row === undefined) {
|
|
429
476
|
const from = { kind: "agent", ...parent };
|
|
477
|
+
const ancestor = ancestors.includes(task.agentId);
|
|
478
|
+
// A sessionless report to a parent goes to the creator's recorded
|
|
479
|
+
// Session. Never create a fresh Session merely to carry a notice.
|
|
480
|
+
const targetSessionId = task.sessionId ??
|
|
481
|
+
(ancestor
|
|
482
|
+
? readSessionDelegator(options.storage, parent.sessionId)?.replyTo.find(({ agentId }) => agentId === task.agentId)
|
|
483
|
+
?.sessionId
|
|
484
|
+
: undefined);
|
|
485
|
+
if (ancestor && targetSessionId === undefined)
|
|
486
|
+
throw new AgentGrantError("delegator_missing");
|
|
430
487
|
let mail = {
|
|
431
488
|
key: task.requestId,
|
|
432
489
|
from,
|
|
433
|
-
to:
|
|
490
|
+
to: targetSessionId === undefined
|
|
434
491
|
? {
|
|
435
492
|
kind: "agent",
|
|
436
493
|
agentId: task.agentId,
|
|
@@ -438,9 +495,9 @@ export function createFleetCorrespondence(options) {
|
|
|
438
495
|
: {
|
|
439
496
|
kind: "agent",
|
|
440
497
|
agentId: task.agentId,
|
|
441
|
-
sessionId:
|
|
498
|
+
sessionId: targetSessionId,
|
|
442
499
|
},
|
|
443
|
-
replyTo: [from],
|
|
500
|
+
replyTo: ancestor ? [] : [from],
|
|
444
501
|
content: task.text,
|
|
445
502
|
createdAt: Date.now(),
|
|
446
503
|
};
|
|
@@ -677,6 +734,8 @@ export function createFleetDelegation(options) {
|
|
|
677
734
|
if (sessionId === undefined)
|
|
678
735
|
throw new DirectoryError(503, "partial_init");
|
|
679
736
|
const settlement = await options.readSettlement(mail.to.agentId, sessionId, accepted.commandId);
|
|
737
|
+
if (settlement !== undefined)
|
|
738
|
+
store.recordSettled(task.requestId);
|
|
680
739
|
return settlement === undefined
|
|
681
740
|
? pending(1000)
|
|
682
741
|
: {
|
|
@@ -691,7 +750,8 @@ export function createFleetDelegation(options) {
|
|
|
691
750
|
* target, so the owner is still waiting for a reply; undefined when none.
|
|
692
751
|
*/
|
|
693
752
|
async function outstanding() {
|
|
694
|
-
|
|
753
|
+
let waiting;
|
|
754
|
+
for (const raw of store.unsettled()) {
|
|
695
755
|
const row = delegationRowSchema.parse(raw);
|
|
696
756
|
if (row.receipt === null)
|
|
697
757
|
continue;
|
|
@@ -706,21 +766,23 @@ export function createFleetDelegation(options) {
|
|
|
706
766
|
sessionId: to.sessionId,
|
|
707
767
|
commandId,
|
|
708
768
|
};
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
settlement
|
|
712
|
-
|
|
713
|
-
catch (cause) {
|
|
769
|
+
const result = await options
|
|
770
|
+
.readSettlement(to.agentId, to.sessionId, commandId)
|
|
771
|
+
.then((settlement) => ({ kind: "read", settlement }), (cause) => ({ kind: "unreadable", cause }));
|
|
772
|
+
if (result.kind === "unreadable") {
|
|
714
773
|
// Work whose state cannot be read is still owed; say why.
|
|
715
|
-
|
|
774
|
+
waiting ??= {
|
|
716
775
|
...target,
|
|
717
|
-
unreadable: cause instanceof Error ? cause.message : "unreadable",
|
|
776
|
+
unreadable: result.cause instanceof Error ? result.cause.message : "unreadable",
|
|
718
777
|
};
|
|
778
|
+
continue;
|
|
719
779
|
}
|
|
720
|
-
if (settlement === undefined)
|
|
721
|
-
|
|
780
|
+
if (result.settlement === undefined)
|
|
781
|
+
waiting ??= target;
|
|
782
|
+
else
|
|
783
|
+
store.recordSettled(decodeMail(row.mail).key);
|
|
722
784
|
}
|
|
723
|
-
return
|
|
785
|
+
return waiting;
|
|
724
786
|
}
|
|
725
787
|
return {
|
|
726
788
|
/** The delegated work this owner still waits on, if any. */
|
package/dist/http-routes.d.ts
CHANGED
|
@@ -42,7 +42,7 @@ export declare function createShiitakeHttpRoutes(resolveSession: ShiitakeSession
|
|
|
42
42
|
};
|
|
43
43
|
};
|
|
44
44
|
output: {
|
|
45
|
-
readonly cause: "closed" | "conflict" | "incompatible" | "invalid" | "rejected" | "unavailable" | "state_reset_required" | "storage_pressure";
|
|
45
|
+
readonly cause: "closed" | "conflict" | "incompatible" | "invalid" | "rejected" | "unavailable" | "state_reset_required" | "storage_pressure" | "archived";
|
|
46
46
|
readonly _tag: "ShiitakeError";
|
|
47
47
|
readonly boundary: "contract" | "extensions" | "instructions" | "model" | "runtime" | "store" | "tools";
|
|
48
48
|
readonly message: string;
|
|
@@ -109,7 +109,7 @@ export declare function createShiitakeHttpRoutes(resolveSession: ShiitakeSession
|
|
|
109
109
|
};
|
|
110
110
|
};
|
|
111
111
|
output: {
|
|
112
|
-
readonly cause: "closed" | "conflict" | "incompatible" | "invalid" | "rejected" | "unavailable" | "state_reset_required" | "storage_pressure";
|
|
112
|
+
readonly cause: "closed" | "conflict" | "incompatible" | "invalid" | "rejected" | "unavailable" | "state_reset_required" | "storage_pressure" | "archived";
|
|
113
113
|
readonly _tag: "ShiitakeError";
|
|
114
114
|
readonly boundary: "contract" | "extensions" | "instructions" | "model" | "runtime" | "store" | "tools";
|
|
115
115
|
readonly message: string;
|
|
@@ -150,7 +150,7 @@ export declare function createShiitakeHttpRoutes(resolveSession: ShiitakeSession
|
|
|
150
150
|
$get: {
|
|
151
151
|
input: {};
|
|
152
152
|
output: {
|
|
153
|
-
readonly cause: "closed" | "conflict" | "incompatible" | "invalid" | "rejected" | "unavailable" | "state_reset_required" | "storage_pressure";
|
|
153
|
+
readonly cause: "closed" | "conflict" | "incompatible" | "invalid" | "rejected" | "unavailable" | "state_reset_required" | "storage_pressure" | "archived";
|
|
154
154
|
readonly _tag: "ShiitakeError";
|
|
155
155
|
readonly boundary: "contract" | "extensions" | "instructions" | "model" | "runtime" | "store" | "tools";
|
|
156
156
|
readonly message: string;
|
|
@@ -238,7 +238,7 @@ export declare function createShiitakeHttpRoutes(resolveSession: ShiitakeSession
|
|
|
238
238
|
};
|
|
239
239
|
};
|
|
240
240
|
output: {
|
|
241
|
-
readonly cause: "closed" | "conflict" | "incompatible" | "invalid" | "rejected" | "unavailable" | "state_reset_required" | "storage_pressure";
|
|
241
|
+
readonly cause: "closed" | "conflict" | "incompatible" | "invalid" | "rejected" | "unavailable" | "state_reset_required" | "storage_pressure" | "archived";
|
|
242
242
|
readonly _tag: "ShiitakeError";
|
|
243
243
|
readonly boundary: "contract" | "extensions" | "instructions" | "model" | "runtime" | "store" | "tools";
|
|
244
244
|
readonly message: string;
|
|
@@ -276,7 +276,7 @@ export declare function createShiitakeHttpRoutes(resolveSession: ShiitakeSession
|
|
|
276
276
|
};
|
|
277
277
|
};
|
|
278
278
|
output: {
|
|
279
|
-
readonly cause: "closed" | "conflict" | "incompatible" | "invalid" | "rejected" | "unavailable" | "state_reset_required" | "storage_pressure";
|
|
279
|
+
readonly cause: "closed" | "conflict" | "incompatible" | "invalid" | "rejected" | "unavailable" | "state_reset_required" | "storage_pressure" | "archived";
|
|
280
280
|
readonly _tag: "ShiitakeError";
|
|
281
281
|
readonly boundary: "contract" | "extensions" | "instructions" | "model" | "runtime" | "store" | "tools";
|
|
282
282
|
readonly message: string;
|
|
@@ -352,7 +352,7 @@ export declare function createShiitakeHttpRoutes(resolveSession: ShiitakeSession
|
|
|
352
352
|
};
|
|
353
353
|
};
|
|
354
354
|
output: {
|
|
355
|
-
readonly cause: "closed" | "conflict" | "incompatible" | "invalid" | "rejected" | "unavailable" | "state_reset_required" | "storage_pressure";
|
|
355
|
+
readonly cause: "closed" | "conflict" | "incompatible" | "invalid" | "rejected" | "unavailable" | "state_reset_required" | "storage_pressure" | "archived";
|
|
356
356
|
readonly _tag: "ShiitakeError";
|
|
357
357
|
readonly boundary: "contract" | "extensions" | "instructions" | "model" | "runtime" | "store" | "tools";
|
|
358
358
|
readonly message: string;
|
|
@@ -481,7 +481,7 @@ export declare function createShiitakeHttpRoutes(resolveSession: ShiitakeSession
|
|
|
481
481
|
};
|
|
482
482
|
};
|
|
483
483
|
output: {
|
|
484
|
-
readonly cause: "closed" | "conflict" | "incompatible" | "invalid" | "rejected" | "unavailable" | "state_reset_required" | "storage_pressure";
|
|
484
|
+
readonly cause: "closed" | "conflict" | "incompatible" | "invalid" | "rejected" | "unavailable" | "state_reset_required" | "storage_pressure" | "archived";
|
|
485
485
|
readonly _tag: "ShiitakeError";
|
|
486
486
|
readonly boundary: "contract" | "extensions" | "instructions" | "model" | "runtime" | "store" | "tools";
|
|
487
487
|
readonly message: string;
|
|
@@ -557,7 +557,7 @@ export declare function createShiitakeHttpRoutes(resolveSession: ShiitakeSession
|
|
|
557
557
|
};
|
|
558
558
|
};
|
|
559
559
|
output: {
|
|
560
|
-
readonly cause: "closed" | "conflict" | "incompatible" | "invalid" | "rejected" | "unavailable" | "state_reset_required" | "storage_pressure";
|
|
560
|
+
readonly cause: "closed" | "conflict" | "incompatible" | "invalid" | "rejected" | "unavailable" | "state_reset_required" | "storage_pressure" | "archived";
|
|
561
561
|
readonly _tag: "ShiitakeError";
|
|
562
562
|
readonly boundary: "contract" | "extensions" | "instructions" | "model" | "runtime" | "store" | "tools";
|
|
563
563
|
readonly message: string;
|
|
@@ -818,13 +818,7 @@ export declare function createShiitakeHttpRoutes(resolveSession: ShiitakeSession
|
|
|
818
818
|
readonly state: "queued";
|
|
819
819
|
readonly commandId: string;
|
|
820
820
|
readonly runningWork: {
|
|
821
|
-
readonly
|
|
822
|
-
readonly sessionId: string;
|
|
823
|
-
readonly commandId: string;
|
|
824
|
-
} | {
|
|
825
|
-
readonly kind: "host";
|
|
826
|
-
readonly lane: string;
|
|
827
|
-
readonly jobId: string;
|
|
821
|
+
readonly phase: "thinking" | "streaming" | "running_tool" | "waiting_on_you" | "cancelling";
|
|
828
822
|
} | null;
|
|
829
823
|
} | {
|
|
830
824
|
readonly state: "running";
|
|
@@ -849,6 +843,8 @@ export declare function createShiitakeHttpRoutes(resolveSession: ShiitakeSession
|
|
|
849
843
|
readonly revision: number;
|
|
850
844
|
readonly text: string;
|
|
851
845
|
readonly thinking: string;
|
|
846
|
+
readonly textOffset: number;
|
|
847
|
+
readonly thinkingOffset: number;
|
|
852
848
|
readonly textTruncated: boolean;
|
|
853
849
|
readonly thinkingTruncated: boolean;
|
|
854
850
|
} | null;
|
|
@@ -926,7 +922,7 @@ export declare function createShiitakeHttpRoutes(resolveSession: ShiitakeSession
|
|
|
926
922
|
};
|
|
927
923
|
};
|
|
928
924
|
output: {
|
|
929
|
-
readonly cause: "closed" | "conflict" | "incompatible" | "invalid" | "rejected" | "unavailable" | "state_reset_required" | "storage_pressure";
|
|
925
|
+
readonly cause: "closed" | "conflict" | "incompatible" | "invalid" | "rejected" | "unavailable" | "state_reset_required" | "storage_pressure" | "archived";
|
|
930
926
|
readonly _tag: "ShiitakeError";
|
|
931
927
|
readonly boundary: "contract" | "extensions" | "instructions" | "model" | "runtime" | "store" | "tools";
|
|
932
928
|
readonly message: string;
|
package/dist/http.d.ts
CHANGED
package/dist/http.js
CHANGED
package/dist/index.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ import type { VerifiedAgentReply } from "./internal/woodstock/index.js";
|
|
|
5
5
|
import type { BirdDogEffect } from "@fungi.computer/bird-dog/effect";
|
|
6
6
|
import type { Accepted } from "./client.js";
|
|
7
7
|
import type { ShiitakeOptions, ShiitakeOwnerAgent } from "./internal/contracts.js";
|
|
8
|
-
export type { AbortCommand, AgentExtensionControls, BranchCommand, CompactCommand, CancelCommand, CancelResult, Accepted, DelegationReceipt, Held, ForkCommand, ForkedSession, OperatorCommand, TitleCommand, PromptCommand, PromptDelivery, SendOptions, ReadOptions, SessionCommand, SessionCommandHandler, SessionExtensionControls, SessionExtensionSlots, SessionFrame, SessionMessage, SessionProgress, SessionToolOutput, SessionContext, SessionSnapshot, SessionInboxState, SessionSummary, SessionSummaryPage, SessionSummaryRow, SessionActivity, AgentRunningWork, SessionTerminal, SessionCompactionMarker, SessionCompactionNotice, SessionCompactionTrigger, ShiitakeEventSourceConstructor, SessionWatch, ShiitakeAgent, ShiitakeSession, SubscribeOptions, TooLate, UnknownRequest, WatchOptions, } from "./client.js";
|
|
8
|
+
export type { AbortCommand, AgentExtensionControls, BranchCommand, CompactCommand, CancelCommand, CancelResult, Accepted, DelegationReceipt, Held, ForkCommand, ForkedSession, OperatorCommand, TitleCommand, PromptCommand, PromptDelivery, SendOptions, ReadOptions, SessionCommand, SessionCommandHandler, SessionExtensionControls, SessionExtensionSlots, SessionFrame, SessionMessage, SessionProgress, SessionProgressDelta, SessionToolOutput, SessionContext, SessionSnapshot, SessionInboxState, SessionSummary, SessionSummaryPage, SessionSummaryRow, SessionActivity, AgentRunningWork, SessionTerminal, SessionCompactionMarker, SessionCompactionNotice, SessionCompactionTrigger, ShiitakeEventSourceConstructor, SessionWatch, ShiitakeAgent, ShiitakeSession, SubscribeOptions, TooLate, UnknownRequest, WatchOptions, } from "./client.js";
|
|
9
9
|
export type { ColdSessionPage, ColdSessionPageRequest, ColdSessionRow, } from "./cold-sessions.js";
|
|
10
10
|
export { parseForkedSession, parseSessionFrame, parseSessionSnapshot, } from "./client.js";
|
|
11
11
|
export type { InstructionSnapshot, InstructionSource, ModelAcquisition, ModelDescription, ModelSource, RuntimeHost, RuntimePendingWork, SqliteCursor, SqliteOwner, SqliteValue, SqliteRow, StoragePressureCheck, CompactionBudget, CompactionOptions, GrantsDelivery, GrantsDeliveryResult, ShiitakeOptions, ShiitakeOwnerAgent, ToolAccess, HostMetaOptions, StandardHostMetaResult, StandardHostMetaSchema, ToolSource, } from "./internal/contracts.js";
|
|
@@ -32,7 +32,7 @@ export type AdmitRequest = Readonly<{
|
|
|
32
32
|
* host passes it, after checking the reply against the mail it sent.
|
|
33
33
|
*/
|
|
34
34
|
reply?: VerifiedAgentReply;
|
|
35
|
-
/** Synchronous owner-local side effect
|
|
35
|
+
/** Synchronous owner-local side effect on first admission, in its transaction. */
|
|
36
36
|
onAccepted?: (sessionId: string, commandId: string) => void;
|
|
37
37
|
/**
|
|
38
38
|
* New work that continues earlier work in this Session (for example, the
|
|
@@ -5,7 +5,7 @@ import { checkHostMeta } from "./host-meta.js";
|
|
|
5
5
|
import { ShiitakeError } from "../errors.js";
|
|
6
6
|
import { decodeClientAcceptedCommand, decodeClientSessionId, decodeClientSessionCreationRequestId, requireDecoded, } from "./client-boundary.js";
|
|
7
7
|
import { publishOwnerObservation } from "./observation-kernel.js";
|
|
8
|
-
import { AdmissionOriginSchema, acceptSessionCommandOwned, readSessionCommandAdmissionByRequest, withdrawSessionRequestOwned, assertSessionRequestNotWithdrawn, hasStoredSession, readWorkSender, recordWorkSender,
|
|
8
|
+
import { AdmissionOriginSchema, acceptSessionCommandOwned, readSessionCommandAdmissionByRequest, withdrawSessionRequestOwned, assertSessionRequestNotWithdrawn, hasStoredSession, hasRecordedRunTerminal, readWorkSender, recordWorkSender, VerifiedAgentReplySchema, } from "./woodstock/index.js";
|
|
9
9
|
const decodeOrigin = Schema.decodeUnknownResult(AdmissionOriginSchema, {
|
|
10
10
|
onExcessProperty: "error",
|
|
11
11
|
});
|
|
@@ -87,7 +87,8 @@ export function openAdmissionDoor(input) {
|
|
|
87
87
|
const targetWorkId = command.type === "prompt" &&
|
|
88
88
|
command.delivery === "steer" &&
|
|
89
89
|
head.state === "running" &&
|
|
90
|
-
!head.cancellationRequested
|
|
90
|
+
!head.cancellationRequested &&
|
|
91
|
+
!hasRecordedRunTerminal(input.owner, sessionId, head.jobId)
|
|
91
92
|
? head.jobId
|
|
92
93
|
: undefined;
|
|
93
94
|
const accepted = acceptSessionCommandOwned(input.owner, sessionId, command, request.meta, origin, input.contract(), targetWorkId === undefined
|
|
@@ -100,8 +101,11 @@ export function openAdmissionDoor(input) {
|
|
|
100
101
|
if (sender !== undefined)
|
|
101
102
|
recordWorkSender(input.owner, sessionId, accepted.accepted.commandId, sender);
|
|
102
103
|
}
|
|
103
|
-
|
|
104
|
-
|
|
104
|
+
// The mail notice is staged in the same transaction as the first command.
|
|
105
|
+
// Replaying that admission must not stage a new notice with a different
|
|
106
|
+
// createdAt under the original Post key.
|
|
107
|
+
if (accepted.delivery === "new")
|
|
108
|
+
request.onAccepted?.(sessionId, accepted.accepted.commandId);
|
|
105
109
|
touched.set(sessionId, (touched.get(sessionId) ?? false) || accepted.delivery === "new");
|
|
106
110
|
return Object.freeze({
|
|
107
111
|
status: "accepted",
|
|
@@ -188,6 +188,11 @@ export type ShiitakeOptions = Readonly<{
|
|
|
188
188
|
store: SqliteOwner;
|
|
189
189
|
/** Host storage-pressure check; absent never refuses for storage pressure. */
|
|
190
190
|
storagePressure?: StoragePressureCheck;
|
|
191
|
+
/** Host-owned, synchronous admission for new Sessions and prompts only. */
|
|
192
|
+
admission?: Readonly<{
|
|
193
|
+
/** Check the host's current flag synchronously inside admission's transaction. */
|
|
194
|
+
assertOpen: () => void;
|
|
195
|
+
}>;
|
|
191
196
|
/** Compaction budgets; absent uses Pi's defaults for every model. */
|
|
192
197
|
compaction?: CompactionOptions;
|
|
193
198
|
/** Runtime host that schedules the opaque durable reconciler. */
|