@xandreed/core 0.3.0 → 0.8.0-next.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/README.md +1 -1
  2. package/dist/conformance.entity.d.ts +15 -0
  3. package/dist/conformance.entity.js +7 -0
  4. package/dist/decision-record.entity.d.ts +31 -0
  5. package/dist/decision-record.entity.functions.d.ts +6 -0
  6. package/dist/decision-record.entity.functions.js +3 -0
  7. package/dist/decision-record.entity.js +24 -0
  8. package/dist/domain/agent-failure.entity.d.ts +6 -6
  9. package/dist/domain/agent-failure.entity.js +12 -1
  10. package/dist/domain/failure.entity.d.ts +2 -2
  11. package/dist/domain/loop-event.entity.d.ts +2 -0
  12. package/dist/domain/message.entity.d.ts +143 -156
  13. package/dist/domain/message.entity.js +6 -6
  14. package/dist/domain/model-call-policy.entity.d.ts +3 -3
  15. package/dist/domain/model-call-policy.entity.js +1 -1
  16. package/dist/domain/model-catalog.entity.d.ts +4 -4
  17. package/dist/domain/model-catalog.entity.js +1 -1
  18. package/dist/domain/model-selection.entity.d.ts +6 -13
  19. package/dist/domain/prompt-provenance.entity.d.ts +6 -6
  20. package/dist/domain/prompt-provenance.entity.js +4 -4
  21. package/dist/domain/token-usage.entity.d.ts +4 -4
  22. package/dist/harness/capability.entity.d.ts +88 -41
  23. package/dist/harness/capability.entity.functions.d.ts +30 -1
  24. package/dist/harness/capability.entity.functions.js +55 -2
  25. package/dist/harness/capability.entity.js +33 -12
  26. package/dist/harness/config.entity.d.ts +28 -28
  27. package/dist/harness/config.entity.js +4 -4
  28. package/dist/harness/plugin-stack.adapter.d.ts +24 -0
  29. package/dist/harness/plugin-stack.adapter.js +8 -0
  30. package/dist/harness/plugin-stack.adapter.test.d.ts +1 -0
  31. package/dist/harness/plugin.adapter.d.ts +15 -4
  32. package/dist/harness/plugin.adapter.js +18 -11
  33. package/dist/harness/plugin.adapter.test.d.ts +1 -0
  34. package/dist/harness/plugin.entity.d.ts +26 -10
  35. package/dist/harness/plugin.entity.js +1 -1
  36. package/dist/harness/session.entity.d.ts +20 -20
  37. package/dist/harness/session.entity.js +1 -1
  38. package/dist/harness/skill-files.d.ts +17 -0
  39. package/dist/harness/skill-files.js +25 -0
  40. package/dist/index.d.ts +48 -4
  41. package/dist/index.js +46 -4
  42. package/dist/loop/cacheKey.d.ts +3 -3
  43. package/dist/loop/cacheKey.js +4 -2
  44. package/dist/loop/mapping.d.ts +4 -5
  45. package/dist/loop/mapping.js +8 -16
  46. package/dist/loop/modelPolicy.d.ts +4 -4
  47. package/dist/loop/modelPolicy.js +2 -2
  48. package/dist/loop/promptProvenance.d.ts +2 -2
  49. package/dist/loop/promptProvenance.js +2 -2
  50. package/dist/loop/stepContext.d.ts +2 -2
  51. package/dist/loop/stepContext.js +2 -2
  52. package/dist/loop/streamFold.js +3 -3
  53. package/dist/loop/toolSchema.d.ts +17 -0
  54. package/dist/loop/toolSchema.js +25 -0
  55. package/dist/loop/toolSchema.test.d.ts +1 -0
  56. package/dist/mcp/bridge.d.ts +15 -15
  57. package/dist/mcp/bridge.js +14 -14
  58. package/dist/memory/memory-log.entity.d.ts +320 -0
  59. package/dist/memory/memory-log.entity.functions.d.ts +89 -0
  60. package/dist/memory/memory-log.entity.functions.js +180 -0
  61. package/dist/memory/memory-log.entity.js +75 -0
  62. package/dist/memory/memory-log.entity.test.d.ts +1 -0
  63. package/dist/memory/memory-session.d.ts +51 -0
  64. package/dist/memory/memory-session.js +97 -0
  65. package/dist/memory/memory-session.test.d.ts +1 -0
  66. package/dist/memory/memory.conformance.d.ts +32 -0
  67. package/dist/memory/memory.conformance.js +102 -0
  68. package/dist/ports/auth-store.port.d.ts +16 -18
  69. package/dist/ports/auth-store.port.js +13 -9
  70. package/dist/ports/capability.port.d.ts +131 -7
  71. package/dist/ports/capability.port.js +2 -2
  72. package/dist/ports/conversation-store.port.d.ts +54 -177
  73. package/dist/ports/conversation-store.port.js +9 -9
  74. package/dist/ports/file-system.port.d.ts +5 -7
  75. package/dist/ports/file-system.port.js +1 -1
  76. package/dist/ports/harness.port.d.ts +19 -13
  77. package/dist/ports/harness.port.js +10 -10
  78. package/dist/ports/mcp-client.port.d.ts +15 -47
  79. package/dist/ports/mcp-client.port.js +3 -3
  80. package/dist/ports/memory.port.d.ts +116 -0
  81. package/dist/ports/memory.port.js +7 -0
  82. package/dist/ports/model-catalog.port.d.ts +1 -1
  83. package/dist/ports/model-catalog.port.js +1 -1
  84. package/dist/ports/permission.port.d.ts +10 -0
  85. package/dist/ports/permission.port.js +4 -0
  86. package/dist/ports/run-context.port.d.ts +28 -0
  87. package/dist/ports/run-context.port.js +4 -0
  88. package/dist/ports/session-log.port.d.ts +25 -0
  89. package/dist/ports/session-log.port.js +4 -0
  90. package/dist/ports/sessions.port.d.ts +141 -0
  91. package/dist/ports/sessions.port.js +4 -0
  92. package/dist/ports/settings-store.port.d.ts +18 -56
  93. package/dist/ports/settings-store.port.js +3 -3
  94. package/dist/ports/shell.port.d.ts +9 -21
  95. package/dist/ports/shell.port.js +1 -1
  96. package/dist/ports/step-loop.port.d.ts +85 -0
  97. package/dist/ports/step-loop.port.js +4 -0
  98. package/dist/ports/tasks.port.d.ts +59 -0
  99. package/dist/ports/tasks.port.js +10 -0
  100. package/dist/ports/tool-registry.port.d.ts +53 -0
  101. package/dist/ports/tool-registry.port.js +4 -0
  102. package/dist/ports/turn-admission.port.d.ts +23 -0
  103. package/dist/ports/turn-admission.port.js +4 -0
  104. package/dist/ports/turn-events.port.d.ts +55 -0
  105. package/dist/ports/turn-events.port.js +7 -0
  106. package/dist/ports/turn-scope.port.d.ts +101 -0
  107. package/dist/ports/turn-scope.port.js +10 -0
  108. package/dist/ports/turn.port.d.ts +113 -0
  109. package/dist/ports/turn.port.js +0 -0
  110. package/dist/ports/utility-llm.port.d.ts +12 -31
  111. package/dist/ports/utility-llm.port.js +1 -1
  112. package/dist/session/chassis.js +7 -7
  113. package/dist/session/session-event.entity.d.ts +55 -0
  114. package/dist/session/session-event.entity.functions.d.ts +31 -0
  115. package/dist/session/session-event.entity.functions.js +42 -0
  116. package/dist/session/session-event.entity.js +37 -0
  117. package/dist/session/session-event.entity.test.d.ts +1 -0
  118. package/dist/session/session-log.conformance.d.ts +13 -0
  119. package/dist/session/session-log.conformance.js +167 -0
  120. package/dist/session/session-log.entity.d.ts +164 -0
  121. package/dist/session/session-log.entity.js +82 -0
  122. package/dist/session/session-log.memory.adapter.d.ts +7 -0
  123. package/dist/session/session-log.memory.adapter.js +82 -0
  124. package/dist/session/session-log.memory.adapter.test.d.ts +1 -0
  125. package/dist/session/sessions.entity.d.ts +201 -0
  126. package/dist/session/sessions.entity.js +98 -0
  127. package/dist/session/tasks.entity.d.ts +39 -0
  128. package/dist/session/tasks.entity.js +26 -0
  129. package/dist/session/turn-admission.open.adapter.d.ts +4 -0
  130. package/dist/session/turn-admission.open.adapter.js +3 -0
  131. package/dist/spec/SpecDoc.d.ts +30 -117
  132. package/dist/spec/SpecDoc.js +10 -10
  133. package/dist/spec/codec.js +1 -1
  134. package/dist/turn/model-request.entity.d.ts +99 -0
  135. package/dist/turn/model-request.entity.functions.d.ts +108 -0
  136. package/dist/turn/model-request.entity.functions.js +167 -0
  137. package/dist/turn/model-request.entity.js +41 -0
  138. package/dist/turn/model-request.entity.test.d.ts +1 -0
  139. package/dist/turn/prompt-sections.d.ts +10 -0
  140. package/dist/turn/prompt-sections.js +3 -0
  141. package/dist/turn/step-loop.conformance.d.ts +16 -0
  142. package/dist/turn/step-loop.conformance.js +164 -0
  143. package/dist/turn/testing.d.ts +30 -0
  144. package/dist/turn/turn-bus.d.ts +23 -0
  145. package/dist/turn/turn-bus.js +54 -0
  146. package/dist/turn/turn-bus.test.d.ts +1 -0
  147. package/dist/turn/turn-event.entity.d.ts +263 -0
  148. package/dist/turn/turn-event.entity.functions.d.ts +35 -0
  149. package/dist/turn/turn-event.entity.functions.js +21 -0
  150. package/dist/turn/turn-event.entity.js +101 -0
  151. package/dist/turn/turn-lifecycle.d.ts +32 -0
  152. package/dist/turn/turn-lifecycle.js +48 -0
  153. package/dist/turn/turn-run.d.ts +26 -0
  154. package/dist/turn/turn-run.js +105 -0
  155. package/dist/turn/turn.adapter.d.ts +21 -0
  156. package/dist/turn/turn.adapter.js +126 -0
  157. package/dist/turn/turn.adapter.test.d.ts +1 -0
  158. package/dist/turn/turn.conformance.d.ts +20 -0
  159. package/dist/turn/turn.conformance.js +74 -0
  160. package/dist/turn/user-message.entity.d.ts +14 -0
  161. package/dist/turn/user-message.entity.js +10 -0
  162. package/dist/util/json.d.ts +2 -2
  163. package/dist/util/json.js +10 -10
  164. package/package.json +2 -3
@@ -0,0 +1,23 @@
1
+ import { Effect } from "effect";
2
+ import type { Scope } from "effect";
3
+ import { HarnessError } from "../harness/plugin.entity.js";
4
+ import type { TurnEventsService, TurnTasksService } from "../ports/turn-events.port.js";
5
+ /**
6
+ * An ordered event bus. `publish` runs every inline subscriber in
7
+ * subscription order before it returns; a handler may publish in turn
8
+ * (depth-first) up to `maxDepth`, which catches reaction cycles. Background
9
+ * subscribers get the event on their own queue and handle it in order on
10
+ * their own fiber; `drain` waits for them. `activity` counts background
11
+ * deliveries so far, so a caller can tell whether a drain left new work.
12
+ */
13
+ export declare const makeTurnEvents: (options: {
14
+ readonly maxDepth: number;
15
+ }) => Effect.Effect<TurnEventsService, never, Scope.Scope>;
16
+ /** Background work forked in `scope`: interrupted when it closes, joined on demand. `activity` counts tasks forked so far. */
17
+ export declare const makeTurnTasks: (scope: Scope.Scope) => Effect.Effect<TurnTasksService>;
18
+ /**
19
+ * Callbacks with a `never` error channel (the loop's, a tool wrapper's
20
+ * publish) carry a HarnessError as a defect; this restores it as a failure
21
+ * at the turn boundary so a subscriber failure fails the turn, typed.
22
+ */
23
+ export declare const harnessDefectsAsFailures: <A, E, R>(effect: Effect.Effect<A, E, R>) => Effect.Effect<A, E | HarnessError, R>;
@@ -0,0 +1,54 @@
1
+ import { Cause, Context, Deferred, Effect, Fiber, Option, Queue, Ref } from "effect";
2
+ import { HarnessError } from "../harness/plugin.entity.js";
3
+ const failureOf = (cause) => Option.getOrElse(Cause.findErrorOption(cause), () => {
4
+ const defect = Cause.squash(cause);
5
+ return defect instanceof HarnessError ? defect : new HarnessError({ code: "events.background", message: Cause.pretty(cause).slice(0, 300) });
6
+ }), defaultCapacity = 256;
7
+ export const makeTurnEvents = (options) => Effect.gen(function* () {
8
+ const subscribers = yield* Ref.make([]), nextId = yield* Ref.make(0), depth = Context.Reference(`@xandreed/core/TurnEvents/depth/${yield* Effect.sync(() => crypto.randomUUID())}`, { defaultValue: () => 0 }), queued = yield* Ref.make(0), publish = (event) => Effect.gen(function* () {
9
+ const current = yield* Effect.service(depth);
10
+ if (current >= options.maxDepth)
11
+ return yield* Effect.fail(new HarnessError({ code: "events.depth", message: `${event._tag} published ${current} levels deep; a reaction cycle?` }));
12
+ const all = yield* Ref.get(subscribers);
13
+ yield* Effect.forEach(all, (subscriber) => subscriber.deliver(event), { discard: !0 }).pipe(Effect.provideService(depth, current + 1));
14
+ }), background = (handle, capacity) => Effect.gen(function* () {
15
+ const queue = yield* Queue.bounded(capacity), failed = yield* Ref.make(Option.none()), take = Queue.take(queue).pipe(Effect.flatMap((item) => Effect.gen(function* () {
16
+ const failure = yield* Ref.get(failed);
17
+ if (item._tag === "Marker") {
18
+ yield* Option.match(failure, { onNone: () => Deferred.succeed(item.done, void 0), onSome: (error) => Deferred.fail(item.done, error) });
19
+ return;
20
+ }
21
+ if (Option.isSome(failure))
22
+ return;
23
+ yield* handle(item.event).pipe(Effect.provideService(depth, item.depth), Effect.catchCause((cause) => Ref.set(failed, Option.some(failureOf(cause)))));
24
+ })));
25
+ yield* Effect.forkScoped(Effect.forever(take));
26
+ const deliver = (event) => Effect.gen(function* () {
27
+ const failure = yield* Ref.get(failed);
28
+ if (Option.isSome(failure))
29
+ return yield* Effect.fail(failure.value);
30
+ yield* Ref.update(queued, (value) => value + 1);
31
+ yield* Queue.offer(queue, { _tag: "Event", event, depth: yield* Effect.service(depth) });
32
+ }), drain = Deferred.make().pipe(Effect.flatMap((done) => Queue.offer(queue, { _tag: "Marker", done }).pipe(Effect.andThen(Deferred.await(done)))));
33
+ return { deliver, drain };
34
+ }), subscribe = (select, handle, subscribeOptions) => Effect.gen(function* () {
35
+ const context = yield* Effect.context(), id = yield* Ref.getAndUpdate(nextId, (value) => value + 1), handled = (selected) => handle(selected).pipe(Effect.provide(context)), lane = (subscribeOptions?.mode ?? "inline") === "background" ? yield* background(handled, subscribeOptions?.capacity ?? defaultCapacity) : { deliver: handled, drain: Effect.void }, deliver = (event) => Option.match(select(event), {
36
+ onNone: () => Effect.void,
37
+ onSome: lane.deliver
38
+ });
39
+ yield* Ref.update(subscribers, (all) => [...all, { id, deliver, drain: lane.drain }]);
40
+ yield* Effect.addFinalizer(() => Ref.update(subscribers, (all) => all.filter((subscriber) => subscriber.id !== id)));
41
+ }), drain = Effect.gen(function* () {
42
+ const before = yield* Ref.get(queued);
43
+ yield* Effect.forEach(yield* Ref.get(subscribers), (subscriber) => subscriber.drain, { discard: !0 });
44
+ if ((yield* Ref.get(queued)) !== before)
45
+ yield* Effect.suspend(() => drain);
46
+ });
47
+ return { publish, subscribe, drain, activity: Ref.get(queued) };
48
+ }), makeTurnTasks = (scope) => Effect.gen(function* () {
49
+ const tasks = yield* Ref.make([]), fork = (tag, task) => Effect.gen(function* () {
50
+ const context = yield* Effect.context(), fiber = yield* Effect.forkIn(task.pipe(Effect.provide(context)), scope);
51
+ yield* Ref.update(tasks, (all) => [...all, { tag, fiber }]);
52
+ }), pending = (tag) => Ref.get(tasks).pipe(Effect.flatMap((all) => Effect.forEach(all.filter((task) => task.tag === tag), (task) => Effect.sync(() => task.fiber.pollUnsafe()))), Effect.map((polls) => polls.some((exit) => exit === void 0))), awaitFrom = (tags, from) => Ref.get(tasks).pipe(Effect.flatMap((all) => all.length === from ? Effect.void : Effect.forEach(all.slice(from).filter((task) => tags.length === 0 || tags.includes(task.tag)), (task) => Fiber.join(task.fiber), { discard: !0 }).pipe(Effect.andThen(Effect.suspend(() => awaitFrom(tags, all.length))))));
53
+ return { fork, pending, await: (tags) => awaitFrom(tags, 0), activity: Ref.get(tasks).pipe(Effect.map((all) => all.length)) };
54
+ }), harnessDefectsAsFailures = (effect) => effect.pipe(Effect.catchDefect((defect) => defect instanceof HarnessError ? Effect.fail(defect) : Effect.die(defect)));
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,263 @@
1
+ import { Schema } from "effect";
2
+ import { UserMessage } from "./user-message.entity.js";
3
+ /** What the host's completion policy decided after one step. */
4
+ export declare const CompletionVerdict: Schema.Struct<{
5
+ readonly complete: Schema.Boolean;
6
+ /** Task tags to await before the verdict is evaluated once more. */
7
+ readonly awaiting: Schema.$Array<Schema.Trimmed>;
8
+ /** Host facts behind the verdict, journaled with it. */
9
+ readonly facts: Schema.$Record<Schema.String, Schema.Unknown>;
10
+ }>;
11
+ export type CompletionVerdict = typeof CompletionVerdict.Type;
12
+ export declare const TurnStartedEvent: Schema.TaggedStruct<"turn.started", {
13
+ readonly runId: Schema.String;
14
+ readonly turn: Schema.Int;
15
+ readonly userMessage: typeof UserMessage;
16
+ }>;
17
+ export declare const StepStartedEvent: Schema.TaggedStruct<"step.started", {
18
+ readonly step: Schema.Int;
19
+ /** Step zero of a host-planned batch: no provider call. */
20
+ readonly planned: Schema.Boolean;
21
+ readonly activeTools: Schema.$Array<Schema.String>;
22
+ }>;
23
+ export declare const ToolStartedEvent: Schema.TaggedStruct<"tool.started", {
24
+ readonly step: Schema.Int;
25
+ readonly invocationId: Schema.String;
26
+ readonly tool: Schema.String;
27
+ readonly input: Schema.Unknown;
28
+ readonly labels: Schema.$Record<Schema.String, Schema.String>;
29
+ readonly stage: Schema.OptionFromNullOr<Schema.String>;
30
+ }>;
31
+ export declare const ToolCompletedEvent: Schema.TaggedStruct<"tool.completed", {
32
+ readonly step: Schema.Int;
33
+ readonly invocationId: Schema.String;
34
+ readonly tool: Schema.String;
35
+ readonly input: Schema.Unknown;
36
+ readonly ok: Schema.Boolean;
37
+ /** The decoded value the handler returned (or failed with). Not journaled. */
38
+ readonly result: Schema.Unknown;
39
+ /** The wire form of `result`, as the model receives it. */
40
+ readonly encoded: Schema.Unknown;
41
+ readonly durationMs: Schema.Number;
42
+ readonly labels: Schema.$Record<Schema.String, Schema.String>;
43
+ readonly stage: Schema.OptionFromNullOr<Schema.String>;
44
+ }>;
45
+ export declare const StepResult: Schema.Struct<{
46
+ readonly entry: Schema.brand<Schema.Trimmed, "EntryId">;
47
+ readonly toolCallId: Schema.brand<Schema.String, "ToolCallId">;
48
+ readonly tool: Schema.String;
49
+ readonly ok: Schema.Boolean;
50
+ }>;
51
+ export type StepResult = typeof StepResult.Type;
52
+ export declare const StepEndedEvent: Schema.TaggedStruct<"step.ended", {
53
+ readonly step: Schema.Int;
54
+ readonly status: Schema.Literals<readonly ["completed", "failed", "cancelled"]>;
55
+ /** The step's recorded tool results, in log order. */
56
+ readonly results: Schema.$Array<Schema.Struct<{
57
+ readonly entry: Schema.brand<Schema.Trimmed, "EntryId">;
58
+ readonly toolCallId: Schema.brand<Schema.String, "ToolCallId">;
59
+ readonly tool: Schema.String;
60
+ readonly ok: Schema.Boolean;
61
+ }>>;
62
+ }>;
63
+ export declare const CompletionEvaluatedEvent: Schema.TaggedStruct<"completion.evaluated", {
64
+ readonly step: Schema.Int;
65
+ readonly verdict: Schema.Struct<{
66
+ readonly complete: Schema.Boolean;
67
+ /** Task tags to await before the verdict is evaluated once more. */
68
+ readonly awaiting: Schema.$Array<Schema.Trimmed>;
69
+ /** Host facts behind the verdict, journaled with it. */
70
+ readonly facts: Schema.$Record<Schema.String, Schema.Unknown>;
71
+ }>;
72
+ }>;
73
+ export declare const SkillsActivatedEvent: Schema.TaggedStruct<"skills.activated", {
74
+ readonly skills: Schema.$Array<Schema.String>;
75
+ readonly tools: Schema.$Array<Schema.String>;
76
+ readonly source: Schema.Literals<readonly ["always", "matcher", "load_skill", "host"]>;
77
+ }>;
78
+ export declare const ContextBuiltEvent: Schema.TaggedStruct<"context.built", {
79
+ readonly step: Schema.Int;
80
+ readonly turn: Schema.Int;
81
+ readonly strategy: Schema.String;
82
+ readonly strategyVersion: Schema.String;
83
+ readonly fingerprint: Schema.String;
84
+ readonly systemFingerprint: Schema.String;
85
+ readonly estimatedTokens: Schema.Int;
86
+ readonly reservedTokens: Schema.Int;
87
+ readonly compactions: Schema.Int;
88
+ readonly activeTools: Schema.$Array<Schema.String>;
89
+ }>;
90
+ export declare const DecisionRecordedEvent: Schema.TaggedStruct<"decision.recorded", {
91
+ readonly record: Schema.Struct<{
92
+ readonly version: Schema.Literal<1>;
93
+ readonly id: Schema.brand<Schema.Trimmed, "DecisionId">;
94
+ readonly family: Schema.NonEmptyString;
95
+ readonly contextHash: Schema.String;
96
+ readonly candidateHash: Schema.String;
97
+ readonly policyVersion: Schema.String;
98
+ readonly candidates: Schema.$Array<Schema.Struct<{
99
+ readonly id: Schema.String;
100
+ readonly description: Schema.String;
101
+ }>>;
102
+ readonly attempts: Schema.$Array<Schema.String>;
103
+ readonly selection: Schema.OptionFromNullOr<Schema.String>;
104
+ readonly validation: Schema.Literals<readonly ["accepted", "rejected", "abstained", "failed", "cancelled", "bypassed"]>;
105
+ readonly fallback: Schema.OptionFromNullOr<Schema.String>;
106
+ readonly applied: Schema.OptionFromNullOr<Schema.String>;
107
+ readonly probabilities: Schema.OptionFromNullOr<Schema.$Record<Schema.String, Schema.Number>>;
108
+ }>;
109
+ }>;
110
+ export declare const AssistantMessageEvent: Schema.TaggedStruct<"assistant.message", {
111
+ readonly step: Schema.Int;
112
+ readonly text: Schema.String;
113
+ readonly reasoning: Schema.String;
114
+ readonly model: Schema.OptionFromNullOr<Schema.String>;
115
+ readonly toolCalls: Schema.$Array<Schema.Struct<{
116
+ readonly id: Schema.String;
117
+ readonly tool: Schema.String;
118
+ readonly input: Schema.Unknown;
119
+ }>>;
120
+ readonly usage: Schema.Struct<{
121
+ readonly inputTokens: Schema.Number;
122
+ readonly outputTokens: Schema.Number;
123
+ readonly totalTokens: Schema.Number;
124
+ readonly cacheReadTokens: Schema.Number;
125
+ }>;
126
+ }>;
127
+ /** A streamed increment — transient: never journaled, restated by assistant.message. */
128
+ export declare const AssistantDeltaEvent: Schema.TaggedStruct<"assistant.delta", {
129
+ readonly step: Schema.Int;
130
+ readonly channel: Schema.Literals<readonly ["text", "reasoning", "tool-params"]>;
131
+ readonly id: Schema.String;
132
+ readonly delta: Schema.String;
133
+ }>;
134
+ export declare const TurnEndedEvent: Schema.TaggedStruct<"turn.ended", {
135
+ readonly runId: Schema.String;
136
+ readonly turn: Schema.Int;
137
+ readonly outcome: Schema.Literals<readonly ["completed", "partial", "failed"]>;
138
+ readonly reply: Schema.OptionFromNullOr<Schema.String>;
139
+ }>;
140
+ /** An application's own event (see `defineHostEvent`); `name` is the host's namespace. */
141
+ export declare const HostEvent: Schema.TaggedStruct<"host", {
142
+ readonly name: Schema.Trimmed;
143
+ readonly data: Schema.$Record<Schema.String, Schema.Unknown>;
144
+ }>;
145
+ export declare const TurnEvent: Schema.Union<readonly [Schema.TaggedStruct<"turn.started", {
146
+ readonly runId: Schema.String;
147
+ readonly turn: Schema.Int;
148
+ readonly userMessage: typeof UserMessage;
149
+ }>, Schema.TaggedStruct<"step.started", {
150
+ readonly step: Schema.Int;
151
+ /** Step zero of a host-planned batch: no provider call. */
152
+ readonly planned: Schema.Boolean;
153
+ readonly activeTools: Schema.$Array<Schema.String>;
154
+ }>, Schema.TaggedStruct<"tool.started", {
155
+ readonly step: Schema.Int;
156
+ readonly invocationId: Schema.String;
157
+ readonly tool: Schema.String;
158
+ readonly input: Schema.Unknown;
159
+ readonly labels: Schema.$Record<Schema.String, Schema.String>;
160
+ readonly stage: Schema.OptionFromNullOr<Schema.String>;
161
+ }>, Schema.TaggedStruct<"tool.completed", {
162
+ readonly step: Schema.Int;
163
+ readonly invocationId: Schema.String;
164
+ readonly tool: Schema.String;
165
+ readonly input: Schema.Unknown;
166
+ readonly ok: Schema.Boolean;
167
+ /** The decoded value the handler returned (or failed with). Not journaled. */
168
+ readonly result: Schema.Unknown;
169
+ /** The wire form of `result`, as the model receives it. */
170
+ readonly encoded: Schema.Unknown;
171
+ readonly durationMs: Schema.Number;
172
+ readonly labels: Schema.$Record<Schema.String, Schema.String>;
173
+ readonly stage: Schema.OptionFromNullOr<Schema.String>;
174
+ }>, Schema.TaggedStruct<"step.ended", {
175
+ readonly step: Schema.Int;
176
+ readonly status: Schema.Literals<readonly ["completed", "failed", "cancelled"]>;
177
+ /** The step's recorded tool results, in log order. */
178
+ readonly results: Schema.$Array<Schema.Struct<{
179
+ readonly entry: Schema.brand<Schema.Trimmed, "EntryId">;
180
+ readonly toolCallId: Schema.brand<Schema.String, "ToolCallId">;
181
+ readonly tool: Schema.String;
182
+ readonly ok: Schema.Boolean;
183
+ }>>;
184
+ }>, Schema.TaggedStruct<"completion.evaluated", {
185
+ readonly step: Schema.Int;
186
+ readonly verdict: Schema.Struct<{
187
+ readonly complete: Schema.Boolean;
188
+ /** Task tags to await before the verdict is evaluated once more. */
189
+ readonly awaiting: Schema.$Array<Schema.Trimmed>;
190
+ /** Host facts behind the verdict, journaled with it. */
191
+ readonly facts: Schema.$Record<Schema.String, Schema.Unknown>;
192
+ }>;
193
+ }>, Schema.TaggedStruct<"skills.activated", {
194
+ readonly skills: Schema.$Array<Schema.String>;
195
+ readonly tools: Schema.$Array<Schema.String>;
196
+ readonly source: Schema.Literals<readonly ["always", "matcher", "load_skill", "host"]>;
197
+ }>, Schema.TaggedStruct<"context.built", {
198
+ readonly step: Schema.Int;
199
+ readonly turn: Schema.Int;
200
+ readonly strategy: Schema.String;
201
+ readonly strategyVersion: Schema.String;
202
+ readonly fingerprint: Schema.String;
203
+ readonly systemFingerprint: Schema.String;
204
+ readonly estimatedTokens: Schema.Int;
205
+ readonly reservedTokens: Schema.Int;
206
+ readonly compactions: Schema.Int;
207
+ readonly activeTools: Schema.$Array<Schema.String>;
208
+ }>, Schema.TaggedStruct<"decision.recorded", {
209
+ readonly record: Schema.Struct<{
210
+ readonly version: Schema.Literal<1>;
211
+ readonly id: Schema.brand<Schema.Trimmed, "DecisionId">;
212
+ readonly family: Schema.NonEmptyString;
213
+ readonly contextHash: Schema.String;
214
+ readonly candidateHash: Schema.String;
215
+ readonly policyVersion: Schema.String;
216
+ readonly candidates: Schema.$Array<Schema.Struct<{
217
+ readonly id: Schema.String;
218
+ readonly description: Schema.String;
219
+ }>>;
220
+ readonly attempts: Schema.$Array<Schema.String>;
221
+ readonly selection: Schema.OptionFromNullOr<Schema.String>;
222
+ readonly validation: Schema.Literals<readonly ["accepted", "rejected", "abstained", "failed", "cancelled", "bypassed"]>;
223
+ readonly fallback: Schema.OptionFromNullOr<Schema.String>;
224
+ readonly applied: Schema.OptionFromNullOr<Schema.String>;
225
+ readonly probabilities: Schema.OptionFromNullOr<Schema.$Record<Schema.String, Schema.Number>>;
226
+ }>;
227
+ }>, Schema.TaggedStruct<"assistant.message", {
228
+ readonly step: Schema.Int;
229
+ readonly text: Schema.String;
230
+ readonly reasoning: Schema.String;
231
+ readonly model: Schema.OptionFromNullOr<Schema.String>;
232
+ readonly toolCalls: Schema.$Array<Schema.Struct<{
233
+ readonly id: Schema.String;
234
+ readonly tool: Schema.String;
235
+ readonly input: Schema.Unknown;
236
+ }>>;
237
+ readonly usage: Schema.Struct<{
238
+ readonly inputTokens: Schema.Number;
239
+ readonly outputTokens: Schema.Number;
240
+ readonly totalTokens: Schema.Number;
241
+ readonly cacheReadTokens: Schema.Number;
242
+ }>;
243
+ }>, Schema.TaggedStruct<"assistant.delta", {
244
+ readonly step: Schema.Int;
245
+ readonly channel: Schema.Literals<readonly ["text", "reasoning", "tool-params"]>;
246
+ readonly id: Schema.String;
247
+ readonly delta: Schema.String;
248
+ }>, Schema.TaggedStruct<"turn.ended", {
249
+ readonly runId: Schema.String;
250
+ readonly turn: Schema.Int;
251
+ readonly outcome: Schema.Literals<readonly ["completed", "partial", "failed"]>;
252
+ readonly reply: Schema.OptionFromNullOr<Schema.String>;
253
+ }>, Schema.TaggedStruct<"host", {
254
+ readonly name: Schema.Trimmed;
255
+ readonly data: Schema.$Record<Schema.String, Schema.Unknown>;
256
+ }>]>;
257
+ export type TurnEvent = typeof TurnEvent.Type;
258
+ export type TurnEventName = TurnEvent["_tag"];
259
+ export type TurnEventOf<Name extends TurnEventName> = Extract<TurnEvent, {
260
+ readonly _tag: Name;
261
+ }>;
262
+ /** Events that exist only for live rendering and are never journaled. */
263
+ export declare const TransientTurnEvents: ReadonlyArray<TurnEventName>;
@@ -0,0 +1,35 @@
1
+ import { Effect, Option, Schema } from "effect";
2
+ import { HarnessError } from "../harness/plugin.entity.js";
3
+ import type { SubscribeOptions, Subscription, TurnEventsService } from "../ports/turn-events.port.js";
4
+ import type { TurnEvent, TurnEventName, TurnEventOf } from "./turn-event.entity.js";
5
+ /** Subscribe to one event kind by name, typed by the event's schema (inline unless `options.mode` says background). */
6
+ export declare const onEvent: <Name extends TurnEventName, R>(name: Name, handle: (event: TurnEventOf<Name>) => Effect.Effect<void, HarnessError, R>, options?: SubscribeOptions) => Subscription<R>;
7
+ /**
8
+ * React to one tool's successful calls, typed by the tool's own schemas:
9
+ * the input and result are narrowed with `Schema.is`, never cast.
10
+ */
11
+ export interface ToolCall<Input, Result> {
12
+ readonly step: number;
13
+ readonly invocationId: string;
14
+ readonly input: Input;
15
+ readonly result: Result;
16
+ }
17
+ export declare const onTool: <Params extends Schema.Top, Success extends Schema.Top, R>(tool: {
18
+ readonly name: string;
19
+ readonly parametersSchema: Params;
20
+ readonly successSchema: Success;
21
+ }, handle: (call: ToolCall<Params["Type"], Success["Type"]>) => Effect.Effect<void, HarnessError, R>, options?: SubscribeOptions) => Subscription<R>;
22
+ /** Attach several subscriptions to one bus. */
23
+ export declare const subscribeAll: <R>(events: TurnEventsService, subscriptions: ReadonlyArray<Subscription<R>>) => Effect.Effect<void, never, import("effect/Scope").Scope | R>;
24
+ /**
25
+ * An application's own typed event. Its name is the host's namespace
26
+ * (e.g. `answer.published`); payloads are encoded with the schema, so a
27
+ * journal sink can persist them like any other event.
28
+ */
29
+ export declare const defineHostEvent: <A, I extends Readonly<Record<string, unknown>>>(name: string, schema: Schema.Codec<A, I>) => {
30
+ name: string;
31
+ make: (data: A) => Effect.Effect<TurnEvent, HarnessError>;
32
+ select: (event: TurnEvent) => Option.Option<A>;
33
+ publish: (events: TurnEventsService, data: A) => Effect.Effect<void, HarnessError, never>;
34
+ on: <R>(handle: (data: A) => Effect.Effect<void, HarnessError, R>, options?: SubscribeOptions) => Subscription<R>;
35
+ };
@@ -0,0 +1,21 @@
1
+ import { Effect, Option, Schema } from "effect";
2
+ import { HarnessError } from "../harness/plugin.entity.js";
3
+ const isNamed = (name) => (event) => event._tag === name;
4
+ export const onEvent = (name, handle, options) => (events) => events.subscribe((event) => Option.liftPredicate(event, isNamed(name)), handle, options), onTool = (tool, handle, options) => {
5
+ const isInput = Schema.is(tool.parametersSchema), isResult = Schema.is(tool.successSchema);
6
+ return (events) => events.subscribe((event) => {
7
+ if (event._tag !== "tool.completed" || event.tool !== tool.name || !event.ok)
8
+ return Option.none();
9
+ const { input, result } = event;
10
+ return isInput(input) && isResult(result) ? Option.some({ step: event.step, invocationId: event.invocationId, input, result }) : Option.none();
11
+ }, handle, options);
12
+ }, subscribeAll = (events, subscriptions) => Effect.forEach(subscriptions, (subscription) => subscription(events), { discard: !0 }), defineHostEvent = (name, schema) => {
13
+ const select = (event) => event._tag === "host" && event.name === name ? Schema.decodeUnknownOption(schema)(event.data) : Option.none(), make = (data) => Schema.encodeEffect(schema)(data).pipe(Effect.map((encoded) => ({ _tag: "host", name, data: encoded })), Effect.mapError((error) => new HarnessError({ code: "events.encode", message: `${name}: ${error.message}` })));
14
+ return {
15
+ name,
16
+ make,
17
+ select,
18
+ publish: (events, data) => make(data).pipe(Effect.flatMap(events.publish)),
19
+ on: (handle, options) => (events) => events.subscribe(select, handle, options)
20
+ };
21
+ };
@@ -0,0 +1,101 @@
1
+ import { Schema } from "effect";
2
+ import { DecisionRecord } from "../decision-record.entity.js";
3
+ import { ToolCallId } from "../domain/message.entity.js";
4
+ import { TokenUsage } from "../domain/token-usage.entity.js";
5
+ import { ActivationSource, EntryId } from "../memory/memory-log.entity.js";
6
+ import { UserMessage } from "./user-message.entity.js";
7
+ const Labels = Schema.Record(Schema.String, Schema.String), Data = Schema.Record(Schema.String, Schema.Unknown);
8
+ export const CompletionVerdict = Schema.Struct({
9
+ complete: Schema.Boolean,
10
+ awaiting: Schema.Array(Schema.Trimmed.check(Schema.isNonEmpty())),
11
+ facts: Data
12
+ }), TurnStartedEvent = Schema.TaggedStruct("turn.started", {
13
+ runId: Schema.String,
14
+ turn: Schema.Int,
15
+ userMessage: UserMessage
16
+ }), StepStartedEvent = Schema.TaggedStruct("step.started", {
17
+ step: Schema.Int,
18
+ planned: Schema.Boolean,
19
+ activeTools: Schema.Array(Schema.String)
20
+ }), ToolStartedEvent = Schema.TaggedStruct("tool.started", {
21
+ step: Schema.Int,
22
+ invocationId: Schema.String,
23
+ tool: Schema.String,
24
+ input: Schema.Unknown,
25
+ labels: Labels,
26
+ stage: Schema.OptionFromNullOr(Schema.String)
27
+ }), ToolCompletedEvent = Schema.TaggedStruct("tool.completed", {
28
+ step: Schema.Int,
29
+ invocationId: Schema.String,
30
+ tool: Schema.String,
31
+ input: Schema.Unknown,
32
+ ok: Schema.Boolean,
33
+ result: Schema.Unknown,
34
+ encoded: Schema.Unknown,
35
+ durationMs: Schema.Number,
36
+ labels: Labels,
37
+ stage: Schema.OptionFromNullOr(Schema.String)
38
+ }), StepResult = Schema.Struct({
39
+ entry: EntryId,
40
+ toolCallId: ToolCallId,
41
+ tool: Schema.String,
42
+ ok: Schema.Boolean
43
+ }), StepEndedEvent = Schema.TaggedStruct("step.ended", {
44
+ step: Schema.Int,
45
+ status: Schema.Literals(["completed", "failed", "cancelled"]),
46
+ results: Schema.Array(StepResult)
47
+ }), CompletionEvaluatedEvent = Schema.TaggedStruct("completion.evaluated", {
48
+ step: Schema.Int,
49
+ verdict: CompletionVerdict
50
+ }), SkillsActivatedEvent = Schema.TaggedStruct("skills.activated", {
51
+ skills: Schema.Array(Schema.String),
52
+ tools: Schema.Array(Schema.String),
53
+ source: ActivationSource
54
+ }), ContextBuiltEvent = Schema.TaggedStruct("context.built", {
55
+ step: Schema.Int,
56
+ turn: Schema.Int,
57
+ strategy: Schema.String,
58
+ strategyVersion: Schema.String,
59
+ fingerprint: Schema.String,
60
+ systemFingerprint: Schema.String,
61
+ estimatedTokens: Schema.Int,
62
+ reservedTokens: Schema.Int,
63
+ compactions: Schema.Int,
64
+ activeTools: Schema.Array(Schema.String)
65
+ }), DecisionRecordedEvent = Schema.TaggedStruct("decision.recorded", {
66
+ record: DecisionRecord
67
+ }), AssistantMessageEvent = Schema.TaggedStruct("assistant.message", {
68
+ step: Schema.Int,
69
+ text: Schema.String,
70
+ reasoning: Schema.String,
71
+ model: Schema.OptionFromNullOr(Schema.String),
72
+ toolCalls: Schema.Array(Schema.Struct({ id: Schema.String, tool: Schema.String, input: Schema.Unknown })),
73
+ usage: TokenUsage
74
+ }), AssistantDeltaEvent = Schema.TaggedStruct("assistant.delta", {
75
+ step: Schema.Int,
76
+ channel: Schema.Literals(["text", "reasoning", "tool-params"]),
77
+ id: Schema.String,
78
+ delta: Schema.String
79
+ }), TurnEndedEvent = Schema.TaggedStruct("turn.ended", {
80
+ runId: Schema.String,
81
+ turn: Schema.Int,
82
+ outcome: Schema.Literals(["completed", "partial", "failed"]),
83
+ reply: Schema.OptionFromNullOr(Schema.String)
84
+ }), HostEvent = Schema.TaggedStruct("host", {
85
+ name: Schema.Trimmed.check(Schema.isNonEmpty()),
86
+ data: Data
87
+ }), TurnEvent = Schema.Union([
88
+ TurnStartedEvent,
89
+ StepStartedEvent,
90
+ ToolStartedEvent,
91
+ ToolCompletedEvent,
92
+ StepEndedEvent,
93
+ CompletionEvaluatedEvent,
94
+ SkillsActivatedEvent,
95
+ ContextBuiltEvent,
96
+ DecisionRecordedEvent,
97
+ AssistantMessageEvent,
98
+ AssistantDeltaEvent,
99
+ TurnEndedEvent,
100
+ HostEvent
101
+ ]), TransientTurnEvents = ["assistant.delta"];
@@ -0,0 +1,32 @@
1
+ import { Effect } from "effect";
2
+ import type { HarnessError } from "../harness/plugin.entity.js";
3
+ import { RunContext } from "../ports/run-context.port.js";
4
+ import type { StepLoop } from "../ports/step-loop.port.js";
5
+ import type { RunTools } from "../ports/tool-registry.port.js";
6
+ import { TurnEvents, TurnTasks } from "../ports/turn-events.port.js";
7
+ import { TurnMemory, TurnToolbox } from "../ports/turn-scope.port.js";
8
+ import type { TurnRunOptions } from "../ports/turn-scope.port.js";
9
+ import type { Turn, TurnOutcome, TurnTools } from "../ports/turn.port.js";
10
+ import type { TurnRunServices } from "./turn-run.js";
11
+ /** Open the turn's tools (once). Their handlers run with the services of where this runs: open them inside the host's layer. */
12
+ export declare const openTurnTools: Effect.Effect<RunTools, HarnessError, TurnToolbox>;
13
+ /** The host's view of the open tools; skills the host activates are recorded as its own. */
14
+ export declare const turnTools: Effect.Effect<TurnTools, HarnessError, TurnToolbox>;
15
+ /** Await the tasks, then drain the background reactions, again until a round starts nothing new. */
16
+ export declare const settleTurn: Effect.Effect<void, HarnessError, TurnEvents | TurnTasks>;
17
+ /** Record the reply (`persistReply`), drain the reactions to it, and flush the journal. */
18
+ export declare const finishTurn: (outcome: TurnOutcome) => Effect.Effect<void, HarnessError, TurnMemory | TurnEvents | RunContext>;
19
+ /**
20
+ * Run a turn's body to its end: once it succeeds, the turn settles (tasks
21
+ * and background reactions) and finishes with its outcome. When it fails
22
+ * or is interrupted, the turn finishes as failed and keeps the body's
23
+ * cause. A HarnessError carried as a defect (a subscriber's failure behind
24
+ * a `never` error channel) fails the turn, typed.
25
+ */
26
+ export declare const guardTurn: <E, R>(body: Effect.Effect<TurnOutcome, E, R>) => Effect.Effect<TurnOutcome, E | HarnessError, R | TurnMemory | TurnEvents | TurnTasks | RunContext>;
27
+ /**
28
+ * The `Turn` a host's code works with, over the turn's services (the one
29
+ * `Agent.turn` hands to `use`): its `run` is `runTurnLoop` with `options`.
30
+ * The message must be persisted and the tools open.
31
+ */
32
+ export declare const turnOf: (options?: TurnRunOptions) => Effect.Effect<Turn, HarnessError, TurnRunServices | RunContext | StepLoop>;
@@ -0,0 +1,48 @@
1
+ import { Effect, Exit, Option } from "effect";
2
+ import { RunContext } from "../ports/run-context.port.js";
3
+ import { TurnEvents, TurnTasks } from "../ports/turn-events.port.js";
4
+ import { TurnMemory, TurnToolbox } from "../ports/turn-scope.port.js";
5
+ import { harnessDefectsAsFailures } from "./turn-bus.js";
6
+ import { runTurnLoop } from "./turn-run.js";
7
+ const failed = { outcome: "failed", reply: Option.none() };
8
+ export const openTurnTools = TurnToolbox.pipe(Effect.flatMap((toolbox) => toolbox.open)), turnTools = TurnToolbox.pipe(Effect.flatMap((toolbox) => toolbox.tools), Effect.map((tools) => ({
9
+ match: tools.match,
10
+ apply: tools.apply,
11
+ select: tools.select,
12
+ activate: (skills) => tools.activate(skills, "host"),
13
+ active: tools.active,
14
+ skills: tools.skills
15
+ }))), settleTurn = Effect.gen(function* () {
16
+ const events = yield* TurnEvents, tasks = yield* TurnTasks, activity = Effect.zipWith(tasks.activity, events.activity, (forked, delivered) => forked + delivered), settle = Effect.gen(function* () {
17
+ const before = yield* activity;
18
+ yield* tasks.await([]);
19
+ yield* events.drain;
20
+ if ((yield* activity) !== before)
21
+ yield* Effect.suspend(() => settle);
22
+ });
23
+ yield* settle;
24
+ }), finishTurn = (outcome) => Effect.gen(function* () {
25
+ yield* (yield* TurnMemory).persistReply(outcome);
26
+ yield* (yield* TurnEvents).drain;
27
+ yield* (yield* RunContext).flush;
28
+ }), guardTurn = (body) => harnessDefectsAsFailures(body.pipe(Effect.tap(() => settleTurn))).pipe(Effect.onExit(Exit.match({
29
+ onSuccess: () => Effect.void,
30
+ onFailure: () => finishTurn(failed).pipe(Effect.catchCause(() => Effect.void))
31
+ })), Effect.tap(finishTurn)), turnOf = (options = {}) => Effect.gen(function* () {
32
+ const services = yield* Effect.context(), run = yield* RunContext, memory = yield* TurnMemory;
33
+ return {
34
+ conversation: run.conversation,
35
+ runId: run.runId,
36
+ turn: yield* memory.number,
37
+ userMessage: run.userMessage,
38
+ memory: run.memory,
39
+ events: run.events,
40
+ tasks: run.tasks,
41
+ tools: yield* turnTools,
42
+ context: memory.context,
43
+ reply: (text) => Effect.succeed({ outcome: "completed", reply: Option.some(text) }),
44
+ run: (policy) => runTurnLoop(policy, options).pipe(Effect.provide(services)),
45
+ flush: run.flush,
46
+ write: run.write
47
+ };
48
+ });
@@ -0,0 +1,26 @@
1
+ import { Effect, Option } from "effect";
2
+ import { HarnessError } from "../harness/plugin.entity.js";
3
+ import { StepLoop } from "../ports/step-loop.port.js";
4
+ import type { RunResult, StepRequest } from "../ports/step-loop.port.js";
5
+ import type { RunTools } from "../ports/tool-registry.port.js";
6
+ import { TurnEvents, TurnTasks } from "../ports/turn-events.port.js";
7
+ import type { TurnPolicy } from "../ports/turn.port.js";
8
+ import { TurnMemory, TurnPrompt, TurnToolbox } from "../ports/turn-scope.port.js";
9
+ import type { TurnRunOptions } from "../ports/turn-scope.port.js";
10
+ /** The turn services one run reads. */
11
+ export type TurnRunServices = TurnMemory | TurnToolbox | TurnPrompt | TurnEvents | TurnTasks;
12
+ /** The tokens the active tools' descriptions and parameter schemas take in a request. */
13
+ export declare const schemaTokens: (tools: RunTools, active: ReadonlyArray<string>) => number;
14
+ /** The prompt-cache key of a conversation: `<prefix>:<conversation>`, none without a prefix. */
15
+ export declare const cacheKeyOf: (prefix: string, conversation: string) => Option.Option<string>;
16
+ /**
17
+ * Prepare one run of the step loop over the turn's services, in this
18
+ * order: the policy's planned skills are activated, the turn-tier sections
19
+ * are recorded, and memory is maintained for the turn's start. Everything
20
+ * where this runs (the policy's services, the turn's, a host layer's) is
21
+ * captured: the policy callbacks, the prompt sections and the tool handlers
22
+ * run with it.
23
+ */
24
+ export declare const stepRequestOf: <P>(policy: TurnPolicy<P>, options?: TurnRunOptions) => Effect.Effect<StepRequest, HarnessError, P | TurnRunServices>;
25
+ /** One run of the turn: `stepRequestOf`, then the StepLoop. */
26
+ export declare const runTurnLoop: <P>(policy: TurnPolicy<P>, options?: TurnRunOptions) => Effect.Effect<RunResult, HarnessError, P | TurnRunServices | StepLoop>;