@fastpaca/cria 0.0.1 → 1.0.1

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 (140) hide show
  1. package/README.md +93 -106
  2. package/dist/ai-sdk/index.d.ts +43 -0
  3. package/dist/ai-sdk/index.d.ts.map +1 -0
  4. package/dist/ai-sdk/index.js +303 -0
  5. package/dist/ai-sdk/index.js.map +1 -0
  6. package/dist/ai-sdk/index.test.d.ts +2 -0
  7. package/dist/ai-sdk/index.test.d.ts.map +1 -0
  8. package/dist/ai-sdk/index.test.js +101 -0
  9. package/dist/ai-sdk/index.test.js.map +1 -0
  10. package/dist/anthropic/index.d.ts +74 -0
  11. package/dist/anthropic/index.d.ts.map +1 -0
  12. package/dist/anthropic/index.js +238 -0
  13. package/dist/anthropic/index.js.map +1 -0
  14. package/dist/anthropic/index.test.d.ts +2 -0
  15. package/dist/anthropic/index.test.d.ts.map +1 -0
  16. package/dist/anthropic/index.test.js +115 -0
  17. package/dist/anthropic/index.test.js.map +1 -0
  18. package/dist/components/additional.test.d.ts +2 -0
  19. package/dist/components/additional.test.d.ts.map +1 -0
  20. package/dist/components/additional.test.js +31 -0
  21. package/dist/components/additional.test.js.map +1 -0
  22. package/dist/components/index.d.ts +148 -0
  23. package/dist/components/index.d.ts.map +1 -0
  24. package/dist/components/index.js +184 -0
  25. package/dist/components/index.js.map +1 -0
  26. package/dist/components/summary.d.ts +91 -0
  27. package/dist/components/summary.d.ts.map +1 -0
  28. package/dist/components/summary.js +118 -0
  29. package/dist/components/summary.js.map +1 -0
  30. package/dist/components/summary.test.d.ts +2 -0
  31. package/dist/components/summary.test.d.ts.map +1 -0
  32. package/dist/components/summary.test.js +101 -0
  33. package/dist/components/summary.test.js.map +1 -0
  34. package/dist/components/vector-search.d.ts +70 -0
  35. package/dist/components/vector-search.d.ts.map +1 -0
  36. package/dist/components/vector-search.js +110 -0
  37. package/dist/components/vector-search.js.map +1 -0
  38. package/dist/components/vector-search.test.d.ts +2 -0
  39. package/dist/components/vector-search.test.d.ts.map +1 -0
  40. package/dist/components/vector-search.test.js +113 -0
  41. package/dist/components/vector-search.test.js.map +1 -0
  42. package/dist/index.d.ts +12 -5
  43. package/dist/index.d.ts.map +1 -1
  44. package/dist/index.js +9 -5
  45. package/dist/index.js.map +1 -1
  46. package/dist/instrumentation/otel.d.ts +19 -0
  47. package/dist/instrumentation/otel.d.ts.map +1 -0
  48. package/dist/instrumentation/otel.js +102 -0
  49. package/dist/instrumentation/otel.js.map +1 -0
  50. package/dist/instrumentation/otel.test.d.ts +2 -0
  51. package/dist/instrumentation/otel.test.d.ts.map +1 -0
  52. package/dist/instrumentation/otel.test.js +116 -0
  53. package/dist/instrumentation/otel.test.js.map +1 -0
  54. package/dist/jsx-dev-runtime.d.ts +2 -0
  55. package/dist/jsx-dev-runtime.d.ts.map +1 -0
  56. package/dist/jsx-dev-runtime.js +2 -0
  57. package/dist/jsx-dev-runtime.js.map +1 -0
  58. package/dist/jsx-runtime.d.ts +30 -8
  59. package/dist/jsx-runtime.d.ts.map +1 -1
  60. package/dist/jsx-runtime.js +13 -10
  61. package/dist/jsx-runtime.js.map +1 -1
  62. package/dist/memory/chroma/index.d.ts +59 -0
  63. package/dist/memory/chroma/index.d.ts.map +1 -0
  64. package/dist/memory/chroma/index.js +172 -0
  65. package/dist/memory/chroma/index.js.map +1 -0
  66. package/dist/memory/index.d.ts +4 -0
  67. package/dist/memory/index.d.ts.map +1 -0
  68. package/dist/memory/index.js +2 -0
  69. package/dist/memory/index.js.map +1 -0
  70. package/dist/memory/key-value.d.ts +71 -0
  71. package/dist/memory/key-value.d.ts.map +1 -0
  72. package/dist/memory/key-value.js +34 -0
  73. package/dist/memory/key-value.js.map +1 -0
  74. package/dist/memory/postgres.d.ts +71 -0
  75. package/dist/memory/postgres.d.ts.map +1 -0
  76. package/dist/memory/postgres.js +109 -0
  77. package/dist/memory/postgres.js.map +1 -0
  78. package/dist/memory/qdrant/index.d.ts +64 -0
  79. package/dist/memory/qdrant/index.d.ts.map +1 -0
  80. package/dist/memory/qdrant/index.js +136 -0
  81. package/dist/memory/qdrant/index.js.map +1 -0
  82. package/dist/memory/redis.d.ts +70 -0
  83. package/dist/memory/redis.d.ts.map +1 -0
  84. package/dist/memory/redis.js +100 -0
  85. package/dist/memory/redis.js.map +1 -0
  86. package/dist/memory/vector.d.ts +53 -0
  87. package/dist/memory/vector.d.ts.map +1 -0
  88. package/dist/memory/vector.js +2 -0
  89. package/dist/memory/vector.js.map +1 -0
  90. package/dist/openai/index.d.ts +46 -0
  91. package/dist/openai/index.d.ts.map +1 -0
  92. package/dist/openai/index.js +260 -0
  93. package/dist/openai/index.js.map +1 -0
  94. package/dist/openai/index.test.d.ts +2 -0
  95. package/dist/openai/index.test.d.ts.map +1 -0
  96. package/dist/openai/index.test.js +204 -0
  97. package/dist/openai/index.test.js.map +1 -0
  98. package/dist/providers/index.d.ts +2 -0
  99. package/dist/providers/index.d.ts.map +1 -0
  100. package/dist/providers/index.js +2 -0
  101. package/dist/providers/index.js.map +1 -0
  102. package/dist/providers/types.d.ts +2 -0
  103. package/dist/providers/types.d.ts.map +1 -0
  104. package/dist/providers/types.js +2 -0
  105. package/dist/providers/types.js.map +1 -0
  106. package/dist/render.d.ts +44 -40
  107. package/dist/render.d.ts.map +1 -1
  108. package/dist/render.js +162 -148
  109. package/dist/render.js.map +1 -1
  110. package/dist/render.test.js +146 -28
  111. package/dist/render.test.js.map +1 -1
  112. package/dist/renderers/markdown.d.ts +3 -0
  113. package/dist/renderers/markdown.d.ts.map +1 -0
  114. package/dist/renderers/markdown.js +43 -0
  115. package/dist/renderers/markdown.js.map +1 -0
  116. package/dist/renderers/shared.d.ts +82 -0
  117. package/dist/renderers/shared.d.ts.map +1 -0
  118. package/dist/renderers/shared.js +156 -0
  119. package/dist/renderers/shared.js.map +1 -0
  120. package/dist/snapshot.d.ts +47 -0
  121. package/dist/snapshot.d.ts.map +1 -0
  122. package/dist/snapshot.js +140 -0
  123. package/dist/snapshot.js.map +1 -0
  124. package/dist/snapshot.test.d.ts +2 -0
  125. package/dist/snapshot.test.d.ts.map +1 -0
  126. package/dist/snapshot.test.js +68 -0
  127. package/dist/snapshot.test.js.map +1 -0
  128. package/dist/tokenizers.d.ts +14 -0
  129. package/dist/tokenizers.d.ts.map +1 -0
  130. package/dist/tokenizers.js +45 -0
  131. package/dist/tokenizers.js.map +1 -0
  132. package/dist/types.d.ts +212 -84
  133. package/dist/types.d.ts.map +1 -1
  134. package/dist/types.js +109 -0
  135. package/dist/types.js.map +1 -1
  136. package/package.json +88 -3
  137. package/dist/components.d.ts +0 -78
  138. package/dist/components.d.ts.map +0 -1
  139. package/dist/components.js +0 -98
  140. package/dist/components.js.map +0 -1
package/dist/render.d.ts CHANGED
@@ -1,44 +1,48 @@
1
- import { type PromptElement, type Tokenizer } from "./types";
2
- /** Options for the render function. */
3
- interface RenderOptions {
4
- /** Function to count tokens in a string (e.g., tiktoken) */
5
- tokenizer: Tokenizer;
6
- /** Maximum token count for the final output */
1
+ import { FitError, type MaybePromise, type PromptElement, type PromptRenderer, type Tokenizer } from "./types";
2
+ export interface RenderOptions {
3
+ tokenizer?: Tokenizer;
4
+ /** Token budget. Omit for unlimited. */
5
+ budget?: number;
6
+ renderer?: PromptRenderer<unknown>;
7
+ hooks?: RenderHooks;
8
+ }
9
+ export interface FitStartEvent {
10
+ element: PromptElement;
7
11
  budget: number;
12
+ totalTokens: number;
13
+ }
14
+ export interface FitIterationEvent {
15
+ iteration: number;
16
+ priority: number;
17
+ totalTokens: number;
18
+ }
19
+ export interface StrategyAppliedEvent {
20
+ target: PromptElement;
21
+ result: PromptElement | null;
22
+ priority: number;
23
+ iteration: number;
24
+ }
25
+ export interface FitCompleteEvent {
26
+ result: PromptElement | null;
27
+ iterations: number;
28
+ totalTokens: number;
29
+ }
30
+ export interface FitErrorEvent {
31
+ error: FitError;
32
+ iteration: number;
33
+ priority: number;
34
+ totalTokens: number;
35
+ }
36
+ export interface RenderHooks {
37
+ onFitStart?: (event: FitStartEvent) => MaybePromise<void>;
38
+ onFitIteration?: (event: FitIterationEvent) => MaybePromise<void>;
39
+ onStrategyApplied?: (event: StrategyAppliedEvent) => MaybePromise<void>;
40
+ onFitComplete?: (event: FitCompleteEvent) => MaybePromise<void>;
41
+ onFitError?: (event: FitErrorEvent) => MaybePromise<void>;
8
42
  }
9
- /**
10
- * Renders a PromptElement tree to a fitted string.
11
- *
12
- * This is the main entry point for Cria. Takes a JSX tree and returns a string
13
- * that fits within the specified token budget.
14
- *
15
- * **Pipeline:**
16
- * 1. `flatten`: Walks the tree, collects text into ordered PromptFragment[]
17
- * 2. `fitToBudget`: Applies strategies starting from lowest priority until under budget
18
- * 3. `join`: Concatenates fragment content into final string
19
- *
20
- * @param element - The root PromptElement (from JSX)
21
- * @param options - Tokenizer and budget configuration
22
- * @returns The fitted prompt string
23
- * @throws {FitError} When the prompt cannot fit within budget
24
- *
25
- * @example
26
- * ```tsx
27
- * import { render, Region, Omit } from "@fastpaca/cria";
28
- *
29
- * const prompt = (
30
- * <Region priority={0}>
31
- * System prompt
32
- * <Omit priority={2}>Optional context</Omit>
33
- * </Region>
34
- * );
35
- *
36
- * const result = render(prompt, {
37
- * tokenizer: (text) => Math.ceil(text.length / 4),
38
- * budget: 1000,
39
- * });
40
- * ```
41
- */
42
- export declare function render(element: PromptElement, { tokenizer, budget }: RenderOptions): string;
43
+ type RenderOutput<TOptions extends RenderOptions> = TOptions extends {
44
+ renderer: PromptRenderer<infer TOutput>;
45
+ } ? TOutput : string;
46
+ export declare function render<TOptions extends RenderOptions>(element: MaybePromise<PromptElement>, { tokenizer, budget, renderer, hooks }: TOptions): Promise<RenderOutput<TOptions>>;
43
47
  export {};
44
48
  //# sourceMappingURL=render.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../src/render.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,aAAa,EAIlB,KAAK,SAAS,EACf,MAAM,SAAS,CAAC;AAEjB,uCAAuC;AACvC,UAAU,aAAa;IACrB,4DAA4D;IAC5D,SAAS,EAAE,SAAS,CAAC;IACrB,+CAA+C;IAC/C,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,wBAAgB,MAAM,CACpB,OAAO,EAAE,aAAa,EACtB,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE,aAAa,GACnC,MAAM,CAQR"}
1
+ {"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../src/render.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,QAAQ,EACR,KAAK,YAAY,EACjB,KAAK,aAAa,EAClB,KAAK,cAAc,EAEnB,KAAK,SAAS,EACf,MAAM,SAAS,CAAC;AAEjB,MAAM,WAAW,aAAa;IAC5B,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,wCAAwC;IACxC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,cAAc,CAAC,OAAO,CAAC,CAAC;IACnC,KAAK,CAAC,EAAE,WAAW,CAAC;CACrB;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,aAAa,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,aAAa,CAAC;IACtB,MAAM,EAAE,aAAa,GAAG,IAAI,CAAC;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,aAAa,GAAG,IAAI,CAAC;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,QAAQ,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,WAAW;IAC1B,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,YAAY,CAAC,IAAI,CAAC,CAAC;IAC1D,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,iBAAiB,KAAK,YAAY,CAAC,IAAI,CAAC,CAAC;IAClE,iBAAiB,CAAC,EAAE,CAAC,KAAK,EAAE,oBAAoB,KAAK,YAAY,CAAC,IAAI,CAAC,CAAC;IACxE,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,gBAAgB,KAAK,YAAY,CAAC,IAAI,CAAC,CAAC;IAChE,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,YAAY,CAAC,IAAI,CAAC,CAAC;CAC3D;AAED,KAAK,YAAY,CAAC,QAAQ,SAAS,aAAa,IAAI,QAAQ,SAAS;IACnE,QAAQ,EAAE,cAAc,CAAC,MAAM,OAAO,CAAC,CAAC;CACzC,GACG,OAAO,GACP,MAAM,CAAC;AAEX,wBAAsB,MAAM,CAAC,QAAQ,SAAS,aAAa,EACzD,OAAO,EAAE,YAAY,CAAC,aAAa,CAAC,EACpC,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE,QAAQ,GAC/C,OAAO,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,CA4CjC"}
package/dist/render.js CHANGED
@@ -1,171 +1,185 @@
1
+ import { markdownRenderer } from "./renderers/markdown";
1
2
  import { FitError, } from "./types";
2
- /**
3
- * Renders a PromptElement tree to a fitted string.
4
- *
5
- * This is the main entry point for Cria. Takes a JSX tree and returns a string
6
- * that fits within the specified token budget.
7
- *
8
- * **Pipeline:**
9
- * 1. `flatten`: Walks the tree, collects text into ordered PromptFragment[]
10
- * 2. `fitToBudget`: Applies strategies starting from lowest priority until under budget
11
- * 3. `join`: Concatenates fragment content into final string
12
- *
13
- * @param element - The root PromptElement (from JSX)
14
- * @param options - Tokenizer and budget configuration
15
- * @returns The fitted prompt string
16
- * @throws {FitError} When the prompt cannot fit within budget
17
- *
18
- * @example
19
- * ```tsx
20
- * import { render, Region, Omit } from "@fastpaca/cria";
21
- *
22
- * const prompt = (
23
- * <Region priority={0}>
24
- * System prompt
25
- * <Omit priority={2}>Optional context</Omit>
26
- * </Region>
27
- * );
28
- *
29
- * const result = render(prompt, {
30
- * tokenizer: (text) => Math.ceil(text.length / 4),
31
- * budget: 1000,
32
- * });
33
- * ```
34
- */
35
- export function render(element, { tokenizer, budget }) {
3
+ export async function render(element, { tokenizer, budget, renderer, hooks }) {
4
+ /*
5
+ * The JSX runtime normalizes children and returns either a PromptElement or a
6
+ * native Promise. Render only awaits that root value and does not walk the tree.
7
+ * Non-Promise thenables are intentionally unsupported.
8
+ */
9
+ const resolvedElement = element instanceof Promise ? await element : element;
10
+ const resolvedRenderer = (renderer ?? markdownRenderer);
11
+ // Skip fitting if no budget specified (unlimited)
12
+ if (budget === undefined || budget === null) {
13
+ return (await resolvedRenderer.render(resolvedElement));
14
+ }
36
15
  if (budget <= 0) {
37
- return "";
16
+ return resolvedRenderer.empty();
17
+ }
18
+ const tokenizerResolution = resolveTokenizer(resolvedElement, tokenizer);
19
+ if (!tokenizerResolution) {
20
+ throw new Error("Token budgeting requires a tokenizer. Provide one to render(), or wrap your prompt in a provider that supplies a tokenizer (e.g. <OpenAIProvider>, <AnthropicProvider>, or <AISDKProvider>). See docs/tokenization.md for details.");
21
+ }
22
+ const tokenizerFn = tokenizerResolution.tokenizer;
23
+ const fitted = await fitToBudget(resolvedElement, budget, tokenizerFn, resolvedRenderer.tokenString, hooks);
24
+ if (!fitted) {
25
+ return resolvedRenderer.empty();
38
26
  }
39
- const fragments = flatten(element, tokenizer, { counter: 0 });
40
- const fitted = fitToBudget(fragments, budget, tokenizer);
41
- return fitted.map((f) => f.content).join("");
27
+ return (await resolvedRenderer.render(fitted));
42
28
  }
43
- /**
44
- * Turns a PromptElement tree into an ordered list of PromptFragment.
45
- *
46
- * - Preserves text order (flush text buffer before descending into child elements).
47
- * - Inherits priority/strategy from the emitting element.
48
- * - Assigns regionId: explicit id if provided, else auto-incrementing counter.
49
- * - Computes token counts with the provided tokenizer.
50
- */
51
- function flatten(element, tokenizer, ctx, fragments = []) {
52
- let buffer = "";
53
- const flushBuffer = () => {
54
- if (buffer.length === 0) {
55
- return;
56
- }
57
- const tokens = tokenizer(buffer);
58
- if (tokens > 0) {
59
- const fragment = {
60
- content: buffer,
61
- tokens,
62
- priority: element.priority,
63
- regionId: element.id ?? `r${ctx.counter++}`,
64
- index: fragments.length,
65
- };
66
- if (element.strategy) {
67
- fragment.strategy = element.strategy;
68
- }
69
- fragments.push(fragment);
70
- }
71
- buffer = "";
72
- };
29
+ async function safeInvoke(handler, event) {
30
+ if (!handler) {
31
+ return;
32
+ }
33
+ await handler(event);
34
+ }
35
+ function resolveTokenizer(element, override) {
36
+ if (override) {
37
+ return { tokenizer: override, source: "options" };
38
+ }
39
+ const providerResolution = findProviderTokenizer(element);
40
+ if (providerResolution) {
41
+ return { ...providerResolution, source: "provider" };
42
+ }
43
+ return null;
44
+ }
45
+ function findProviderTokenizer(element) {
46
+ const providerTokenizer = element.context?.provider?.tokenizer;
47
+ if (providerTokenizer) {
48
+ return {
49
+ tokenizer: providerTokenizer,
50
+ providerName: element.context?.provider?.name,
51
+ };
52
+ }
73
53
  for (const child of element.children) {
74
- if (!child) {
75
- continue;
76
- }
77
54
  if (typeof child === "string") {
78
- buffer += child;
55
+ continue;
79
56
  }
80
- else {
81
- // Flush current text before descending to maintain order
82
- flushBuffer();
83
- flatten(child, tokenizer, ctx, fragments);
57
+ const found = findProviderTokenizer(child);
58
+ if (found) {
59
+ return found;
84
60
  }
85
61
  }
86
- // Flush any trailing text
87
- flushBuffer();
88
- return fragments;
62
+ return null;
89
63
  }
90
- /**
91
- * Finds the highest priority number (least important) among fragments with strategies.
92
- */
93
- function findLowestImportancePriority(fragments) {
94
- const priorities = fragments
95
- .filter((f) => f.strategy !== undefined)
96
- .map((f) => f.priority);
97
- if (priorities.length === 0) {
98
- return null;
64
+ async function fitToBudget(element, budget, tokenizer, tokenString, hooks) {
65
+ let current = element;
66
+ let iteration = 0;
67
+ let totalTokens = tokenizer(tokenString(element));
68
+ await safeInvoke(hooks?.onFitStart, {
69
+ element,
70
+ budget,
71
+ totalTokens,
72
+ });
73
+ while (current && totalTokens > budget) {
74
+ iteration++;
75
+ const lowestImportancePriority = findLowestImportancePriority(current);
76
+ if (lowestImportancePriority === null) {
77
+ const error = new FitError(totalTokens - budget, -1, iteration);
78
+ await safeInvoke(hooks?.onFitError, {
79
+ error,
80
+ iteration,
81
+ priority: -1,
82
+ totalTokens,
83
+ });
84
+ throw error;
85
+ }
86
+ await safeInvoke(hooks?.onFitIteration, {
87
+ iteration,
88
+ priority: lowestImportancePriority,
89
+ totalTokens,
90
+ });
91
+ const baseCtx = {
92
+ budget,
93
+ tokenizer,
94
+ tokenString,
95
+ totalTokens,
96
+ iteration,
97
+ };
98
+ const applied = await applyStrategiesAtPriority(current, lowestImportancePriority, baseCtx, {}, // Start with empty context at the root
99
+ hooks, iteration);
100
+ current = applied.element;
101
+ const nextTokens = current ? tokenizer(tokenString(current)) : 0;
102
+ if (nextTokens >= totalTokens) {
103
+ const error = new FitError(nextTokens - budget, lowestImportancePriority, iteration);
104
+ await safeInvoke(hooks?.onFitError, {
105
+ error,
106
+ iteration,
107
+ priority: lowestImportancePriority,
108
+ totalTokens: nextTokens,
109
+ });
110
+ throw error;
111
+ }
112
+ totalTokens = nextTokens;
99
113
  }
100
- return Math.max(...priorities);
114
+ await safeInvoke(hooks?.onFitComplete, {
115
+ result: current,
116
+ iterations: iteration,
117
+ totalTokens,
118
+ });
119
+ return current;
101
120
  }
102
- /**
103
- * Applies a single strategy to its target fragment.
104
- * Splices replacements in-place and recomputes token counts.
105
- */
106
- function applyStrategy(result, target, budget, tokenizer, iteration) {
107
- const strategy = target.strategy;
108
- const targetIndex = result.findIndex((f) => f.regionId === target.regionId);
109
- if (targetIndex === -1) {
110
- return;
121
+ function findLowestImportancePriority(element) {
122
+ let maxPriority = element.strategy ? element.priority : null;
123
+ for (const child of element.children) {
124
+ if (typeof child === "string") {
125
+ continue;
126
+ }
127
+ const childMax = findLowestImportancePriority(child);
128
+ maxPriority = maxNullable(maxPriority, childMax);
111
129
  }
112
- const currentTarget = result[targetIndex];
113
- if (!currentTarget) {
114
- return;
130
+ return maxPriority;
131
+ }
132
+ function maxNullable(a, b) {
133
+ if (a === null) {
134
+ return b;
115
135
  }
116
- const input = {
117
- fragments: result,
118
- target: currentTarget,
119
- budget,
120
- tokenizer,
121
- totalTokens: result.reduce((sum, f) => sum + f.tokens, 0),
122
- iteration,
123
- };
124
- const replacement = strategy(input);
125
- // Splice replacement at target position
126
- result.splice(targetIndex, 1, ...replacement);
127
- // Recompute tokens for modified fragments
128
- for (const frag of replacement) {
129
- frag.tokens = tokenizer(frag.content);
136
+ if (b === null) {
137
+ return a;
130
138
  }
139
+ return Math.max(a, b);
131
140
  }
132
- /**
133
- * Repeatedly applies strategies starting from the least-important priority
134
- * until the total token count is within budget.
135
- *
136
- * Throws FitError if:
137
- * - No progress is made in an iteration (strategies didn't reduce tokens)
138
- * - No strategies remain but still over budget
139
- */
140
- function fitToBudget(fragments, budget, tokenizer) {
141
- const result = [...fragments];
142
- let iteration = 0;
143
- const maxIterations = 1000;
144
- while (true) {
145
- const totalTokens = result.reduce((sum, f) => sum + f.tokens, 0);
146
- if (totalTokens <= budget) {
147
- return result;
148
- }
149
- iteration++;
150
- if (iteration > maxIterations) {
151
- throw new FitError(totalTokens - budget, -1, iteration);
141
+ async function applyStrategiesAtPriority(element, priority, baseCtx, inheritedContext, hooks, iteration) {
142
+ // Merge this element's context with inherited context
143
+ // Element context overrides inherited context
144
+ const mergedContext = element.context
145
+ ? { ...inheritedContext, ...element.context }
146
+ : inheritedContext;
147
+ let childrenChanged = false;
148
+ const nextChildren = [];
149
+ for (const child of element.children) {
150
+ if (typeof child === "string") {
151
+ nextChildren.push(child);
152
+ continue;
152
153
  }
153
- const lowestImportancePriority = findLowestImportancePriority(result);
154
- if (lowestImportancePriority === null) {
155
- throw new FitError(totalTokens - budget, -1, iteration);
154
+ // Pass merged context to children
155
+ const applied = await applyStrategiesAtPriority(child, priority, baseCtx, mergedContext, hooks, iteration);
156
+ if (applied.applied) {
157
+ childrenChanged = true;
156
158
  }
157
- // Collect all targets at this priority
158
- const targets = result.filter((f) => f.strategy !== undefined && f.priority === lowestImportancePriority);
159
- const tokensBefore = totalTokens;
160
- // Apply strategies in stable order
161
- for (const target of targets) {
162
- applyStrategy(result, target, budget, tokenizer, iteration);
159
+ if (applied.element) {
160
+ nextChildren.push(applied.element);
163
161
  }
164
- // Check progress
165
- const tokensAfter = result.reduce((sum, f) => sum + f.tokens, 0);
166
- if (tokensAfter >= tokensBefore) {
167
- throw new FitError(tokensAfter - budget, lowestImportancePriority, iteration);
162
+ else {
163
+ childrenChanged = true;
168
164
  }
169
165
  }
166
+ const nextElement = childrenChanged
167
+ ? { ...element, children: nextChildren }
168
+ : element;
169
+ if (nextElement.strategy && nextElement.priority === priority) {
170
+ const replacement = await nextElement.strategy({
171
+ ...baseCtx,
172
+ target: nextElement,
173
+ context: mergedContext,
174
+ });
175
+ await safeInvoke(hooks?.onStrategyApplied, {
176
+ target: nextElement,
177
+ result: replacement,
178
+ priority,
179
+ iteration,
180
+ });
181
+ return { element: replacement, applied: true };
182
+ }
183
+ return { element: nextElement, applied: childrenChanged };
170
184
  }
171
185
  //# sourceMappingURL=render.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"render.js","sourceRoot":"","sources":["../src/render.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"render.js","sourceRoot":"","sources":["../src/render.ts"],"names":[],"mappings":"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"}