@fungi.computer/shiitake 0.0.0-stage → 0.1.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 (164) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +454 -2
  3. package/dist/agar-extension.d.ts +9 -0
  4. package/dist/agar-extension.js +38 -0
  5. package/dist/agent-control.d.ts +77 -0
  6. package/dist/agent-control.js +434 -0
  7. package/dist/client-entry.d.ts +211 -0
  8. package/dist/client-entry.js +101 -0
  9. package/dist/client-wire.d.ts +199 -0
  10. package/dist/client-wire.js +271 -0
  11. package/dist/client.d.ts +439 -0
  12. package/dist/client.js +4 -0
  13. package/dist/cloudflare.d.ts +220 -0
  14. package/dist/cloudflare.js +531 -0
  15. package/dist/effect.d.ts +42 -0
  16. package/dist/effect.js +20 -0
  17. package/dist/errors.d.ts +50 -0
  18. package/dist/errors.js +81 -0
  19. package/dist/extension-client.d.ts +38 -0
  20. package/dist/extension-client.js +56 -0
  21. package/dist/extension-contract.d.ts +73 -0
  22. package/dist/extension-contract.js +11 -0
  23. package/dist/extensions.d.ts +589 -0
  24. package/dist/extensions.js +263 -0
  25. package/dist/fleet.d.ts +313 -0
  26. package/dist/fleet.js +540 -0
  27. package/dist/hosted.d.ts +133 -0
  28. package/dist/hosted.js +265 -0
  29. package/dist/http-routes.d.ts +772 -0
  30. package/dist/http-routes.js +242 -0
  31. package/dist/http.d.ts +1 -0
  32. package/dist/http.js +1 -0
  33. package/dist/index.d.ts +35 -0
  34. package/dist/index.js +13 -0
  35. package/dist/internal/accepted-run-executor.d.ts +23 -0
  36. package/dist/internal/accepted-run-executor.js +129 -0
  37. package/dist/internal/admission-door.d.ts +75 -0
  38. package/dist/internal/admission-door.js +105 -0
  39. package/dist/internal/agent-close.d.ts +4 -0
  40. package/dist/internal/agent-close.js +42 -0
  41. package/dist/internal/browser-sessions.d.ts +31 -0
  42. package/dist/internal/browser-sessions.js +173 -0
  43. package/dist/internal/client-boundary.d.ts +262 -0
  44. package/dist/internal/client-boundary.js +202 -0
  45. package/dist/internal/compaction/compaction.d.ts +54 -0
  46. package/dist/internal/compaction/compaction.js +291 -0
  47. package/dist/internal/compaction/session-compaction.d.ts +69 -0
  48. package/dist/internal/compaction/session-compaction.js +330 -0
  49. package/dist/internal/compaction/settings.d.ts +11 -0
  50. package/dist/internal/compaction/settings.js +40 -0
  51. package/dist/internal/compaction/utils.d.ts +45 -0
  52. package/dist/internal/compaction/utils.js +319 -0
  53. package/dist/internal/contracts.d.ts +235 -0
  54. package/dist/internal/contracts.js +1 -0
  55. package/dist/internal/coordinator.d.ts +18 -0
  56. package/dist/internal/coordinator.js +362 -0
  57. package/dist/internal/document-codec.d.ts +11 -0
  58. package/dist/internal/document-codec.js +39 -0
  59. package/dist/internal/effect-client.d.ts +13 -0
  60. package/dist/internal/effect-client.js +102 -0
  61. package/dist/internal/effect-contracts.d.ts +236 -0
  62. package/dist/internal/effect-contracts.js +2 -0
  63. package/dist/internal/extension-command-registry.d.ts +11 -0
  64. package/dist/internal/extension-command-registry.js +29 -0
  65. package/dist/internal/extension-command-tools.d.ts +17 -0
  66. package/dist/internal/extension-command-tools.js +50 -0
  67. package/dist/internal/extension-context.d.ts +25 -0
  68. package/dist/internal/extension-context.js +35 -0
  69. package/dist/internal/extension-definitions.d.ts +5 -0
  70. package/dist/internal/extension-definitions.js +6 -0
  71. package/dist/internal/extension-hook.d.ts +25 -0
  72. package/dist/internal/extension-hook.js +46 -0
  73. package/dist/internal/extension-roster.d.ts +23 -0
  74. package/dist/internal/extension-roster.js +228 -0
  75. package/dist/internal/extension-runtime.d.ts +63 -0
  76. package/dist/internal/extension-runtime.js +1004 -0
  77. package/dist/internal/failure.d.ts +2 -0
  78. package/dist/internal/failure.js +9 -0
  79. package/dist/internal/host-meta.d.ts +41 -0
  80. package/dist/internal/host-meta.js +39 -0
  81. package/dist/internal/json-value.d.ts +4 -0
  82. package/dist/internal/json-value.js +3 -0
  83. package/dist/internal/model-acquisition.d.ts +21 -0
  84. package/dist/internal/model-acquisition.js +98 -0
  85. package/dist/internal/model-preference.d.ts +21 -0
  86. package/dist/internal/model-preference.js +20 -0
  87. package/dist/internal/observation-kernel.d.ts +28 -0
  88. package/dist/internal/observation-kernel.js +169 -0
  89. package/dist/internal/promise-facade.d.ts +18 -0
  90. package/dist/internal/promise-facade.js +172 -0
  91. package/dist/internal/run-scope.d.ts +27 -0
  92. package/dist/internal/run-scope.js +214 -0
  93. package/dist/internal/runtime-coordinator.d.ts +34 -0
  94. package/dist/internal/runtime-coordinator.js +233 -0
  95. package/dist/internal/runtime-core.d.ts +19 -0
  96. package/dist/internal/runtime-core.js +39 -0
  97. package/dist/internal/runtime-reconciliation.d.ts +18 -0
  98. package/dist/internal/runtime-reconciliation.js +162 -0
  99. package/dist/internal/session-context.d.ts +11 -0
  100. package/dist/internal/session-context.js +67 -0
  101. package/dist/internal/session-status.d.ts +10 -0
  102. package/dist/internal/session-status.js +52 -0
  103. package/dist/internal/woodstock/agent-reply.d.ts +25 -0
  104. package/dist/internal/woodstock/agent-reply.js +67 -0
  105. package/dist/internal/woodstock/client-projection.d.ts +29 -0
  106. package/dist/internal/woodstock/client-projection.js +512 -0
  107. package/dist/internal/woodstock/compaction-activity.d.ts +17 -0
  108. package/dist/internal/woodstock/compaction-activity.js +32 -0
  109. package/dist/internal/woodstock/cursor.d.ts +9 -0
  110. package/dist/internal/woodstock/cursor.js +44 -0
  111. package/dist/internal/woodstock/extension-store.d.ts +72 -0
  112. package/dist/internal/woodstock/extension-store.js +262 -0
  113. package/dist/internal/woodstock/fleet-store.d.ts +36 -0
  114. package/dist/internal/woodstock/fleet-store.js +100 -0
  115. package/dist/internal/woodstock/identities.d.ts +6 -0
  116. package/dist/internal/woodstock/identities.js +11 -0
  117. package/dist/internal/woodstock/index.d.ts +170 -0
  118. package/dist/internal/woodstock/index.js +546 -0
  119. package/dist/internal/woodstock/progress.d.ts +32 -0
  120. package/dist/internal/woodstock/progress.js +89 -0
  121. package/dist/internal/woodstock/run-recovery.d.ts +8 -0
  122. package/dist/internal/woodstock/run-recovery.js +95 -0
  123. package/dist/internal/woodstock/session-attention.d.ts +16 -0
  124. package/dist/internal/woodstock/session-attention.js +88 -0
  125. package/dist/internal/woodstock/session-documents.d.ts +18 -0
  126. package/dist/internal/woodstock/session-documents.js +51 -0
  127. package/dist/internal/woodstock/session-entry.d.ts +478 -0
  128. package/dist/internal/woodstock/session-entry.js +484 -0
  129. package/dist/internal/woodstock/session-grants.d.ts +24 -0
  130. package/dist/internal/woodstock/session-grants.js +84 -0
  131. package/dist/internal/woodstock/session-inbox.d.ts +56 -0
  132. package/dist/internal/woodstock/session-inbox.js +307 -0
  133. package/dist/internal/woodstock/session-store.d.ts +432 -0
  134. package/dist/internal/woodstock/session-store.js +2006 -0
  135. package/dist/internal/woodstock/storage-admission.d.ts +14 -0
  136. package/dist/internal/woodstock/storage-admission.js +44 -0
  137. package/dist/model-preference.d.ts +20 -0
  138. package/dist/model-preference.js +30 -0
  139. package/dist/node.d.ts +64 -0
  140. package/dist/node.js +256 -0
  141. package/dist/remote-client.d.ts +11 -0
  142. package/dist/remote-client.js +298 -0
  143. package/dist/session-attention.d.ts +35 -0
  144. package/dist/session-attention.js +22 -0
  145. package/dist/session-documents.d.ts +28 -0
  146. package/dist/session-documents.js +1 -0
  147. package/dist/testing.d.ts +54 -0
  148. package/dist/testing.js +215 -0
  149. package/docs/api/README.md +26 -0
  150. package/docs/api/agar-extension.md +40 -0
  151. package/docs/api/agent-control.md +151 -0
  152. package/docs/api/client-entry.md +344 -0
  153. package/docs/api/client.md +1112 -0
  154. package/docs/api/cloudflare.md +500 -0
  155. package/docs/api/effect.md +884 -0
  156. package/docs/api/extensions.md +2003 -0
  157. package/docs/api/fleet.md +734 -0
  158. package/docs/api/hosted.md +382 -0
  159. package/docs/api/http.md +111 -0
  160. package/docs/api/index.md +1116 -0
  161. package/docs/api/model-preference.md +151 -0
  162. package/docs/api/node.md +142 -0
  163. package/docs/api/testing.md +250 -0
  164. package/package.json +130 -3
@@ -0,0 +1,319 @@
1
+ import * as Schema from "effect/Schema";
2
+ const isString = Schema.is(Schema.String);
3
+ const COMPACTION_SUMMARY_PREFIX = `The conversation history before this point was compacted into the following summary:
4
+
5
+ <summary>
6
+ `;
7
+ const COMPACTION_SUMMARY_SUFFIX = `
8
+ </summary>`;
9
+ /** Pi's native compaction boundary projection, retained without a custom role. */
10
+ export function compactionSummaryMessage(summary, timestamp) {
11
+ return {
12
+ role: "user",
13
+ content: [
14
+ {
15
+ type: "text",
16
+ text: COMPACTION_SUMMARY_PREFIX + summary + COMPACTION_SUMMARY_SUFFIX,
17
+ },
18
+ ],
19
+ timestamp,
20
+ };
21
+ }
22
+ export function createFileOps() {
23
+ return { edited: new Set(), read: new Set(), written: new Set() };
24
+ }
25
+ export function extractFileOpsFromMessage(message, fileOps) {
26
+ if (message.role !== "assistant")
27
+ return;
28
+ for (const block of message.content) {
29
+ if (block.type !== "toolCall")
30
+ continue;
31
+ const path = block.arguments.path;
32
+ if (!isString(path))
33
+ continue;
34
+ if (block.name === "edit")
35
+ fileOps.edited.add(path);
36
+ if (block.name === "read")
37
+ fileOps.read.add(path);
38
+ if (block.name === "write")
39
+ fileOps.written.add(path);
40
+ }
41
+ }
42
+ export function computeFileLists(fileOps) {
43
+ const modified = new Set([...fileOps.edited, ...fileOps.written]);
44
+ return {
45
+ modifiedFiles: [...modified].sort(),
46
+ readFiles: [...fileOps.read].filter((file) => !modified.has(file)).sort(),
47
+ };
48
+ }
49
+ export function formatFileOperations(readFiles, modifiedFiles) {
50
+ const sections = [];
51
+ if (readFiles.length > 0)
52
+ sections.push(`<read-files>\n${readFiles.join("\n")}\n</read-files>`);
53
+ if (modifiedFiles.length > 0)
54
+ sections.push(`<modified-files>\n${modifiedFiles.join("\n")}\n</modified-files>`);
55
+ return sections.length === 0 ? "" : `\n\n${sections.join("\n\n")}`;
56
+ }
57
+ const TOOL_RESULT_MAX_CHARS = 2000;
58
+ function textContent(content) {
59
+ return content
60
+ .filter((part) => part.type === "text")
61
+ .map((part) => part.text ?? "")
62
+ .join("");
63
+ }
64
+ function truncateForSummary(text) {
65
+ if (text.length <= TOOL_RESULT_MAX_CHARS)
66
+ return text;
67
+ const remainingCharacters = String(text.length - TOOL_RESULT_MAX_CHARS);
68
+ return `${text.slice(0, TOOL_RESULT_MAX_CHARS)}\n\n[... ${remainingCharacters} more characters truncated]`;
69
+ }
70
+ /** Pi v0.84.4's summary serialization, retained as a separate walk. */
71
+ function serializeUserMessage(message) {
72
+ const content = isString(message.content)
73
+ ? message.content
74
+ : textContent(message.content);
75
+ return content ? `[User]: ${content}` : undefined;
76
+ }
77
+ function serializeAssistantMessage(message) {
78
+ const text = [];
79
+ const thinking = [];
80
+ const calls = [];
81
+ for (const block of message.content) {
82
+ if (block.type === "text")
83
+ text.push(block.text);
84
+ else if (block.type === "thinking")
85
+ thinking.push(block.thinking);
86
+ else {
87
+ const args = Object.entries(block.arguments)
88
+ .map(([key, value]) => `${key}=${JSON.stringify(value)}`)
89
+ .join(", ");
90
+ calls.push(`${block.name}(${args})`);
91
+ }
92
+ }
93
+ const parts = [];
94
+ if (thinking.length > 0)
95
+ parts.push(`[Assistant thinking]: ${thinking.join("\n")}`);
96
+ if (text.length > 0)
97
+ parts.push(`[Assistant]: ${text.join("\n")}`);
98
+ if (calls.length > 0)
99
+ parts.push(`[Assistant tool calls]: ${calls.join("; ")}`);
100
+ return parts;
101
+ }
102
+ function serializeToolResultMessage(message) {
103
+ const content = textContent(message.content);
104
+ return content ? `[Tool result]: ${truncateForSummary(content)}` : undefined;
105
+ }
106
+ export function serializeConversation(messages) {
107
+ const parts = [];
108
+ for (const message of messages) {
109
+ if (message.role === "system") {
110
+ const content = isString(message.content)
111
+ ? message.content
112
+ : textContent(message.content);
113
+ if (content)
114
+ parts.push(`[System]: ${content}`);
115
+ }
116
+ else if (message.role === "user") {
117
+ const serialized = serializeUserMessage(message);
118
+ if (serialized !== undefined)
119
+ parts.push(serialized);
120
+ }
121
+ else if (message.role === "assistant") {
122
+ parts.push(...serializeAssistantMessage(message));
123
+ }
124
+ else {
125
+ const serialized = serializeToolResultMessage(message);
126
+ if (serialized !== undefined)
127
+ parts.push(serialized);
128
+ }
129
+ }
130
+ return parts.join("\n\n");
131
+ }
132
+ const ESTIMATED_IMAGE_CHARS = 4800;
133
+ function estimateTextAndImageContentChars(content) {
134
+ if (isString(content))
135
+ return content.length;
136
+ return content.reduce((chars, block) => chars +
137
+ (block.type === "text"
138
+ ? (block.text?.length ?? 0)
139
+ : block.type === "image"
140
+ ? ESTIMATED_IMAGE_CHARS
141
+ : 0), 0);
142
+ }
143
+ /** Pi's chars/4 estimator, including its image and tool-call constants. */
144
+ export function estimateTokens(message) {
145
+ let chars = 0;
146
+ switch (message.role) {
147
+ case "system":
148
+ return Math.ceil(estimateTextAndImageContentChars(message.content) / 4);
149
+ case "user":
150
+ return Math.ceil(estimateTextAndImageContentChars(message.content) / 4);
151
+ case "assistant":
152
+ for (const block of message.content) {
153
+ if (block.type === "text")
154
+ chars += block.text.length;
155
+ else if (block.type === "thinking")
156
+ chars += block.thinking.length;
157
+ else
158
+ chars += block.name.length + JSON.stringify(block.arguments).length;
159
+ }
160
+ return Math.ceil(chars / 4);
161
+ case "toolResult":
162
+ return Math.ceil(estimateTextAndImageContentChars(message.content) / 4);
163
+ }
164
+ }
165
+ function calculateContextTokens(usage) {
166
+ return (usage.totalTokens ||
167
+ usage.input + usage.output + usage.cacheRead + usage.cacheWrite);
168
+ }
169
+ function validAssistantUsage(message) {
170
+ if (message.role !== "assistant")
171
+ return undefined;
172
+ if (message.stopReason === "aborted" || message.stopReason === "error")
173
+ return undefined;
174
+ return calculateContextTokens(message.usage) > 0 ? message.usage : undefined;
175
+ }
176
+ export function estimateContextTokens(messages) {
177
+ let index = null;
178
+ let usageTokens = 0;
179
+ for (let cursor = messages.length - 1; cursor >= 0; cursor -= 1) {
180
+ const message = messages[cursor];
181
+ if (message === undefined)
182
+ continue;
183
+ const usage = validAssistantUsage(message);
184
+ if (usage !== undefined) {
185
+ index = cursor;
186
+ usageTokens = calculateContextTokens(usage);
187
+ break;
188
+ }
189
+ }
190
+ if (index === null) {
191
+ const tokens = messages.reduce((sum, message) => sum + estimateTokens(message), 0);
192
+ return {
193
+ tokens,
194
+ usageTokens: 0,
195
+ trailingTokens: tokens,
196
+ lastUsageIndex: null,
197
+ };
198
+ }
199
+ const trailingTokens = messages
200
+ .slice(index + 1)
201
+ .reduce((sum, message) => sum + estimateTokens(message), 0);
202
+ return {
203
+ tokens: usageTokens + trailingTokens,
204
+ usageTokens,
205
+ trailingTokens,
206
+ lastUsageIndex: index,
207
+ };
208
+ }
209
+ export function shouldCompact(contextTokens, contextWindow, settings) {
210
+ if (!settings.enabled)
211
+ return false;
212
+ return contextTokens > contextWindow - settings.reserveTokens;
213
+ }
214
+ export const DEFAULT_COMPACTION_SETTINGS = {
215
+ enabled: true,
216
+ reserveTokens: 16384,
217
+ keepRecentTokens: 20000,
218
+ };
219
+ export const SUMMARIZATION_SYSTEM_PROMPT = `You are a context summarization assistant. Your task is to read a conversation between a user and an AI coding assistant, then produce a structured summary following the exact format specified.
220
+
221
+ Do NOT continue the conversation. Do NOT respond to any questions in the conversation. ONLY output the structured summary.`;
222
+ export const SUMMARIZATION_PROMPT = `The messages above are a conversation to summarize. Create a structured context checkpoint summary that another LLM will use to continue the work.
223
+
224
+ Use this EXACT format:
225
+
226
+ ## Goal
227
+ [What is the user trying to accomplish? Can be multiple items if the session covers different tasks.]
228
+
229
+ ## Constraints & Preferences
230
+ - [Any constraints, preferences, or requirements mentioned by user]
231
+ - [Or "(none)" if none were mentioned]
232
+
233
+ ## Progress
234
+ ### Done
235
+ - [x] [Completed tasks/changes]
236
+
237
+ ### In Progress
238
+ - [ ] [Current work]
239
+
240
+ ### Blocked
241
+ - [Issues preventing progress, if any]
242
+
243
+ ## Key Decisions
244
+ - **[Decision]**: [Brief rationale]
245
+
246
+ ## Next Steps
247
+ 1. [Ordered list of what should happen next]
248
+
249
+ ## Critical Context
250
+ - [Any data, examples, or references needed to continue]
251
+ - [Or "(none)" if not applicable]
252
+
253
+ Keep each section concise. Preserve exact file paths, function names, and error messages.`;
254
+ const UPDATE_SUMMARIZATION_INSTRUCTIONS = `Update the existing structured summary with new information. RULES:
255
+ - PRESERVE all existing information from the previous summary
256
+ - ADD new progress, decisions, and context from the new messages
257
+ - UPDATE the Progress section: move items from "In Progress" to "Done" when completed
258
+ - UPDATE "Next Steps" based on what was accomplished
259
+ - PRESERVE exact file paths, function names, and error messages
260
+ - If something is no longer relevant, you may remove it
261
+
262
+ Use this EXACT format:
263
+
264
+ ## Goal
265
+ [Preserve existing goals, add new ones if the task expanded]
266
+
267
+ ## Constraints & Preferences
268
+ - [Preserve existing, add new ones discovered]
269
+
270
+ ## Progress
271
+ ### Done
272
+ - [x] [Include previously done items AND newly completed items]
273
+
274
+ ### In Progress
275
+ - [ ] [Current work - update based on progress]
276
+
277
+ ### Blocked
278
+ - [Current blockers - remove if resolved]
279
+
280
+ ## Key Decisions
281
+ - **[Decision]**: [Brief rationale] (preserve all previous, add new)
282
+
283
+ ## Next Steps
284
+ 1. [Update based on current state]
285
+
286
+ ## Critical Context
287
+ - [Preserve important context, add new if needed]
288
+
289
+ Keep each section concise. Preserve exact file paths, function names, and error messages.`;
290
+ export const UPDATE_SUMMARIZATION_PROMPT = `The messages above are NEW conversation messages to incorporate into the existing summary provided in <previous-summary> tags.
291
+
292
+ ${UPDATE_SUMMARIZATION_INSTRUCTIONS}`;
293
+ // Pi 0.99.2's split-turn prompt (#9908): the earlier wording read as an
294
+ // instruction to reconstruct hidden messages, which some models refused.
295
+ export const TURN_PREFIX_SUMMARIZATION_PROMPT = `The messages above are earlier context from an ongoing conversation. Later messages are stored separately and do not need to be reconstructed.
296
+
297
+ Create a concise checkpoint of the user's request and the progress shown above. This checkpoint will be placed before the later messages so the conversation can continue with the necessary context.
298
+
299
+ ## Original Request
300
+ [What did the user ask for?]
301
+
302
+ ## Progress So Far
303
+ - [Key decisions and work completed in these messages]
304
+
305
+ ## Context Needed to Continue
306
+ - [Information from these messages needed to understand the later work]
307
+
308
+ Only summarize information explicitly present above. Do not infer or recreate later messages.`;
309
+ export function summaryFailure(response, label) {
310
+ if (response.stopReason === "error") {
311
+ const errorMessage = response.errorMessage;
312
+ return `${label} failed: ${errorMessage !== undefined && errorMessage.length > 0 ? errorMessage : "Unknown error"}`;
313
+ }
314
+ if (response.stopReason === "length")
315
+ return `${label} failed: generation hit the token cap and the summary is incomplete`;
316
+ return response.content.some((part) => part.type === "toolCall")
317
+ ? `${label} attempted to call a tool`
318
+ : undefined;
319
+ }
@@ -0,0 +1,235 @@
1
+ import type { HostMetaOptions } from "./host-meta.js";
2
+ import type { SessionTerminal, ShiitakeAgent } from "../client.js";
3
+ import type { GrantsDelivery, GrantsDeliveryResult } from "./woodstock/index.js";
4
+ import type { Json } from "../extensions.js";
5
+ import type { ExtensionRosterV0 } from "../extensions.js";
6
+ import type { Api, AssistantMessage, Model, MuleStreamFunction } from "@fungi.computer/mule/effect";
7
+ import type { AccessOptions, CapabilitySource, ExecutionOptions, ModuleRegistration, Sandbox } from "@fungi.computer/mycelium";
8
+ import type { ModelPreference } from "./model-preference.js";
9
+ import type { WatchdogSqliteValue, WatchdogSqliteRow, WatchdogSqliteOwner, WatchdogSqliteCursor } from "@fungi.computer/watchdog";
10
+ export { watchdogSqliteRowSchema as sqliteRowSchema } from "@fungi.computer/watchdog";
11
+ /** Native SQLite scalar and row grammar shared with the work queue owner. */
12
+ export type SqliteValue = WatchdogSqliteValue;
13
+ /** Raw row grammar shared by Woodstock and Watchdog. */
14
+ export type SqliteRow = WatchdogSqliteRow;
15
+ /** Native rows stay raw until the query's maintained schema decodes them. */
16
+ export type SqliteCursor = WatchdogSqliteCursor & Readonly<{
17
+ /** Return one raw row or throw when none exists. */
18
+ one: () => SqliteRow;
19
+ }>;
20
+ /** Synchronous SQL and transactions held by the surrounding runtime. */
21
+ export type SqliteOwner = Omit<WatchdogSqliteOwner, "sql"> & Readonly<{
22
+ /** Native synchronous SQL, returning raw rows for the query owner to decode. */
23
+ sql: Readonly<{
24
+ /** Execute a statement with SQLite scalar bindings. */
25
+ exec: (statement: string, ...bindings: SqliteValue[]) => SqliteCursor;
26
+ }>;
27
+ }>;
28
+ /** Acquired Pi model and optional explicit Pi stream function. */
29
+ export type ModelAcquisition = Readonly<{
30
+ /** Exact Pi model selected for this run. */
31
+ model: Model<Api>;
32
+ /** Optional explicit Pi stream function for custom providers and tests. */
33
+ stream?: MuleStreamFunction;
34
+ /** Provider's bounded Retry-After for a clean HTTP refusal, if reported. */
35
+ retryAfterMs?: (message: AssistantMessage) => number | undefined;
36
+ /** Release the acquired model resources. */
37
+ release: () => Promise<void>;
38
+ }>;
39
+ /** Deterministic host seam for model selection and ready egress. */
40
+ export type ModelSource = Readonly<{
41
+ /** Acquire one selection and its request-scoped egress. */
42
+ acquire: (input: Readonly<{
43
+ sessionId: string;
44
+ preference: ModelPreference | null;
45
+ signal: AbortSignal;
46
+ }>) => Promise<ModelAcquisition>;
47
+ /**
48
+ * Read the context window of the model a run would select now, without
49
+ * contacting the provider. Null when the model has none; a source without
50
+ * this reader leaves the window unknown.
51
+ */
52
+ describe?: (input: Readonly<{
53
+ sessionId: string;
54
+ preference: ModelPreference | null;
55
+ signal: AbortSignal;
56
+ }>) => Promise<ModelDescription>;
57
+ }>;
58
+ /** What a Session's footer may know about its selected model. */
59
+ export type ModelDescription = Readonly<{
60
+ contextWindow: number | null;
61
+ }>;
62
+ /** Immutable instruction snapshot captured for one run. */
63
+ export type InstructionSnapshot = Readonly<{
64
+ /** Revision of the captured instruction inputs. */
65
+ revision: string;
66
+ /** Bounded instruction text for one run. */
67
+ text: string;
68
+ /** Capability modules captured with this instruction snapshot. */
69
+ modules?: readonly ModuleRegistration[];
70
+ /** Release run-scoped host resources after the accepted run settles. */
71
+ release?: () => void;
72
+ }>;
73
+ /** Host seam for one bounded instruction snapshot. */
74
+ export type InstructionSource = Readonly<{
75
+ /** Load the session's bounded instruction snapshot. */
76
+ load: (input: Readonly<{
77
+ sessionId: string;
78
+ commandId: string;
79
+ signal: AbortSignal;
80
+ }>) => Promise<InstructionSnapshot>;
81
+ }>;
82
+ /** Mycelium construction inputs captured by the Shiitake-owned run scope. */
83
+ export type ToolSource = Readonly<{
84
+ /** Host-owned limit for one scoped tool invocation. */
85
+ execution?: ExecutionOptions;
86
+ /** Mycelium module descriptors visible in the run scope. */
87
+ modules?: readonly ModuleRegistration[];
88
+ /**
89
+ * Dynamic host capability projections acquired by Mycelium. Each run acquires
90
+ * them with its Session in `context.session`, so a host projects only what
91
+ * that Session is permitted to use.
92
+ */
93
+ sources?: readonly CapabilitySource[];
94
+ /** Sandbox used by the scoped capability surface. */
95
+ sandbox: Sandbox;
96
+ /**
97
+ * The Agent-wide access defaults for every tool of the run, as data. A
98
+ * Session's grants the host delivered with the owner's `grants.deliver` override
99
+ * the default key by key. Mycelium reads them at every call; Shiitake never
100
+ * interprets them. Absent is full access.
101
+ */
102
+ access?: ToolAccess;
103
+ }>;
104
+ /** Promise host for scheduling the opaque durable reconciler. */
105
+ export type RuntimePendingWork = Readonly<{
106
+ /** Immediate recovery work remains subject to the host's retry cadence. */
107
+ pending: boolean;
108
+ /** Earliest owner-supplied wall-clock candidate for the shared host wake. */
109
+ nextWakeAt: number | null;
110
+ }>;
111
+ /** Promise host for scheduling the opaque durable reconciler. */
112
+ export type RuntimeHost = Readonly<{
113
+ /** Bind the one repeatable zero-input reconciliation callback. */
114
+ bind: (input: Readonly<{
115
+ reconcile: () => Promise<void>;
116
+ pendingWork: () => Promise<RuntimePendingWork>;
117
+ }>) => Promise<Readonly<{
118
+ /** Commit owner mutations together with the host wake guarantee. No external I/O. */
119
+ commit: <A>(mutation: () => Promise<A>) => Promise<A>;
120
+ /** Request one later reconciliation without running it inline. */
121
+ requestWake: () => Promise<void>;
122
+ /** Stop callbacks and release the bound host registration. */
123
+ close: () => Promise<void>;
124
+ }>>;
125
+ }>;
126
+ /**
127
+ * A host's disk budget for owner storage, with the platform's own measure of
128
+ * it. Near the budget, Shiitake refuses new Sessions and new prompts with a
129
+ * typed `storage_pressure` error while admitted work finishes.
130
+ */
131
+ export type StorageBudget = Readonly<{
132
+ /**
133
+ * Bytes the owner database occupies now, read from the platform, such as
134
+ * Cloudflare's `ctx.storage.sql.databaseSize`.
135
+ */
136
+ usedBytes: () => number;
137
+ /** The host's budget for those bytes. */
138
+ budgetBytes: number;
139
+ }>;
140
+ /** One model's compaction token budgets; omitted fields fall back. */
141
+ export type CompactionBudget = Readonly<{
142
+ /** Tokens reserved for the model's response; compaction runs past window minus this. */
143
+ reserveTokens?: number;
144
+ /** Recent tokens kept verbatim instead of summarized. */
145
+ keepRecentTokens?: number;
146
+ }>;
147
+ /**
148
+ * Pi's compaction settings. Each budget resolves through the exact
149
+ * `provider/modelId` override, then the ordinary value, then Pi's default
150
+ * (16384 reserve, 20000 kept). `enabled` is global and governs automatic
151
+ * compaction only; a manual compaction always runs.
152
+ */
153
+ export type CompactionOptions = CompactionBudget & Readonly<{
154
+ enabled?: boolean;
155
+ /** Budgets keyed by exact, case-sensitive `provider/modelId`. */
156
+ modelOverrides?: Readonly<Record<string, CompactionBudget>>;
157
+ }>;
158
+ /** Validated immutable construction bag for the durable harness. */
159
+ export type ShiitakeOptions = Readonly<{
160
+ /**
161
+ * The schema of the opaque metadata this host attaches to prompts and
162
+ * operator lines. Shiitake checks, stores and returns it; it never reads it.
163
+ */
164
+ meta?: HostMetaOptions;
165
+ /** Native owner storage and synchronous transaction capability. */
166
+ store: SqliteOwner;
167
+ /** Disk budget for `store`; absent never refuses for storage pressure. */
168
+ storageBudget?: StorageBudget;
169
+ /** Compaction budgets; absent uses Pi's defaults for every model. */
170
+ compaction?: CompactionOptions;
171
+ /** Runtime host that schedules the opaque durable reconciler. */
172
+ runtime: RuntimeHost;
173
+ /** Host model source returning Pi's own model representation. */
174
+ model: ModelSource;
175
+ /** Host instruction snapshot seam. */
176
+ instructions: InstructionSource;
177
+ /** Scoped Mycelium construction inputs, omitted when no capabilities exist. */
178
+ tools?: ToolSource;
179
+ /**
180
+ * The host's explicit extension roster and grants. Required: a host with no
181
+ * extensions passes `{ roster: [], grants: [] }`.
182
+ */
183
+ extensions: ExtensionRosterV0;
184
+ }>;
185
+ /**
186
+ * A host's access data for its Agent's tools. Grants are keyed by module id;
187
+ * a module an extension built is granted by that extension's id. A missing id
188
+ * keeps full access, so a first-time host writes no permission code.
189
+ */
190
+ export type ToolAccess = Pick<AccessOptions,
191
+ /** The Agent-wide default; a Session's delivered grants override it. */
192
+ "grants"
193
+ /** Keys refused unless a delivery or the default names them: fail closed. */
194
+ | "required"
195
+ /** Ask a person to approve one `confirm` call; absent refuses those calls. */
196
+ | "confirm"
197
+ /** Operator-only observer of each refusal; never changes the decision. */
198
+ | "onRefused">;
199
+ /**
200
+ * The in-process owner of a durable harness. Only the host holds it, so only
201
+ * the host can write a Session's grants or attach metadata; no HTTP or
202
+ * remote client can.
203
+ */
204
+ export type ShiitakeOwnerAgent = ShiitakeAgent & Readonly<{
205
+ /** Each Session's delivered tool grants, read at every call. */
206
+ grants: Readonly<{
207
+ /**
208
+ * Store one versioned delivery of the host's decision, synchronously,
209
+ * so the very next tool call reads it. Versions never move back: an
210
+ * older one throws a conflict and writes nothing. The same version with
211
+ * other grants replaces them; an identical replay is `unchanged`.
212
+ */
213
+ deliver: (sessionId: string, delivery: GrantsDelivery) => GrantsDeliveryResult;
214
+ /** One Session's newest delivery; null when the host delivered none. */
215
+ read: (sessionId: string) => GrantsDelivery | null;
216
+ }>;
217
+ /**
218
+ * The same Agent whose prompts and operator lines carry `meta`, checked
219
+ * against the host's metadata schema and stored beside each message.
220
+ */
221
+ withMeta: (meta: Json) => ShiitakeAgent;
222
+ }>;
223
+ export type { GrantsDelivery, GrantsDeliveryResult, } from "./woodstock/index.js";
224
+ export type { HostMetaOptions, StandardHostMetaResult, StandardHostMetaSchema, } from "./host-meta.js";
225
+ /** Exact accepted-work facts, independent of the current Session branch or page. */
226
+ export type CommandSettlement = Readonly<{
227
+ /** Durable terminal and the command that ended the work's opaque metadata. */
228
+ terminal: SessionTerminal;
229
+ /** Last completed assistant text; cancelled work returns no answer. */
230
+ content: string;
231
+ /** Provider-native usage facts, retaining model identity without transcript content. */
232
+ usage: readonly Pick<AssistantMessage, "provider" | "model" | "usage">[];
233
+ /** Distinct tool-call intentions belonging to this exact work. */
234
+ toolCalls: number;
235
+ }>;
@@ -0,0 +1 @@
1
+ export { watchdogSqliteRowSchema as sqliteRowSchema } from "@fungi.computer/watchdog";
@@ -0,0 +1,18 @@
1
+ import type { BirdDogMail } from "@fungi.computer/bird-dog";
2
+ import type { VerifiedAgentReply } from "./woodstock/index.js";
3
+ import * as Effect from "effect/Effect";
4
+ import { ShiitakeError } from "../errors.js";
5
+ import type { Json } from "../extensions.js";
6
+ import type { ShiitakeEffectOwner, ShiitakeEffectOptions } from "./effect-contracts.js";
7
+ import type { RuntimeCoordinator } from "./runtime-coordinator.js";
8
+ /** Construct the Effect-native coordinator over the private owner modules. */
9
+ export declare function openCoordinator(options: ShiitakeEffectOptions, runtime: RuntimeCoordinator): ShiitakeEffectOwner;
10
+ /**
11
+ * Accept one addressed mail envelope; the door decodes it as a prompt. `reply`
12
+ * is the host's authentication of a delegated Agent's reply; only then does
13
+ * the model see the line inside the verified-reply tag.
14
+ */
15
+ export declare function acceptAddressedMail(runtime: RuntimeCoordinator, mail: BirdDogMail, meta?: Json, reply?: VerifiedAgentReply): Effect.Effect<Readonly<{
16
+ status: "accepted";
17
+ commandId: string;
18
+ }>, ShiitakeError, never>;