@llm4ts/flow 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (198) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +41 -0
  3. package/dist/AzureDevOpsTool.d.ts +60 -0
  4. package/dist/AzureDevOpsTool.d.ts.map +1 -0
  5. package/dist/AzureDevOpsTool.js +163 -0
  6. package/dist/AzureDevOpsTool.js.map +1 -0
  7. package/dist/Bench.d.ts +133 -0
  8. package/dist/Bench.d.ts.map +1 -0
  9. package/dist/Bench.js +272 -0
  10. package/dist/Bench.js.map +1 -0
  11. package/dist/BenchReport.d.ts +9 -0
  12. package/dist/BenchReport.d.ts.map +1 -0
  13. package/dist/BenchReport.js +360 -0
  14. package/dist/BenchReport.js.map +1 -0
  15. package/dist/CapabilityGuard.d.ts +6 -0
  16. package/dist/CapabilityGuard.d.ts.map +1 -0
  17. package/dist/CapabilityGuard.js +25 -0
  18. package/dist/CapabilityGuard.js.map +1 -0
  19. package/dist/Chat.d.ts +15 -0
  20. package/dist/Chat.d.ts.map +1 -0
  21. package/dist/Chat.js +36 -0
  22. package/dist/Chat.js.map +1 -0
  23. package/dist/Classified.d.ts +14 -0
  24. package/dist/Classified.d.ts.map +1 -0
  25. package/dist/Classified.js +48 -0
  26. package/dist/Classified.js.map +1 -0
  27. package/dist/CostLedger.d.ts +55 -0
  28. package/dist/CostLedger.d.ts.map +1 -0
  29. package/dist/CostLedger.js +126 -0
  30. package/dist/CostLedger.js.map +1 -0
  31. package/dist/CostTracker.d.ts +13 -0
  32. package/dist/CostTracker.d.ts.map +1 -0
  33. package/dist/CostTracker.js +116 -0
  34. package/dist/CostTracker.js.map +1 -0
  35. package/dist/Equiv.d.ts +163 -0
  36. package/dist/Equiv.d.ts.map +1 -0
  37. package/dist/Equiv.js +256 -0
  38. package/dist/Equiv.js.map +1 -0
  39. package/dist/EquivReport.d.ts +16 -0
  40. package/dist/EquivReport.d.ts.map +1 -0
  41. package/dist/EquivReport.js +77 -0
  42. package/dist/EquivReport.js.map +1 -0
  43. package/dist/Flow.d.ts +25 -0
  44. package/dist/Flow.d.ts.map +1 -0
  45. package/dist/Flow.js +39 -0
  46. package/dist/Flow.js.map +1 -0
  47. package/dist/FlowContext.d.ts +23 -0
  48. package/dist/FlowContext.d.ts.map +1 -0
  49. package/dist/FlowContext.js +4 -0
  50. package/dist/FlowContext.js.map +1 -0
  51. package/dist/FlowError.d.ts +80 -0
  52. package/dist/FlowError.d.ts.map +1 -0
  53. package/dist/FlowError.js +92 -0
  54. package/dist/FlowError.js.map +1 -0
  55. package/dist/FlowEvents.d.ts +101 -0
  56. package/dist/FlowEvents.d.ts.map +1 -0
  57. package/dist/FlowEvents.js +103 -0
  58. package/dist/FlowEvents.js.map +1 -0
  59. package/dist/FlowRecorder.d.ts +26 -0
  60. package/dist/FlowRecorder.d.ts.map +1 -0
  61. package/dist/FlowRecorder.js +74 -0
  62. package/dist/FlowRecorder.js.map +1 -0
  63. package/dist/GitHubTool.d.ts +53 -0
  64. package/dist/GitHubTool.d.ts.map +1 -0
  65. package/dist/GitHubTool.js +191 -0
  66. package/dist/GitHubTool.js.map +1 -0
  67. package/dist/GitTool.d.ts +46 -0
  68. package/dist/GitTool.d.ts.map +1 -0
  69. package/dist/GitTool.js +97 -0
  70. package/dist/GitTool.js.map +1 -0
  71. package/dist/Interaction.d.ts +21 -0
  72. package/dist/Interaction.d.ts.map +1 -0
  73. package/dist/Interaction.js +9 -0
  74. package/dist/Interaction.js.map +1 -0
  75. package/dist/McpServer.d.ts +18 -0
  76. package/dist/McpServer.d.ts.map +1 -0
  77. package/dist/McpServer.js +122 -0
  78. package/dist/McpServer.js.map +1 -0
  79. package/dist/Mermaid.d.ts +7 -0
  80. package/dist/Mermaid.d.ts.map +1 -0
  81. package/dist/Mermaid.js +98 -0
  82. package/dist/Mermaid.js.map +1 -0
  83. package/dist/Pack.d.ts +40 -0
  84. package/dist/Pack.d.ts.map +1 -0
  85. package/dist/Pack.js +141 -0
  86. package/dist/Pack.js.map +1 -0
  87. package/dist/Package.d.ts +2 -0
  88. package/dist/Package.d.ts.map +1 -0
  89. package/dist/Package.js +2 -0
  90. package/dist/Package.js.map +1 -0
  91. package/dist/Persistence.d.ts +32 -0
  92. package/dist/Persistence.d.ts.map +1 -0
  93. package/dist/Persistence.js +85 -0
  94. package/dist/Persistence.js.map +1 -0
  95. package/dist/Plan.d.ts +26 -0
  96. package/dist/Plan.d.ts.map +1 -0
  97. package/dist/Plan.js +101 -0
  98. package/dist/Plan.js.map +1 -0
  99. package/dist/PlanExecution.d.ts +7 -0
  100. package/dist/PlanExecution.d.ts.map +1 -0
  101. package/dist/PlanExecution.js +19 -0
  102. package/dist/PlanExecution.js.map +1 -0
  103. package/dist/Planner.d.ts +32 -0
  104. package/dist/Planner.d.ts.map +1 -0
  105. package/dist/Planner.js +97 -0
  106. package/dist/Planner.js.map +1 -0
  107. package/dist/PrSummary.d.ts +15 -0
  108. package/dist/PrSummary.d.ts.map +1 -0
  109. package/dist/PrSummary.js +29 -0
  110. package/dist/PrSummary.js.map +1 -0
  111. package/dist/PriceList.d.ts +11 -0
  112. package/dist/PriceList.d.ts.map +1 -0
  113. package/dist/PriceList.js +79 -0
  114. package/dist/PriceList.js.map +1 -0
  115. package/dist/Provenance.d.ts +27 -0
  116. package/dist/Provenance.d.ts.map +1 -0
  117. package/dist/Provenance.js +38 -0
  118. package/dist/Provenance.js.map +1 -0
  119. package/dist/Replay.d.ts +29 -0
  120. package/dist/Replay.d.ts.map +1 -0
  121. package/dist/Replay.js +181 -0
  122. package/dist/Replay.js.map +1 -0
  123. package/dist/Review.d.ts +71 -0
  124. package/dist/Review.d.ts.map +1 -0
  125. package/dist/Review.js +204 -0
  126. package/dist/Review.js.map +1 -0
  127. package/dist/ReviewCache.d.ts +6 -0
  128. package/dist/ReviewCache.d.ts.map +1 -0
  129. package/dist/ReviewCache.js +28 -0
  130. package/dist/ReviewCache.js.map +1 -0
  131. package/dist/Reviewer.d.ts +12 -0
  132. package/dist/Reviewer.d.ts.map +1 -0
  133. package/dist/Reviewer.js +30 -0
  134. package/dist/Reviewer.js.map +1 -0
  135. package/dist/SpecChecks.d.ts +17 -0
  136. package/dist/SpecChecks.d.ts.map +1 -0
  137. package/dist/SpecChecks.js +107 -0
  138. package/dist/SpecChecks.js.map +1 -0
  139. package/dist/Survey.d.ts +32 -0
  140. package/dist/Survey.d.ts.map +1 -0
  141. package/dist/Survey.js +119 -0
  142. package/dist/Survey.js.map +1 -0
  143. package/dist/TransientRetry.d.ts +16 -0
  144. package/dist/TransientRetry.d.ts.map +1 -0
  145. package/dist/TransientRetry.js +102 -0
  146. package/dist/TransientRetry.js.map +1 -0
  147. package/dist/Workspace.d.ts +39 -0
  148. package/dist/Workspace.d.ts.map +1 -0
  149. package/dist/Workspace.js +192 -0
  150. package/dist/Workspace.js.map +1 -0
  151. package/dist/WorkspaceLayout.d.ts +3 -0
  152. package/dist/WorkspaceLayout.d.ts.map +1 -0
  153. package/dist/WorkspaceLayout.js +19 -0
  154. package/dist/WorkspaceLayout.js.map +1 -0
  155. package/dist/WorkspaceTools.d.ts +4 -0
  156. package/dist/WorkspaceTools.d.ts.map +1 -0
  157. package/dist/WorkspaceTools.js +130 -0
  158. package/dist/WorkspaceTools.js.map +1 -0
  159. package/package.json +91 -0
  160. package/src/AzureDevOpsTool.ts +291 -0
  161. package/src/Bench.ts +340 -0
  162. package/src/BenchReport.ts +447 -0
  163. package/src/CapabilityGuard.ts +43 -0
  164. package/src/Chat.ts +60 -0
  165. package/src/Classified.ts +67 -0
  166. package/src/CostLedger.ts +171 -0
  167. package/src/CostTracker.ts +170 -0
  168. package/src/Equiv.ts +378 -0
  169. package/src/EquivReport.ts +92 -0
  170. package/src/Flow.ts +72 -0
  171. package/src/FlowContext.ts +23 -0
  172. package/src/FlowError.ts +112 -0
  173. package/src/FlowEvents.ts +147 -0
  174. package/src/FlowRecorder.ts +116 -0
  175. package/src/GitHubTool.ts +315 -0
  176. package/src/GitTool.ts +214 -0
  177. package/src/Interaction.ts +23 -0
  178. package/src/McpServer.ts +168 -0
  179. package/src/Mermaid.ts +112 -0
  180. package/src/Pack.ts +213 -0
  181. package/src/Package.ts +1 -0
  182. package/src/Persistence.ts +198 -0
  183. package/src/Plan.ts +119 -0
  184. package/src/PlanExecution.ts +46 -0
  185. package/src/Planner.ts +134 -0
  186. package/src/PrSummary.ts +37 -0
  187. package/src/PriceList.ts +91 -0
  188. package/src/Provenance.ts +85 -0
  189. package/src/Replay.ts +265 -0
  190. package/src/Review.ts +337 -0
  191. package/src/ReviewCache.ts +45 -0
  192. package/src/Reviewer.ts +31 -0
  193. package/src/SpecChecks.ts +143 -0
  194. package/src/Survey.ts +144 -0
  195. package/src/TransientRetry.ts +238 -0
  196. package/src/Workspace.ts +255 -0
  197. package/src/WorkspaceLayout.ts +22 -0
  198. package/src/WorkspaceTools.ts +188 -0
@@ -0,0 +1,19 @@
1
+ import * as Effect from "effect/Effect";
2
+ import { StageCompleted, StageFailed, StageStarted } from "./FlowEvents.js";
3
+ const errorMessage = (error) => error instanceof Error && error.message.length > 0 ? error.message : String(error);
4
+ export const stage = (events, name, effect) => events.publish(StageStarted.make({ stage: name })).pipe(Effect.andThen(effect), Effect.tap(() => events.publish(StageCompleted.make({ stage: name }))), Effect.tapError((error) => events.publish(StageFailed.make({
5
+ stage: name,
6
+ message: errorMessage(error)
7
+ }))));
8
+ export const implementTaskLoop = Effect.fn("@llm4ts/flow/PlanExecution.implementTaskLoop")(function* (store, events, planPath, plan, perTask) {
9
+ let current = plan;
10
+ for (const task of plan.tasks) {
11
+ if (!task.completed) {
12
+ yield* stage(events, task.title, perTask(task));
13
+ current = current.complete(task.title);
14
+ yield* store.save(planPath, current);
15
+ }
16
+ }
17
+ return current;
18
+ });
19
+ //# sourceMappingURL=PlanExecution.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PlanExecution.js","sourceRoot":"","sources":["../src/PlanExecution.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AACvC,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,YAAY,EAAwB,MAAM,iBAAiB,CAAA;AAKjG,MAAM,YAAY,GAAG,CAAC,KAAc,EAAU,EAAE,CAC9C,KAAK,YAAY,KAAK,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;AAEpF,MAAM,CAAC,MAAM,KAAK,GAAG,CACnB,MAAuB,EACvB,IAAY,EACZ,MAA8B,EACN,EAAE,CAC1B,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CACrD,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EACtB,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EACtE,MAAM,CAAC,QAAQ,CAAC,CAAC,KAAK,EAAE,EAAE,CACxB,MAAM,CAAC,OAAO,CACZ,WAAW,CAAC,IAAI,CAAC;IACf,KAAK,EAAE,IAAI;IACX,OAAO,EAAE,YAAY,CAAC,KAAK,CAAC;CAC7B,CAAC,CACH,CACF,CACF,CAAA;AAEH,MAAM,CAAC,MAAM,iBAAiB,GAAG,MAAM,CAAC,EAAE,CAAC,8CAA8C,CAAC,CACxF,QAAQ,CAAC,EACP,KAAqB,EACrB,MAAuB,EACvB,QAAgB,EAChB,IAAU,EACV,OAAkD;IAElD,IAAI,OAAO,GAAG,IAAI,CAAA;IAClB,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;QAC9B,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;YACpB,KAAK,CAAC,CAAC,KAAK,CAAC,MAAM,EAAE,IAAI,CAAC,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAA;YAC/C,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;YACtC,KAAK,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAA;QACtC,CAAC;IACH,CAAC;IACD,OAAO,OAAO,CAAA;AAChB,CAAC,CACF,CAAA"}
@@ -0,0 +1,32 @@
1
+ import * as Effect from "effect/Effect";
2
+ import * as Schema from "effect/Schema";
3
+ import type { LlmServiceShape } from "@llm4ts/core/LlmService";
4
+ import type { JsonSchema } from "@llm4ts/core/Models";
5
+ import { FlowLlmError } from "./FlowError.ts";
6
+ import { Plan } from "./Plan.ts";
7
+ declare const Proceed_base: Schema.Class<Proceed, Schema.Struct<{
8
+ readonly kind: Schema.Literal<"Proceed">;
9
+ readonly value: typeof Plan;
10
+ }>, {}>;
11
+ export declare class Proceed extends Proceed_base {
12
+ }
13
+ declare const Blocked_base: Schema.Class<Blocked, Schema.Struct<{
14
+ readonly kind: Schema.Literal<"Blocked">;
15
+ readonly reason: Schema.String;
16
+ }>, {}>;
17
+ export declare class Blocked extends Blocked_base {
18
+ }
19
+ export declare const Verdict: Schema.Union<readonly [typeof Proceed, typeof Blocked]>;
20
+ export type Verdict = typeof Verdict.Type;
21
+ export declare const planJsonSchema: JsonSchema;
22
+ export declare const defaultPlanInstructions: string;
23
+ export declare const planFrom: (reasoning: LlmServiceShape, prompt: string, instructions?: any) => Effect.Effect<Plan, FlowLlmError, never>;
24
+ export declare const reviewPlanInstructions: string;
25
+ export declare const reviewPlan: (reasoning: LlmServiceShape, plan: Plan, instructions?: any) => Effect.Effect<Plan, FlowLlmError, never>;
26
+ export declare const briefInstructions: string;
27
+ export declare const writeBrief: (reasoning: LlmServiceShape, prompt: string, instructions?: any) => Effect.Effect<string, FlowLlmError, never>;
28
+ export declare const briefPlan: (reasoning: LlmServiceShape, plan: Plan, prompt: string, instructions?: any) => Effect.Effect<Plan, FlowLlmError, never>;
29
+ export declare const assessThenPlanInstructions: string;
30
+ export declare const assessThenPlan: (reasoning: LlmServiceShape, prompt: string, instructions?: any) => Effect.Effect<Proceed | Blocked, FlowLlmError, never>;
31
+ export {};
32
+ //# sourceMappingURL=Planner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Planner.d.ts","sourceRoot":"","sources":["../src/Planner.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AACvC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AACvC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAA;AAC9D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAA;AAErD,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAC7C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;;;;;AAEhC,qBAAa,OAAQ,SAAQ,YAG3B;CAAG;;;;;AAEL,qBAAa,OAAQ,SAAQ,YAG3B;CAAG;AAEL,eAAO,MAAM,OAAO,yDAAmC,CAAA;AACvD,MAAM,MAAM,OAAO,GAAG,OAAO,OAAO,CAAC,IAAI,CAAA;AAEzC,eAAO,MAAM,cAAc,EAAE,UAmB5B,CAAA;AAYD,eAAO,MAAM,uBAAuB,QAMxB,CAAA;AAEZ,eAAO,MAAM,QAAQ,8GAQnB,CAAA;AAEF,eAAO,MAAM,sBAAsB,QAKvB,CAAA;AAEZ,eAAO,MAAM,UAAU,0GAYrB,CAAA;AAEF,eAAO,MAAM,iBAAiB,QAIlB,CAAA;AAEZ,eAAO,MAAM,UAAU,gHASrB,CAAA;AAEF,eAAO,MAAM,SAAS,0HAQpB,CAAA;AAEF,eAAO,MAAM,0BAA0B,QAK3B,CAAA;AAEZ,eAAO,MAAM,cAAc,2HAQzB,CAAA"}
@@ -0,0 +1,97 @@
1
+ import * as Effect from "effect/Effect";
2
+ import * as Schema from "effect/Schema";
3
+ import { collect } from "@llm4ts/core/Streaming";
4
+ import { FlowLlmError } from "./FlowError.js";
5
+ import { Plan } from "./Plan.js";
6
+ export class Proceed extends Schema.Class("Proceed")({
7
+ kind: Schema.Literal("Proceed"),
8
+ value: Plan
9
+ }) {
10
+ }
11
+ export class Blocked extends Schema.Class("Blocked")({
12
+ kind: Schema.Literal("Blocked"),
13
+ reason: Schema.String
14
+ }) {
15
+ }
16
+ export const Verdict = Schema.Union([Proceed, Blocked]);
17
+ export const planJsonSchema = {
18
+ type: "object",
19
+ properties: {
20
+ epicId: { type: "string" },
21
+ tasks: {
22
+ type: "array",
23
+ items: {
24
+ type: "object",
25
+ properties: {
26
+ title: { type: "string" },
27
+ description: { type: "string" },
28
+ completed: { type: "boolean" }
29
+ },
30
+ required: ["title", "description", "completed"]
31
+ }
32
+ },
33
+ brief: { type: "string" }
34
+ },
35
+ required: ["epicId", "tasks"]
36
+ };
37
+ const verdictJsonSchema = {
38
+ type: "object",
39
+ properties: {
40
+ kind: { type: "string", enum: ["Proceed", "Blocked"] },
41
+ value: planJsonSchema,
42
+ reason: { type: "string" }
43
+ },
44
+ required: ["kind"]
45
+ };
46
+ export const defaultPlanInstructions = [
47
+ "You are a planning assistant. Break the user's request into an ordered list of small,",
48
+ "independently implementable tasks. Each task must be a thin vertical slice with an observable",
49
+ "outcome, described in terms of behavior rather than mechanism. Choose a short kebab-case epicId.",
50
+ 'Respond only with JSON: {"epicId":"kebab-case-id","tasks":',
51
+ '[{"title":"...","description":"...","completed":false}]}'
52
+ ].join("\n");
53
+ export const planFrom = Effect.fn("@llm4ts/flow/Planner.from")(function* (reasoning, prompt, instructions = defaultPlanInstructions) {
54
+ return yield* reasoning
55
+ .executeStructured(`${instructions}\n\nRequest:\n${prompt}`, Plan, planJsonSchema)
56
+ .pipe(Effect.mapError(FlowLlmError.from));
57
+ });
58
+ export const reviewPlanInstructions = [
59
+ "Review the draft implementation plan for correctness, completeness, simplicity, and concision.",
60
+ "Keep the same epicId unless it is clearly wrong. Return the complete improved plan, not a patch.",
61
+ 'Respond only with JSON: {"epicId":"kebab-case-id","tasks":',
62
+ '[{"title":"...","description":"...","completed":false}]}'
63
+ ].join("\n");
64
+ export const reviewPlan = Effect.fn("@llm4ts/flow/Planner.review")(function* (reasoning, plan, instructions = reviewPlanInstructions) {
65
+ const improved = yield* reasoning
66
+ .executeStructured(`${instructions}\n\nDraft plan:\n${plan.render}`, Plan, planJsonSchema)
67
+ .pipe(Effect.mapError(FlowLlmError.from));
68
+ return Plan.make({
69
+ ...improved,
70
+ ...(plan.brief === undefined ? {} : { brief: plan.brief })
71
+ });
72
+ });
73
+ export const briefInstructions = [
74
+ "Write a concise codebase brief for an engineer about to implement this change:",
75
+ "relevant modules and file paths, important APIs and types, conventions, and build/test commands.",
76
+ "Explore the repository as needed. Do not restate the task list. Return plain prose."
77
+ ].join("\n");
78
+ export const writeBrief = Effect.fn("@llm4ts/flow/Planner.brief")(function* (reasoning, prompt, instructions = briefInstructions) {
79
+ const response = yield* collect(reasoning.executeStream(`${instructions}\n\nChange request:\n${prompt}`)).pipe(Effect.mapError(FlowLlmError.from));
80
+ return response.content.trim();
81
+ });
82
+ export const briefPlan = Effect.fn("@llm4ts/flow/Planner.briefPlan")(function* (reasoning, plan, prompt, instructions = briefInstructions) {
83
+ const brief = yield* writeBrief(reasoning, prompt, instructions);
84
+ return Plan.make({ ...plan, brief });
85
+ });
86
+ export const assessThenPlanInstructions = [
87
+ "First decide whether this request is ready to implement.",
88
+ 'Respond only with JSON using exactly one form: {"kind":"Blocked","reason":"why it cannot proceed"}',
89
+ 'or {"kind":"Proceed","value":{"epicId":"kebab-id","tasks":',
90
+ '[{"title":"...","description":"...","completed":false}]}}.'
91
+ ].join("\n");
92
+ export const assessThenPlan = Effect.fn("@llm4ts/flow/Planner.assessThenPlan")(function* (reasoning, prompt, instructions = assessThenPlanInstructions) {
93
+ return yield* reasoning
94
+ .executeStructured(`${instructions}\n\nRequest:\n${prompt}`, Verdict, verdictJsonSchema)
95
+ .pipe(Effect.mapError(FlowLlmError.from));
96
+ });
97
+ //# sourceMappingURL=Planner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Planner.js","sourceRoot":"","sources":["../src/Planner.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import * as Effect from "effect/Effect";
2
+ import * as Schema from "effect/Schema";
3
+ import type { LlmServiceShape } from "@llm4ts/core/LlmService";
4
+ import type { JsonSchema } from "@llm4ts/core/Models";
5
+ import { FlowLlmError } from "./FlowError.ts";
6
+ declare const PrSummary_base: Schema.Class<PrSummary, Schema.Struct<{
7
+ readonly title: Schema.String;
8
+ readonly body: Schema.String;
9
+ }>, {}>;
10
+ export declare class PrSummary extends PrSummary_base {
11
+ }
12
+ export declare const prSummaryJsonSchema: JsonSchema;
13
+ export declare const summarisePr: (reasoning: LlmServiceShape, diff: string, context?: string | undefined) => Effect.Effect<PrSummary, FlowLlmError, never>;
14
+ export {};
15
+ //# sourceMappingURL=PrSummary.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PrSummary.d.ts","sourceRoot":"","sources":["../src/PrSummary.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AACvC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AACvC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAA;AAC9D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAA;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;;;;;AAE7C,qBAAa,SAAU,SAAQ,cAG7B;CAAG;AAEL,eAAO,MAAM,mBAAmB,EAAE,UAOjC,CAAA;AAED,eAAO,MAAM,WAAW,2HAgBtB,CAAA"}
@@ -0,0 +1,29 @@
1
+ import * as Effect from "effect/Effect";
2
+ import * as Schema from "effect/Schema";
3
+ import { FlowLlmError } from "./FlowError.js";
4
+ export class PrSummary extends Schema.Class("PrSummary")({
5
+ title: Schema.String,
6
+ body: Schema.String
7
+ }) {
8
+ }
9
+ export const prSummaryJsonSchema = {
10
+ type: "object",
11
+ properties: {
12
+ title: { type: "string" },
13
+ body: { type: "string" }
14
+ },
15
+ required: ["title", "body"]
16
+ };
17
+ export const summarisePr = Effect.fn("@llm4ts/flow/PrSummary.summarise")(function* (reasoning, diff, context) {
18
+ const contextBlock = context === undefined || context.length === 0 ? "" : `\nContext:\n${context}\n`;
19
+ const prompt = [
20
+ 'Summarise this change as a pull request. Respond only with JSON: {"title":"...","body":"..."}.',
21
+ contextBlock,
22
+ "Diff:",
23
+ diff
24
+ ].join("\n");
25
+ return yield* reasoning
26
+ .executeStructured(prompt, PrSummary, prSummaryJsonSchema)
27
+ .pipe(Effect.mapError(FlowLlmError.from));
28
+ });
29
+ //# sourceMappingURL=PrSummary.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PrSummary.js","sourceRoot":"","sources":["../src/PrSummary.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AACvC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AAGvC,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAE7C,MAAM,OAAO,SAAU,SAAQ,MAAM,CAAC,KAAK,CAAY,WAAW,CAAC,CAAC;IAClE,KAAK,EAAE,MAAM,CAAC,MAAM;IACpB,IAAI,EAAE,MAAM,CAAC,MAAM;CACpB,CAAC;CAAG;AAEL,MAAM,CAAC,MAAM,mBAAmB,GAAe;IAC7C,IAAI,EAAE,QAAQ;IACd,UAAU,EAAE;QACV,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;QACzB,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;KACzB;IACD,QAAQ,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC;CAC5B,CAAA;AAED,MAAM,CAAC,MAAM,WAAW,GAAG,MAAM,CAAC,EAAE,CAAC,kCAAkC,CAAC,CAAC,QAAQ,CAAC,EAChF,SAA0B,EAC1B,IAAY,EACZ,OAAgB;IAEhB,MAAM,YAAY,GAChB,OAAO,KAAK,SAAS,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,eAAe,OAAO,IAAI,CAAA;IACjF,MAAM,MAAM,GAAG;QACb,gGAAgG;QAChG,YAAY;QACZ,OAAO;QACP,IAAI;KACL,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IACZ,OAAO,KAAK,CAAC,CAAC,SAAS;SACpB,iBAAiB,CAAC,MAAM,EAAE,SAAS,EAAE,mBAAmB,CAAC;SACzD,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAA;AAC7C,CAAC,CAAC,CAAA"}
@@ -0,0 +1,11 @@
1
+ import type { TokenUsage } from "@llm4ts/core/Models";
2
+ export interface ModelRate {
3
+ readonly prefix: string;
4
+ readonly inputUsdPerMillion: number;
5
+ readonly outputUsdPerMillion: number;
6
+ readonly cachedInputMultiplier: number;
7
+ }
8
+ export declare const PricesAsOf = "2026-07";
9
+ export declare const ModelRates: ReadonlyArray<ModelRate>;
10
+ export declare const estimateCostUsd: (model: string, usage: TokenUsage) => number | undefined;
11
+ //# sourceMappingURL=PriceList.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PriceList.d.ts","sourceRoot":"","sources":["../src/PriceList.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAA;AAErD,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAA;IACnC,QAAQ,CAAC,mBAAmB,EAAE,MAAM,CAAA;IACpC,QAAQ,CAAC,qBAAqB,EAAE,MAAM,CAAA;CACvC;AAED,eAAO,MAAM,UAAU,YAAY,CAAA;AAEnC,eAAO,MAAM,UAAU,EAAE,aAAa,CAAC,SAAS,CAmE9C,CAAA;AAEF,eAAO,MAAM,eAAe,GAAI,OAAO,MAAM,EAAE,OAAO,UAAU,KAAG,MAAM,GAAG,SAU3E,CAAA"}
@@ -0,0 +1,79 @@
1
+ export const PricesAsOf = "2026-07";
2
+ export const ModelRates = Object.freeze([
3
+ {
4
+ prefix: "claude-fable-5",
5
+ inputUsdPerMillion: 10,
6
+ outputUsdPerMillion: 50,
7
+ cachedInputMultiplier: 0.1
8
+ },
9
+ {
10
+ prefix: "claude-opus-4",
11
+ inputUsdPerMillion: 15,
12
+ outputUsdPerMillion: 75,
13
+ cachedInputMultiplier: 0.1
14
+ },
15
+ {
16
+ prefix: "claude-sonnet-4",
17
+ inputUsdPerMillion: 3,
18
+ outputUsdPerMillion: 15,
19
+ cachedInputMultiplier: 0.1
20
+ },
21
+ {
22
+ prefix: "claude-haiku-4",
23
+ inputUsdPerMillion: 1,
24
+ outputUsdPerMillion: 5,
25
+ cachedInputMultiplier: 0.1
26
+ },
27
+ {
28
+ prefix: "gemini-2.5-pro",
29
+ inputUsdPerMillion: 1.25,
30
+ outputUsdPerMillion: 10,
31
+ cachedInputMultiplier: 0.1
32
+ },
33
+ {
34
+ prefix: "gemini-2.5-flash",
35
+ inputUsdPerMillion: 0.3,
36
+ outputUsdPerMillion: 2.5,
37
+ cachedInputMultiplier: 0.1
38
+ },
39
+ {
40
+ prefix: "gpt-5.5",
41
+ inputUsdPerMillion: 5,
42
+ outputUsdPerMillion: 30,
43
+ cachedInputMultiplier: 0.1
44
+ },
45
+ {
46
+ prefix: "grok-4.5",
47
+ inputUsdPerMillion: 2,
48
+ outputUsdPerMillion: 6,
49
+ cachedInputMultiplier: 0.1
50
+ },
51
+ {
52
+ prefix: "grok-4.3",
53
+ inputUsdPerMillion: 1.25,
54
+ outputUsdPerMillion: 2.5,
55
+ cachedInputMultiplier: 0.1
56
+ },
57
+ {
58
+ prefix: "grok-4.20",
59
+ inputUsdPerMillion: 1.25,
60
+ outputUsdPerMillion: 2.5,
61
+ cachedInputMultiplier: 0.1
62
+ },
63
+ {
64
+ prefix: "grok-build-0.1",
65
+ inputUsdPerMillion: 1,
66
+ outputUsdPerMillion: 2,
67
+ cachedInputMultiplier: 0.1
68
+ }
69
+ ]);
70
+ export const estimateCostUsd = (model, usage) => {
71
+ const rate = ModelRates.find(({ prefix }) => model.startsWith(prefix));
72
+ if (rate === undefined) {
73
+ return undefined;
74
+ }
75
+ return ((usage.prompt / 1_000_000) * rate.inputUsdPerMillion +
76
+ (usage.completion / 1_000_000) * rate.outputUsdPerMillion +
77
+ ((usage.cached ?? 0) / 1_000_000) * rate.inputUsdPerMillion * rate.cachedInputMultiplier);
78
+ };
79
+ //# sourceMappingURL=PriceList.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PriceList.js","sourceRoot":"","sources":["../src/PriceList.ts"],"names":[],"mappings":"AASA,MAAM,CAAC,MAAM,UAAU,GAAG,SAAS,CAAA;AAEnC,MAAM,CAAC,MAAM,UAAU,GAA6B,MAAM,CAAC,MAAM,CAAC;IAChE;QACE,MAAM,EAAE,gBAAgB;QACxB,kBAAkB,EAAE,EAAE;QACtB,mBAAmB,EAAE,EAAE;QACvB,qBAAqB,EAAE,GAAG;KAC3B;IACD;QACE,MAAM,EAAE,eAAe;QACvB,kBAAkB,EAAE,EAAE;QACtB,mBAAmB,EAAE,EAAE;QACvB,qBAAqB,EAAE,GAAG;KAC3B;IACD;QACE,MAAM,EAAE,iBAAiB;QACzB,kBAAkB,EAAE,CAAC;QACrB,mBAAmB,EAAE,EAAE;QACvB,qBAAqB,EAAE,GAAG;KAC3B;IACD;QACE,MAAM,EAAE,gBAAgB;QACxB,kBAAkB,EAAE,CAAC;QACrB,mBAAmB,EAAE,CAAC;QACtB,qBAAqB,EAAE,GAAG;KAC3B;IACD;QACE,MAAM,EAAE,gBAAgB;QACxB,kBAAkB,EAAE,IAAI;QACxB,mBAAmB,EAAE,EAAE;QACvB,qBAAqB,EAAE,GAAG;KAC3B;IACD;QACE,MAAM,EAAE,kBAAkB;QAC1B,kBAAkB,EAAE,GAAG;QACvB,mBAAmB,EAAE,GAAG;QACxB,qBAAqB,EAAE,GAAG;KAC3B;IACD;QACE,MAAM,EAAE,SAAS;QACjB,kBAAkB,EAAE,CAAC;QACrB,mBAAmB,EAAE,EAAE;QACvB,qBAAqB,EAAE,GAAG;KAC3B;IACD;QACE,MAAM,EAAE,UAAU;QAClB,kBAAkB,EAAE,CAAC;QACrB,mBAAmB,EAAE,CAAC;QACtB,qBAAqB,EAAE,GAAG;KAC3B;IACD;QACE,MAAM,EAAE,UAAU;QAClB,kBAAkB,EAAE,IAAI;QACxB,mBAAmB,EAAE,GAAG;QACxB,qBAAqB,EAAE,GAAG;KAC3B;IACD;QACE,MAAM,EAAE,WAAW;QACnB,kBAAkB,EAAE,IAAI;QACxB,mBAAmB,EAAE,GAAG;QACxB,qBAAqB,EAAE,GAAG;KAC3B;IACD;QACE,MAAM,EAAE,gBAAgB;QACxB,kBAAkB,EAAE,CAAC;QACrB,mBAAmB,EAAE,CAAC;QACtB,qBAAqB,EAAE,GAAG;KAC3B;CACF,CAAC,CAAA;AAEF,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,KAAa,EAAE,KAAiB,EAAsB,EAAE;IACtF,MAAM,IAAI,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAA;IACtE,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QACvB,OAAO,SAAS,CAAA;IAClB,CAAC;IACD,OAAO,CACL,CAAC,KAAK,CAAC,MAAM,GAAG,SAAS,CAAC,GAAG,IAAI,CAAC,kBAAkB;QACpD,CAAC,KAAK,CAAC,UAAU,GAAG,SAAS,CAAC,GAAG,IAAI,CAAC,mBAAmB;QACzD,CAAC,CAAC,KAAK,CAAC,MAAM,IAAI,CAAC,CAAC,GAAG,SAAS,CAAC,GAAG,IAAI,CAAC,kBAAkB,GAAG,IAAI,CAAC,qBAAqB,CACzF,CAAA;AACH,CAAC,CAAA"}
@@ -0,0 +1,27 @@
1
+ import * as Effect from "effect/Effect";
2
+ import * as Schema from "effect/Schema";
3
+ import { PersistenceError, type FlowError } from "./FlowError.ts";
4
+ import type { PlainFileStoreShape } from "./Persistence.ts";
5
+ declare const Provenance_base: Schema.Class<Provenance, Schema.Struct<{
6
+ readonly schema: Schema.Int;
7
+ readonly pack: Schema.String;
8
+ readonly llm4tsVersion: Schema.String;
9
+ readonly createdAt: Schema.String;
10
+ readonly approvedBy: Schema.optionalKey<Schema.String>;
11
+ readonly seats: Schema.$Record<Schema.String, Schema.String>;
12
+ readonly specs: Schema.$Record<Schema.String, Schema.String>;
13
+ readonly gateVerdicts: Schema.$Record<Schema.String, Schema.String>;
14
+ readonly equivalenceReport: Schema.optionalKey<Schema.String>;
15
+ readonly fixSpecs: Schema.$Array<Schema.String>;
16
+ }>, {}>;
17
+ export declare class Provenance extends Provenance_base {
18
+ }
19
+ export interface ProvenanceStoreShape {
20
+ readonly write: (path: string, provenance: Provenance) => Effect.Effect<void, FlowError>;
21
+ readonly load: (path: string) => Effect.Effect<Provenance, FlowError>;
22
+ readonly extend: (path: string, update: (current: Provenance) => Provenance) => Effect.Effect<Provenance, FlowError>;
23
+ readonly hashFiles: (root: string, paths: ReadonlyArray<string>) => Effect.Effect<Readonly<Record<string, string>>, PersistenceError>;
24
+ }
25
+ export declare const makeProvenanceStore: (files: PlainFileStoreShape) => ProvenanceStoreShape;
26
+ export {};
27
+ //# sourceMappingURL=Provenance.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Provenance.d.ts","sourceRoot":"","sources":["../src/Provenance.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AACvC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AACvC,OAAO,EAAE,gBAAgB,EAAkB,KAAK,SAAS,EAAE,MAAM,gBAAgB,CAAA;AACjF,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAA;;;;;;;;;;;;;AAE3D,qBAAa,UAAW,SAAQ,eAW9B;CAAG;AAKL,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,SAAS,CAAC,CAAA;IACxF,QAAQ,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,UAAU,EAAE,SAAS,CAAC,CAAA;IACrE,QAAQ,CAAC,MAAM,EAAE,CACf,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,CAAC,OAAO,EAAE,UAAU,KAAK,UAAU,KACxC,MAAM,CAAC,MAAM,CAAC,UAAU,EAAE,SAAS,CAAC,CAAA;IACzC,QAAQ,CAAC,SAAS,EAAE,CAClB,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,aAAa,CAAC,MAAM,CAAC,KACzB,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,EAAE,gBAAgB,CAAC,CAAA;CACvE;AAED,eAAO,MAAM,mBAAmB,GAAI,OAAO,mBAAmB,KAAG,oBAkDhE,CAAA"}
@@ -0,0 +1,38 @@
1
+ import * as Effect from "effect/Effect";
2
+ import * as Schema from "effect/Schema";
3
+ import { PersistenceError, PlanParseError } from "./FlowError.js";
4
+ export class Provenance extends Schema.Class("Provenance")({
5
+ schema: Schema.Int,
6
+ pack: Schema.String,
7
+ llm4tsVersion: Schema.String,
8
+ createdAt: Schema.String,
9
+ approvedBy: Schema.optionalKey(Schema.String),
10
+ seats: Schema.Record(Schema.String, Schema.String),
11
+ specs: Schema.Record(Schema.String, Schema.String),
12
+ gateVerdicts: Schema.Record(Schema.String, Schema.String),
13
+ equivalenceReport: Schema.optionalKey(Schema.String),
14
+ fixSpecs: Schema.Array(Schema.String)
15
+ }) {
16
+ }
17
+ const join = (root, path) => `${root.replace(/[\\/]+$/, "")}/${path.replace(/^[\\/]+/, "")}`;
18
+ export const makeProvenanceStore = (files) => {
19
+ const write = (path, provenance) => Schema.encodeEffect(Schema.fromJsonString(Provenance))(provenance).pipe(Effect.mapError((error) => PlanParseError.make({
20
+ message: `failed to encode provenance manifest ${path}: ${String(error)}`
21
+ })), Effect.flatMap((contents) => files.writeAtomic(path, `${contents}\n`)));
22
+ const load = (path) => Effect.flatMap(files.read(path), (contents) => contents === undefined
23
+ ? Effect.fail(PersistenceError.make({
24
+ message: `provenance manifest does not exist: ${path}`
25
+ }))
26
+ : Schema.decodeUnknownEffect(Schema.fromJsonString(Provenance))(contents).pipe(Effect.mapError((error) => PlanParseError.make({
27
+ message: `malformed provenance manifest ${path}: ${String(error)}`
28
+ }))));
29
+ const extend = (path, update) => Effect.flatMap(load(path), (current) => {
30
+ const updated = update(current);
31
+ return write(path, updated).pipe(Effect.as(updated));
32
+ });
33
+ const hashFiles = (root, paths) => Effect.forEach(paths, (path) => files
34
+ .hashSha256(join(root, path))
35
+ .pipe(Effect.map((hash) => [path, hash]))).pipe(Effect.map(Object.fromEntries));
36
+ return { write, load, extend, hashFiles };
37
+ };
38
+ //# sourceMappingURL=Provenance.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Provenance.js","sourceRoot":"","sources":["../src/Provenance.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ import * as Effect from "effect/Effect";
2
+ import * as Schema from "effect/Schema";
3
+ import type { LlmServiceShape } from "@llm4ts/core/LlmService";
4
+ import { TokenUsage } from "@llm4ts/core/Models";
5
+ import { PlanParseError, UnsupportedSchemaVersion } from "./FlowError.ts";
6
+ import { TraceLine } from "./FlowRecorder.ts";
7
+ import type { PlainFileStoreShape } from "./Persistence.ts";
8
+ export declare const CurrentTraceSchema = 1;
9
+ declare const ReplaySuccess_base: Schema.Class<ReplaySuccess, Schema.TaggedStruct<"Success", {
10
+ readonly text: Schema.String;
11
+ readonly usage: Schema.optionalKey<typeof TokenUsage>;
12
+ readonly model: Schema.optionalKey<Schema.String>;
13
+ }>, {}>;
14
+ export declare class ReplaySuccess extends ReplaySuccess_base {
15
+ }
16
+ declare const ReplayFailure_base: Schema.Class<ReplayFailure, Schema.TaggedStruct<"Failure", {
17
+ readonly message: Schema.String;
18
+ readonly model: Schema.optionalKey<Schema.String>;
19
+ }>, {}>;
20
+ export declare class ReplayFailure extends ReplayFailure_base {
21
+ }
22
+ export declare const ReplayTurn: Schema.Union<readonly [typeof ReplaySuccess, typeof ReplayFailure]>;
23
+ export type ReplayTurn = typeof ReplayTurn.Type;
24
+ export declare const segmentReplayTurns: (lines: ReadonlyArray<TraceLine>) => ReadonlyArray<ReplayTurn>;
25
+ export declare const readTrace: (files: PlainFileStoreShape, path: string) => Effect.Effect<readonly TraceLine[], import("./FlowError.ts").PersistenceError | PlanParseError | UnsupportedSchemaVersion | import("./FlowError.ts").WorkspacePathError | import("./FlowError.ts").WorkspaceLimitError | import("./FlowError.ts").WorkspaceIoError | import("./FlowError.ts").FlowAborted | import("./FlowError.ts").ProcessError | import("./FlowError.ts").FlowLlmError | import("./FlowError.ts").FlowCapabilityDenied | import("./FlowError.ts").BudgetExceeded, never>;
26
+ export declare const makeReplayConnector: (turns: readonly (ReplaySuccess | ReplayFailure)[]) => Effect.Effect<LlmServiceShape, never, never>;
27
+ export declare const replayFromTrace: (files: PlainFileStoreShape, path: string) => Effect.Effect<LlmServiceShape, import("./FlowError.ts").PersistenceError | PlanParseError | UnsupportedSchemaVersion | import("./FlowError.ts").WorkspacePathError | import("./FlowError.ts").WorkspaceLimitError | import("./FlowError.ts").WorkspaceIoError | import("./FlowError.ts").FlowAborted | import("./FlowError.ts").ProcessError | import("./FlowError.ts").FlowLlmError | import("./FlowError.ts").FlowCapabilityDenied | import("./FlowError.ts").BudgetExceeded, never>;
28
+ export {};
29
+ //# sourceMappingURL=Replay.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Replay.d.ts","sourceRoot":"","sources":["../src/Replay.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AAEvC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AAGvC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAA;AAC9D,OAAO,EAAY,UAAU,EAAE,MAAM,qBAAqB,CAAA;AAE1D,OAAO,EAAE,cAAc,EAAE,wBAAwB,EAAkB,MAAM,gBAAgB,CAAA;AACzF,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAA;AAC7C,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAA;AAE3D,eAAO,MAAM,kBAAkB,IAAI,CAAA;;;;;;AAEnC,qBAAa,aAAc,SAAQ,kBAIjC;CAAG;;;;;AAEL,qBAAa,aAAc,SAAQ,kBAGjC;CAAG;AAEL,eAAO,MAAM,UAAU,qEAA+C,CAAA;AACtE,MAAM,MAAM,UAAU,GAAG,OAAO,UAAU,CAAC,IAAI,CAAA;AA8C/C,eAAO,MAAM,kBAAkB,GAAI,OAAO,aAAa,CAAC,SAAS,CAAC,KAAG,aAAa,CAAC,UAAU,CAgE5F,CAAA;AAID,eAAO,MAAM,SAAS,2gBAqCpB,CAAA;AAEF,eAAO,MAAM,mBAAmB,qGA6E9B,CAAA;AAEF,eAAO,MAAM,eAAe,sgBAM1B,CAAA"}
package/dist/Replay.js ADDED
@@ -0,0 +1,181 @@
1
+ import * as Effect from "effect/Effect";
2
+ import * as Ref from "effect/Ref";
3
+ import * as Schema from "effect/Schema";
4
+ import * as Stream from "effect/Stream";
5
+ import { InvalidRequestError, ParseError, ProviderError } from "@llm4ts/core/Errors";
6
+ import { LlmChunk, TokenUsage } from "@llm4ts/core/Models";
7
+ import { collect } from "@llm4ts/core/Streaming";
8
+ import { PlanParseError, UnsupportedSchemaVersion } from "./FlowError.js";
9
+ import { TraceLine } from "./FlowRecorder.js";
10
+ export const CurrentTraceSchema = 1;
11
+ export class ReplaySuccess extends Schema.TaggedClass()("Success", {
12
+ text: Schema.String,
13
+ usage: Schema.optionalKey(TokenUsage),
14
+ model: Schema.optionalKey(Schema.String)
15
+ }) {
16
+ }
17
+ export class ReplayFailure extends Schema.TaggedClass()("Failure", {
18
+ message: Schema.String,
19
+ model: Schema.optionalKey(Schema.String)
20
+ }) {
21
+ }
22
+ export const ReplayTurn = Schema.Union([ReplaySuccess, ReplayFailure]);
23
+ const stringField = (fields, key) => {
24
+ const value = fields[key];
25
+ return typeof value === "string" ? value : undefined;
26
+ };
27
+ const integerField = (fields, key) => {
28
+ const value = stringField(fields, key);
29
+ if (value === undefined || !/^-?\d+$/.test(value)) {
30
+ return undefined;
31
+ }
32
+ const parsed = Number(value);
33
+ return Number.isSafeInteger(parsed) ? parsed : undefined;
34
+ };
35
+ const isSafeInteger = (value) => typeof value === "number" && Number.isSafeInteger(value);
36
+ const flowEventFields = (line) => {
37
+ const event = line.fields.event;
38
+ if (typeof event !== "string") {
39
+ return line.fields;
40
+ }
41
+ try {
42
+ const decoded = JSON.parse(event);
43
+ if (typeof decoded !== "object" || decoded === null) {
44
+ return line.fields;
45
+ }
46
+ return Object.fromEntries(Object.keys(decoded).map((key) => [
47
+ key,
48
+ Reflect.get(decoded, key)
49
+ ]));
50
+ }
51
+ catch {
52
+ return line.fields;
53
+ }
54
+ };
55
+ export const segmentReplayTurns = (lines) => {
56
+ let pendingUsage;
57
+ let pendingModel;
58
+ const turns = [];
59
+ for (const line of [...lines].sort((left, right) => left.seq - right.seq)) {
60
+ const fields = flowEventFields(line);
61
+ switch (line.kind) {
62
+ case "TokensUsed": {
63
+ const usageValue = typeof fields.usage === "object" && fields.usage !== null
64
+ ? {
65
+ prompt: Reflect.get(fields.usage, "prompt"),
66
+ completion: Reflect.get(fields.usage, "completion"),
67
+ total: Reflect.get(fields.usage, "total"),
68
+ cached: Reflect.get(fields.usage, "cached")
69
+ }
70
+ : fields;
71
+ const prompt = typeof usageValue.prompt === "number" ? usageValue.prompt : integerField(fields, "prompt");
72
+ const completion = typeof usageValue.completion === "number"
73
+ ? usageValue.completion
74
+ : integerField(fields, "completion");
75
+ const total = typeof usageValue.total === "number" ? usageValue.total : integerField(fields, "total");
76
+ const cached = typeof usageValue.cached === "number" ? usageValue.cached : undefined;
77
+ if (isSafeInteger(prompt) && isSafeInteger(completion) && isSafeInteger(total)) {
78
+ pendingUsage = TokenUsage.make({
79
+ prompt,
80
+ completion,
81
+ total,
82
+ ...(cached === undefined ? {} : { cached })
83
+ });
84
+ }
85
+ pendingModel = stringField(fields, "model") ?? pendingModel;
86
+ break;
87
+ }
88
+ case "AssistantMessage":
89
+ turns.push(ReplaySuccess.make({
90
+ text: stringField(fields, "text") ?? "",
91
+ ...(pendingUsage === undefined ? {} : { usage: pendingUsage }),
92
+ ...(pendingModel === undefined ? {} : { model: pendingModel })
93
+ }));
94
+ pendingUsage = undefined;
95
+ pendingModel = undefined;
96
+ break;
97
+ case "StreamError": {
98
+ const model = stringField(fields, "model");
99
+ turns.push(ReplayFailure.make({
100
+ message: stringField(fields, "message") ?? "",
101
+ ...(model === undefined ? {} : { model })
102
+ }));
103
+ pendingUsage = undefined;
104
+ pendingModel = undefined;
105
+ break;
106
+ }
107
+ }
108
+ }
109
+ return turns;
110
+ };
111
+ const traceCodec = Schema.fromJsonString(TraceLine);
112
+ export const readTrace = Effect.fn("@llm4ts/flow/Replay.readTrace")(function* (files, path) {
113
+ const contents = yield* files.read(path);
114
+ if (contents === undefined) {
115
+ return yield* PlanParseError.make({
116
+ message: `trace does not exist: ${path}`
117
+ });
118
+ }
119
+ const lines = contents
120
+ .split(/\r?\n/u)
121
+ .map((line) => line.trim())
122
+ .filter((line) => line.length > 0);
123
+ const decoded = yield* Effect.forEach(lines, (line, index) => Schema.decodeUnknownEffect(traceCodec)(line).pipe(Effect.mapError((error) => PlanParseError.make({
124
+ message: `malformed trace at ${path}:${index + 1}: ${String(error)}`
125
+ }))), { concurrency: 1 });
126
+ for (const line of decoded) {
127
+ const actual = line.schemaVersion ?? 1;
128
+ if (actual !== CurrentTraceSchema) {
129
+ return yield* UnsupportedSchemaVersion.make({
130
+ path,
131
+ expected: CurrentTraceSchema,
132
+ actual
133
+ });
134
+ }
135
+ }
136
+ return [...decoded].sort((left, right) => left.seq - right.seq);
137
+ });
138
+ export const makeReplayConnector = Effect.fn("@llm4ts/flow/Replay.makeConnector")(function* (turns) {
139
+ const cursor = yield* Ref.make(0);
140
+ const next = Stream.unwrap(Ref.getAndUpdate(cursor, (index) => index + 1).pipe(Effect.map((index) => {
141
+ const turn = turns[index];
142
+ if (turn === undefined) {
143
+ return Stream.fail(ProviderError.make({
144
+ message: `replay trace exhausted at turn ${index}`
145
+ }));
146
+ }
147
+ if (turn._tag === "Failure") {
148
+ return Stream.fail(ProviderError.make({ message: turn.message }));
149
+ }
150
+ return Stream.succeed(LlmChunk.make({
151
+ delta: turn.text,
152
+ finishReason: "stop",
153
+ ...(turn.usage === undefined ? {} : { usage: turn.usage }),
154
+ metadata: {
155
+ provider: "replay",
156
+ ...(turn.model === undefined ? {} : { model: turn.model })
157
+ }
158
+ }));
159
+ })));
160
+ return {
161
+ executeStream: (_prompt) => next,
162
+ executeStreamWithHistory: (_messages) => next,
163
+ executeWithTools: (_prompt, _tools) => Effect.fail(InvalidRequestError.make({
164
+ message: "replay does not support tool calling"
165
+ })),
166
+ executeStructured: (_prompt, schema) => collect(next).pipe(Effect.flatMap((response) => Schema.decodeUnknownEffect(Schema.fromJsonString(schema))(response.content)), Effect.mapError((error) => ParseError.make({
167
+ message: `replay structured parse error: ${String(error)}`,
168
+ raw: error instanceof ParseError ? error.raw : ""
169
+ }))),
170
+ executeStructuredWithUsage: (_prompt, schema) => collect(next).pipe(Effect.flatMap((response) => Schema.decodeUnknownEffect(Schema.fromJsonString(schema))(response.content).pipe(Effect.map((value) => [value, response.usage, response.metadata.model]))), Effect.mapError((error) => ParseError.make({
171
+ message: `replay structured parse error: ${String(error)}`,
172
+ raw: ""
173
+ }))),
174
+ isAvailable: Effect.succeed(true)
175
+ };
176
+ });
177
+ export const replayFromTrace = Effect.fn("@llm4ts/flow/Replay.fromTrace")(function* (files, path) {
178
+ const lines = yield* readTrace(files, path);
179
+ return yield* makeReplayConnector(segmentReplayTurns(lines));
180
+ });
181
+ //# sourceMappingURL=Replay.js.map