@astrosheep/keiyaku 4.5.28 → 4.5.29

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 (97) hide show
  1. package/build/src/akuma/akuma-handle.d.ts +7 -0
  2. package/build/src/akuma/akuma-handle.js +19 -6
  3. package/build/src/akuma/akuma-instance.d.ts +0 -1
  4. package/build/src/akuma/akuma-instance.js +2 -4
  5. package/build/src/akuma/akuma-observe.js +0 -1
  6. package/build/src/akuma/akuma-product.d.ts +4 -8
  7. package/build/src/akuma/akuma-product.js +3 -20
  8. package/build/src/akuma/akuma.d.ts +0 -8
  9. package/build/src/akuma/akuma.js +0 -5
  10. package/build/src/akuma/archetype.d.ts +6 -6
  11. package/build/src/akuma/archetype.js +18 -28
  12. package/build/src/akuma/body.d.ts +4 -26
  13. package/build/src/akuma/body.js +18 -2
  14. package/build/src/akuma/call-initial-tell.d.ts +55 -0
  15. package/build/src/akuma/call-initial-tell.js +32 -0
  16. package/build/src/akuma/call-input.d.ts +0 -3
  17. package/build/src/akuma/call-input.js +0 -7
  18. package/build/src/akuma/call-request.d.ts +13 -10
  19. package/build/src/akuma/call-request.js +26 -14
  20. package/build/src/akuma/fleet-execution.d.ts +13 -1
  21. package/build/src/akuma/fleet-execution.js +67 -14
  22. package/build/src/akuma/fleet-observation.d.ts +26 -18
  23. package/build/src/akuma/fleet-observation.js +7 -1
  24. package/build/src/akuma/heart/facts.d.ts +2 -3
  25. package/build/src/akuma/heart/soul.js +1 -6
  26. package/build/src/akuma/projection-read.js +1 -2
  27. package/build/src/akuma/provider-recipe.d.ts +0 -10
  28. package/build/src/akuma/provider-recipe.js +0 -23
  29. package/build/src/akuma/provider.d.ts +1 -2
  30. package/build/src/akuma/providers/acp/index.js +0 -11
  31. package/build/src/akuma/providers/claude/index.js +2 -14
  32. package/build/src/akuma/providers/codex-app-server/index.js +0 -22
  33. package/build/src/akuma/providers/grok-build/index.js +0 -11
  34. package/build/src/akuma/providers/opencode-sdk/index.js +0 -10
  35. package/build/src/akuma/providers/pi/index.js +1 -5
  36. package/build/src/akuma/requests.d.ts +0 -1
  37. package/build/src/akuma/requests.js +0 -7
  38. package/build/src/akuma/turn-drive.d.ts +3 -0
  39. package/build/src/akuma/turn-drive.js +2 -2
  40. package/build/src/{library → cli}/catalog.d.ts +7 -30
  41. package/build/src/cli/catalog.js +1 -0
  42. package/build/src/cli/commands/akuma-invoke.d.ts +3 -3
  43. package/build/src/cli/commands/akuma-invoke.js +70 -97
  44. package/build/src/cli/commands/akuma.js +28 -21
  45. package/build/src/cli/commands/bind.js +4 -5
  46. package/build/src/cli/commands/contract-help.d.ts +21 -18
  47. package/build/src/cli/commands/contract-help.js +44 -84
  48. package/build/src/cli/commands/contract-invoke.js +6 -6
  49. package/build/src/cli/commands/contract.d.ts +1 -1
  50. package/build/src/cli/commands/contract.js +1 -6
  51. package/build/src/cli/commands/install.d.ts +1 -1
  52. package/build/src/cli/commands/install.js +1 -1
  53. package/build/src/cli/commands/nuke.js +2 -2
  54. package/build/src/cli/commands/task.js +48 -16
  55. package/build/src/cli/invoke.js +48 -11
  56. package/build/src/cli/parse.js +2 -0
  57. package/build/src/cli/render/akuma-activity.d.ts +42 -11
  58. package/build/src/cli/render/akuma-activity.js +307 -125
  59. package/build/src/cli/render/akuma-tool.d.ts +7 -1
  60. package/build/src/cli/render/akuma-tool.js +35 -23
  61. package/build/src/cli/render/akuma.d.ts +5 -9
  62. package/build/src/cli/render/akuma.js +68 -98
  63. package/build/src/cli/render/audit.js +2 -2
  64. package/build/src/cli/render/catalog.d.ts +1 -1
  65. package/build/src/cli/render/catalog.js +1 -0
  66. package/build/src/cli/render/contract.js +3 -3
  67. package/build/src/cli/render/kanshi.js +2 -2
  68. package/build/src/cli/render/receipt.js +4 -4
  69. package/build/src/cli/render/refusal.js +2 -2
  70. package/build/src/cli/render/settings.js +2 -2
  71. package/build/src/cli/render/task.js +2 -2
  72. package/build/src/cli/render/terminal.d.ts +5 -0
  73. package/build/src/cli/render/terminal.js +13 -0
  74. package/build/src/cli/result.d.ts +1 -1
  75. package/build/src/cli/runtime.js +10 -4
  76. package/build/src/cli/selectors.js +2 -2
  77. package/build/src/index.d.ts +1 -0
  78. package/build/src/index.js +1 -0
  79. package/build/src/library/akuma-creation.d.ts +28 -15
  80. package/build/src/library/akuma-creation.js +141 -107
  81. package/build/src/library/akumas.d.ts +42 -0
  82. package/build/src/library/akumas.js +61 -0
  83. package/build/src/library/composition.d.ts +14 -402
  84. package/build/src/library/composition.js +24 -25
  85. package/build/src/library/contract-handle.d.ts +7 -2
  86. package/build/src/library/contract-handle.js +14 -2
  87. package/build/src/library/contract-types.d.ts +9 -2
  88. package/build/src/library/contract.d.ts +8 -15
  89. package/build/src/library/contract.js +21 -39
  90. package/build/src/library/fleet.js +12 -12
  91. package/build/src/library/keiyaku.d.ts +8 -424
  92. package/build/src/library/keiyaku.js +3 -17
  93. package/build/src/runtime/proc/windows-launch.exe +0 -0
  94. package/package.json +5 -1
  95. package/build/src/akuma/akuma-product-symbols.d.ts +0 -1
  96. package/build/src/akuma/akuma-product-symbols.js +0 -1
  97. package/build/src/library/catalog.js +0 -130
@@ -1,3 +1,4 @@
1
+ import { type CallInitialTell, type CallInitialTellAdmission } from "./call-initial-tell.js";
1
2
  import { type TellResult, type TellWakeRuntime } from "./body.js";
2
3
  import { HeldAkumaLeash, type KillEvidence, type TellFact, type TurnOutcome } from "./heart/index.js";
3
4
  import { type AkuId, type AkumaPaths } from "./identity.js";
@@ -18,6 +19,7 @@ export type TellAdmission = Readonly<{
18
19
  tell: TellFact;
19
20
  wake: Promise<TellResult>;
20
21
  }>;
22
+ export type InitialTellAdmission = CallInitialTellAdmission;
21
23
  export type InterruptAdmission = Readonly<{
22
24
  kind: "unavailable";
23
25
  evidence: "hung" | "untidy" | "unavailable";
@@ -53,6 +55,10 @@ export declare class AkumaHandle {
53
55
  timeoutMs?: number;
54
56
  signal?: AbortSignal;
55
57
  }>): Promise<AkumaStatus>;
58
+ admitInitialTell(initialTell: CallInitialTell, options?: Readonly<{
59
+ signal?: AbortSignal;
60
+ runtime?: TellWakeRuntime;
61
+ }>): Promise<InitialTellAdmission>;
56
62
  tell(body: string, tellId?: string, recordedAt?: string, runtime?: TellWakeRuntime, options?: Readonly<{
57
63
  schemaJson?: string;
58
64
  initiator?: string;
@@ -82,6 +88,7 @@ export declare class AkumaHandle {
82
88
  }>): Promise<Readonly<{
83
89
  reason: WaitReason;
84
90
  outcome: TurnOutcome | null;
91
+ completedAt: string | null;
85
92
  }>>;
86
93
  private boundTellOutcome;
87
94
  interrupt(body: string, options?: Readonly<{
@@ -1,4 +1,5 @@
1
1
  import { randomUUID } from "node:crypto";
2
+ import { admitCallInitialTell } from "./call-initial-tell.js";
2
3
  import { handoffPendingTells, wakeRecordedTell } from "./body.js";
3
4
  import { HeldAkumaLeash, activitySlice, readForkPoint, readHeart, readKill, readLastAnsweredTurn, readSoul, readTell, readTurn, recordTell, requestPause, requestStop, projectTell, } from "./heart/index.js";
4
5
  import { acquireLeash } from "./control.js";
@@ -150,6 +151,15 @@ export class AkumaHandle {
150
151
  async wait(predicate = defaultWaitComplete, options = {}) {
151
152
  return (await this.waitReceipt(predicate, options)).status;
152
153
  }
154
+ async admitInitialTell(initialTell, options = {}) {
155
+ return await admitCallInitialTell({
156
+ world: this.worldPath,
157
+ id: this.id,
158
+ initialTell,
159
+ ...(options.signal === undefined ? {} : { signal: options.signal }),
160
+ wake: (tell) => wakeRecordedTell(this.paths, tell.id, options.runtime, options.signal),
161
+ });
162
+ }
153
163
  async tell(body, tellId = randomUUID(), recordedAt = new Date().toISOString(), runtime, options = {}) {
154
164
  const admitted = await this.admitTell(body, tellId, recordedAt, runtime, options);
155
165
  if (admitted.kind === "not-born")
@@ -212,17 +222,21 @@ export class AkumaHandle {
212
222
  if (options.observe !== undefined) {
213
223
  await options.observe(await bornLiveStatus(this.paths, this.id, { aperture: "monitoring", admittedTellId: tellId }));
214
224
  }
215
- return { outcome, terminalWithoutTurn: tell.state === "told" && tell.binding === undefined };
225
+ return { ...outcome, terminalWithoutTurn: tell.state === "told" && tell.binding === undefined };
216
226
  },
217
227
  complete: (observed) => observed.outcome !== null || observed.terminalWithoutTurn,
218
228
  });
219
- return { reason: waited.reason, outcome: waited.value.outcome };
229
+ return {
230
+ reason: waited.reason,
231
+ outcome: waited.value.outcome,
232
+ completedAt: waited.value.completedAt,
233
+ };
220
234
  }
221
235
  async boundTellOutcome(tell) {
222
236
  if (tell.binding === undefined)
223
- return null;
224
- const turn = await readTurn(this.paths, tell.binding.turnSequence);
225
- return turn?.end?.outcome ?? null;
237
+ return { outcome: null, completedAt: null };
238
+ const end = (await readTurn(this.paths, tell.binding.turnSequence))?.end;
239
+ return { outcome: end?.outcome ?? null, completedAt: end?.completedAt ?? null };
226
240
  }
227
241
  async interrupt(body, options = {}) {
228
242
  const admitted = await this.admitInterrupt(body, options);
@@ -331,7 +345,6 @@ export class AkumaHandle {
331
345
  ...(source.description === undefined ? {} : { description: source.description }),
332
346
  provider: source.provider,
333
347
  options: source.options,
334
- ...(source.readonly === undefined ? {} : { readonly: source.readonly }),
335
348
  allowed: source.allowed,
336
349
  cwd: source.cwd,
337
350
  origin: { kind: "fork", parent: this.id, at: input.at },
@@ -28,7 +28,6 @@ export type AkumaBirthInput = Readonly<{
28
28
  cwd?: string;
29
29
  home?: string;
30
30
  settings?: Settings;
31
- readonly?: true;
32
31
  allowed?: readonly AllowedAction[];
33
32
  }>;
34
33
  export type AkumaTellOptions<T> = Readonly<{
@@ -1,5 +1,5 @@
1
1
  import { randomUUID } from "node:crypto";
2
- import { callReadonly, canonicalBirthCwd } from "./call-input.js";
2
+ import { canonicalBirthCwd } from "./call-input.js";
3
3
  import { spawnAkumaBody } from "./body.js";
4
4
  import { decodeAllowedActions, unionAllowedActions } from "./allowed.js";
5
5
  import { AkumaDecodeError, AkumaProviderError } from "./akuma-errors.js";
@@ -98,8 +98,7 @@ export class Akuma {
98
98
  const name = archetype;
99
99
  const home = input.home === undefined ? {} : { home: input.home };
100
100
  const settings = input.settings ?? (await readSettings({ root: input.root, ...home }));
101
- const readonly = callReadonly(input.readonly, "Akuma birth readonly must be true");
102
- const loaded = await loadArchetype({ name, project: input.root, ...home, settings, ...readonly });
101
+ const loaded = await loadArchetype({ name, project: input.root, ...home, settings });
103
102
  const allowed = input.allowed === undefined
104
103
  ? loaded.allowed
105
104
  : unionAllowedActions(loaded.allowed, decodeAllowedActions(input.allowed, "Akuma birth allowed"));
@@ -115,7 +114,6 @@ export class Akuma {
115
114
  ...(loaded.description === undefined ? {} : { description: loaded.description }),
116
115
  provider: loaded.provider,
117
116
  options: loaded.options,
118
- ...(loaded.readonly === undefined ? {} : { readonly: loaded.readonly }),
119
117
  allowed,
120
118
  cwd,
121
119
  origin: { kind: "direct" },
@@ -77,7 +77,6 @@ export async function bornLiveStatus(paths, expected, input) {
77
77
  life: currentLife,
78
78
  cwd: soul.cwd,
79
79
  allowed: soul.allowed,
80
- ...(soul.readonly === undefined ? {} : { readonly: soul.readonly }),
81
80
  ...(resumeUnsupported ? { strandedReason: "resume-unsupported" } : {}),
82
81
  timeline: selected.snapshot,
83
82
  },
@@ -1,6 +1,6 @@
1
1
  import { AkumaHandle } from "./akuma-handle.js";
2
2
  import type { AkumaCallContext, AkumaCallInput, AkumaCompleteList, AkumaConfiguration, AkumaList, AkumaListInput } from "./akuma.js";
3
- import { CALL_WITH_CONTEXT } from "./akuma-product-symbols.js";
3
+ import type { CallInitialTell } from "./call-initial-tell.js";
4
4
  import type { WorldRoot } from "../world.js";
5
5
  import type { BodyLaunch } from "./body.js";
6
6
  import type { AllocatedAkuma } from "./identity.js";
@@ -9,6 +9,7 @@ type BornExecution = Readonly<{
9
9
  cwd: string;
10
10
  source: "input" | "caller" | "process" | "world";
11
11
  }>;
12
+ export type InitialCallTell = CallInitialTell;
12
13
  export type BornAkumaCall = Readonly<{
13
14
  kind: "born";
14
15
  allocated: AllocatedAkuma;
@@ -20,9 +21,6 @@ export type BornAkumaCall = Readonly<{
20
21
  kind: "direct";
21
22
  };
22
23
  }>;
23
- initialBody?: string;
24
- initiator?: string;
25
- initialSchemaJson?: string;
26
24
  execution: BornExecution;
27
25
  }>;
28
26
  export type RequestedAkumaCall = Readonly<{
@@ -32,8 +30,8 @@ export type RequestedAkumaCall = Readonly<{
32
30
  execution: BornExecution;
33
31
  }>;
34
32
  export type AkumaBornCall = BornAkumaCall | RequestedAkumaCall;
35
- type AkumaCallLaunchInput = Omit<AkumaCallInput, "body"> & Readonly<{
36
- body?: string;
33
+ type AkumaCallLaunchInput = Omit<AkumaCallInput, "body" | "schema"> & Readonly<{
34
+ initialTell: InitialCallTell;
37
35
  }>;
38
36
  export declare const PAGE_POOL_SIZE = 16;
39
37
  export declare function boundedMap<Value, Result>(values: readonly Value[], mapper: (value: Value) => Promise<Result>): Promise<readonly Result[]>;
@@ -46,12 +44,10 @@ declare class AkumaProduct {
46
44
  id: string;
47
45
  }>): AkumaHandle;
48
46
  listArchetypes(): Promise<readonly string[]>;
49
- invoke(input: AkumaCallLaunchInput): Promise<AkumaHandle>;
50
47
  admit(input: AkumaCallLaunchInput, context: AkumaCallContext): Promise<AkumaBornCall>;
51
48
  publish(born: AkumaBornCall, completion?: Readonly<{
52
49
  contractId?: string;
53
50
  }>, signal?: AbortSignal): Promise<AkumaHandle>;
54
- [CALL_WITH_CONTEXT](input: AkumaCallLaunchInput, context: AkumaCallContext): Promise<AkumaHandle>;
55
51
  listComplete(input?: Readonly<{
56
52
  archetype?: string;
57
53
  }>): Promise<AkumaCompleteList>;
@@ -2,8 +2,7 @@ import { randomUUID } from "node:crypto";
2
2
  import { readdir, stat } from "node:fs/promises";
3
3
  import { boundedListLimit, projectBoundedList } from "../bounded-list.js";
4
4
  import { AkumaHandle } from "./akuma-handle.js";
5
- import { CALL_WITH_CONTEXT } from "./akuma-product-symbols.js";
6
- import { callReadonly, canonicalBirthCwd } from "./call-input.js";
5
+ import { canonicalBirthCwd } from "./call-input.js";
7
6
  import { fleetListRow, readAkumaBirthCwd } from "./akuma-observe.js";
8
7
  import { akuIdFromDirectoryName, akumaPaths, akumaRunRoot, archetypeName, parseAkuId } from "./identity.js";
9
8
  import { loadArchetype, listArchetypes as readArchetypes } from "./archetype.js";
@@ -13,7 +12,6 @@ import { requestForwardedAkumaCall } from "./call-request.js";
13
12
  import { executionChannel } from "./requests.js";
14
13
  import { decodeAllowedActions, unionAllowedActions } from "./allowed.js";
15
14
  import { settings as readSettings } from "../settings.js";
16
- import { schemaJsonText } from "./schema.js";
17
15
  async function admitBodyRequest(input) {
18
16
  const cwd = input.call.cwd === undefined
19
17
  ? undefined
@@ -25,8 +23,7 @@ async function admitBodyRequest(input) {
25
23
  id: randomUUID(),
26
24
  world: input.path,
27
25
  archetype: input.name,
28
- ...(input.call.body === undefined ? {} : { body: input.call.body }),
29
- ...(input.call.initiator === undefined ? {} : { initiator: input.call.initiator }),
26
+ initialTell: input.call.initialTell,
30
27
  ...(cwd === undefined ? {} : { cwd }),
31
28
  recipe: input.recipe,
32
29
  ...(input.call.signal === undefined ? {} : { signal: input.call.signal }),
@@ -60,9 +57,6 @@ async function admitDirect(input) {
60
57
  cwd,
61
58
  origin: { kind: "direct" },
62
59
  },
63
- ...(input.call.body === undefined ? {} : { initialBody: input.call.body }),
64
- ...(input.call.initiator === undefined ? {} : { initiator: input.call.initiator }),
65
- ...(input.call.schema === undefined ? {} : { initialSchemaJson: schemaJsonText(input.call.schema) }),
66
60
  execution: {
67
61
  cwd,
68
62
  source: input.call.cwd !== undefined ? "input" : initiatorCwd === undefined ? "world" : "process",
@@ -183,15 +177,11 @@ class AkumaProduct {
183
177
  ...(this.configuration.home === undefined ? {} : { home: this.configuration.home }),
184
178
  });
185
179
  }
186
- async invoke(input) {
187
- return await this[CALL_WITH_CONTEXT](input, { initiatorCwd: process.cwd() });
188
- }
189
180
  async admit(input, context) {
190
- const readonly = callReadonly(input.readonly);
191
181
  const name = archetypeName(input.archetype);
192
182
  const home = this.configuration.home === undefined ? {} : { home: this.configuration.home };
193
183
  const settings = this.configuration.settings ?? (await readSettings({ root: this.path, ...home }));
194
- const archetype = await loadArchetype({ name, project: this.path, ...home, settings, ...readonly });
184
+ const archetype = await loadArchetype({ name, project: this.path, ...home, settings });
195
185
  const allowed = input.allowed === undefined
196
186
  ? archetype.allowed
197
187
  : unionAllowedActions(archetype.allowed, decodeAllowedActions(input.allowed, "Akuma call allowed"));
@@ -200,7 +190,6 @@ class AkumaProduct {
200
190
  ...(archetype.description === undefined ? {} : { description: archetype.description }),
201
191
  provider: archetype.provider,
202
192
  options: archetype.options,
203
- ...(archetype.readonly === undefined ? {} : { readonly: archetype.readonly }),
204
193
  allowed,
205
194
  });
206
195
  if (execution.kind === "body-request")
@@ -217,9 +206,6 @@ class AkumaProduct {
217
206
  launch: async (allocated) => await spawnAkumaBody({
218
207
  paths: allocated.paths,
219
208
  seed: born.seed,
220
- ...(born.initialBody === undefined ? {} : { initialBody: born.initialBody }),
221
- ...(born.initiator === undefined ? {} : { initiator: born.initiator }),
222
- ...(born.initialSchemaJson === undefined ? {} : { initialSchemaJson: born.initialSchemaJson }),
223
209
  ...(Object.keys(completion).length === 0 ? {} : { completion }),
224
210
  }),
225
211
  });
@@ -228,9 +214,6 @@ class AkumaProduct {
228
214
  source: born.execution.source,
229
215
  });
230
216
  }
231
- async [CALL_WITH_CONTEXT](input, context) {
232
- return await this.publish(await this.admit(input, context));
233
- }
234
217
  async listComplete(input = {}) {
235
218
  if (typeof input !== "object" || input === null || Array.isArray(input))
236
219
  throw new TypeError("Akuma complete list input must be an object");
@@ -51,12 +51,6 @@ export declare const akumaStatusSchema: z.ZodObject<{
51
51
  "contract.deliver": "contract.deliver";
52
52
  "contract.review": "contract.review";
53
53
  }>>, z.ZodTransform<import("./allowed.js").AllowedActions, ("task.add" | "task.addDocument" | "task.compose" | "task.done" | "task.drop" | "task.hold" | "task.resume" | "task.start" | "task.stop" | "task.update" | "akuma.call" | "akuma.kill" | "akuma.tell" | "contract.audit" | "contract.deliver" | "contract.review")[]>>;
54
- readonly: z.ZodOptional<z.ZodUnion<readonly [z.ZodObject<{
55
- enforcement: z.ZodLiteral<"native">;
56
- }, z.core.$strict>, z.ZodObject<{
57
- enforcement: z.ZodLiteral<"none">;
58
- diagnostic: z.ZodString;
59
- }, z.core.$strict>]>>;
60
54
  timeline: z.ZodUnion<readonly [z.ZodObject<{
61
55
  reportedChanges: z.ZodReadonly<z.ZodArray<z.ZodObject<{
62
56
  sequence: z.ZodNumber;
@@ -442,7 +436,6 @@ export type AkumaStatus = z.infer<typeof akumaStatusSchema>;
442
436
  export declare function parseAkumaStatus(value: unknown): AkumaStatus;
443
437
  export { defaultWaitComplete } from "./akuma-observe.js";
444
438
  export { withoutReportedChanges } from "./projection.js";
445
- export type { ReadonlyRestraint } from "./provider-recipe.js";
446
439
  export type * from "./projection.js";
447
440
  export type UnbornAkumaListRow = Readonly<{
448
441
  id: AkuId;
@@ -469,7 +462,6 @@ export type AkumaCallInput = Readonly<{
469
462
  archetype: string;
470
463
  body: string;
471
464
  cwd?: string;
472
- readonly?: true;
473
465
  allowed?: readonly AllowedAction[];
474
466
  schema?: Schema<unknown>;
475
467
  initiator?: string;
@@ -18,17 +18,12 @@ export const akumaIdSchema = z.string().transform((value, context) => {
18
18
  return z.NEVER;
19
19
  }
20
20
  });
21
- const readonlySchema = z.union([
22
- z.object({ enforcement: z.literal("native") }).strict(),
23
- z.object({ enforcement: z.literal("none"), diagnostic: z.string().refine((value) => value.trim() !== "") }).strict(),
24
- ]);
25
21
  export const akumaStatusSchema = z
26
22
  .object({
27
23
  id: akumaIdSchema,
28
24
  life: z.enum(["running", "asleep", "stranded", "hung", "untidy", "killed"]),
29
25
  cwd: z.string().optional(),
30
26
  allowed: allowedActionsSchema,
31
- readonly: readonlySchema.optional(),
32
27
  timeline: activitySnapshotSchema,
33
28
  strandedReason: z.literal("resume-unsupported").optional(),
34
29
  })
@@ -1,6 +1,7 @@
1
+ import { type BoundedList } from "../bounded-list.js";
1
2
  import type { Settings } from "../settings.js";
2
3
  import type { ProviderAdapter } from "./provider.js";
3
- import { type ProviderExecution, type ProviderOptions, type ReadonlyRestraint } from "./provider-recipe.js";
4
+ import { type ProviderExecution, type ProviderOptions } from "./provider-recipe.js";
4
5
  import { type AllowedActions } from "./allowed.js";
5
6
  type DecodedArchetype = Readonly<{
6
7
  name: string;
@@ -8,7 +9,6 @@ type DecodedArchetype = Readonly<{
8
9
  provider: string;
9
10
  description?: string;
10
11
  options: ProviderOptions;
11
- readonly?: true;
12
12
  allowed: AllowedActions;
13
13
  }>;
14
14
  export type ArchetypeCatalogRow = Readonly<{
@@ -19,9 +19,8 @@ export type ArchetypeCatalogRow = Readonly<{
19
19
  type ArchetypeDefinition = DecodedArchetype & Readonly<{
20
20
  adapter: ProviderAdapter;
21
21
  }>;
22
- type AdmittedArchetype = Omit<ArchetypeDefinition, "provider" | "readonly"> & Readonly<{
22
+ type AdmittedArchetype = Omit<ArchetypeDefinition, "provider"> & Readonly<{
23
23
  provider: ProviderExecution;
24
- readonly?: ReadonlyRestraint;
25
24
  }>;
26
25
  export declare class AkumaArchetypeError extends Error {
27
26
  readonly archetype: string;
@@ -35,12 +34,13 @@ type ArchetypeCoordinates = Readonly<{
35
34
  home?: string;
36
35
  }>;
37
36
  export declare function listArchetypes(input?: ArchetypeCoordinates): Promise<readonly string[]>;
38
- export declare function listArchetypeDefinitions(input?: ArchetypeCoordinates): Promise<readonly ArchetypeCatalogRow[]>;
37
+ export declare function listArchetypeDefinitions(input?: ArchetypeCoordinates & Readonly<{
38
+ limit?: number;
39
+ }>): Promise<BoundedList<ArchetypeCatalogRow>>;
39
40
  export declare function loadArchetype(input: Readonly<{
40
41
  name: string;
41
42
  project?: string;
42
43
  home?: string;
43
44
  settings: Settings;
44
- readonly?: true;
45
45
  }>): Promise<AdmittedArchetype>;
46
46
  export {};
@@ -2,6 +2,7 @@ import { readFile, readdir } from "node:fs/promises";
2
2
  import { homedir } from "node:os";
3
3
  import { join } from "node:path";
4
4
  import { parseDocument } from "yaml";
5
+ import { boundedListLimit } from "../bounded-list.js";
5
6
  import { archetypeName } from "./identity.js";
6
7
  import { decodeProviderOptions, decodeProviderRecipe, } from "./provider-recipe.js";
7
8
  import { resolveProviderExecution } from "./providers/index.js";
@@ -99,13 +100,6 @@ function archetypeEnum(values, key, allowed) {
99
100
  throw new TypeError(`Akuma ${key} must be one of ${allowed.join(", ")}`);
100
101
  return value;
101
102
  }
102
- function archetypeReadonly(values) {
103
- if (!("readonly" in values))
104
- return undefined;
105
- if (values.readonly !== true)
106
- throw new TypeError("Akuma readonly must be true");
107
- return true;
108
- }
109
103
  function parseArchetypeFrontmatter(markdown) {
110
104
  const lines = markdown.split(/\r?\n/u);
111
105
  if (lines[0]?.trim() !== "---")
@@ -126,13 +120,9 @@ function decodeArchetypeFields(values) {
126
120
  const provider = archetypeField(values, "provider");
127
121
  const baseValue = archetypeField(values, "base");
128
122
  const base = baseValue === undefined ? undefined : archetypeName(baseValue);
129
- if ("access" in values)
130
- throw new TypeError("Akuma access is not supported; use readonly: true");
131
123
  const model = archetypeField(values, "model");
132
124
  const effort = archetypeField(values, "effort");
133
- const readonly = archetypeReadonly(values);
134
125
  const network = archetypeEnum(values, "network", ["disabled", "enabled"]);
135
- const sandbox = archetypeEnum(values, "sandbox", ["full-access"]);
136
126
  const description = archetypeField(values, "description");
137
127
  const allowedPresent = "allowed" in values;
138
128
  const allowed = allowedPresent ? decodeAllowedActions(values.allowed) : undefined;
@@ -142,9 +132,7 @@ function decodeArchetypeFields(values) {
142
132
  ...(provider === undefined ? {} : { provider }),
143
133
  ...(model === undefined ? {} : { model }),
144
134
  ...(effort === undefined ? {} : { effort }),
145
- ...(readonly === undefined ? {} : { readonly }),
146
135
  ...(network === undefined ? {} : { network }),
147
- ...(sandbox === undefined ? {} : { sandbox }),
148
136
  ...(description === undefined ? {} : { description }),
149
137
  ...(allowed === undefined ? {} : { allowed }),
150
138
  allowedPresent,
@@ -168,7 +156,6 @@ function decodeArchetype(name, path, markdown) {
168
156
  ...(fields.model === undefined ? {} : { model: fields.model }),
169
157
  ...(fields.effort === undefined ? {} : { effort: fields.effort }),
170
158
  ...(fields.network === undefined ? {} : { network: fields.network }),
171
- ...(fields.sandbox === undefined ? {} : { sandbox: fields.sandbox }),
172
159
  ...(systemPrompt.length === 0
173
160
  ? {}
174
161
  : {
@@ -176,7 +163,6 @@ function decodeArchetype(name, path, markdown) {
176
163
  systemPromptMode: fields.systemPromptMode ?? "append",
177
164
  }),
178
165
  }),
179
- ...(fields.readonly === undefined ? {} : { readonly: fields.readonly }),
180
166
  ...(fields.allowed === undefined ? {} : { allowed: fields.allowed }),
181
167
  allowedPresent: fields.allowedPresent,
182
168
  });
@@ -197,7 +183,6 @@ function mergeArchetype(base, local) {
197
183
  : { description: base.description }
198
184
  : { description: local.description }),
199
185
  options,
200
- ...(local.readonly === true || base?.readonly === true ? { readonly: true } : {}),
201
186
  allowed,
202
187
  });
203
188
  }
@@ -242,7 +227,15 @@ async function resolveArchetype(name, input, source, chain = []) {
242
227
  export async function listArchetypeDefinitions(input = {}) {
243
228
  // Reads still run concurrently, but the reported failure is the first invalid
244
229
  // definition in catalog byte order, not whichever read happened to finish first.
245
- const settled = await Promise.allSettled((await archetypePaths(input)).map(async ({ name, path }) => {
230
+ const limit = input.limit === undefined ? undefined : boundedListLimit(input.limit);
231
+ const all = await archetypePaths(input);
232
+ const selected = limit === undefined
233
+ ? { paths: all, hasMore: false }
234
+ : (() => {
235
+ const paths = all.slice(0, limit + 1);
236
+ return { paths: paths.slice(0, limit), hasMore: paths.length > limit };
237
+ })();
238
+ const settled = await Promise.allSettled(selected.paths.map(async ({ name, path }) => {
246
239
  try {
247
240
  const definition = await resolveArchetype(name, input, undefined);
248
241
  return Object.freeze({
@@ -260,7 +253,10 @@ export async function listArchetypeDefinitions(input = {}) {
260
253
  const firstInvalid = settled.find((result) => result.status === "rejected");
261
254
  if (firstInvalid !== undefined)
262
255
  throw firstInvalid.reason;
263
- return settled.map((result) => result.value);
256
+ return {
257
+ rows: settled.map((result) => result.value),
258
+ hasMore: selected.hasMore,
259
+ };
264
260
  }
265
261
  function record(value) {
266
262
  return value !== null && typeof value === "object" && !Array.isArray(value)
@@ -314,7 +310,7 @@ function providerExecution(settings, name) {
314
310
  return decodeProviderRecipe({ name, ...builtin });
315
311
  throw new TypeError(`unknown provider ${name}`);
316
312
  }
317
- async function admitArchetype(archetype, settings, callReadonly) {
313
+ async function admitArchetype(archetype, settings) {
318
314
  let selected;
319
315
  try {
320
316
  selected = await resolveProviderExecution(providerExecution(settings, archetype.provider));
@@ -326,25 +322,19 @@ async function admitArchetype(archetype, settings, callReadonly) {
326
322
  }
327
323
  const execution = selected.execution;
328
324
  const adapter = selected.adapter;
329
- const effectiveReadonly = archetype.readonly === true || callReadonly === true;
330
- const admission = adapter.admitOptions({
331
- ...archetype.options,
332
- ...(effectiveReadonly ? { readonly: true } : {}),
333
- });
325
+ const admission = adapter.admitOptions(archetype.options);
334
326
  if (admission.kind === "refused") {
335
327
  throw new AkumaArchetypeError(archetype.name, [archetype.path], `is unsupported: ${admission.diagnostic}`);
336
328
  }
337
- const { readonly: _readonly, ...definition } = archetype;
338
329
  return Object.freeze({
339
- ...definition,
330
+ ...archetype,
340
331
  provider: execution,
341
332
  adapter,
342
333
  options: admission.options,
343
- ...(admission.readonly === undefined ? {} : { readonly: admission.readonly }),
344
334
  });
345
335
  }
346
336
  export async function loadArchetype(input) {
347
337
  const name = archetypeName(input.name);
348
338
  const definition = await resolveArchetype(name, input, undefined);
349
- return await admitArchetype(definition, input.settings, input.readonly);
339
+ return await admitArchetype(definition, input.settings);
350
340
  }
@@ -1,10 +1,12 @@
1
1
  import type { AkumaCallRequestChildLaunch } from "./call-request.js";
2
- import { type SessionFact, type Soul, type TellRow } from "./heart/index.js";
2
+ import { type SessionFact, type Soul } from "./heart/index.js";
3
3
  import { type AkumaPaths } from "./identity.js";
4
+ import { type TellResult } from "./call-initial-tell.js";
5
+ export type { TellResult, TellWake } from "./call-initial-tell.js";
4
6
  import { type WorldRoot } from "../world.js";
5
7
  import type { ProviderAdapter } from "./provider.js";
6
8
  import type { ErasedRequestCommand } from "./request-wire.js";
7
- import { type OwnedProcess, type RunLogReference } from "../runtime/proc/run.js";
9
+ import { type OwnedProcess } from "../runtime/proc/run.js";
8
10
  export declare const LEASH_HELD_EXIT = 75;
9
11
  export { CONTROL_RESPONSE_MS } from "./body-supervisor.js";
10
12
  export type BodyLaunch = Readonly<{
@@ -19,30 +21,6 @@ export type BodyLaunch = Readonly<{
19
21
  contractId?: string;
20
22
  }>;
21
23
  }>;
22
- export type TellWake = Readonly<{
23
- kind: "told";
24
- }> | Readonly<{
25
- kind: "pursuing";
26
- bodySequence: number;
27
- }> | Readonly<{
28
- kind: "held";
29
- }> | Readonly<{
30
- kind: "failed";
31
- diagnostic: string;
32
- child?: Readonly<{
33
- code: number | null;
34
- signal: string | null;
35
- log: RunLogReference;
36
- }>;
37
- }>;
38
- export type TellResult = Readonly<{
39
- admission: Readonly<{
40
- tellId: string;
41
- fact: "recorded";
42
- }>;
43
- row: TellRow;
44
- wake: TellWake;
45
- }>;
46
24
  export type TellWakeRuntime = Readonly<{
47
25
  spawn(paths: AkumaPaths): Promise<OwnedProcess>;
48
26
  schedule?(milliseconds: number, signal: AbortSignal): Promise<void>;
@@ -5,13 +5,14 @@ import { abortable, abortableDelay } from "./abort.js";
5
5
  import { BodySupervisor } from "./body-supervisor.js";
6
6
  import { driveTurn, turnRecipe } from "./turn-drive.js";
7
7
  import { HeldAkumaLeash, breakBody, decidePendingTellDisposition, drainPendingTells, endTurn, failOpenBoundTurns, finishBodyIfIdle, heartExists, isHeartAbsent, probeLeash, projectTell, readHeart, readLatestTurnForBody, readOpenBoundTurns, readOpenPendingTellDisposition, readTell, readTurn, readNonterminalRequests, resolvePendingTellDisposition, } from "./heart/index.js";
8
- import { worldRootForAkumaPaths } from "./identity.js";
8
+ import { pathsForAkuId, worldRootForAkumaPaths } from "./identity.js";
9
+ import { admitCallInitialTell, } from "./call-initial-tell.js";
9
10
  import { akumaExecutionEnvironment } from "./providers/execution-environment.js";
10
11
  import { pluginRuntime } from "../plugin/runtime.js";
11
12
  import { World } from "../world.js";
12
13
  import { resolveProviderExecution } from "./providers/index.js";
13
14
  import { clearBodyRequestTransport, settleBodyRequests } from "./request-serve.js";
14
- import { spawnDetachedProcess, } from "../runtime/proc/run.js";
15
+ import { spawnDetachedProcess } from "../runtime/proc/run.js";
15
16
  const LEASH_RETRY_MS = 100;
16
17
  const WAKE_REREAD_MS = 100;
17
18
  export const LEASH_HELD_EXIT = 75;
@@ -344,6 +345,20 @@ function bodyEndEmitter(launch, soul) {
344
345
  }
345
346
  })();
346
347
  }
348
+ async function admitInitialCallTell(runtime, input) {
349
+ const paths = pathsForAkuId(runtime.world, input.id);
350
+ return await admitCallInitialTell({
351
+ world: runtime.world,
352
+ id: input.id,
353
+ initialTell: input.initialTell,
354
+ signal: input.signal,
355
+ now: runtime.now,
356
+ wake: async (tell) => await wakeRecordedTell(paths, tell.id, {
357
+ spawn: async (tellPaths) => await (runtime.spawnBody ?? spawnAkumaBody)({ paths: tellPaths, refuseIfHeld: true }),
358
+ schedule: abortableDelay,
359
+ }, input.signal),
360
+ });
361
+ }
347
362
  async function runBodyTurns(input) {
348
363
  const { launch, soul, adapter, bodySequence, supervisor, runtime, turnOutcome } = input;
349
364
  let initial = launch.initialBody;
@@ -371,6 +386,7 @@ async function runBodyTurns(input) {
371
386
  bodySequence,
372
387
  supervisor,
373
388
  runtimeSpawn: runtime.spawnChild ?? spawnAkumaBody,
389
+ admitInitialTell: async (admission) => await admitInitialCallTell(runtime, admission),
374
390
  body: initial ?? "",
375
391
  ...(initial === undefined ? {} : { call: initial }),
376
392
  ...(launch.initiator === undefined ? {} : { initiator: launch.initiator }),
@@ -0,0 +1,55 @@
1
+ import { type TellFact, type TellRow } from "./heart/index.js";
2
+ import { type AkuId } from "./identity.js";
3
+ import type { WorldRoot } from "../world.js";
4
+ export type CallInitialTell = Readonly<{
5
+ tellId: string;
6
+ body: string;
7
+ schemaJson?: string;
8
+ initiator?: string;
9
+ }>;
10
+ export type TellWake = Readonly<{
11
+ kind: "told";
12
+ }> | Readonly<{
13
+ kind: "pursuing";
14
+ bodySequence: number;
15
+ }> | Readonly<{
16
+ kind: "held";
17
+ }> | Readonly<{
18
+ kind: "failed";
19
+ diagnostic: string;
20
+ child?: Readonly<{
21
+ code: number | null;
22
+ signal: string | null;
23
+ log: Readonly<{
24
+ path: string;
25
+ from: number;
26
+ to: number;
27
+ }>;
28
+ }>;
29
+ }>;
30
+ export type TellResult = Readonly<{
31
+ admission: Readonly<{
32
+ tellId: string;
33
+ fact: "recorded";
34
+ }>;
35
+ row: TellRow;
36
+ wake: TellWake;
37
+ }>;
38
+ export type CallInitialTellAdmission = Readonly<{
39
+ kind: "admitted";
40
+ tell: TellFact;
41
+ wake: Promise<TellResult>;
42
+ }> | Readonly<{
43
+ kind: "not-born";
44
+ }> | Readonly<{
45
+ kind: "birth-failed";
46
+ diagnostic: string;
47
+ }>;
48
+ export declare function admitCallInitialTell(input: Readonly<{
49
+ world: WorldRoot;
50
+ id: AkuId;
51
+ initialTell: CallInitialTell;
52
+ signal?: AbortSignal;
53
+ now?: () => string;
54
+ wake(tell: TellFact): Promise<TellResult>;
55
+ }>): Promise<CallInitialTellAdmission>;