@yolk-sdk/agent 0.1.0-canary.76 → 0.1.0-canary.77

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 (50) hide show
  1. package/README.md +16 -0
  2. package/dist/compaction/index.d.mts +2 -2
  3. package/dist/compaction/index.mjs +2 -2
  4. package/dist/compaction/retry.d.mts +22 -1
  5. package/dist/compaction/retry.d.mts.map +1 -1
  6. package/dist/compaction/retry.mjs +46 -13
  7. package/dist/compaction/retry.mjs.map +1 -1
  8. package/dist/loop/accumulator.d.mts +4 -2
  9. package/dist/loop/accumulator.d.mts.map +1 -1
  10. package/dist/loop/accumulator.mjs +13 -11
  11. package/dist/loop/accumulator.mjs.map +1 -1
  12. package/dist/loop/collect.d.mts +37 -0
  13. package/dist/loop/collect.d.mts.map +1 -0
  14. package/dist/loop/collect.mjs +126 -0
  15. package/dist/loop/collect.mjs.map +1 -0
  16. package/dist/loop/error.d.mts +4 -1
  17. package/dist/loop/error.d.mts.map +1 -1
  18. package/dist/loop/error.mjs +4 -2
  19. package/dist/loop/error.mjs.map +1 -1
  20. package/dist/loop/index.d.mts +4 -2
  21. package/dist/loop/index.mjs +4 -2
  22. package/dist/loop/layer.d.mts +17 -0
  23. package/dist/loop/layer.d.mts.map +1 -0
  24. package/dist/loop/layer.mjs +15 -0
  25. package/dist/loop/layer.mjs.map +1 -0
  26. package/dist/loop/run.mjs +9 -8
  27. package/dist/loop/run.mjs.map +1 -1
  28. package/dist/loop/services/tool-executor.d.mts +8 -3
  29. package/dist/loop/services/tool-executor.d.mts.map +1 -1
  30. package/dist/loop/services/tool-executor.mjs +11 -3
  31. package/dist/loop/services/tool-executor.mjs.map +1 -1
  32. package/dist/loop/testing/faux-provider.mjs +1 -1
  33. package/dist/providers/openai/codex-provider.d.mts +4 -4
  34. package/dist/providers/openai/codex-provider.d.mts.map +1 -1
  35. package/dist/providers/openai/codex-provider.mjs +23 -3
  36. package/dist/providers/openai/codex-provider.mjs.map +1 -1
  37. package/dist/skillset/name.d.mts +2 -2
  38. package/dist/skillset/name.d.mts.map +1 -1
  39. package/package.json +1 -1
  40. package/src/compaction/index.ts +10 -2
  41. package/src/compaction/retry.ts +96 -25
  42. package/src/loop/README.md +15 -0
  43. package/src/loop/accumulator.ts +27 -21
  44. package/src/loop/collect.ts +238 -0
  45. package/src/loop/error.ts +5 -1
  46. package/src/loop/index.ts +8 -0
  47. package/src/loop/layer.ts +31 -0
  48. package/src/loop/run.ts +14 -14
  49. package/src/loop/services/tool-executor.ts +16 -4
  50. package/src/providers/openai/codex-provider.ts +88 -12
package/README.md CHANGED
@@ -129,6 +129,22 @@ const program = run({
129
129
  // Provide LLM provider, loop config, context transformer, and tool executor layers in the host app.
130
130
  ```
131
131
 
132
+ Loop composition is those four Layers plus `run` / `runModelTurn` / `runToolBatch`.
133
+ Merge them with `makeAgentLoopLayer`. Omitted tools use `ToolExecutor.unavailable`; omitted transformer/config use identity and `LoopConfig.defaultLayer`.
134
+ Intercept by decorating a service (`decorateLLMProvider`), not with hooks.
135
+ Durable hosts fold model-turn steps with `collectModelTurn`. Use `collectModelTurnAttempt` when the fold must retain partial output after a failed stream. Kernel incomplete streams (zero `Done` events) set optional `LLMError.responseIssue: 'missing_done'` and stay `invalid_response` / `retryable: false`.
136
+
137
+ ```ts
138
+ import { makeAgentLoopLayer } from '@yolk-sdk/agent/loop'
139
+ import { FauxProvider, Reply } from '@yolk-sdk/agent/loop/testing'
140
+
141
+ const LoopLayer = makeAgentLoopLayer({
142
+ provider: FauxProvider.layer(Reply.text('ok'))
143
+ })
144
+ ```
145
+
146
+ Guide source: [Loop and runtime](https://github.com/magoz/yolk-sdk/blob/main/apps/docs/content/docs/agent/loop-runtime.mdx#compose-the-loop-layer).
147
+
132
148
  ## OAuth credentials
133
149
 
134
150
  `@yolk-sdk/agent/oauth` defines provider-neutral access-token, broker, freshness, and credential-source
@@ -2,7 +2,7 @@ import { ContextBudget, ContextBudgetInput, ContextBudgetStatus, contextBudgetSt
2
2
  import { CompactionCheckpointInput, CompactionSummarySourceMessageOptions, compactionCheckpointCloseTag, compactionCheckpointOpenTag, compactionSummarySourceMessages, defaultCompactionCheckpointHeader, dropLeadingCompactionCheckpointMessage, isCompactionCheckpointMessage, isCompactionCheckpointText, makeCompactionCheckpointMessage, makeCompactionCheckpointText } from "./checkpoint.mjs";
3
3
  import { MessageTokenEstimator, TokenEstimateOptions, TranscriptTokenEstimator, defaultCharactersPerToken, defaultMediaPartTokens, defaultMessageOverheadTokens, estimateAgentMessageTokens, estimateAgentMessagesTokens, estimateContentTokens, estimateTextTokens } from "./estimator.mjs";
4
4
  import { CompactionMessageFormatOptions, PreviewSummaryMessageOptions, compactionContentText, defaultCompactionToolOutputMaxCharacters, defaultPreviewSummaryHeader, defaultSummaryPreviewMaxCharacters, formatAgentMessageForCompaction, formatAgentMessagesForCompaction, makePreviewSummaryContent, makePreviewSummaryMessage, previewAgentMessage, truncateCompactionToolOutput, truncateSummaryPreview } from "./summary.mjs";
5
- import { ContextOverflowRetryCompactionResult, ContextOverflowRetryCompactor, ContextOverflowRetryProviderInput, makeContextOverflowRetryProvider } from "./retry.mjs";
5
+ import { ContextOverflowRetryCompactionResult, ContextOverflowRetryCompactor, ContextOverflowRetryProviderInput, OverflowCompactionDecision, applyOverflowCompaction, isOverflowCompactionAttemptCount, makeContextOverflowRetryProvider, overflowCompactionAttemptAllowed, overflowCompactionMaxAttempts, overflowCompactionMayRun } from "./retry.mjs";
6
6
  import { ApplyCompactionPlanOptions, CompactCompactionPlan, CompactionResult, CompactionSkipReason, CompletedCompactionResult, SkippedCompactionPlan, SkippedCompactionResult, WindowCompactionPlan, WindowCompactionPlanOptions, applyCompactionPlan, defaultCompactionTailMessageCount, defaultMinimumCompactionMessages, planWindowCompaction, windowTailStartIndex } from "./window.mjs";
7
7
  import { SummaryMessageFactory, WindowCompactionOptions, compactWindowMessages, makeWindowCompactionTransformer } from "./transformer.mjs";
8
- export { type ApplyCompactionPlanOptions, type CompactCompactionPlan, type CompactionCheckpointInput, type CompactionMessageFormatOptions, type CompactionResult, type CompactionSkipReason, type CompactionSummarySourceMessageOptions, type CompletedCompactionResult, type ContextBudget, type ContextBudgetInput, type ContextBudgetStatus, type ContextOverflowRetryCompactionResult, type ContextOverflowRetryCompactor, type ContextOverflowRetryProviderInput, type MessageTokenEstimator, type PreviewSummaryMessageOptions, type SkippedCompactionPlan, type SkippedCompactionResult, type SummaryMessageFactory, type TokenEstimateOptions, type TranscriptTokenEstimator, type WindowCompactionOptions, type WindowCompactionPlan, type WindowCompactionPlanOptions, applyCompactionPlan, compactWindowMessages, compactionCheckpointCloseTag, compactionCheckpointOpenTag, compactionContentText, compactionSummarySourceMessages, contextBudgetStatus, contextBudgetUsageRatio, defaultCharactersPerToken, defaultCompactionCheckpointHeader, defaultCompactionTailMessageCount, defaultCompactionToolOutputMaxCharacters, defaultMediaPartTokens, defaultMessageOverheadTokens, defaultMinimumCompactionMessages, defaultPreviewSummaryHeader, defaultSummaryPreviewMaxCharacters, dropLeadingCompactionCheckpointMessage, estimateAgentMessageTokens, estimateAgentMessagesTokens, estimateContentTokens, estimateTextTokens, formatAgentMessageForCompaction, formatAgentMessagesForCompaction, isCompactionCheckpointMessage, isCompactionCheckpointText, makeCompactionCheckpointMessage, makeCompactionCheckpointText, makeContextBudget, makeContextOverflowRetryProvider, makePreviewSummaryContent, makePreviewSummaryMessage, makeWindowCompactionTransformer, planWindowCompaction, previewAgentMessage, truncateCompactionToolOutput, truncateSummaryPreview, windowTailStartIndex };
8
+ export { type ApplyCompactionPlanOptions, type CompactCompactionPlan, type CompactionCheckpointInput, type CompactionMessageFormatOptions, type CompactionResult, type CompactionSkipReason, type CompactionSummarySourceMessageOptions, type CompletedCompactionResult, type ContextBudget, type ContextBudgetInput, type ContextBudgetStatus, type ContextOverflowRetryCompactionResult, type ContextOverflowRetryCompactor, type ContextOverflowRetryProviderInput, type MessageTokenEstimator, type OverflowCompactionDecision, type PreviewSummaryMessageOptions, type SkippedCompactionPlan, type SkippedCompactionResult, type SummaryMessageFactory, type TokenEstimateOptions, type TranscriptTokenEstimator, type WindowCompactionOptions, type WindowCompactionPlan, type WindowCompactionPlanOptions, applyCompactionPlan, applyOverflowCompaction, compactWindowMessages, compactionCheckpointCloseTag, compactionCheckpointOpenTag, compactionContentText, compactionSummarySourceMessages, contextBudgetStatus, contextBudgetUsageRatio, defaultCharactersPerToken, defaultCompactionCheckpointHeader, defaultCompactionTailMessageCount, defaultCompactionToolOutputMaxCharacters, defaultMediaPartTokens, defaultMessageOverheadTokens, defaultMinimumCompactionMessages, defaultPreviewSummaryHeader, defaultSummaryPreviewMaxCharacters, dropLeadingCompactionCheckpointMessage, estimateAgentMessageTokens, estimateAgentMessagesTokens, estimateContentTokens, estimateTextTokens, formatAgentMessageForCompaction, formatAgentMessagesForCompaction, isCompactionCheckpointMessage, isCompactionCheckpointText, isOverflowCompactionAttemptCount, makeCompactionCheckpointMessage, makeCompactionCheckpointText, makeContextBudget, makeContextOverflowRetryProvider, makePreviewSummaryContent, makePreviewSummaryMessage, makeWindowCompactionTransformer, overflowCompactionAttemptAllowed, overflowCompactionMaxAttempts, overflowCompactionMayRun, planWindowCompaction, previewAgentMessage, truncateCompactionToolOutput, truncateSummaryPreview, windowTailStartIndex };
@@ -2,7 +2,7 @@ import { contextBudgetStatus, contextBudgetUsageRatio, makeContextBudget } from
2
2
  import { compactionCheckpointCloseTag, compactionCheckpointOpenTag, compactionSummarySourceMessages, defaultCompactionCheckpointHeader, dropLeadingCompactionCheckpointMessage, isCompactionCheckpointMessage, isCompactionCheckpointText, makeCompactionCheckpointMessage, makeCompactionCheckpointText } from "./checkpoint.mjs";
3
3
  import { defaultCharactersPerToken, defaultMediaPartTokens, defaultMessageOverheadTokens, estimateAgentMessageTokens, estimateAgentMessagesTokens, estimateContentTokens, estimateTextTokens } from "./estimator.mjs";
4
4
  import { compactionContentText, defaultCompactionToolOutputMaxCharacters, defaultPreviewSummaryHeader, defaultSummaryPreviewMaxCharacters, formatAgentMessageForCompaction, formatAgentMessagesForCompaction, makePreviewSummaryContent, makePreviewSummaryMessage, previewAgentMessage, truncateCompactionToolOutput, truncateSummaryPreview } from "./summary.mjs";
5
- import { makeContextOverflowRetryProvider } from "./retry.mjs";
5
+ import { applyOverflowCompaction, isOverflowCompactionAttemptCount, makeContextOverflowRetryProvider, overflowCompactionAttemptAllowed, overflowCompactionMaxAttempts, overflowCompactionMayRun } from "./retry.mjs";
6
6
  import { applyCompactionPlan, defaultCompactionTailMessageCount, defaultMinimumCompactionMessages, planWindowCompaction, windowTailStartIndex } from "./window.mjs";
7
7
  import { compactWindowMessages, makeWindowCompactionTransformer } from "./transformer.mjs";
8
- export { applyCompactionPlan, compactWindowMessages, compactionCheckpointCloseTag, compactionCheckpointOpenTag, compactionContentText, compactionSummarySourceMessages, contextBudgetStatus, contextBudgetUsageRatio, defaultCharactersPerToken, defaultCompactionCheckpointHeader, defaultCompactionTailMessageCount, defaultCompactionToolOutputMaxCharacters, defaultMediaPartTokens, defaultMessageOverheadTokens, defaultMinimumCompactionMessages, defaultPreviewSummaryHeader, defaultSummaryPreviewMaxCharacters, dropLeadingCompactionCheckpointMessage, estimateAgentMessageTokens, estimateAgentMessagesTokens, estimateContentTokens, estimateTextTokens, formatAgentMessageForCompaction, formatAgentMessagesForCompaction, isCompactionCheckpointMessage, isCompactionCheckpointText, makeCompactionCheckpointMessage, makeCompactionCheckpointText, makeContextBudget, makeContextOverflowRetryProvider, makePreviewSummaryContent, makePreviewSummaryMessage, makeWindowCompactionTransformer, planWindowCompaction, previewAgentMessage, truncateCompactionToolOutput, truncateSummaryPreview, windowTailStartIndex };
8
+ export { applyCompactionPlan, applyOverflowCompaction, compactWindowMessages, compactionCheckpointCloseTag, compactionCheckpointOpenTag, compactionContentText, compactionSummarySourceMessages, contextBudgetStatus, contextBudgetUsageRatio, defaultCharactersPerToken, defaultCompactionCheckpointHeader, defaultCompactionTailMessageCount, defaultCompactionToolOutputMaxCharacters, defaultMediaPartTokens, defaultMessageOverheadTokens, defaultMinimumCompactionMessages, defaultPreviewSummaryHeader, defaultSummaryPreviewMaxCharacters, dropLeadingCompactionCheckpointMessage, estimateAgentMessageTokens, estimateAgentMessagesTokens, estimateContentTokens, estimateTextTokens, formatAgentMessageForCompaction, formatAgentMessagesForCompaction, isCompactionCheckpointMessage, isCompactionCheckpointText, isOverflowCompactionAttemptCount, makeCompactionCheckpointMessage, makeCompactionCheckpointText, makeContextBudget, makeContextOverflowRetryProvider, makePreviewSummaryContent, makePreviewSummaryMessage, makeWindowCompactionTransformer, overflowCompactionAttemptAllowed, overflowCompactionMaxAttempts, overflowCompactionMayRun, planWindowCompaction, previewAgentMessage, truncateCompactionToolOutput, truncateSummaryPreview, windowTailStartIndex };
@@ -10,6 +10,12 @@ type ContextOverflowRetryCompactionResult = {
10
10
  readonly _tag: 'Skipped';
11
11
  readonly messages: ReadonlyArray<AgentMessage>;
12
12
  };
13
+ type OverflowCompactionDecision = {
14
+ readonly _tag: 'Compacted';
15
+ readonly messages: ReadonlyArray<AgentMessage>;
16
+ } | {
17
+ readonly _tag: 'Skipped';
18
+ };
13
19
  type ContextOverflowRetryCompactor = (messages: ReadonlyArray<AgentMessage>) => Effect.Effect<ContextOverflowRetryCompactionResult, unknown>;
14
20
  type ContextOverflowRetryProviderInput = {
15
21
  readonly provider: {
@@ -18,9 +24,24 @@ type ContextOverflowRetryProviderInput = {
18
24
  readonly messagesRef?: Ref.Ref<ReadonlyArray<AgentMessage>>;
19
25
  readonly compact: ContextOverflowRetryCompactor;
20
26
  };
27
+ type OverflowCompactionInput = ContextOverflowRetryCompactionResult | OverflowCompactionDecision;
28
+ /** Durable persist-then-retry and in-process silent retry both compact at most once. */
29
+ declare const overflowCompactionMaxAttempts = 1;
30
+ declare const isOverflowCompactionAttemptCount: (attempt: number) => boolean;
31
+ declare const overflowCompactionAttemptAllowed: (attempt: number) => boolean;
32
+ declare const overflowCompactionMayRun: (input: {
33
+ readonly attempt: number;
34
+ readonly outputStarted: boolean;
35
+ }) => boolean;
36
+ declare const applyOverflowCompaction: <E, R>(input: {
37
+ readonly compact: (messages: ReadonlyArray<AgentMessage>) => Effect.Effect<OverflowCompactionInput, E, R>;
38
+ readonly messages: ReadonlyArray<AgentMessage>;
39
+ readonly attempt: number;
40
+ readonly outputStarted: boolean;
41
+ }) => Effect.Effect<OverflowCompactionDecision, E, R>;
21
42
  declare const makeContextOverflowRetryProvider: (input: ContextOverflowRetryProviderInput) => Effect.Effect<{
22
43
  readonly stream: (request: LLMRequest) => Stream.Stream<LLMEvent, LLMProviderError>;
23
44
  }, never, never>;
24
45
  //#endregion
25
- export { ContextOverflowRetryCompactionResult, ContextOverflowRetryCompactor, ContextOverflowRetryProviderInput, makeContextOverflowRetryProvider };
46
+ export { ContextOverflowRetryCompactionResult, ContextOverflowRetryCompactor, ContextOverflowRetryProviderInput, OverflowCompactionDecision, applyOverflowCompaction, isOverflowCompactionAttemptCount, makeContextOverflowRetryProvider, overflowCompactionAttemptAllowed, overflowCompactionMaxAttempts, overflowCompactionMayRun };
26
47
  //# sourceMappingURL=retry.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"retry.d.mts","names":[],"sources":["../../src/compaction/retry.ts"],"mappings":";;;;;KASY,oCAAA;EAAA,SAEG,IAAA;EAAA,SACA,QAAA,EAAU,aAAA,CAAc,YAAA;AAAA;EAAA,SAGxB,IAAA;EAAA,SACA,QAAA,EAAU,aAAA,CAAc,YAAA;AAAA;AAAA,KAG3B,6BAAA,IACV,QAAA,EAAU,aAAA,CAAc,YAAA,MACrB,MAAA,CAAO,MAAA,CAAO,oCAAA;AAAA,KAEP,iCAAA;EAAA,SACD,QAAA;IAAA,SACE,MAAA,GAAS,OAAA,EAAS,UAAA,KAAe,MAAA,CAAO,MAAA,CAAO,QAAA,EAAU,gBAAA;EAAA;EAAA,SAE3D,WAAA,GAAc,GAAA,CAAI,GAAA,CAAI,aAAA,CAAc,YAAA;EAAA,SACpC,OAAA,EAAS,6BAAA;AAAA;AAAA,cAyCP,gCAAA,GAAoC,KAAA,EAAO,iCAAA,KAAiC,MAAA,CAAA,MAAA;EAAA"}
1
+ {"version":3,"file":"retry.d.mts","names":[],"sources":["../../src/compaction/retry.ts"],"mappings":";;;;;KASY,oCAAA;EAAA,SAEG,IAAA;EAAA,SACA,QAAA,EAAU,aAAA,CAAc,YAAA;AAAA;EAAA,SAGxB,IAAA;EAAA,SACA,QAAA,EAAU,aAAA,CAAc,YAAA;AAAA;AAAA,KAG3B,0BAAA;EAAA,SAEG,IAAA;EAAA,SACA,QAAA,EAAU,aAAa,CAAC,YAAA;AAAA;EAAA,SAGxB,IAAA;AAAA;AAAA,KAGH,6BAAA,IACV,QAAA,EAAU,aAAA,CAAc,YAAA,MACrB,MAAA,CAAO,MAAA,CAAO,oCAAA;AAAA,KAEP,iCAAA;EAAA,SACD,QAAA;IAAA,SACE,MAAA,GAAS,OAAA,EAAS,UAAA,KAAe,MAAA,CAAO,MAAA,CAAO,QAAA,EAAU,gBAAA;EAAA;EAAA,SAE3D,WAAA,GAAc,GAAA,CAAI,GAAA,CAAI,aAAA,CAAc,YAAA;EAAA,SACpC,OAAA,EAAS,6BAAA;AAAA;AAAA,KAGf,uBAAA,GAA0B,oCAAA,GAAuC,0BAA0B;;cAGnF,6BAAA;AAAA,cAEA,gCAAA,GAAoC,OAAe;AAAA,cAGnD,gCAAA,GAAoC,OAAe;AAAA,cAGnD,wBAAA,GAA4B,KAAA;EAAA,SAC9B,OAAA;EAAA,SACA,aAAA;AAAA;AAAA,cAkBE,uBAAA,SAAiC,KAAA;EAAA,SACnC,OAAA,GACP,QAAA,EAAU,aAAA,CAAc,YAAA,MACrB,MAAA,CAAO,MAAA,CAAO,uBAAA,EAAyB,CAAA,EAAG,CAAA;EAAA,SACtC,QAAA,EAAU,aAAA,CAAc,YAAA;EAAA,SACxB,OAAA;EAAA,SACA,aAAA;AAAA,MACP,MAAA,CAAO,MAAA,CAAO,0BAAA,EAA4B,CAAA,EAAG,CAAA;AAAA,cA4DpC,gCAAA,GAAoC,KAAA,EAAO,iCAAA,KAAiC,MAAA,CAAA,MAAA;EAAA"}
@@ -1,21 +1,54 @@
1
1
  import { Effect, Ref, Stream } from "effect";
2
2
  import { LLMProvider } from "@yolk-sdk/agent/loop";
3
3
  //#region src/compaction/retry.ts
4
- const contextOverflowRetryStream = (input, retried, request) => input.provider.stream(request).pipe(Stream.catchTags({ LLMError: (error) => {
4
+ /** Durable persist-then-retry and in-process silent retry both compact at most once. */
5
+ const overflowCompactionMaxAttempts = 1;
6
+ const isOverflowCompactionAttemptCount = (attempt) => Number.isSafeInteger(attempt) && attempt >= 0;
7
+ const overflowCompactionAttemptAllowed = (attempt) => isOverflowCompactionAttemptCount(attempt) && attempt < 1;
8
+ const overflowCompactionMayRun = (input) => overflowCompactionAttemptAllowed(input.attempt) && !input.outputStarted;
9
+ const llmEventStartsOutput = (event) => {
10
+ switch (event._tag) {
11
+ case "TextDelta":
12
+ case "ReasoningDelta":
13
+ case "ToolCall":
14
+ case "ToolInputStart":
15
+ case "ToolInputDelta":
16
+ case "ProviderToolResult": return true;
17
+ case "Done":
18
+ case "Usage": return false;
19
+ }
20
+ };
21
+ const applyOverflowCompaction = (input) => {
22
+ if (!overflowCompactionMayRun(input)) return Effect.succeed({ _tag: "Skipped" });
23
+ return input.compact(input.messages).pipe(Effect.map((result) => result._tag === "Compacted" ? {
24
+ _tag: "Compacted",
25
+ messages: result.messages
26
+ } : { _tag: "Skipped" }));
27
+ };
28
+ const contextOverflowRetryStream = (input, attempts, outputStarted, request) => input.provider.stream(request).pipe(Stream.tap((event) => llmEventStartsOutput(event) ? Ref.set(outputStarted, true) : Effect.void), Stream.catchTags({ LLMError: (error) => {
5
29
  if (error.cause !== "context_overflow") return Stream.fail(error);
6
- return Stream.unwrap(Ref.get(retried).pipe(Effect.flatMap((alreadyRetried) => {
7
- if (alreadyRetried) return Effect.succeed(Stream.fail(error));
8
- return Ref.set(retried, true).pipe(Effect.flatMap(() => input.compact(request.messages)), Effect.flatMap((result) => {
9
- if (result._tag === "Skipped") return Effect.succeed(Stream.fail(error));
10
- return (input.messagesRef === void 0 ? Effect.void : Ref.set(input.messagesRef, result.messages)).pipe(Effect.as(input.provider.stream({
11
- ...request,
12
- messages: result.messages
13
- })));
14
- }), Effect.catch(() => Effect.succeed(Stream.fail(error))));
15
- })));
30
+ return Stream.unwrap(Effect.gen(function* () {
31
+ const attempt = yield* Ref.get(attempts);
32
+ const started = yield* Ref.get(outputStarted);
33
+ const decision = yield* applyOverflowCompaction({
34
+ compact: input.compact,
35
+ messages: request.messages,
36
+ attempt,
37
+ outputStarted: started
38
+ }).pipe(Effect.catch(() => Effect.succeed({ _tag: "Skipped" })));
39
+ yield* Ref.set(attempts, attempt + 1);
40
+ if (decision._tag === "Skipped") return Stream.fail(error);
41
+ if (input.messagesRef !== void 0) yield* Ref.set(input.messagesRef, decision.messages);
42
+ return input.provider.stream({
43
+ ...request,
44
+ messages: decision.messages
45
+ }).pipe(Stream.tap((event) => llmEventStartsOutput(event) ? Ref.set(outputStarted, true) : Effect.void));
46
+ }));
16
47
  } }));
17
- const makeContextOverflowRetryProvider = (input) => Effect.succeed(LLMProvider.of({ stream: (request) => Stream.unwrap(Ref.make(false).pipe(Effect.map((retried) => contextOverflowRetryStream(input, retried, request)))) }));
48
+ const makeContextOverflowRetryProvider = (input) => Effect.succeed(LLMProvider.of({ stream: (request) => Stream.unwrap(Effect.gen(function* () {
49
+ return contextOverflowRetryStream(input, yield* Ref.make(0), yield* Ref.make(false), request);
50
+ })) }));
18
51
  //#endregion
19
- export { makeContextOverflowRetryProvider };
52
+ export { applyOverflowCompaction, isOverflowCompactionAttemptCount, makeContextOverflowRetryProvider, overflowCompactionAttemptAllowed, overflowCompactionMaxAttempts, overflowCompactionMayRun };
20
53
 
21
54
  //# sourceMappingURL=retry.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"retry.mjs","names":[],"sources":["../../src/compaction/retry.ts"],"sourcesContent":["import { Effect, Ref, Stream } from 'effect'\nimport type { AgentMessage } from '@yolk-sdk/agent/protocol'\nimport {\n LLMProvider,\n type LLMEvent,\n type LLMProviderError,\n type LLMRequest\n} from '@yolk-sdk/agent/loop'\n\nexport type ContextOverflowRetryCompactionResult =\n | {\n readonly _tag: 'Compacted'\n readonly messages: ReadonlyArray<AgentMessage>\n }\n | {\n readonly _tag: 'Skipped'\n readonly messages: ReadonlyArray<AgentMessage>\n }\n\nexport type ContextOverflowRetryCompactor = (\n messages: ReadonlyArray<AgentMessage>\n) => Effect.Effect<ContextOverflowRetryCompactionResult, unknown>\n\nexport type ContextOverflowRetryProviderInput = {\n readonly provider: {\n readonly stream: (request: LLMRequest) => Stream.Stream<LLMEvent, LLMProviderError>\n }\n readonly messagesRef?: Ref.Ref<ReadonlyArray<AgentMessage>>\n readonly compact: ContextOverflowRetryCompactor\n}\n\nconst contextOverflowRetryStream = (\n input: ContextOverflowRetryProviderInput,\n retried: Ref.Ref<boolean>,\n request: LLMRequest\n) =>\n input.provider.stream(request).pipe(\n Stream.catchTags({\n LLMError: error => {\n if (error.cause !== 'context_overflow') return Stream.fail(error)\n\n return Stream.unwrap(\n Ref.get(retried).pipe(\n Effect.flatMap(alreadyRetried => {\n if (alreadyRetried) return Effect.succeed(Stream.fail(error))\n\n return Ref.set(retried, true).pipe(\n Effect.flatMap(() => input.compact(request.messages)),\n Effect.flatMap(result => {\n if (result._tag === 'Skipped') return Effect.succeed(Stream.fail(error))\n\n const setMessages =\n input.messagesRef === undefined\n ? Effect.void\n : Ref.set(input.messagesRef, result.messages)\n\n return setMessages.pipe(\n Effect.as(input.provider.stream({ ...request, messages: result.messages }))\n )\n }),\n Effect.catch(() => Effect.succeed(Stream.fail(error)))\n )\n })\n )\n )\n }\n })\n )\n\nexport const makeContextOverflowRetryProvider = (input: ContextOverflowRetryProviderInput) =>\n Effect.succeed(\n LLMProvider.of({\n stream: request =>\n Stream.unwrap(\n Ref.make(false).pipe(\n Effect.map(retried => contextOverflowRetryStream(input, retried, request))\n )\n )\n })\n )\n"],"mappings":";;;AA+BA,MAAM,8BACJ,OACA,SACA,YAEA,MAAM,SAAS,OAAO,OAAO,EAAE,KAC7B,OAAO,UAAU,EACf,WAAU,UAAS;CACjB,IAAI,MAAM,UAAU,oBAAoB,OAAO,OAAO,KAAK,KAAK;CAEhE,OAAO,OAAO,OACZ,IAAI,IAAI,OAAO,EAAE,KACf,OAAO,SAAQ,mBAAkB;EAC/B,IAAI,gBAAgB,OAAO,OAAO,QAAQ,OAAO,KAAK,KAAK,CAAC;EAE5D,OAAO,IAAI,IAAI,SAAS,IAAI,EAAE,KAC5B,OAAO,cAAc,MAAM,QAAQ,QAAQ,QAAQ,CAAC,GACpD,OAAO,SAAQ,WAAU;GACvB,IAAI,OAAO,SAAS,WAAW,OAAO,OAAO,QAAQ,OAAO,KAAK,KAAK,CAAC;GAOvE,QAJE,MAAM,gBAAgB,KAAA,IAClB,OAAO,OACP,IAAI,IAAI,MAAM,aAAa,OAAO,QAAQ,GAE7B,KACjB,OAAO,GAAG,MAAM,SAAS,OAAO;IAAE,GAAG;IAAS,UAAU,OAAO;GAAS,CAAC,CAAC,CAC5E;EACF,CAAC,GACD,OAAO,YAAY,OAAO,QAAQ,OAAO,KAAK,KAAK,CAAC,CAAC,CACvD;CACF,CAAC,CACH,CACF;AACF,EACF,CAAC,CACH;AAEF,MAAa,oCAAoC,UAC/C,OAAO,QACL,YAAY,GAAG,EACb,SAAQ,YACN,OAAO,OACL,IAAI,KAAK,KAAK,EAAE,KACd,OAAO,KAAI,YAAW,2BAA2B,OAAO,SAAS,OAAO,CAAC,CAC3E,CACF,EACJ,CAAC,CACH"}
1
+ {"version":3,"file":"retry.mjs","names":[],"sources":["../../src/compaction/retry.ts"],"sourcesContent":["import { Effect, Ref, Stream } from 'effect'\nimport type { AgentMessage } from '@yolk-sdk/agent/protocol'\nimport {\n LLMProvider,\n type LLMEvent,\n type LLMProviderError,\n type LLMRequest\n} from '@yolk-sdk/agent/loop'\n\nexport type ContextOverflowRetryCompactionResult =\n | {\n readonly _tag: 'Compacted'\n readonly messages: ReadonlyArray<AgentMessage>\n }\n | {\n readonly _tag: 'Skipped'\n readonly messages: ReadonlyArray<AgentMessage>\n }\n\nexport type OverflowCompactionDecision =\n | {\n readonly _tag: 'Compacted'\n readonly messages: ReadonlyArray<AgentMessage>\n }\n | {\n readonly _tag: 'Skipped'\n }\n\nexport type ContextOverflowRetryCompactor = (\n messages: ReadonlyArray<AgentMessage>\n) => Effect.Effect<ContextOverflowRetryCompactionResult, unknown>\n\nexport type ContextOverflowRetryProviderInput = {\n readonly provider: {\n readonly stream: (request: LLMRequest) => Stream.Stream<LLMEvent, LLMProviderError>\n }\n readonly messagesRef?: Ref.Ref<ReadonlyArray<AgentMessage>>\n readonly compact: ContextOverflowRetryCompactor\n}\n\ntype OverflowCompactionInput = ContextOverflowRetryCompactionResult | OverflowCompactionDecision\n\n/** Durable persist-then-retry and in-process silent retry both compact at most once. */\nexport const overflowCompactionMaxAttempts = 1\n\nexport const isOverflowCompactionAttemptCount = (attempt: number) =>\n Number.isSafeInteger(attempt) && attempt >= 0\n\nexport const overflowCompactionAttemptAllowed = (attempt: number) =>\n isOverflowCompactionAttemptCount(attempt) && attempt < overflowCompactionMaxAttempts\n\nexport const overflowCompactionMayRun = (input: {\n readonly attempt: number\n readonly outputStarted: boolean\n}) => overflowCompactionAttemptAllowed(input.attempt) && !input.outputStarted\n\nconst llmEventStartsOutput = (event: LLMEvent) => {\n switch (event._tag) {\n case 'TextDelta':\n case 'ReasoningDelta':\n case 'ToolCall':\n case 'ToolInputStart':\n case 'ToolInputDelta':\n case 'ProviderToolResult':\n return true\n case 'Done':\n case 'Usage':\n return false\n }\n}\n\nexport const applyOverflowCompaction = <E, R>(input: {\n readonly compact: (\n messages: ReadonlyArray<AgentMessage>\n ) => Effect.Effect<OverflowCompactionInput, E, R>\n readonly messages: ReadonlyArray<AgentMessage>\n readonly attempt: number\n readonly outputStarted: boolean\n}): Effect.Effect<OverflowCompactionDecision, E, R> => {\n if (!overflowCompactionMayRun(input)) {\n return Effect.succeed({ _tag: 'Skipped' })\n }\n\n return input\n .compact(input.messages)\n .pipe(\n Effect.map(result =>\n result._tag === 'Compacted'\n ? { _tag: 'Compacted' as const, messages: result.messages }\n : { _tag: 'Skipped' as const }\n )\n )\n}\n\nconst contextOverflowRetryStream = (\n input: ContextOverflowRetryProviderInput,\n attempts: Ref.Ref<number>,\n outputStarted: Ref.Ref<boolean>,\n request: LLMRequest\n) =>\n input.provider.stream(request).pipe(\n Stream.tap(event => (llmEventStartsOutput(event) ? Ref.set(outputStarted, true) : Effect.void)),\n Stream.catchTags({\n LLMError: error => {\n if (error.cause !== 'context_overflow') return Stream.fail(error)\n\n return Stream.unwrap(\n Effect.gen(function* () {\n const attempt = yield* Ref.get(attempts)\n const started = yield* Ref.get(outputStarted)\n const decision = yield* applyOverflowCompaction({\n compact: input.compact,\n messages: request.messages,\n attempt,\n outputStarted: started\n }).pipe(Effect.catch(() => Effect.succeed({ _tag: 'Skipped' as const })))\n\n yield* Ref.set(attempts, attempt + 1)\n\n if (decision._tag === 'Skipped') return Stream.fail(error)\n\n if (input.messagesRef !== undefined) {\n yield* Ref.set(input.messagesRef, decision.messages)\n }\n\n return input.provider\n .stream({ ...request, messages: decision.messages })\n .pipe(\n Stream.tap(event =>\n llmEventStartsOutput(event) ? Ref.set(outputStarted, true) : Effect.void\n )\n )\n })\n )\n }\n })\n )\n\nexport const makeContextOverflowRetryProvider = (input: ContextOverflowRetryProviderInput) =>\n Effect.succeed(\n LLMProvider.of({\n stream: request =>\n Stream.unwrap(\n Effect.gen(function* () {\n const attempts = yield* Ref.make(0)\n const outputStarted = yield* Ref.make(false)\n return contextOverflowRetryStream(input, attempts, outputStarted, request)\n })\n )\n })\n )\n"],"mappings":";;;;AA2CA,MAAa,gCAAgC;AAE7C,MAAa,oCAAoC,YAC/C,OAAO,cAAc,OAAO,KAAK,WAAW;AAE9C,MAAa,oCAAoC,YAC/C,iCAAiC,OAAO,KAAK,UAAA;AAE/C,MAAa,4BAA4B,UAGnC,iCAAiC,MAAM,OAAO,KAAK,CAAC,MAAM;AAEhE,MAAM,wBAAwB,UAAoB;CAChD,QAAQ,MAAM,MAAd;EACE,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK,sBACH,OAAO;EACT,KAAK;EACL,KAAK,SACH,OAAO;CACX;AACF;AAEA,MAAa,2BAAiC,UAOS;CACrD,IAAI,CAAC,yBAAyB,KAAK,GACjC,OAAO,OAAO,QAAQ,EAAE,MAAM,UAAU,CAAC;CAG3C,OAAO,MACJ,QAAQ,MAAM,QAAQ,EACtB,KACC,OAAO,KAAI,WACT,OAAO,SAAS,cACZ;EAAE,MAAM;EAAsB,UAAU,OAAO;CAAS,IACxD,EAAE,MAAM,UAAmB,CACjC,CACF;AACJ;AAEA,MAAM,8BACJ,OACA,UACA,eACA,YAEA,MAAM,SAAS,OAAO,OAAO,EAAE,KAC7B,OAAO,KAAI,UAAU,qBAAqB,KAAK,IAAI,IAAI,IAAI,eAAe,IAAI,IAAI,OAAO,IAAK,GAC9F,OAAO,UAAU,EACf,WAAU,UAAS;CACjB,IAAI,MAAM,UAAU,oBAAoB,OAAO,OAAO,KAAK,KAAK;CAEhE,OAAO,OAAO,OACZ,OAAO,IAAI,aAAa;EACtB,MAAM,UAAU,OAAO,IAAI,IAAI,QAAQ;EACvC,MAAM,UAAU,OAAO,IAAI,IAAI,aAAa;EAC5C,MAAM,WAAW,OAAO,wBAAwB;GAC9C,SAAS,MAAM;GACf,UAAU,QAAQ;GAClB;GACA,eAAe;EACjB,CAAC,EAAE,KAAK,OAAO,YAAY,OAAO,QAAQ,EAAE,MAAM,UAAmB,CAAC,CAAC,CAAC;EAExE,OAAO,IAAI,IAAI,UAAU,UAAU,CAAC;EAEpC,IAAI,SAAS,SAAS,WAAW,OAAO,OAAO,KAAK,KAAK;EAEzD,IAAI,MAAM,gBAAgB,KAAA,GACxB,OAAO,IAAI,IAAI,MAAM,aAAa,SAAS,QAAQ;EAGrD,OAAO,MAAM,SACV,OAAO;GAAE,GAAG;GAAS,UAAU,SAAS;EAAS,CAAC,EAClD,KACC,OAAO,KAAI,UACT,qBAAqB,KAAK,IAAI,IAAI,IAAI,eAAe,IAAI,IAAI,OAAO,IACtE,CACF;CACJ,CAAC,CACH;AACF,EACF,CAAC,CACH;AAEF,MAAa,oCAAoC,UAC/C,OAAO,QACL,YAAY,GAAG,EACb,SAAQ,YACN,OAAO,OACL,OAAO,IAAI,aAAa;CAGtB,OAAO,2BAA2B,OAAO,OAFjB,IAAI,KAAK,CAAC,GAEiB,OADtB,IAAI,KAAK,KAAK,GACuB,OAAO;AAC3E,CAAC,CACH,EACJ,CAAC,CACH"}
@@ -1,11 +1,13 @@
1
1
  import { LLMEvent } from "./llm-event.mjs";
2
- import { AssistantAgentMessage } from "@yolk-sdk/agent/protocol";
2
+ import { AssistantAgentMessage, AssistantPart } from "@yolk-sdk/agent/protocol";
3
3
 
4
4
  //#region src/loop/accumulator.d.ts
5
5
  declare const collectText: (events: ReadonlyArray<LLMEvent>) => string;
6
6
  declare const collectReasoning: (events: ReadonlyArray<LLMEvent>) => string;
7
7
  declare const collectToolCalls: (events: ReadonlyArray<LLMEvent>) => import("@yolk-sdk/agent/protocol").ToolCall[];
8
+ /** Incremental assistant-part reducer. Shared with collect; not a public loop export. */
9
+ declare const applyAssistantLlmEvent: (parts: ReadonlyArray<AssistantPart>, event: LLMEvent) => ReadonlyArray<AssistantPart>;
8
10
  declare const accumulateAssistantMessage: (events: ReadonlyArray<LLMEvent>) => AssistantAgentMessage;
9
11
  //#endregion
10
- export { accumulateAssistantMessage, collectReasoning, collectText, collectToolCalls };
12
+ export { accumulateAssistantMessage, applyAssistantLlmEvent, collectReasoning, collectText, collectToolCalls };
11
13
  //# sourceMappingURL=accumulator.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"accumulator.d.mts","names":[],"sources":["../../src/loop/accumulator.ts"],"mappings":";;;;cAYa,WAAA,GAAe,MAAA,EAAQ,aAAa,CAAC,QAAA;AAAA,cAGrC,gBAAA,GAAoB,MAAA,EAAQ,aAAa,CAAC,QAAA;AAAA,cAM1C,gBAAA,GAAoB,MAAA,EAAQ,aAAa,CAAC,QAAA,yCAAS,QAAA;AAAA,cA6CnD,0BAAA,GAA8B,MAAA,EAAQ,aAAA,CAAc,QAAA,MAAS,qBAAA"}
1
+ {"version":3,"file":"accumulator.d.mts","names":[],"sources":["../../src/loop/accumulator.ts"],"mappings":";;;;cAYa,WAAA,GAAe,MAAA,EAAQ,aAAa,CAAC,QAAA;AAAA,cAGrC,gBAAA,GAAoB,MAAA,EAAQ,aAAa,CAAC,QAAA;AAAA,cAM1C,gBAAA,GAAoB,MAAA,EAAQ,aAAa,CAAC,QAAA,yCAAS,QAAA;;cAInD,sBAAA,GACX,KAAA,EAAO,aAAA,CAAc,aAAA,GACrB,KAAA,EAAO,QAAA,KACN,aAAA,CAAc,aAAA;AAAA,cA4CJ,0BAAA,GAA8B,MAAA,EAAQ,aAAA,CAAc,QAAA,MAAS,qBAAA"}
@@ -3,15 +3,8 @@ import { AssistantAgentMessage, AssistantReasoningPart, AssistantTextPart, HostT
3
3
  const collectText = (events) => events.reduce((text, event) => event._tag === "TextDelta" ? `${text}${event.text}` : text, "");
4
4
  const collectReasoning = (events) => events.reduce((text, event) => event._tag === "ReasoningDelta" ? `${text}${event.text}` : text, "");
5
5
  const collectToolCalls = (events) => events.flatMap((event) => event._tag === "ToolCall" ? [event.call] : []);
6
- const appendTextPart = (parts, text) => {
7
- const last = parts.at(-1);
8
- return last?._tag === "Text" ? [...parts.slice(0, -1), AssistantTextPart.make({ content: appendTextToContent(last.content, text) })] : [...parts, AssistantTextPart.make({ content: text })];
9
- };
10
- const appendReasoningPart = (parts, text) => {
11
- const last = parts.at(-1);
12
- return last?._tag === "Reasoning" ? [...parts.slice(0, -1), AssistantReasoningPart.make({ text: `${last.text}${text}` })] : [...parts, AssistantReasoningPart.make({ text })];
13
- };
14
- const accumulateAssistantParts = (events) => events.reduce((parts, event) => {
6
+ /** Incremental assistant-part reducer. Shared with collect; not a public loop export. */
7
+ const applyAssistantLlmEvent = (parts, event) => {
15
8
  switch (event._tag) {
16
9
  case "TextDelta": return appendTextPart(parts, event.text);
17
10
  case "ReasoningDelta": return appendReasoningPart(parts, event.text);
@@ -29,12 +22,21 @@ const accumulateAssistantParts = (events) => events.reduce((parts, event) => {
29
22
  case "ToolInputStart":
30
23
  case "Usage": return parts;
31
24
  }
32
- }, []);
25
+ };
26
+ const appendTextPart = (parts, text) => {
27
+ const last = parts.at(-1);
28
+ return last?._tag === "Text" ? [...parts.slice(0, -1), AssistantTextPart.make({ content: appendTextToContent(last.content, text) })] : [...parts, AssistantTextPart.make({ content: text })];
29
+ };
30
+ const appendReasoningPart = (parts, text) => {
31
+ const last = parts.at(-1);
32
+ return last?._tag === "Reasoning" ? [...parts.slice(0, -1), AssistantReasoningPart.make({ text: `${last.text}${text}` })] : [...parts, AssistantReasoningPart.make({ text })];
33
+ };
34
+ const accumulateAssistantParts = (events) => events.reduce(applyAssistantLlmEvent, []);
33
35
  const accumulateAssistantMessage = (events) => {
34
36
  const parts = accumulateAssistantParts(events);
35
37
  return AssistantAgentMessage.make({ parts });
36
38
  };
37
39
  //#endregion
38
- export { accumulateAssistantMessage, collectReasoning, collectText, collectToolCalls };
40
+ export { accumulateAssistantMessage, applyAssistantLlmEvent, collectReasoning, collectText, collectToolCalls };
39
41
 
40
42
  //# sourceMappingURL=accumulator.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"accumulator.mjs","names":[],"sources":["../../src/loop/accumulator.ts"],"sourcesContent":["import {\n AssistantAgentMessage,\n AssistantReasoningPart,\n AssistantTextPart,\n appendTextToContent,\n HostToolCallPart,\n ProviderToolCallPart,\n ProviderToolResultPart,\n type AssistantPart\n} from '@yolk-sdk/agent/protocol'\nimport type { LLMEvent } from './llm-event.ts'\n\nexport const collectText = (events: ReadonlyArray<LLMEvent>) =>\n events.reduce((text, event) => (event._tag === 'TextDelta' ? `${text}${event.text}` : text), '')\n\nexport const collectReasoning = (events: ReadonlyArray<LLMEvent>) =>\n events.reduce(\n (text, event) => (event._tag === 'ReasoningDelta' ? `${text}${event.text}` : text),\n ''\n )\n\nexport const collectToolCalls = (events: ReadonlyArray<LLMEvent>) =>\n events.flatMap(event => (event._tag === 'ToolCall' ? [event.call] : []))\n\nconst appendTextPart = (parts: ReadonlyArray<AssistantPart>, text: string) => {\n const last = parts.at(-1)\n\n return last?._tag === 'Text'\n ? [\n ...parts.slice(0, -1),\n AssistantTextPart.make({ content: appendTextToContent(last.content, text) })\n ]\n : [...parts, AssistantTextPart.make({ content: text })]\n}\n\nconst appendReasoningPart = (parts: ReadonlyArray<AssistantPart>, text: string) => {\n const last = parts.at(-1)\n\n return last?._tag === 'Reasoning'\n ? [...parts.slice(0, -1), AssistantReasoningPart.make({ text: `${last.text}${text}` })]\n : [...parts, AssistantReasoningPart.make({ text })]\n}\n\nconst accumulateAssistantParts = (events: ReadonlyArray<LLMEvent>) =>\n events.reduce<ReadonlyArray<AssistantPart>>((parts, event) => {\n switch (event._tag) {\n case 'TextDelta':\n return appendTextPart(parts, event.text)\n case 'ReasoningDelta':\n return appendReasoningPart(parts, event.text)\n case 'ToolCall':\n return [...parts, HostToolCallPart.make({ call: event.call })]\n case 'ProviderToolResult':\n return [\n ...parts,\n ProviderToolCallPart.make({ call: event.call }),\n ProviderToolResultPart.make({ toolCallId: event.call.id, result: event.result })\n ]\n case 'Done':\n case 'ToolInputDelta':\n case 'ToolInputStart':\n case 'Usage':\n return parts\n }\n }, [])\n\nexport const accumulateAssistantMessage = (events: ReadonlyArray<LLMEvent>) => {\n const parts = accumulateAssistantParts(events)\n\n return AssistantAgentMessage.make({ parts })\n}\n"],"mappings":";;AAYA,MAAa,eAAe,WAC1B,OAAO,QAAQ,MAAM,UAAW,MAAM,SAAS,cAAc,GAAG,OAAO,MAAM,SAAS,MAAO,EAAE;AAEjG,MAAa,oBAAoB,WAC/B,OAAO,QACJ,MAAM,UAAW,MAAM,SAAS,mBAAmB,GAAG,OAAO,MAAM,SAAS,MAC7E,EACF;AAEF,MAAa,oBAAoB,WAC/B,OAAO,SAAQ,UAAU,MAAM,SAAS,aAAa,CAAC,MAAM,IAAI,IAAI,CAAC,CAAE;AAEzE,MAAM,kBAAkB,OAAqC,SAAiB;CAC5E,MAAM,OAAO,MAAM,GAAG,EAAE;CAExB,OAAO,MAAM,SAAS,SAClB,CACE,GAAG,MAAM,MAAM,GAAG,EAAE,GACpB,kBAAkB,KAAK,EAAE,SAAS,oBAAoB,KAAK,SAAS,IAAI,EAAE,CAAC,CAC7E,IACA,CAAC,GAAG,OAAO,kBAAkB,KAAK,EAAE,SAAS,KAAK,CAAC,CAAC;AAC1D;AAEA,MAAM,uBAAuB,OAAqC,SAAiB;CACjF,MAAM,OAAO,MAAM,GAAG,EAAE;CAExB,OAAO,MAAM,SAAS,cAClB,CAAC,GAAG,MAAM,MAAM,GAAG,EAAE,GAAG,uBAAuB,KAAK,EAAE,MAAM,GAAG,KAAK,OAAO,OAAO,CAAC,CAAC,IACpF,CAAC,GAAG,OAAO,uBAAuB,KAAK,EAAE,KAAK,CAAC,CAAC;AACtD;AAEA,MAAM,4BAA4B,WAChC,OAAO,QAAsC,OAAO,UAAU;CAC5D,QAAQ,MAAM,MAAd;EACE,KAAK,aACH,OAAO,eAAe,OAAO,MAAM,IAAI;EACzC,KAAK,kBACH,OAAO,oBAAoB,OAAO,MAAM,IAAI;EAC9C,KAAK,YACH,OAAO,CAAC,GAAG,OAAO,iBAAiB,KAAK,EAAE,MAAM,MAAM,KAAK,CAAC,CAAC;EAC/D,KAAK,sBACH,OAAO;GACL,GAAG;GACH,qBAAqB,KAAK,EAAE,MAAM,MAAM,KAAK,CAAC;GAC9C,uBAAuB,KAAK;IAAE,YAAY,MAAM,KAAK;IAAI,QAAQ,MAAM;GAAO,CAAC;EACjF;EACF,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK,SACH,OAAO;CACX;AACF,GAAG,CAAC,CAAC;AAEP,MAAa,8BAA8B,WAAoC;CAC7E,MAAM,QAAQ,yBAAyB,MAAM;CAE7C,OAAO,sBAAsB,KAAK,EAAE,MAAM,CAAC;AAC7C"}
1
+ {"version":3,"file":"accumulator.mjs","names":[],"sources":["../../src/loop/accumulator.ts"],"sourcesContent":["import {\n AssistantAgentMessage,\n AssistantReasoningPart,\n AssistantTextPart,\n appendTextToContent,\n HostToolCallPart,\n ProviderToolCallPart,\n ProviderToolResultPart,\n type AssistantPart\n} from '@yolk-sdk/agent/protocol'\nimport type { LLMEvent } from './llm-event.ts'\n\nexport const collectText = (events: ReadonlyArray<LLMEvent>) =>\n events.reduce((text, event) => (event._tag === 'TextDelta' ? `${text}${event.text}` : text), '')\n\nexport const collectReasoning = (events: ReadonlyArray<LLMEvent>) =>\n events.reduce(\n (text, event) => (event._tag === 'ReasoningDelta' ? `${text}${event.text}` : text),\n ''\n )\n\nexport const collectToolCalls = (events: ReadonlyArray<LLMEvent>) =>\n events.flatMap(event => (event._tag === 'ToolCall' ? [event.call] : []))\n\n/** Incremental assistant-part reducer. Shared with collect; not a public loop export. */\nexport const applyAssistantLlmEvent = (\n parts: ReadonlyArray<AssistantPart>,\n event: LLMEvent\n): ReadonlyArray<AssistantPart> => {\n switch (event._tag) {\n case 'TextDelta':\n return appendTextPart(parts, event.text)\n case 'ReasoningDelta':\n return appendReasoningPart(parts, event.text)\n case 'ToolCall':\n return [...parts, HostToolCallPart.make({ call: event.call })]\n case 'ProviderToolResult':\n return [\n ...parts,\n ProviderToolCallPart.make({ call: event.call }),\n ProviderToolResultPart.make({ toolCallId: event.call.id, result: event.result })\n ]\n case 'Done':\n case 'ToolInputDelta':\n case 'ToolInputStart':\n case 'Usage':\n return parts\n }\n}\n\nconst appendTextPart = (parts: ReadonlyArray<AssistantPart>, text: string) => {\n const last = parts.at(-1)\n\n return last?._tag === 'Text'\n ? [\n ...parts.slice(0, -1),\n AssistantTextPart.make({ content: appendTextToContent(last.content, text) })\n ]\n : [...parts, AssistantTextPart.make({ content: text })]\n}\n\nconst appendReasoningPart = (parts: ReadonlyArray<AssistantPart>, text: string) => {\n const last = parts.at(-1)\n\n return last?._tag === 'Reasoning'\n ? [...parts.slice(0, -1), AssistantReasoningPart.make({ text: `${last.text}${text}` })]\n : [...parts, AssistantReasoningPart.make({ text })]\n}\n\nconst accumulateAssistantParts = (events: ReadonlyArray<LLMEvent>) =>\n events.reduce<ReadonlyArray<AssistantPart>>(applyAssistantLlmEvent, [])\n\nexport const accumulateAssistantMessage = (events: ReadonlyArray<LLMEvent>) => {\n const parts = accumulateAssistantParts(events)\n\n return AssistantAgentMessage.make({ parts })\n}\n"],"mappings":";;AAYA,MAAa,eAAe,WAC1B,OAAO,QAAQ,MAAM,UAAW,MAAM,SAAS,cAAc,GAAG,OAAO,MAAM,SAAS,MAAO,EAAE;AAEjG,MAAa,oBAAoB,WAC/B,OAAO,QACJ,MAAM,UAAW,MAAM,SAAS,mBAAmB,GAAG,OAAO,MAAM,SAAS,MAC7E,EACF;AAEF,MAAa,oBAAoB,WAC/B,OAAO,SAAQ,UAAU,MAAM,SAAS,aAAa,CAAC,MAAM,IAAI,IAAI,CAAC,CAAE;;AAGzE,MAAa,0BACX,OACA,UACiC;CACjC,QAAQ,MAAM,MAAd;EACE,KAAK,aACH,OAAO,eAAe,OAAO,MAAM,IAAI;EACzC,KAAK,kBACH,OAAO,oBAAoB,OAAO,MAAM,IAAI;EAC9C,KAAK,YACH,OAAO,CAAC,GAAG,OAAO,iBAAiB,KAAK,EAAE,MAAM,MAAM,KAAK,CAAC,CAAC;EAC/D,KAAK,sBACH,OAAO;GACL,GAAG;GACH,qBAAqB,KAAK,EAAE,MAAM,MAAM,KAAK,CAAC;GAC9C,uBAAuB,KAAK;IAAE,YAAY,MAAM,KAAK;IAAI,QAAQ,MAAM;GAAO,CAAC;EACjF;EACF,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK,SACH,OAAO;CACX;AACF;AAEA,MAAM,kBAAkB,OAAqC,SAAiB;CAC5E,MAAM,OAAO,MAAM,GAAG,EAAE;CAExB,OAAO,MAAM,SAAS,SAClB,CACE,GAAG,MAAM,MAAM,GAAG,EAAE,GACpB,kBAAkB,KAAK,EAAE,SAAS,oBAAoB,KAAK,SAAS,IAAI,EAAE,CAAC,CAC7E,IACA,CAAC,GAAG,OAAO,kBAAkB,KAAK,EAAE,SAAS,KAAK,CAAC,CAAC;AAC1D;AAEA,MAAM,uBAAuB,OAAqC,SAAiB;CACjF,MAAM,OAAO,MAAM,GAAG,EAAE;CAExB,OAAO,MAAM,SAAS,cAClB,CAAC,GAAG,MAAM,MAAM,GAAG,EAAE,GAAG,uBAAuB,KAAK,EAAE,MAAM,GAAG,KAAK,OAAO,OAAO,CAAC,CAAC,IACpF,CAAC,GAAG,OAAO,uBAAuB,KAAK,EAAE,KAAK,CAAC,CAAC;AACtD;AAEA,MAAM,4BAA4B,WAChC,OAAO,OAAqC,wBAAwB,CAAC,CAAC;AAExE,MAAa,8BAA8B,WAAoC;CAC7E,MAAM,QAAQ,yBAAyB,MAAM;CAE7C,OAAO,sBAAsB,KAAK,EAAE,MAAM,CAAC;AAC7C"}
@@ -0,0 +1,37 @@
1
+ import { Effect, Stream } from "effect";
2
+ import { AgentEvent, AgentMessage, AgentUsage, ToolCall } from "@yolk-sdk/agent/protocol";
3
+
4
+ //#region src/loop/collect.d.ts
5
+ type ModelTurnResult = {
6
+ readonly assistantMessage: AgentMessage | undefined;
7
+ readonly toolCalls: ReadonlyArray<ToolCall>;
8
+ readonly usage: AgentUsage;
9
+ readonly stopReason: 'stop' | 'tool_use';
10
+ };
11
+ type ModelTurnCollection = ModelTurnResult & {
12
+ readonly outputStarted: boolean;
13
+ readonly partialAssistantMessage: AgentMessage | undefined;
14
+ };
15
+ type CollectModelTurnAttemptResult<E, E2 = never> = {
16
+ readonly _tag: 'Collected';
17
+ readonly collection: ModelTurnCollection;
18
+ } | {
19
+ readonly _tag: 'StreamFailed';
20
+ readonly error: E;
21
+ readonly collection: ModelTurnCollection;
22
+ } | {
23
+ readonly _tag: 'SinkFailed';
24
+ readonly error: E2;
25
+ readonly collection: ModelTurnCollection;
26
+ };
27
+ declare const collectModelTurnAttempt: <E, R, E2 = never, R2 = never>(stream: Stream.Stream<AgentEvent, E, R>, options?: {
28
+ readonly onEvent?: (event: AgentEvent) => Effect.Effect<void, E2, R2>;
29
+ readonly initialUsage?: AgentUsage;
30
+ }) => Effect.Effect<CollectModelTurnAttemptResult<E, E2>, E | E2, R | R2>;
31
+ declare const collectModelTurn: <E, R, E2 = never, R2 = never>(stream: Stream.Stream<AgentEvent, E, R>, options?: {
32
+ readonly onEvent?: (event: AgentEvent) => Effect.Effect<void, E2, R2>;
33
+ readonly initialUsage?: AgentUsage;
34
+ }) => Effect.Effect<ModelTurnResult, E | E2, R | R2>;
35
+ //#endregion
36
+ export { CollectModelTurnAttemptResult, ModelTurnCollection, ModelTurnResult, collectModelTurn, collectModelTurnAttempt };
37
+ //# sourceMappingURL=collect.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"collect.d.mts","names":[],"sources":["../../src/loop/collect.ts"],"mappings":";;;;KAoBY,eAAA;EAAA,SACD,gBAAA,EAAkB,YAAA;EAAA,SAClB,SAAA,EAAW,aAAA,CAAc,QAAA;EAAA,SACzB,KAAA,EAAO,UAAA;EAAA,SACP,UAAA;AAAA;AAAA,KAGC,mBAAA,GAAsB,eAAA;EAAA,SACvB,aAAA;EAAA,SACA,uBAAA,EAAyB,YAAY;AAAA;AAAA,KAGpC,6BAAA;EAAA,SACG,IAAA;EAAA,SAA4B,UAAA,EAAY,mBAAA;AAAA;EAAA,SACxC,IAAA;EAAA,SAA+B,KAAA,EAAO,CAAA;EAAA,SAAY,UAAA,EAAY,mBAAA;AAAA;EAAA,SAC9D,IAAA;EAAA,SAA6B,KAAA,EAAO,EAAA;EAAA,SAAa,UAAA,EAAY,mBAAA;AAAA;AAAA,cAkJ/D,uBAAA,iCACX,MAAA,EAAQ,MAAA,CAAO,MAAA,CAAO,UAAA,EAAY,CAAA,EAAG,CAAA,GACrC,OAAA;EAAA,SACW,OAAA,IAAW,KAAA,EAAO,UAAA,KAAe,MAAA,CAAO,MAAA,OAAa,EAAA,EAAI,EAAA;EAAA,SACzD,YAAA,GAAe,UAAA;AAAA,MAEzB,MAAA,CAAO,MAAA,CAAO,6BAAA,CAA8B,CAAA,EAAG,EAAA,GAAK,CAAA,GAAI,EAAA,EAAI,CAAA,GAAI,EAAA;AAAA,cAoCtD,gBAAA,iCACX,MAAA,EAAQ,MAAA,CAAO,MAAA,CAAO,UAAA,EAAY,CAAA,EAAG,CAAA,GACrC,OAAA;EAAA,SACW,OAAA,IAAW,KAAA,EAAO,UAAA,KAAe,MAAA,CAAO,MAAA,OAAa,EAAA,EAAI,EAAA;EAAA,SACzD,YAAA,GAAe,UAAA;AAAA,MAEzB,MAAA,CAAO,MAAA,CAAO,eAAA,EAAiB,CAAA,GAAI,EAAA,EAAI,CAAA,GAAI,EAAA"}
@@ -0,0 +1,126 @@
1
+ import { applyAssistantLlmEvent } from "./accumulator.mjs";
2
+ import { LLMProviderToolResult, LLMReasoningDelta as LLMReasoningDelta$1, LLMTextDelta as LLMTextDelta$1, LLMToolCall } from "./llm-event.mjs";
3
+ import { Cause, Data, Effect, Exit, Ref, Result, Stream } from "effect";
4
+ import { AssistantAgentMessage, addAgentUsage, zeroAgentUsage } from "@yolk-sdk/agent/protocol";
5
+ //#region src/loop/collect.ts
6
+ var CollectModelTurnSinkError = class extends Data.TaggedError("CollectModelTurnSinkError") {};
7
+ const isPureTypedFailure = (cause) => Cause.hasFails(cause) && !Cause.hasDies(cause) && !Cause.hasInterrupts(cause);
8
+ const mapFailReason = (reason, error) => Cause.makeFailReason(error).annotate(Cause.reasonAnnotations(reason));
9
+ const markSinkCause = (cause) => Cause.fromReasons(cause.reasons.map((reason) => Cause.isFailReason(reason) ? mapFailReason(reason, new CollectModelTurnSinkError({ error: reason.error })) : reason));
10
+ const restoreAttemptCause = (cause) => Cause.fromReasons(cause.reasons.map((reason) => {
11
+ if (!Cause.isFailReason(reason)) return reason;
12
+ if (reason.error instanceof CollectModelTurnSinkError) return mapFailReason(reason, reason.error.error);
13
+ return mapFailReason(reason, reason.error);
14
+ }));
15
+ const withSinkProvenance = (effect) => effect.pipe(Effect.exit, Effect.flatMap((exit) => Exit.isSuccess(exit) ? Effect.succeed(exit.value) : Effect.failCause(markSinkCause(exit.cause))));
16
+ const emptyCollection = (initialUsage) => ({
17
+ assistantMessage: void 0,
18
+ toolCalls: [],
19
+ usage: initialUsage ?? zeroAgentUsage,
20
+ stopReason: "stop",
21
+ outputStarted: false,
22
+ partialAssistantMessage: void 0
23
+ });
24
+ const toModelTurnResult = (collection) => ({
25
+ assistantMessage: collection.assistantMessage,
26
+ toolCalls: collection.toolCalls,
27
+ usage: collection.usage,
28
+ stopReason: collection.stopReason
29
+ });
30
+ const eventStartsOutput = (event) => {
31
+ switch (event._tag) {
32
+ case "LLMTextDelta":
33
+ case "LLMReasoningDelta":
34
+ case "AssistantMessage":
35
+ case "ToolInputStart":
36
+ case "ToolInputDelta":
37
+ case "ToolInputEnd":
38
+ case "ProviderToolResult": return true;
39
+ default: return false;
40
+ }
41
+ };
42
+ const llmEventFromAgentEvent = (event) => {
43
+ switch (event._tag) {
44
+ case "LLMTextDelta": return LLMTextDelta$1.make({ text: event.text });
45
+ case "LLMReasoningDelta": return LLMReasoningDelta$1.make({ text: event.text });
46
+ case "ToolInputEnd": return LLMToolCall.make({ call: event.call });
47
+ case "ProviderToolResult": return LLMProviderToolResult.make({
48
+ call: event.call,
49
+ result: event.result
50
+ });
51
+ default: return;
52
+ }
53
+ };
54
+ const assistantParts = (message) => message?._tag === "Assistant" ? message.parts : [];
55
+ const withAssistantParts = (parts) => parts.length === 0 ? void 0 : AssistantAgentMessage.make({ parts });
56
+ const applyPartialAssistant = (message, event) => {
57
+ const llmEvent = llmEventFromAgentEvent(event);
58
+ if (llmEvent === void 0) return message;
59
+ return withAssistantParts(applyAssistantLlmEvent(assistantParts(message), llmEvent));
60
+ };
61
+ const applyModelTurnEvent = (acc, event) => {
62
+ const outputStarted = acc.outputStarted || eventStartsOutput(event);
63
+ const partialAssistantMessage = event._tag === "AssistantMessage" ? event.message : applyPartialAssistant(acc.partialAssistantMessage, event);
64
+ switch (event._tag) {
65
+ case "AssistantMessage": return {
66
+ ...acc,
67
+ assistantMessage: event.message,
68
+ partialAssistantMessage,
69
+ outputStarted
70
+ };
71
+ case "ToolInputEnd": return {
72
+ ...acc,
73
+ toolCalls: [...acc.toolCalls, event.call],
74
+ partialAssistantMessage,
75
+ outputStarted
76
+ };
77
+ case "TurnEnd": return {
78
+ ...acc,
79
+ stopReason: event.reason,
80
+ partialAssistantMessage,
81
+ outputStarted
82
+ };
83
+ case "UsageUpdate": return {
84
+ ...acc,
85
+ usage: addAgentUsage(acc.usage, event.usage),
86
+ partialAssistantMessage,
87
+ outputStarted
88
+ };
89
+ default: return {
90
+ ...acc,
91
+ partialAssistantMessage,
92
+ outputStarted
93
+ };
94
+ }
95
+ };
96
+ const collectModelTurnAttempt = (stream, options) => Effect.gen(function* () {
97
+ const collection = yield* Ref.make(emptyCollection(options?.initialUsage));
98
+ const onEvent = options?.onEvent;
99
+ const exit = yield* stream.pipe(Stream.runForEach((event) => Ref.update(collection, (current) => applyModelTurnEvent(current, event)).pipe(Effect.flatMap(() => onEvent === void 0 ? Effect.void : withSinkProvenance(onEvent(event))))), Effect.exit);
100
+ const state = yield* Ref.get(collection);
101
+ if (Exit.isSuccess(exit)) return {
102
+ _tag: "Collected",
103
+ collection: state
104
+ };
105
+ if (!isPureTypedFailure(exit.cause)) return yield* Effect.failCause(restoreAttemptCause(exit.cause));
106
+ const found = Cause.findError(exit.cause);
107
+ if (Result.isFailure(found)) return yield* Effect.failCause(restoreAttemptCause(exit.cause));
108
+ if (found.success instanceof CollectModelTurnSinkError) return {
109
+ _tag: "SinkFailed",
110
+ error: found.success.error,
111
+ collection: state
112
+ };
113
+ return {
114
+ _tag: "StreamFailed",
115
+ error: found.success,
116
+ collection: state
117
+ };
118
+ });
119
+ const collectModelTurn = (stream, options) => collectModelTurnAttempt(stream, options).pipe(Effect.flatMap((outcome) => {
120
+ if (outcome._tag === "Collected") return Effect.succeed(toModelTurnResult(outcome.collection));
121
+ return Effect.fail(outcome.error);
122
+ }));
123
+ //#endregion
124
+ export { collectModelTurn, collectModelTurnAttempt };
125
+
126
+ //# sourceMappingURL=collect.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"collect.mjs","names":["LLMTextDelta","LLMReasoningDelta"],"sources":["../../src/loop/collect.ts"],"sourcesContent":["import { Cause, Data, Effect, Exit, Ref, Result, Stream } from 'effect'\nimport {\n AssistantAgentMessage,\n addAgentUsage,\n zeroAgentUsage,\n type AgentEvent,\n type AgentMessage,\n type AgentUsage,\n type AssistantPart,\n type ToolCall\n} from '@yolk-sdk/agent/protocol'\nimport { applyAssistantLlmEvent } from './accumulator.ts'\nimport {\n LLMProviderToolResult,\n LLMReasoningDelta,\n LLMTextDelta,\n LLMToolCall,\n type LLMEvent\n} from './llm-event.ts'\n\nexport type ModelTurnResult = {\n readonly assistantMessage: AgentMessage | undefined\n readonly toolCalls: ReadonlyArray<ToolCall>\n readonly usage: AgentUsage\n readonly stopReason: 'stop' | 'tool_use'\n}\n\nexport type ModelTurnCollection = ModelTurnResult & {\n readonly outputStarted: boolean\n readonly partialAssistantMessage: AgentMessage | undefined\n}\n\nexport type CollectModelTurnAttemptResult<E, E2 = never> =\n | { readonly _tag: 'Collected'; readonly collection: ModelTurnCollection }\n | { readonly _tag: 'StreamFailed'; readonly error: E; readonly collection: ModelTurnCollection }\n | { readonly _tag: 'SinkFailed'; readonly error: E2; readonly collection: ModelTurnCollection }\n\nclass CollectModelTurnSinkError<E2> extends Data.TaggedError('CollectModelTurnSinkError')<{\n readonly error: E2\n}> {}\n\nconst isPureTypedFailure = <E>(cause: Cause.Cause<E>): boolean =>\n Cause.hasFails(cause) && !Cause.hasDies(cause) && !Cause.hasInterrupts(cause)\n\n// Effect beta.80 Cause.map constructs `new Fail(mapped)` and drops Fail.annotations.\nconst mapFailReason = <E, E2>(reason: Cause.Fail<E>, error: E2): Cause.Fail<E2> =>\n Cause.makeFailReason(error).annotate(Cause.reasonAnnotations(reason))\n\nconst markSinkCause = <E2>(cause: Cause.Cause<E2>): Cause.Cause<CollectModelTurnSinkError<E2>> =>\n Cause.fromReasons(\n cause.reasons.map(reason =>\n Cause.isFailReason(reason)\n ? mapFailReason(reason, new CollectModelTurnSinkError({ error: reason.error }))\n : reason\n )\n )\n\nconst restoreAttemptCause = <E, E2>(\n cause: Cause.Cause<E | CollectModelTurnSinkError<E2>>\n): Cause.Cause<E | E2> =>\n Cause.fromReasons(\n cause.reasons.map((reason): Cause.Reason<E | E2> => {\n if (!Cause.isFailReason(reason)) {\n return reason\n }\n if (reason.error instanceof CollectModelTurnSinkError) {\n return mapFailReason(reason, reason.error.error)\n }\n return mapFailReason(reason, reason.error)\n })\n )\n\nconst withSinkProvenance = <A, E2, R2>(\n effect: Effect.Effect<A, E2, R2>\n): Effect.Effect<A, CollectModelTurnSinkError<E2>, R2> =>\n effect.pipe(\n Effect.exit,\n Effect.flatMap(exit =>\n Exit.isSuccess(exit)\n ? Effect.succeed(exit.value)\n : Effect.failCause(markSinkCause(exit.cause))\n )\n )\n\nconst emptyCollection = (initialUsage?: AgentUsage): ModelTurnCollection => ({\n assistantMessage: undefined,\n toolCalls: [],\n usage: initialUsage ?? zeroAgentUsage,\n stopReason: 'stop',\n outputStarted: false,\n partialAssistantMessage: undefined\n})\n\nconst toModelTurnResult = (collection: ModelTurnCollection): ModelTurnResult => ({\n assistantMessage: collection.assistantMessage,\n toolCalls: collection.toolCalls,\n usage: collection.usage,\n stopReason: collection.stopReason\n})\n\nconst eventStartsOutput = (event: AgentEvent) => {\n switch (event._tag) {\n case 'LLMTextDelta':\n case 'LLMReasoningDelta':\n case 'AssistantMessage':\n case 'ToolInputStart':\n case 'ToolInputDelta':\n case 'ToolInputEnd':\n case 'ProviderToolResult':\n return true\n default:\n return false\n }\n}\n\nconst llmEventFromAgentEvent = (event: AgentEvent): LLMEvent | undefined => {\n switch (event._tag) {\n case 'LLMTextDelta':\n return LLMTextDelta.make({ text: event.text })\n case 'LLMReasoningDelta':\n return LLMReasoningDelta.make({ text: event.text })\n case 'ToolInputEnd':\n return LLMToolCall.make({ call: event.call })\n case 'ProviderToolResult':\n return LLMProviderToolResult.make({ call: event.call, result: event.result })\n default:\n return undefined\n }\n}\n\nconst assistantParts = (message: AgentMessage | undefined): ReadonlyArray<AssistantPart> =>\n message?._tag === 'Assistant' ? message.parts : []\n\nconst withAssistantParts = (parts: ReadonlyArray<AssistantPart>): AgentMessage | undefined =>\n parts.length === 0 ? undefined : AssistantAgentMessage.make({ parts })\n\nconst applyPartialAssistant = (\n message: AgentMessage | undefined,\n event: AgentEvent\n): AgentMessage | undefined => {\n const llmEvent = llmEventFromAgentEvent(event)\n if (llmEvent === undefined) return message\n return withAssistantParts(applyAssistantLlmEvent(assistantParts(message), llmEvent))\n}\n\nconst applyModelTurnEvent = (acc: ModelTurnCollection, event: AgentEvent): ModelTurnCollection => {\n const outputStarted = acc.outputStarted || eventStartsOutput(event)\n const partialAssistantMessage =\n event._tag === 'AssistantMessage'\n ? event.message\n : applyPartialAssistant(acc.partialAssistantMessage, event)\n\n switch (event._tag) {\n case 'AssistantMessage':\n return {\n ...acc,\n assistantMessage: event.message,\n partialAssistantMessage,\n outputStarted\n }\n case 'ToolInputEnd':\n return {\n ...acc,\n toolCalls: [...acc.toolCalls, event.call],\n partialAssistantMessage,\n outputStarted\n }\n case 'TurnEnd':\n return { ...acc, stopReason: event.reason, partialAssistantMessage, outputStarted }\n case 'UsageUpdate':\n return {\n ...acc,\n usage: addAgentUsage(acc.usage, event.usage),\n partialAssistantMessage,\n outputStarted\n }\n default:\n return { ...acc, partialAssistantMessage, outputStarted }\n }\n}\n\nexport const collectModelTurnAttempt = <E, R, E2 = never, R2 = never>(\n stream: Stream.Stream<AgentEvent, E, R>,\n options?: {\n readonly onEvent?: (event: AgentEvent) => Effect.Effect<void, E2, R2>\n readonly initialUsage?: AgentUsage\n }\n): Effect.Effect<CollectModelTurnAttemptResult<E, E2>, E | E2, R | R2> =>\n Effect.gen(function* () {\n const collection = yield* Ref.make(emptyCollection(options?.initialUsage))\n const onEvent = options?.onEvent\n const exit = yield* stream.pipe(\n Stream.runForEach(event =>\n Ref.update(collection, current => applyModelTurnEvent(current, event)).pipe(\n Effect.flatMap(() =>\n onEvent === undefined ? Effect.void : withSinkProvenance(onEvent(event))\n )\n )\n ),\n Effect.exit\n )\n const state = yield* Ref.get(collection)\n\n if (Exit.isSuccess(exit)) {\n return { _tag: 'Collected', collection: state }\n }\n\n if (!isPureTypedFailure(exit.cause)) {\n return yield* Effect.failCause(restoreAttemptCause(exit.cause))\n }\n\n const found = Cause.findError(exit.cause)\n if (Result.isFailure(found)) {\n return yield* Effect.failCause(restoreAttemptCause(exit.cause))\n }\n\n if (found.success instanceof CollectModelTurnSinkError) {\n return { _tag: 'SinkFailed', error: found.success.error, collection: state }\n }\n\n return { _tag: 'StreamFailed', error: found.success, collection: state }\n })\n\nexport const collectModelTurn = <E, R, E2 = never, R2 = never>(\n stream: Stream.Stream<AgentEvent, E, R>,\n options?: {\n readonly onEvent?: (event: AgentEvent) => Effect.Effect<void, E2, R2>\n readonly initialUsage?: AgentUsage\n }\n): Effect.Effect<ModelTurnResult, E | E2, R | R2> =>\n collectModelTurnAttempt(stream, options).pipe(\n Effect.flatMap((outcome): Effect.Effect<ModelTurnResult, E | E2> => {\n if (outcome._tag === 'Collected') {\n return Effect.succeed(toModelTurnResult(outcome.collection))\n }\n return Effect.fail(outcome.error)\n })\n )\n"],"mappings":";;;;;AAqCA,IAAM,4BAAN,cAA4C,KAAK,YAAY,2BAA2B,EAErF,CAAC;AAEJ,MAAM,sBAAyB,UAC7B,MAAM,SAAS,KAAK,KAAK,CAAC,MAAM,QAAQ,KAAK,KAAK,CAAC,MAAM,cAAc,KAAK;AAG9E,MAAM,iBAAwB,QAAuB,UACnD,MAAM,eAAe,KAAK,EAAE,SAAS,MAAM,kBAAkB,MAAM,CAAC;AAEtE,MAAM,iBAAqB,UACzB,MAAM,YACJ,MAAM,QAAQ,KAAI,WAChB,MAAM,aAAa,MAAM,IACrB,cAAc,QAAQ,IAAI,0BAA0B,EAAE,OAAO,OAAO,MAAM,CAAC,CAAC,IAC5E,MACN,CACF;AAEF,MAAM,uBACJ,UAEA,MAAM,YACJ,MAAM,QAAQ,KAAK,WAAiC;CAClD,IAAI,CAAC,MAAM,aAAa,MAAM,GAC5B,OAAO;CAET,IAAI,OAAO,iBAAiB,2BAC1B,OAAO,cAAc,QAAQ,OAAO,MAAM,KAAK;CAEjD,OAAO,cAAc,QAAQ,OAAO,KAAK;AAC3C,CAAC,CACH;AAEF,MAAM,sBACJ,WAEA,OAAO,KACL,OAAO,MACP,OAAO,SAAQ,SACb,KAAK,UAAU,IAAI,IACf,OAAO,QAAQ,KAAK,KAAK,IACzB,OAAO,UAAU,cAAc,KAAK,KAAK,CAAC,CAChD,CACF;AAEF,MAAM,mBAAmB,kBAAoD;CAC3E,kBAAkB,KAAA;CAClB,WAAW,CAAC;CACZ,OAAO,gBAAgB;CACvB,YAAY;CACZ,eAAe;CACf,yBAAyB,KAAA;AAC3B;AAEA,MAAM,qBAAqB,gBAAsD;CAC/E,kBAAkB,WAAW;CAC7B,WAAW,WAAW;CACtB,OAAO,WAAW;CAClB,YAAY,WAAW;AACzB;AAEA,MAAM,qBAAqB,UAAsB;CAC/C,QAAQ,MAAM,MAAd;EACE,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK,sBACH,OAAO;EACT,SACE,OAAO;CACX;AACF;AAEA,MAAM,0BAA0B,UAA4C;CAC1E,QAAQ,MAAM,MAAd;EACE,KAAK,gBACH,OAAOA,eAAa,KAAK,EAAE,MAAM,MAAM,KAAK,CAAC;EAC/C,KAAK,qBACH,OAAOC,oBAAkB,KAAK,EAAE,MAAM,MAAM,KAAK,CAAC;EACpD,KAAK,gBACH,OAAO,YAAY,KAAK,EAAE,MAAM,MAAM,KAAK,CAAC;EAC9C,KAAK,sBACH,OAAO,sBAAsB,KAAK;GAAE,MAAM,MAAM;GAAM,QAAQ,MAAM;EAAO,CAAC;EAC9E,SACE;CACJ;AACF;AAEA,MAAM,kBAAkB,YACtB,SAAS,SAAS,cAAc,QAAQ,QAAQ,CAAC;AAEnD,MAAM,sBAAsB,UAC1B,MAAM,WAAW,IAAI,KAAA,IAAY,sBAAsB,KAAK,EAAE,MAAM,CAAC;AAEvE,MAAM,yBACJ,SACA,UAC6B;CAC7B,MAAM,WAAW,uBAAuB,KAAK;CAC7C,IAAI,aAAa,KAAA,GAAW,OAAO;CACnC,OAAO,mBAAmB,uBAAuB,eAAe,OAAO,GAAG,QAAQ,CAAC;AACrF;AAEA,MAAM,uBAAuB,KAA0B,UAA2C;CAChG,MAAM,gBAAgB,IAAI,iBAAiB,kBAAkB,KAAK;CAClE,MAAM,0BACJ,MAAM,SAAS,qBACX,MAAM,UACN,sBAAsB,IAAI,yBAAyB,KAAK;CAE9D,QAAQ,MAAM,MAAd;EACE,KAAK,oBACH,OAAO;GACL,GAAG;GACH,kBAAkB,MAAM;GACxB;GACA;EACF;EACF,KAAK,gBACH,OAAO;GACL,GAAG;GACH,WAAW,CAAC,GAAG,IAAI,WAAW,MAAM,IAAI;GACxC;GACA;EACF;EACF,KAAK,WACH,OAAO;GAAE,GAAG;GAAK,YAAY,MAAM;GAAQ;GAAyB;EAAc;EACpF,KAAK,eACH,OAAO;GACL,GAAG;GACH,OAAO,cAAc,IAAI,OAAO,MAAM,KAAK;GAC3C;GACA;EACF;EACF,SACE,OAAO;GAAE,GAAG;GAAK;GAAyB;EAAc;CAC5D;AACF;AAEA,MAAa,2BACX,QACA,YAKA,OAAO,IAAI,aAAa;CACtB,MAAM,aAAa,OAAO,IAAI,KAAK,gBAAgB,SAAS,YAAY,CAAC;CACzE,MAAM,UAAU,SAAS;CACzB,MAAM,OAAO,OAAO,OAAO,KACzB,OAAO,YAAW,UAChB,IAAI,OAAO,aAAY,YAAW,oBAAoB,SAAS,KAAK,CAAC,EAAE,KACrE,OAAO,cACL,YAAY,KAAA,IAAY,OAAO,OAAO,mBAAmB,QAAQ,KAAK,CAAC,CACzE,CACF,CACF,GACA,OAAO,IACT;CACA,MAAM,QAAQ,OAAO,IAAI,IAAI,UAAU;CAEvC,IAAI,KAAK,UAAU,IAAI,GACrB,OAAO;EAAE,MAAM;EAAa,YAAY;CAAM;CAGhD,IAAI,CAAC,mBAAmB,KAAK,KAAK,GAChC,OAAO,OAAO,OAAO,UAAU,oBAAoB,KAAK,KAAK,CAAC;CAGhE,MAAM,QAAQ,MAAM,UAAU,KAAK,KAAK;CACxC,IAAI,OAAO,UAAU,KAAK,GACxB,OAAO,OAAO,OAAO,UAAU,oBAAoB,KAAK,KAAK,CAAC;CAGhE,IAAI,MAAM,mBAAmB,2BAC3B,OAAO;EAAE,MAAM;EAAc,OAAO,MAAM,QAAQ;EAAO,YAAY;CAAM;CAG7E,OAAO;EAAE,MAAM;EAAgB,OAAO,MAAM;EAAS,YAAY;CAAM;AACzE,CAAC;AAEH,MAAa,oBACX,QACA,YAKA,wBAAwB,QAAQ,OAAO,EAAE,KACvC,OAAO,SAAS,YAAoD;CAClE,IAAI,QAAQ,SAAS,aACnB,OAAO,OAAO,QAAQ,kBAAkB,QAAQ,UAAU,CAAC;CAE7D,OAAO,OAAO,KAAK,QAAQ,KAAK;AAClC,CAAC,CACH"}
@@ -2,11 +2,14 @@ import { AgentError, ProviderErrorInfo } from "@yolk-sdk/agent/protocol";
2
2
  import * as Schema from "effect/Schema";
3
3
 
4
4
  //#region src/loop/error.d.ts
5
+ declare const LLMResponseIssue: Schema.Literal<"missing_done">;
6
+ type LLMResponseIssue = typeof LLMResponseIssue.Type;
5
7
  declare const LLMError_base: Schema.Class<LLMError, Schema.TaggedStruct<"LLMError", {
6
8
  readonly cause: Schema.Literals<readonly ["validation_error", "provider_error", "rate_limit", "overloaded", "context_overflow", "invalid_response"]>;
7
9
  readonly message: Schema.String;
8
10
  readonly retryable: Schema.Boolean;
9
11
  readonly provider: Schema.optional<typeof ProviderErrorInfo>;
12
+ readonly responseIssue: Schema.optional<Schema.Literal<"missing_done">>;
10
13
  }>, import("effect/Cause").YieldableError>;
11
14
  declare class LLMError extends LLMError_base {}
12
15
  declare const FauxExhaustedError_base: Schema.Class<FauxExhaustedError, Schema.TaggedStruct<"FauxExhaustedError", {
@@ -33,5 +36,5 @@ type LLMProviderError = LLMError | FauxExhaustedError | AbortError;
33
36
  type AgentLoopError = LLMProviderError | ToolError | ContextTransformError;
34
37
  declare const agentLoopErrorToAgentError: (error: AgentLoopError) => AgentError;
35
38
  //#endregion
36
- export { AbortError, AgentLoopError, ContextTransformError, FauxExhaustedError, LLMError, LLMProviderError, ToolError, agentLoopErrorToAgentError };
39
+ export { AbortError, AgentLoopError, ContextTransformError, FauxExhaustedError, LLMError, LLMProviderError, LLMResponseIssue, ToolError, agentLoopErrorToAgentError };
37
40
  //# sourceMappingURL=error.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"error.d.mts","names":[],"sources":["../../src/loop/error.ts"],"mappings":";;;;cAC6F,aAAA;;;;;;cAEhF,QAAA,SAAiB,aAY5B;AAAA,cAAG,uBAAA;;;cAEQ,kBAAA,SAA2B,uBAKvC;AAAA,cAAG,cAAA;;;;;cAES,SAAA,SAAkB,cAa7B;AAAA,cAAG,0BAAA;;;;;cAEQ,qBAAA,SAA8B,0BAO1C;AAAA,cAAG,eAAA;;;cAES,UAAA,SAAmB,eAE9B;AAAA,KAEU,gBAAA,GAAmB,QAAA,GAAW,kBAAA,GAAqB,UAAA;AAAA,KAEnD,cAAA,GAAiB,gBAAA,GAAmB,SAAA,GAAY,qBAAA;AAAA,cAmB/C,0BAAA,GAA8B,KAAA,EAAO,cAAA,KAAiB,UAkClE"}
1
+ {"version":3,"file":"error.d.mts","names":[],"sources":["../../src/loop/error.ts"],"mappings":";;;;cAGa,gBAAA,EAAgB,MAAA,CAAA,OAAA;AAAA,KACjB,gBAAA,UAA0B,gBAAA,CAAiB,IAAI;AAAA,cAAA,aAAA;;;;;;;cAE9C,QAAA,SAAiB,aAa5B;AAAA,cAAG,uBAAA;;;cAEQ,kBAAA,SAA2B,uBAKvC;AAAA,cAAG,cAAA;;;;;cAES,SAAA,SAAkB,cAa7B;AAAA,cAAG,0BAAA;;;;;cAEQ,qBAAA,SAA8B,0BAO1C;AAAA,cAAG,eAAA;;;cAES,UAAA,SAAmB,eAE9B;AAAA,KAEU,gBAAA,GAAmB,QAAA,GAAW,kBAAA,GAAqB,UAAA;AAAA,KAEnD,cAAA,GAAiB,gBAAA,GAAmB,SAAA,GAAY,qBAAA;AAAA,cAmB/C,0BAAA,GAA8B,KAAA,EAAO,cAAA,KAAiB,UAkClE"}
@@ -1,6 +1,7 @@
1
1
  import { AgentError, ProviderErrorInfo } from "@yolk-sdk/agent/protocol";
2
2
  import * as Schema from "effect/Schema";
3
3
  //#region src/loop/error.ts
4
+ const LLMResponseIssue = Schema.Literal("missing_done");
4
5
  var LLMError = class extends Schema.TaggedErrorClass()("LLMError", {
5
6
  cause: Schema.Literals([
6
7
  "validation_error",
@@ -12,7 +13,8 @@ var LLMError = class extends Schema.TaggedErrorClass()("LLMError", {
12
13
  ]),
13
14
  message: Schema.String,
14
15
  retryable: Schema.Boolean,
15
- provider: Schema.optional(ProviderErrorInfo)
16
+ provider: Schema.optional(ProviderErrorInfo),
17
+ responseIssue: Schema.optional(LLMResponseIssue)
16
18
  }) {};
17
19
  var FauxExhaustedError = class extends Schema.TaggedErrorClass()("FauxExhaustedError", { message: Schema.String }) {};
18
20
  var ToolError = class extends Schema.TaggedErrorClass()("ToolError", {
@@ -82,6 +84,6 @@ const agentLoopErrorToAgentError = (error) => {
82
84
  }
83
85
  };
84
86
  //#endregion
85
- export { AbortError, ContextTransformError, FauxExhaustedError, LLMError, ToolError, agentLoopErrorToAgentError };
87
+ export { AbortError, ContextTransformError, FauxExhaustedError, LLMError, LLMResponseIssue, ToolError, agentLoopErrorToAgentError };
86
88
 
87
89
  //# sourceMappingURL=error.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"error.mjs","names":[],"sources":["../../src/loop/error.ts"],"sourcesContent":["import * as Schema from 'effect/Schema'\nimport { AgentError, ProviderErrorInfo, type AgentErrorCode } from '@yolk-sdk/agent/protocol'\n\nexport class LLMError extends Schema.TaggedErrorClass<LLMError>()('LLMError', {\n cause: Schema.Literals([\n 'validation_error',\n 'provider_error',\n 'rate_limit',\n 'overloaded',\n 'context_overflow',\n 'invalid_response'\n ]),\n message: Schema.String,\n retryable: Schema.Boolean,\n provider: Schema.optional(ProviderErrorInfo)\n}) {}\n\nexport class FauxExhaustedError extends Schema.TaggedErrorClass<FauxExhaustedError>()(\n 'FauxExhaustedError',\n {\n message: Schema.String\n }\n) {}\n\nexport class ToolError extends Schema.TaggedErrorClass<ToolError>()('ToolError', {\n tool: Schema.String,\n message: Schema.String,\n cause: Schema.Literals([\n 'validation',\n 'invalid_input',\n 'execution',\n 'timeout',\n 'permission',\n 'denied',\n 'not_found',\n 'unavailable'\n ])\n}) {}\n\nexport class ContextTransformError extends Schema.TaggedErrorClass<ContextTransformError>()(\n 'ContextTransformError',\n {\n cause: Schema.Literals(['context_overflow', 'invalid_response']),\n message: Schema.String,\n retryable: Schema.Boolean\n }\n) {}\n\nexport class AbortError extends Schema.TaggedErrorClass<AbortError>()('AbortError', {\n reason: Schema.Literals(['user', 'system', 'max_turns'])\n}) {}\n\nexport type LLMProviderError = LLMError | FauxExhaustedError | AbortError\n\nexport type AgentLoopError = LLMProviderError | ToolError | ContextTransformError\n\nconst toolErrorCode = (error: ToolError): AgentErrorCode => {\n switch (error.cause) {\n case 'validation':\n case 'invalid_input':\n return 'validation_error'\n case 'timeout':\n return 'tool_timeout'\n case 'permission':\n case 'denied':\n return 'tool_denied'\n case 'execution':\n case 'not_found':\n case 'unavailable':\n return 'tool_error'\n }\n}\n\nexport const agentLoopErrorToAgentError = (error: AgentLoopError): AgentError => {\n switch (error._tag) {\n case 'LLMError':\n return AgentError.make({\n code: error.cause,\n message: error.message,\n retryable: error.retryable,\n ...(error.provider === undefined ? {} : { provider: error.provider })\n })\n case 'ToolError':\n return AgentError.make({\n code: toolErrorCode(error),\n message: error.message,\n retryable: error.cause === 'timeout'\n })\n case 'ContextTransformError':\n return AgentError.make({\n code: error.cause,\n message: error.message,\n retryable: error.retryable\n })\n case 'AbortError':\n return AgentError.make({\n code: 'aborted',\n message: `Agent run aborted: ${error.reason}`,\n retryable: error.reason === 'system'\n })\n case 'FauxExhaustedError':\n return AgentError.make({\n code: 'provider_error',\n message: error.message,\n retryable: false\n })\n }\n}\n"],"mappings":";;;AAGA,IAAa,WAAb,cAA8B,OAAO,iBAA2B,EAAE,YAAY;CAC5E,OAAO,OAAO,SAAS;EACrB;EACA;EACA;EACA;EACA;EACA;CACF,CAAC;CACD,SAAS,OAAO;CAChB,WAAW,OAAO;CAClB,UAAU,OAAO,SAAS,iBAAiB;AAC7C,CAAC,EAAE,CAAC;AAEJ,IAAa,qBAAb,cAAwC,OAAO,iBAAqC,EAClF,sBACA,EACE,SAAS,OAAO,OAClB,CACF,EAAE,CAAC;AAEH,IAAa,YAAb,cAA+B,OAAO,iBAA4B,EAAE,aAAa;CAC/E,MAAM,OAAO;CACb,SAAS,OAAO;CAChB,OAAO,OAAO,SAAS;EACrB;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF,CAAC;AACH,CAAC,EAAE,CAAC;AAEJ,IAAa,wBAAb,cAA2C,OAAO,iBAAwC,EACxF,yBACA;CACE,OAAO,OAAO,SAAS,CAAC,oBAAoB,kBAAkB,CAAC;CAC/D,SAAS,OAAO;CAChB,WAAW,OAAO;AACpB,CACF,EAAE,CAAC;AAEH,IAAa,aAAb,cAAgC,OAAO,iBAA6B,EAAE,cAAc,EAClF,QAAQ,OAAO,SAAS;CAAC;CAAQ;CAAU;AAAW,CAAC,EACzD,CAAC,EAAE,CAAC;AAMJ,MAAM,iBAAiB,UAAqC;CAC1D,QAAQ,MAAM,OAAd;EACE,KAAK;EACL,KAAK,iBACH,OAAO;EACT,KAAK,WACH,OAAO;EACT,KAAK;EACL,KAAK,UACH,OAAO;EACT,KAAK;EACL,KAAK;EACL,KAAK,eACH,OAAO;CACX;AACF;AAEA,MAAa,8BAA8B,UAAsC;CAC/E,QAAQ,MAAM,MAAd;EACE,KAAK,YACH,OAAO,WAAW,KAAK;GACrB,MAAM,MAAM;GACZ,SAAS,MAAM;GACf,WAAW,MAAM;GACjB,GAAI,MAAM,aAAa,KAAA,IAAY,CAAC,IAAI,EAAE,UAAU,MAAM,SAAS;EACrE,CAAC;EACH,KAAK,aACH,OAAO,WAAW,KAAK;GACrB,MAAM,cAAc,KAAK;GACzB,SAAS,MAAM;GACf,WAAW,MAAM,UAAU;EAC7B,CAAC;EACH,KAAK,yBACH,OAAO,WAAW,KAAK;GACrB,MAAM,MAAM;GACZ,SAAS,MAAM;GACf,WAAW,MAAM;EACnB,CAAC;EACH,KAAK,cACH,OAAO,WAAW,KAAK;GACrB,MAAM;GACN,SAAS,sBAAsB,MAAM;GACrC,WAAW,MAAM,WAAW;EAC9B,CAAC;EACH,KAAK,sBACH,OAAO,WAAW,KAAK;GACrB,MAAM;GACN,SAAS,MAAM;GACf,WAAW;EACb,CAAC;CACL;AACF"}
1
+ {"version":3,"file":"error.mjs","names":[],"sources":["../../src/loop/error.ts"],"sourcesContent":["import * as Schema from 'effect/Schema'\nimport { AgentError, ProviderErrorInfo, type AgentErrorCode } from '@yolk-sdk/agent/protocol'\n\nexport const LLMResponseIssue = Schema.Literal('missing_done')\nexport type LLMResponseIssue = typeof LLMResponseIssue.Type\n\nexport class LLMError extends Schema.TaggedErrorClass<LLMError>()('LLMError', {\n cause: Schema.Literals([\n 'validation_error',\n 'provider_error',\n 'rate_limit',\n 'overloaded',\n 'context_overflow',\n 'invalid_response'\n ]),\n message: Schema.String,\n retryable: Schema.Boolean,\n provider: Schema.optional(ProviderErrorInfo),\n responseIssue: Schema.optional(LLMResponseIssue)\n}) {}\n\nexport class FauxExhaustedError extends Schema.TaggedErrorClass<FauxExhaustedError>()(\n 'FauxExhaustedError',\n {\n message: Schema.String\n }\n) {}\n\nexport class ToolError extends Schema.TaggedErrorClass<ToolError>()('ToolError', {\n tool: Schema.String,\n message: Schema.String,\n cause: Schema.Literals([\n 'validation',\n 'invalid_input',\n 'execution',\n 'timeout',\n 'permission',\n 'denied',\n 'not_found',\n 'unavailable'\n ])\n}) {}\n\nexport class ContextTransformError extends Schema.TaggedErrorClass<ContextTransformError>()(\n 'ContextTransformError',\n {\n cause: Schema.Literals(['context_overflow', 'invalid_response']),\n message: Schema.String,\n retryable: Schema.Boolean\n }\n) {}\n\nexport class AbortError extends Schema.TaggedErrorClass<AbortError>()('AbortError', {\n reason: Schema.Literals(['user', 'system', 'max_turns'])\n}) {}\n\nexport type LLMProviderError = LLMError | FauxExhaustedError | AbortError\n\nexport type AgentLoopError = LLMProviderError | ToolError | ContextTransformError\n\nconst toolErrorCode = (error: ToolError): AgentErrorCode => {\n switch (error.cause) {\n case 'validation':\n case 'invalid_input':\n return 'validation_error'\n case 'timeout':\n return 'tool_timeout'\n case 'permission':\n case 'denied':\n return 'tool_denied'\n case 'execution':\n case 'not_found':\n case 'unavailable':\n return 'tool_error'\n }\n}\n\nexport const agentLoopErrorToAgentError = (error: AgentLoopError): AgentError => {\n switch (error._tag) {\n case 'LLMError':\n return AgentError.make({\n code: error.cause,\n message: error.message,\n retryable: error.retryable,\n ...(error.provider === undefined ? {} : { provider: error.provider })\n })\n case 'ToolError':\n return AgentError.make({\n code: toolErrorCode(error),\n message: error.message,\n retryable: error.cause === 'timeout'\n })\n case 'ContextTransformError':\n return AgentError.make({\n code: error.cause,\n message: error.message,\n retryable: error.retryable\n })\n case 'AbortError':\n return AgentError.make({\n code: 'aborted',\n message: `Agent run aborted: ${error.reason}`,\n retryable: error.reason === 'system'\n })\n case 'FauxExhaustedError':\n return AgentError.make({\n code: 'provider_error',\n message: error.message,\n retryable: false\n })\n }\n}\n"],"mappings":";;;AAGA,MAAa,mBAAmB,OAAO,QAAQ,cAAc;AAG7D,IAAa,WAAb,cAA8B,OAAO,iBAA2B,EAAE,YAAY;CAC5E,OAAO,OAAO,SAAS;EACrB;EACA;EACA;EACA;EACA;EACA;CACF,CAAC;CACD,SAAS,OAAO;CAChB,WAAW,OAAO;CAClB,UAAU,OAAO,SAAS,iBAAiB;CAC3C,eAAe,OAAO,SAAS,gBAAgB;AACjD,CAAC,EAAE,CAAC;AAEJ,IAAa,qBAAb,cAAwC,OAAO,iBAAqC,EAClF,sBACA,EACE,SAAS,OAAO,OAClB,CACF,EAAE,CAAC;AAEH,IAAa,YAAb,cAA+B,OAAO,iBAA4B,EAAE,aAAa;CAC/E,MAAM,OAAO;CACb,SAAS,OAAO;CAChB,OAAO,OAAO,SAAS;EACrB;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF,CAAC;AACH,CAAC,EAAE,CAAC;AAEJ,IAAa,wBAAb,cAA2C,OAAO,iBAAwC,EACxF,yBACA;CACE,OAAO,OAAO,SAAS,CAAC,oBAAoB,kBAAkB,CAAC;CAC/D,SAAS,OAAO;CAChB,WAAW,OAAO;AACpB,CACF,EAAE,CAAC;AAEH,IAAa,aAAb,cAAgC,OAAO,iBAA6B,EAAE,cAAc,EAClF,QAAQ,OAAO,SAAS;CAAC;CAAQ;CAAU;AAAW,CAAC,EACzD,CAAC,EAAE,CAAC;AAMJ,MAAM,iBAAiB,UAAqC;CAC1D,QAAQ,MAAM,OAAd;EACE,KAAK;EACL,KAAK,iBACH,OAAO;EACT,KAAK,WACH,OAAO;EACT,KAAK;EACL,KAAK,UACH,OAAO;EACT,KAAK;EACL,KAAK;EACL,KAAK,eACH,OAAO;CACX;AACF;AAEA,MAAa,8BAA8B,UAAsC;CAC/E,QAAQ,MAAM,MAAd;EACE,KAAK,YACH,OAAO,WAAW,KAAK;GACrB,MAAM,MAAM;GACZ,SAAS,MAAM;GACf,WAAW,MAAM;GACjB,GAAI,MAAM,aAAa,KAAA,IAAY,CAAC,IAAI,EAAE,UAAU,MAAM,SAAS;EACrE,CAAC;EACH,KAAK,aACH,OAAO,WAAW,KAAK;GACrB,MAAM,cAAc,KAAK;GACzB,SAAS,MAAM;GACf,WAAW,MAAM,UAAU;EAC7B,CAAC;EACH,KAAK,yBACH,OAAO,WAAW,KAAK;GACrB,MAAM,MAAM;GACZ,SAAS,MAAM;GACf,WAAW,MAAM;EACnB,CAAC;EACH,KAAK,cACH,OAAO,WAAW,KAAK;GACrB,MAAM;GACN,SAAS,sBAAsB,MAAM;GACrC,WAAW,MAAM,WAAW;EAC9B,CAAC;EACH,KAAK,sBACH,OAAO,WAAW,KAAK;GACrB,MAAM;GACN,SAAS,MAAM;GACf,WAAW;EACb,CAAC;CACL;AACF"}
@@ -1,9 +1,11 @@
1
1
  import { LLMDone, LLMEvent, LLMProviderToolResult, LLMReasoningDelta, LLMTextDelta, LLMToolCall, LLMToolInputDelta, LLMToolInputStart, LLMUsage } from "./llm-event.mjs";
2
2
  import { accumulateAssistantMessage, collectReasoning, collectText, collectToolCalls } from "./accumulator.mjs";
3
- import { AbortError, AgentLoopError, ContextTransformError, FauxExhaustedError, LLMError, LLMProviderError, ToolError, agentLoopErrorToAgentError } from "./error.mjs";
3
+ import { CollectModelTurnAttemptResult, ModelTurnCollection, ModelTurnResult, collectModelTurn, collectModelTurnAttempt } from "./collect.mjs";
4
+ import { AbortError, AgentLoopError, ContextTransformError, FauxExhaustedError, LLMError, LLMProviderError, LLMResponseIssue, ToolError, agentLoopErrorToAgentError } from "./error.mjs";
4
5
  import { ContextTransformResult, ContextTransformer } from "./services/context-transformer.mjs";
5
6
  import { LLMProvider, LLMRequest } from "./services/llm-provider.mjs";
6
7
  import { LoopConfig, LoopConfigShape } from "./services/loop-config.mjs";
7
8
  import { ToolExecutor } from "./services/tool-executor.mjs";
9
+ import { decorateLLMProvider, makeAgentLoopLayer } from "./layer.mjs";
8
10
  import { AgentLoopRunId, ModelTurnConfig, PreparedToolBatch, RunConfig, ToolBatchConfig, prepareToolBatch, run, runModelTurn, runToolBatch } from "./run.mjs";
9
- export { AbortError, type AgentLoopError, type AgentLoopRunId, ContextTransformError, type ContextTransformResult, ContextTransformer, FauxExhaustedError, LLMDone, LLMError, LLMEvent, LLMProvider, type LLMProviderError, LLMProviderToolResult, LLMReasoningDelta, type LLMRequest, LLMTextDelta, LLMToolCall, LLMToolInputDelta, LLMToolInputStart, LLMUsage, LoopConfig, type LoopConfigShape, type ModelTurnConfig, type PreparedToolBatch, type RunConfig, type ToolBatchConfig, ToolError, ToolExecutor, accumulateAssistantMessage, agentLoopErrorToAgentError, collectReasoning, collectText, collectToolCalls, prepareToolBatch, run, runModelTurn, runToolBatch };
11
+ export { AbortError, type AgentLoopError, type AgentLoopRunId, type CollectModelTurnAttemptResult, ContextTransformError, type ContextTransformResult, ContextTransformer, FauxExhaustedError, LLMDone, LLMError, LLMEvent, LLMProvider, type LLMProviderError, LLMProviderToolResult, LLMReasoningDelta, type LLMRequest, LLMResponseIssue, LLMTextDelta, LLMToolCall, LLMToolInputDelta, LLMToolInputStart, LLMUsage, LoopConfig, type LoopConfigShape, type ModelTurnCollection, type ModelTurnConfig, type ModelTurnResult, type PreparedToolBatch, type RunConfig, type ToolBatchConfig, ToolError, ToolExecutor, accumulateAssistantMessage, agentLoopErrorToAgentError, collectModelTurn, collectModelTurnAttempt, collectReasoning, collectText, collectToolCalls, decorateLLMProvider, makeAgentLoopLayer, prepareToolBatch, run, runModelTurn, runToolBatch };