@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.
- package/README.md +93 -106
- package/dist/ai-sdk/index.d.ts +43 -0
- package/dist/ai-sdk/index.d.ts.map +1 -0
- package/dist/ai-sdk/index.js +303 -0
- package/dist/ai-sdk/index.js.map +1 -0
- package/dist/ai-sdk/index.test.d.ts +2 -0
- package/dist/ai-sdk/index.test.d.ts.map +1 -0
- package/dist/ai-sdk/index.test.js +101 -0
- package/dist/ai-sdk/index.test.js.map +1 -0
- package/dist/anthropic/index.d.ts +74 -0
- package/dist/anthropic/index.d.ts.map +1 -0
- package/dist/anthropic/index.js +238 -0
- package/dist/anthropic/index.js.map +1 -0
- package/dist/anthropic/index.test.d.ts +2 -0
- package/dist/anthropic/index.test.d.ts.map +1 -0
- package/dist/anthropic/index.test.js +115 -0
- package/dist/anthropic/index.test.js.map +1 -0
- package/dist/components/additional.test.d.ts +2 -0
- package/dist/components/additional.test.d.ts.map +1 -0
- package/dist/components/additional.test.js +31 -0
- package/dist/components/additional.test.js.map +1 -0
- package/dist/components/index.d.ts +148 -0
- package/dist/components/index.d.ts.map +1 -0
- package/dist/components/index.js +184 -0
- package/dist/components/index.js.map +1 -0
- package/dist/components/summary.d.ts +91 -0
- package/dist/components/summary.d.ts.map +1 -0
- package/dist/components/summary.js +118 -0
- package/dist/components/summary.js.map +1 -0
- package/dist/components/summary.test.d.ts +2 -0
- package/dist/components/summary.test.d.ts.map +1 -0
- package/dist/components/summary.test.js +101 -0
- package/dist/components/summary.test.js.map +1 -0
- package/dist/components/vector-search.d.ts +70 -0
- package/dist/components/vector-search.d.ts.map +1 -0
- package/dist/components/vector-search.js +110 -0
- package/dist/components/vector-search.js.map +1 -0
- package/dist/components/vector-search.test.d.ts +2 -0
- package/dist/components/vector-search.test.d.ts.map +1 -0
- package/dist/components/vector-search.test.js +113 -0
- package/dist/components/vector-search.test.js.map +1 -0
- package/dist/index.d.ts +12 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -5
- package/dist/index.js.map +1 -1
- package/dist/instrumentation/otel.d.ts +19 -0
- package/dist/instrumentation/otel.d.ts.map +1 -0
- package/dist/instrumentation/otel.js +102 -0
- package/dist/instrumentation/otel.js.map +1 -0
- package/dist/instrumentation/otel.test.d.ts +2 -0
- package/dist/instrumentation/otel.test.d.ts.map +1 -0
- package/dist/instrumentation/otel.test.js +116 -0
- package/dist/instrumentation/otel.test.js.map +1 -0
- package/dist/jsx-dev-runtime.d.ts +2 -0
- package/dist/jsx-dev-runtime.d.ts.map +1 -0
- package/dist/jsx-dev-runtime.js +2 -0
- package/dist/jsx-dev-runtime.js.map +1 -0
- package/dist/jsx-runtime.d.ts +30 -8
- package/dist/jsx-runtime.d.ts.map +1 -1
- package/dist/jsx-runtime.js +13 -10
- package/dist/jsx-runtime.js.map +1 -1
- package/dist/memory/chroma/index.d.ts +59 -0
- package/dist/memory/chroma/index.d.ts.map +1 -0
- package/dist/memory/chroma/index.js +172 -0
- package/dist/memory/chroma/index.js.map +1 -0
- package/dist/memory/index.d.ts +4 -0
- package/dist/memory/index.d.ts.map +1 -0
- package/dist/memory/index.js +2 -0
- package/dist/memory/index.js.map +1 -0
- package/dist/memory/key-value.d.ts +71 -0
- package/dist/memory/key-value.d.ts.map +1 -0
- package/dist/memory/key-value.js +34 -0
- package/dist/memory/key-value.js.map +1 -0
- package/dist/memory/postgres.d.ts +71 -0
- package/dist/memory/postgres.d.ts.map +1 -0
- package/dist/memory/postgres.js +109 -0
- package/dist/memory/postgres.js.map +1 -0
- package/dist/memory/qdrant/index.d.ts +64 -0
- package/dist/memory/qdrant/index.d.ts.map +1 -0
- package/dist/memory/qdrant/index.js +136 -0
- package/dist/memory/qdrant/index.js.map +1 -0
- package/dist/memory/redis.d.ts +70 -0
- package/dist/memory/redis.d.ts.map +1 -0
- package/dist/memory/redis.js +100 -0
- package/dist/memory/redis.js.map +1 -0
- package/dist/memory/vector.d.ts +53 -0
- package/dist/memory/vector.d.ts.map +1 -0
- package/dist/memory/vector.js +2 -0
- package/dist/memory/vector.js.map +1 -0
- package/dist/openai/index.d.ts +46 -0
- package/dist/openai/index.d.ts.map +1 -0
- package/dist/openai/index.js +260 -0
- package/dist/openai/index.js.map +1 -0
- package/dist/openai/index.test.d.ts +2 -0
- package/dist/openai/index.test.d.ts.map +1 -0
- package/dist/openai/index.test.js +204 -0
- package/dist/openai/index.test.js.map +1 -0
- package/dist/providers/index.d.ts +2 -0
- package/dist/providers/index.d.ts.map +1 -0
- package/dist/providers/index.js +2 -0
- package/dist/providers/index.js.map +1 -0
- package/dist/providers/types.d.ts +2 -0
- package/dist/providers/types.d.ts.map +1 -0
- package/dist/providers/types.js +2 -0
- package/dist/providers/types.js.map +1 -0
- package/dist/render.d.ts +44 -40
- package/dist/render.d.ts.map +1 -1
- package/dist/render.js +162 -148
- package/dist/render.js.map +1 -1
- package/dist/render.test.js +146 -28
- package/dist/render.test.js.map +1 -1
- package/dist/renderers/markdown.d.ts +3 -0
- package/dist/renderers/markdown.d.ts.map +1 -0
- package/dist/renderers/markdown.js +43 -0
- package/dist/renderers/markdown.js.map +1 -0
- package/dist/renderers/shared.d.ts +82 -0
- package/dist/renderers/shared.d.ts.map +1 -0
- package/dist/renderers/shared.js +156 -0
- package/dist/renderers/shared.js.map +1 -0
- package/dist/snapshot.d.ts +47 -0
- package/dist/snapshot.d.ts.map +1 -0
- package/dist/snapshot.js +140 -0
- package/dist/snapshot.js.map +1 -0
- package/dist/snapshot.test.d.ts +2 -0
- package/dist/snapshot.test.d.ts.map +1 -0
- package/dist/snapshot.test.js +68 -0
- package/dist/snapshot.test.js.map +1 -0
- package/dist/tokenizers.d.ts +14 -0
- package/dist/tokenizers.d.ts.map +1 -0
- package/dist/tokenizers.js +45 -0
- package/dist/tokenizers.js.map +1 -0
- package/dist/types.d.ts +212 -84
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +109 -0
- package/dist/types.js.map +1 -1
- package/package.json +88 -3
- package/dist/components.d.ts +0 -78
- package/dist/components.d.ts.map +0 -1
- package/dist/components.js +0 -98
- package/dist/components.js.map +0 -1
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import type { Child } from "../jsx-runtime";
|
|
2
|
+
import type { PromptElement, PromptRole, Strategy } from "../types";
|
|
3
|
+
interface RegionProps {
|
|
4
|
+
/** Lower number = higher importance. Default: 0 (highest priority) */
|
|
5
|
+
priority?: number;
|
|
6
|
+
/** Optional strategy to apply when this region needs to shrink */
|
|
7
|
+
strategy?: Strategy;
|
|
8
|
+
/** Stable identifier for caching/debugging */
|
|
9
|
+
id?: string;
|
|
10
|
+
/** Content of this region */
|
|
11
|
+
children?: Child;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* The fundamental building block of Cria prompts—think of it as `<div>`.
|
|
15
|
+
*
|
|
16
|
+
* Regions define sections of your prompt with a priority level. During fitting,
|
|
17
|
+
* regions with higher priority numbers (less important) are reduced first.
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```tsx
|
|
21
|
+
* <Region priority={0}>You are a helpful assistant.</Region>
|
|
22
|
+
* <Region priority={2}>{documents}</Region>
|
|
23
|
+
* <Region priority={1}>{userMessage}</Region>
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
export declare function Region({ priority, strategy, id, children, }: RegionProps): PromptElement;
|
|
27
|
+
interface SemanticRegionProps {
|
|
28
|
+
/** Lower number = higher importance. Default: 0 (highest priority) */
|
|
29
|
+
priority?: number;
|
|
30
|
+
/** Optional strategy to apply when this region needs to shrink */
|
|
31
|
+
strategy?: Strategy;
|
|
32
|
+
/** Stable identifier for caching/debugging */
|
|
33
|
+
id?: string;
|
|
34
|
+
}
|
|
35
|
+
interface MessageProps extends SemanticRegionProps {
|
|
36
|
+
/** The message role (user, assistant, system, etc.) */
|
|
37
|
+
messageRole: PromptRole;
|
|
38
|
+
children?: Child;
|
|
39
|
+
}
|
|
40
|
+
export declare function Message({ messageRole, priority, strategy, id, children, }: MessageProps): PromptElement;
|
|
41
|
+
interface ReasoningProps extends SemanticRegionProps {
|
|
42
|
+
text: string;
|
|
43
|
+
}
|
|
44
|
+
export declare function Reasoning({ text, priority, strategy, id, }: ReasoningProps): PromptElement;
|
|
45
|
+
interface ToolCallProps extends SemanticRegionProps {
|
|
46
|
+
toolCallId: string;
|
|
47
|
+
toolName: string;
|
|
48
|
+
input: unknown;
|
|
49
|
+
}
|
|
50
|
+
export declare function ToolCall({ toolCallId, toolName, input, priority, strategy, id, }: ToolCallProps): PromptElement;
|
|
51
|
+
interface ToolResultProps extends SemanticRegionProps {
|
|
52
|
+
toolCallId: string;
|
|
53
|
+
toolName: string;
|
|
54
|
+
output: unknown;
|
|
55
|
+
}
|
|
56
|
+
export declare function ToolResult({ toolCallId, toolName, output, priority, strategy, id, }: ToolResultProps): PromptElement;
|
|
57
|
+
interface TruncateProps {
|
|
58
|
+
/** Maximum token count for this region's content */
|
|
59
|
+
budget: number;
|
|
60
|
+
/** Which end to truncate from. Default: "start" */
|
|
61
|
+
from?: "start" | "end";
|
|
62
|
+
/** Lower number = higher importance. Default: 0 */
|
|
63
|
+
priority?: number;
|
|
64
|
+
/** Stable identifier for caching/debugging */
|
|
65
|
+
id?: string;
|
|
66
|
+
/** Content to truncate */
|
|
67
|
+
children?: Child;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* A region that truncates its content to fit within a token budget.
|
|
71
|
+
*
|
|
72
|
+
* When the overall prompt exceeds budget, Truncate regions progressively
|
|
73
|
+
* remove content from the specified direction until they meet their budget.
|
|
74
|
+
*
|
|
75
|
+
* @example
|
|
76
|
+
* ```tsx
|
|
77
|
+
* <Truncate budget={20000} priority={2}>
|
|
78
|
+
* {conversationHistory}
|
|
79
|
+
* </Truncate>
|
|
80
|
+
* ```
|
|
81
|
+
*/
|
|
82
|
+
export declare function Truncate({ budget, from, priority, id, children, }: TruncateProps): PromptElement;
|
|
83
|
+
interface OmitProps {
|
|
84
|
+
/** Lower number = higher importance. Default: 0 */
|
|
85
|
+
priority?: number;
|
|
86
|
+
/** Stable identifier for caching/debugging */
|
|
87
|
+
id?: string;
|
|
88
|
+
/** Content that may be omitted */
|
|
89
|
+
children?: Child;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* A region that is entirely removed when the prompt needs to shrink.
|
|
93
|
+
*
|
|
94
|
+
* Use Omit for "nice to have" content that can be dropped entirely if needed.
|
|
95
|
+
* When the prompt exceeds budget, Omit regions are removed (lowest priority first).
|
|
96
|
+
*
|
|
97
|
+
* @example
|
|
98
|
+
* ```tsx
|
|
99
|
+
* <Omit priority={3}>
|
|
100
|
+
* {optionalExamples}
|
|
101
|
+
* </Omit>
|
|
102
|
+
* ```
|
|
103
|
+
*/
|
|
104
|
+
export declare function Omit({ priority, id, children, }: OmitProps): PromptElement;
|
|
105
|
+
interface LastProps {
|
|
106
|
+
/** Number of children to keep */
|
|
107
|
+
N: number;
|
|
108
|
+
/** Priority for this region. Default: 0 */
|
|
109
|
+
priority?: number;
|
|
110
|
+
/** Children to filter */
|
|
111
|
+
children?: Child;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Keeps only the last N children.
|
|
115
|
+
*
|
|
116
|
+
* @example
|
|
117
|
+
* ```tsx
|
|
118
|
+
* <Last N={50}>{messages}</Last>
|
|
119
|
+
* ```
|
|
120
|
+
*/
|
|
121
|
+
export declare function Last({ N, priority, children, }: LastProps): PromptElement;
|
|
122
|
+
export type { StoredSummary, Summarizer, SummarizerContext } from "./summary";
|
|
123
|
+
export { Summary } from "./summary";
|
|
124
|
+
export type { ResultFormatter } from "./vector-search";
|
|
125
|
+
export { VectorSearch } from "./vector-search";
|
|
126
|
+
interface SeparatorProps {
|
|
127
|
+
value?: string;
|
|
128
|
+
priority?: number;
|
|
129
|
+
id?: string;
|
|
130
|
+
children?: Child;
|
|
131
|
+
}
|
|
132
|
+
export declare function Separator({ value, priority, id, children, }: SeparatorProps): PromptElement;
|
|
133
|
+
interface ExamplesProps {
|
|
134
|
+
title?: string;
|
|
135
|
+
separator?: string;
|
|
136
|
+
priority?: number;
|
|
137
|
+
id?: string;
|
|
138
|
+
children?: Child;
|
|
139
|
+
}
|
|
140
|
+
export declare function Examples({ title, separator, priority, id, children, }: ExamplesProps): PromptElement;
|
|
141
|
+
interface CodeBlockProps {
|
|
142
|
+
code: string;
|
|
143
|
+
language?: string;
|
|
144
|
+
priority?: number;
|
|
145
|
+
id?: string;
|
|
146
|
+
}
|
|
147
|
+
export declare function CodeBlock({ code, language, priority, id, }: CodeBlockProps): PromptElement;
|
|
148
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The fundamental building block of Cria prompts—think of it as `<div>`.
|
|
3
|
+
*
|
|
4
|
+
* Regions define sections of your prompt with a priority level. During fitting,
|
|
5
|
+
* regions with higher priority numbers (less important) are reduced first.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```tsx
|
|
9
|
+
* <Region priority={0}>You are a helpful assistant.</Region>
|
|
10
|
+
* <Region priority={2}>{documents}</Region>
|
|
11
|
+
* <Region priority={1}>{userMessage}</Region>
|
|
12
|
+
* ```
|
|
13
|
+
*/
|
|
14
|
+
export function Region({ priority = 0, strategy, id, children = [], }) {
|
|
15
|
+
return {
|
|
16
|
+
priority,
|
|
17
|
+
children: children,
|
|
18
|
+
...(strategy && { strategy }),
|
|
19
|
+
...(id && { id }),
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
export function Message({ messageRole, priority = 0, strategy, id, children = [], }) {
|
|
23
|
+
return {
|
|
24
|
+
kind: "message",
|
|
25
|
+
role: messageRole,
|
|
26
|
+
priority,
|
|
27
|
+
children: children,
|
|
28
|
+
...(strategy && { strategy }),
|
|
29
|
+
...(id && { id }),
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
export function Reasoning({ text, priority = 0, strategy, id, }) {
|
|
33
|
+
return {
|
|
34
|
+
kind: "reasoning",
|
|
35
|
+
text,
|
|
36
|
+
priority,
|
|
37
|
+
children: [],
|
|
38
|
+
...(strategy && { strategy }),
|
|
39
|
+
...(id && { id }),
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
export function ToolCall({ toolCallId, toolName, input, priority = 0, strategy, id, }) {
|
|
43
|
+
return {
|
|
44
|
+
kind: "tool-call",
|
|
45
|
+
toolCallId,
|
|
46
|
+
toolName,
|
|
47
|
+
input,
|
|
48
|
+
priority,
|
|
49
|
+
children: [],
|
|
50
|
+
...(strategy && { strategy }),
|
|
51
|
+
...(id && { id }),
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
export function ToolResult({ toolCallId, toolName, output, priority = 0, strategy, id, }) {
|
|
55
|
+
return {
|
|
56
|
+
kind: "tool-result",
|
|
57
|
+
toolCallId,
|
|
58
|
+
toolName,
|
|
59
|
+
output,
|
|
60
|
+
priority,
|
|
61
|
+
children: [],
|
|
62
|
+
...(strategy && { strategy }),
|
|
63
|
+
...(id && { id }),
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* A region that truncates its content to fit within a token budget.
|
|
68
|
+
*
|
|
69
|
+
* When the overall prompt exceeds budget, Truncate regions progressively
|
|
70
|
+
* remove content from the specified direction until they meet their budget.
|
|
71
|
+
*
|
|
72
|
+
* @example
|
|
73
|
+
* ```tsx
|
|
74
|
+
* <Truncate budget={20000} priority={2}>
|
|
75
|
+
* {conversationHistory}
|
|
76
|
+
* </Truncate>
|
|
77
|
+
* ```
|
|
78
|
+
*/
|
|
79
|
+
export function Truncate({ budget, from = "start", priority = 0, id, children = [], }) {
|
|
80
|
+
const strategy = (input) => {
|
|
81
|
+
const content = input.tokenString(input.target);
|
|
82
|
+
let tokens = input.tokenizer(content);
|
|
83
|
+
if (tokens <= budget) {
|
|
84
|
+
return input.target;
|
|
85
|
+
}
|
|
86
|
+
let truncated = content;
|
|
87
|
+
while (tokens > budget && truncated.length > 0) {
|
|
88
|
+
const charsToRemove = Math.max(1, Math.floor(truncated.length * 0.1));
|
|
89
|
+
truncated =
|
|
90
|
+
from === "start"
|
|
91
|
+
? truncated.slice(charsToRemove)
|
|
92
|
+
: truncated.slice(0, -charsToRemove);
|
|
93
|
+
tokens = input.tokenizer(truncated);
|
|
94
|
+
}
|
|
95
|
+
if (truncated.length === 0) {
|
|
96
|
+
return null;
|
|
97
|
+
}
|
|
98
|
+
return { ...input.target, children: [truncated] };
|
|
99
|
+
};
|
|
100
|
+
return {
|
|
101
|
+
priority,
|
|
102
|
+
children: children,
|
|
103
|
+
strategy,
|
|
104
|
+
...(id && { id }),
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* A region that is entirely removed when the prompt needs to shrink.
|
|
109
|
+
*
|
|
110
|
+
* Use Omit for "nice to have" content that can be dropped entirely if needed.
|
|
111
|
+
* When the prompt exceeds budget, Omit regions are removed (lowest priority first).
|
|
112
|
+
*
|
|
113
|
+
* @example
|
|
114
|
+
* ```tsx
|
|
115
|
+
* <Omit priority={3}>
|
|
116
|
+
* {optionalExamples}
|
|
117
|
+
* </Omit>
|
|
118
|
+
* ```
|
|
119
|
+
*/
|
|
120
|
+
export function Omit({ priority = 0, id, children = [], }) {
|
|
121
|
+
const strategy = () => null;
|
|
122
|
+
return {
|
|
123
|
+
priority,
|
|
124
|
+
children: children,
|
|
125
|
+
strategy,
|
|
126
|
+
...(id && { id }),
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Keeps only the last N children.
|
|
131
|
+
*
|
|
132
|
+
* @example
|
|
133
|
+
* ```tsx
|
|
134
|
+
* <Last N={50}>{messages}</Last>
|
|
135
|
+
* ```
|
|
136
|
+
*/
|
|
137
|
+
export function Last({ N, priority = 0, children = [], }) {
|
|
138
|
+
const normalizedChildren = children;
|
|
139
|
+
const lastN = normalizedChildren.slice(-N);
|
|
140
|
+
return {
|
|
141
|
+
priority,
|
|
142
|
+
children: lastN,
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
export { Summary } from "./summary";
|
|
146
|
+
export { VectorSearch } from "./vector-search";
|
|
147
|
+
/**
|
|
148
|
+
* Intersperse a separator between elements of an array.
|
|
149
|
+
*/
|
|
150
|
+
function intersperse(items, separator) {
|
|
151
|
+
if (items.length === 0) {
|
|
152
|
+
return [];
|
|
153
|
+
}
|
|
154
|
+
return items.flatMap((item, i) => (i === 0 ? [item] : [separator, item]));
|
|
155
|
+
}
|
|
156
|
+
export function Separator({ value = "\n", priority = 0, id, children = [], }) {
|
|
157
|
+
const normalized = children;
|
|
158
|
+
return {
|
|
159
|
+
priority,
|
|
160
|
+
children: intersperse(normalized, value),
|
|
161
|
+
...(id && { id }),
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
export function Examples({ title = "Examples:", separator = "\n\n", priority = 2, id, children = [], }) {
|
|
165
|
+
const normalized = children;
|
|
166
|
+
const withSeparators = intersperse(normalized, separator);
|
|
167
|
+
const prefixed = title
|
|
168
|
+
? [`${title}\n`, ...withSeparators]
|
|
169
|
+
: withSeparators;
|
|
170
|
+
return {
|
|
171
|
+
priority,
|
|
172
|
+
children: prefixed,
|
|
173
|
+
...(id && { id }),
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
export function CodeBlock({ code, language, priority = 0, id, }) {
|
|
177
|
+
const fenced = `\`\`\`${language ?? ""}\n${code}\n\`\`\`\n`;
|
|
178
|
+
return {
|
|
179
|
+
priority,
|
|
180
|
+
children: [fenced],
|
|
181
|
+
...(id && { id }),
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import type { Child } from "../jsx-runtime";
|
|
2
|
+
import type { KVMemory } from "../memory";
|
|
3
|
+
import type { MaybePromise, PromptElement } from "../types";
|
|
4
|
+
/**
|
|
5
|
+
* Stored summary data persisted across renders.
|
|
6
|
+
*/
|
|
7
|
+
export interface StoredSummary {
|
|
8
|
+
/** The summary text content */
|
|
9
|
+
content: string;
|
|
10
|
+
/** Token count of the summary */
|
|
11
|
+
tokenCount: number;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Context passed to the summarizer function.
|
|
15
|
+
*/
|
|
16
|
+
export interface SummarizerContext {
|
|
17
|
+
/** The content to summarize (as rendered string) */
|
|
18
|
+
content: string;
|
|
19
|
+
/** Previous summary to build upon (null if first summary) */
|
|
20
|
+
existingSummary: string | null;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Function that generates summaries.
|
|
24
|
+
*/
|
|
25
|
+
export type Summarizer = (ctx: SummarizerContext) => MaybePromise<string>;
|
|
26
|
+
interface SummaryProps {
|
|
27
|
+
/** Unique identifier for this summary in the store */
|
|
28
|
+
id: string;
|
|
29
|
+
/** Storage adapter for persisting summaries */
|
|
30
|
+
store: KVMemory<StoredSummary>;
|
|
31
|
+
/**
|
|
32
|
+
* Function that generates summaries.
|
|
33
|
+
* If omitted, uses the ModelProvider from render options with a default prompt.
|
|
34
|
+
*/
|
|
35
|
+
summarize?: Summarizer;
|
|
36
|
+
/** Priority for this region (higher number = reduced first). Default: 0 */
|
|
37
|
+
priority?: number;
|
|
38
|
+
/** Content to potentially summarize */
|
|
39
|
+
children?: Child;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* A region that summarizes its content when the prompt needs to shrink.
|
|
43
|
+
*
|
|
44
|
+
* When the overall prompt exceeds budget and this region is selected for
|
|
45
|
+
* reduction (based on priority), the summarizer is called and the result
|
|
46
|
+
* replaces the original content.
|
|
47
|
+
*
|
|
48
|
+
* If no `summarize` function is provided, the component will use the
|
|
49
|
+
* `ModelProvider` from an ancestor provider component with a default
|
|
50
|
+
* summarization prompt.
|
|
51
|
+
*
|
|
52
|
+
* @example Using a custom summarizer
|
|
53
|
+
* ```tsx
|
|
54
|
+
* import { InMemoryStore, Summary, type StoredSummary } from "@fastpaca/cria";
|
|
55
|
+
*
|
|
56
|
+
* const store = new InMemoryStore<StoredSummary>();
|
|
57
|
+
*
|
|
58
|
+
* <Summary
|
|
59
|
+
* id="conv-history"
|
|
60
|
+
* store={store}
|
|
61
|
+
* summarize={async ({ content, existingSummary }) => {
|
|
62
|
+
* return callAI(`Summarize, building on: ${existingSummary}\n\n${content}`);
|
|
63
|
+
* }}
|
|
64
|
+
* priority={2}
|
|
65
|
+
* >
|
|
66
|
+
* {conversationHistory}
|
|
67
|
+
* </Summary>
|
|
68
|
+
* ```
|
|
69
|
+
*
|
|
70
|
+
* @example Using a provider component
|
|
71
|
+
* ```tsx
|
|
72
|
+
* import { InMemoryStore, Summary, type StoredSummary, render } from "@fastpaca/cria";
|
|
73
|
+
* import { AISDKProvider } from "@fastpaca/cria/ai-sdk";
|
|
74
|
+
* import { openai } from "@ai-sdk/openai";
|
|
75
|
+
*
|
|
76
|
+
* const store = new InMemoryStore<StoredSummary>();
|
|
77
|
+
*
|
|
78
|
+
* const prompt = (
|
|
79
|
+
* <AISDKProvider model={openai("gpt-4o")}>
|
|
80
|
+
* <Summary id="conv-history" store={store} priority={2}>
|
|
81
|
+
* {conversationHistory}
|
|
82
|
+
* </Summary>
|
|
83
|
+
* </AISDKProvider>
|
|
84
|
+
* );
|
|
85
|
+
*
|
|
86
|
+
* const result = await render(prompt, { tokenizer, budget: 4000 });
|
|
87
|
+
* ```
|
|
88
|
+
*/
|
|
89
|
+
export declare function Summary({ id, store, summarize, priority, children, }: SummaryProps): PromptElement;
|
|
90
|
+
export {};
|
|
91
|
+
//# sourceMappingURL=summary.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"summary.d.ts","sourceRoot":"","sources":["../../src/components/summary.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAC5C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,KAAK,EACV,YAAY,EAGZ,aAAa,EAGd,MAAM,UAAU,CAAC;AAElB;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,+BAA+B;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,iCAAiC;IACjC,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,oDAAoD;IACpD,OAAO,EAAE,MAAM,CAAC;IAChB,6DAA6D;IAC7D,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;CAChC;AAED;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG,CAAC,GAAG,EAAE,iBAAiB,KAAK,YAAY,CAAC,MAAM,CAAC,CAAC;AAwF1E,UAAU,YAAY;IACpB,sDAAsD;IACtD,EAAE,EAAE,MAAM,CAAC;IACX,+CAA+C;IAC/C,KAAK,EAAE,QAAQ,CAAC,aAAa,CAAC,CAAC;IAC/B;;;OAGG;IACH,SAAS,CAAC,EAAE,UAAU,CAAC;IACvB,2EAA2E;IAC3E,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,uCAAuC;IACvC,QAAQ,CAAC,EAAE,KAAK,CAAC;CAClB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+CG;AACH,wBAAgB,OAAO,CAAC,EACtB,EAAE,EACF,KAAK,EACL,SAAS,EACT,QAAY,EACZ,QAAa,GACd,EAAE,YAAY,GAAG,aAAa,CAM9B"}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Default summarizer that uses a ModelProvider.
|
|
3
|
+
* This is used when no custom summarize function is provided.
|
|
4
|
+
*/
|
|
5
|
+
async function defaultSummarizer(ctx, provider) {
|
|
6
|
+
const systemPrompt = "You are a conversation summarizer. Create a concise summary that captures the key points and context needed to continue the conversation. Be brief but preserve essential information.";
|
|
7
|
+
let userPrompt;
|
|
8
|
+
if (ctx.existingSummary) {
|
|
9
|
+
userPrompt = `Here is the existing summary of the conversation so far:
|
|
10
|
+
|
|
11
|
+
${ctx.existingSummary}
|
|
12
|
+
|
|
13
|
+
Here is new conversation content to incorporate into the summary:
|
|
14
|
+
|
|
15
|
+
${ctx.content}
|
|
16
|
+
|
|
17
|
+
Please provide an updated summary that incorporates both the existing summary and the new content.`;
|
|
18
|
+
}
|
|
19
|
+
else {
|
|
20
|
+
userPrompt = `Please summarize the following conversation:
|
|
21
|
+
|
|
22
|
+
${ctx.content}`;
|
|
23
|
+
}
|
|
24
|
+
const result = await provider.completion({
|
|
25
|
+
system: systemPrompt,
|
|
26
|
+
messages: [{ role: "user", content: userPrompt }],
|
|
27
|
+
});
|
|
28
|
+
return result.text;
|
|
29
|
+
}
|
|
30
|
+
function createSummaryStrategy({ id, store, summarize, }) {
|
|
31
|
+
return async (input) => {
|
|
32
|
+
const { target, tokenizer, tokenString, context } = input;
|
|
33
|
+
const content = tokenString(target);
|
|
34
|
+
const existingEntry = await store.get(id);
|
|
35
|
+
const summarizerContext = {
|
|
36
|
+
content,
|
|
37
|
+
existingSummary: existingEntry?.data.content ?? null,
|
|
38
|
+
};
|
|
39
|
+
let newSummary;
|
|
40
|
+
if (summarize) {
|
|
41
|
+
newSummary = await summarize(summarizerContext);
|
|
42
|
+
}
|
|
43
|
+
else if (context.provider) {
|
|
44
|
+
newSummary = await defaultSummarizer(summarizerContext, context.provider);
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
throw new Error(`Summary "${id}" requires either a 'summarize' function or a provider component ancestor (e.g. <AISDKProvider>)`);
|
|
48
|
+
}
|
|
49
|
+
const newTokenCount = tokenizer(newSummary);
|
|
50
|
+
await store.set(id, {
|
|
51
|
+
content: newSummary,
|
|
52
|
+
tokenCount: newTokenCount,
|
|
53
|
+
});
|
|
54
|
+
// Return as an assistant message so it renders properly
|
|
55
|
+
return {
|
|
56
|
+
kind: "message",
|
|
57
|
+
role: "assistant",
|
|
58
|
+
priority: target.priority,
|
|
59
|
+
children: [`[Summary of earlier conversation]\n${newSummary}`],
|
|
60
|
+
};
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* A region that summarizes its content when the prompt needs to shrink.
|
|
65
|
+
*
|
|
66
|
+
* When the overall prompt exceeds budget and this region is selected for
|
|
67
|
+
* reduction (based on priority), the summarizer is called and the result
|
|
68
|
+
* replaces the original content.
|
|
69
|
+
*
|
|
70
|
+
* If no `summarize` function is provided, the component will use the
|
|
71
|
+
* `ModelProvider` from an ancestor provider component with a default
|
|
72
|
+
* summarization prompt.
|
|
73
|
+
*
|
|
74
|
+
* @example Using a custom summarizer
|
|
75
|
+
* ```tsx
|
|
76
|
+
* import { InMemoryStore, Summary, type StoredSummary } from "@fastpaca/cria";
|
|
77
|
+
*
|
|
78
|
+
* const store = new InMemoryStore<StoredSummary>();
|
|
79
|
+
*
|
|
80
|
+
* <Summary
|
|
81
|
+
* id="conv-history"
|
|
82
|
+
* store={store}
|
|
83
|
+
* summarize={async ({ content, existingSummary }) => {
|
|
84
|
+
* return callAI(`Summarize, building on: ${existingSummary}\n\n${content}`);
|
|
85
|
+
* }}
|
|
86
|
+
* priority={2}
|
|
87
|
+
* >
|
|
88
|
+
* {conversationHistory}
|
|
89
|
+
* </Summary>
|
|
90
|
+
* ```
|
|
91
|
+
*
|
|
92
|
+
* @example Using a provider component
|
|
93
|
+
* ```tsx
|
|
94
|
+
* import { InMemoryStore, Summary, type StoredSummary, render } from "@fastpaca/cria";
|
|
95
|
+
* import { AISDKProvider } from "@fastpaca/cria/ai-sdk";
|
|
96
|
+
* import { openai } from "@ai-sdk/openai";
|
|
97
|
+
*
|
|
98
|
+
* const store = new InMemoryStore<StoredSummary>();
|
|
99
|
+
*
|
|
100
|
+
* const prompt = (
|
|
101
|
+
* <AISDKProvider model={openai("gpt-4o")}>
|
|
102
|
+
* <Summary id="conv-history" store={store} priority={2}>
|
|
103
|
+
* {conversationHistory}
|
|
104
|
+
* </Summary>
|
|
105
|
+
* </AISDKProvider>
|
|
106
|
+
* );
|
|
107
|
+
*
|
|
108
|
+
* const result = await render(prompt, { tokenizer, budget: 4000 });
|
|
109
|
+
* ```
|
|
110
|
+
*/
|
|
111
|
+
export function Summary({ id, store, summarize, priority = 0, children = [], }) {
|
|
112
|
+
return {
|
|
113
|
+
priority,
|
|
114
|
+
strategy: createSummaryStrategy({ id, store, summarize }),
|
|
115
|
+
children: children,
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
//# sourceMappingURL=summary.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"summary.js","sourceRoot":"","sources":["../../src/components/summary.ts"],"names":[],"mappings":"AAoCA;;;GAGG;AACH,KAAK,UAAU,iBAAiB,CAC9B,GAAsB,EACtB,QAAuB;IAEvB,MAAM,YAAY,GAChB,wLAAwL,CAAC;IAE3L,IAAI,UAAkB,CAAC;IACvB,IAAI,GAAG,CAAC,eAAe,EAAE,CAAC;QACxB,UAAU,GAAG;;EAEf,GAAG,CAAC,eAAe;;;;EAInB,GAAG,CAAC,OAAO;;mGAEsF,CAAC;IAClG,CAAC;SAAM,CAAC;QACN,UAAU,GAAG;;EAEf,GAAG,CAAC,OAAO,EAAE,CAAC;IACd,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,UAAU,CAAC;QACvC,MAAM,EAAE,YAAY;QACpB,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC;KAClD,CAAC,CAAC;IAEH,OAAO,MAAM,CAAC,IAAI,CAAC;AACrB,CAAC;AAQD,SAAS,qBAAqB,CAAC,EAC7B,EAAE,EACF,KAAK,EACL,SAAS,GACc;IACvB,OAAO,KAAK,EAAE,KAAoB,EAAE,EAAE;QACpC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,WAAW,EAAE,OAAO,EAAE,GAAG,KAAK,CAAC;QAE1D,MAAM,OAAO,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC;QACpC,MAAM,aAAa,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAE1C,MAAM,iBAAiB,GAAsB;YAC3C,OAAO;YACP,eAAe,EAAE,aAAa,EAAE,IAAI,CAAC,OAAO,IAAI,IAAI;SACrD,CAAC;QAEF,IAAI,UAAkB,CAAC;QACvB,IAAI,SAAS,EAAE,CAAC;YACd,UAAU,GAAG,MAAM,SAAS,CAAC,iBAAiB,CAAC,CAAC;QAClD,CAAC;aAAM,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;YAC5B,UAAU,GAAG,MAAM,iBAAiB,CAAC,iBAAiB,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;QAC5E,CAAC;aAAM,CAAC;YACN,MAAM,IAAI,KAAK,CACb,YAAY,EAAE,kGAAkG,CACjH,CAAC;QACJ,CAAC;QAED,MAAM,aAAa,GAAG,SAAS,CAAC,UAAU,CAAC,CAAC;QAE5C,MAAM,KAAK,CAAC,GAAG,CAAC,EAAE,EAAE;YAClB,OAAO,EAAE,UAAU;YACnB,UAAU,EAAE,aAAa;SAC1B,CAAC,CAAC;QAEH,wDAAwD;QACxD,OAAO;YACL,IAAI,EAAE,SAAS;YACf,IAAI,EAAE,WAAW;YACjB,QAAQ,EAAE,MAAM,CAAC,QAAQ;YACzB,QAAQ,EAAE,CAAC,sCAAsC,UAAU,EAAE,CAAC;SAC/D,CAAC;IACJ,CAAC,CAAC;AACJ,CAAC;AAkBD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+CG;AACH,MAAM,UAAU,OAAO,CAAC,EACtB,EAAE,EACF,KAAK,EACL,SAAS,EACT,QAAQ,GAAG,CAAC,EACZ,QAAQ,GAAG,EAAE,GACA;IACb,OAAO;QACL,QAAQ;QACR,QAAQ,EAAE,qBAAqB,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC;QACzD,QAAQ,EAAE,QAA0B;KACrC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"summary.test.d.ts","sourceRoot":"","sources":["../../src/components/summary.test.tsx"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "@fastpaca/cria/jsx-runtime";
|
|
2
|
+
import { expect, test } from "vitest";
|
|
3
|
+
import { InMemoryStore, Last, Region, render, Summary, } from "../index";
|
|
4
|
+
// Simple tokenizer: 1 token per 4 characters
|
|
5
|
+
const tokenizer = (text) => Math.ceil(text.length / 4);
|
|
6
|
+
test("Summary: triggers summarization when over budget", async () => {
|
|
7
|
+
const store = new InMemoryStore();
|
|
8
|
+
let summarizeCalled = false;
|
|
9
|
+
const summarize = ({ content }) => {
|
|
10
|
+
summarizeCalled = true;
|
|
11
|
+
return `Summary of: ${content.slice(0, 20)}...`;
|
|
12
|
+
};
|
|
13
|
+
const longContent = "A".repeat(200);
|
|
14
|
+
const element = (_jsx(Region, { priority: 0, children: _jsx(Summary, { id: "test-1", priority: 1, store: store, summarize: summarize, children: longContent }) }));
|
|
15
|
+
// Render with small budget to trigger summarization
|
|
16
|
+
// Budget needs to fit the summary output + "[Summary of earlier conversation]\n" prefix
|
|
17
|
+
const result = await render(element, { tokenizer, budget: 30 });
|
|
18
|
+
expect(summarizeCalled).toBe(true);
|
|
19
|
+
expect(result).toContain("Summary of:");
|
|
20
|
+
expect(result.length).toBeLessThan(longContent.length);
|
|
21
|
+
});
|
|
22
|
+
test("Summary: stores summary in store", async () => {
|
|
23
|
+
const store = new InMemoryStore();
|
|
24
|
+
const summarize = () => "This is the summary";
|
|
25
|
+
const element = (_jsx(Region, { priority: 0, children: _jsx(Summary, { id: "test-2", priority: 1, store: store, summarize: summarize, children: "Long content ".repeat(50) }) }));
|
|
26
|
+
await render(element, { tokenizer, budget: 20 });
|
|
27
|
+
const entry = store.get("test-2");
|
|
28
|
+
expect(entry).not.toBeNull();
|
|
29
|
+
expect(entry?.data.content).toBe("This is the summary");
|
|
30
|
+
expect(entry?.data.tokenCount).toBeGreaterThan(0);
|
|
31
|
+
expect(entry?.updatedAt).toBeGreaterThan(0);
|
|
32
|
+
});
|
|
33
|
+
test("Summary: passes existing summary to summarizer", async () => {
|
|
34
|
+
const store = new InMemoryStore();
|
|
35
|
+
// Pre-populate store
|
|
36
|
+
store.set("test-3", {
|
|
37
|
+
content: "Previous summary",
|
|
38
|
+
tokenCount: 10,
|
|
39
|
+
});
|
|
40
|
+
let receivedExisting = null;
|
|
41
|
+
const summarize = ({ existingSummary, }) => {
|
|
42
|
+
receivedExisting = existingSummary;
|
|
43
|
+
return "Updated summary";
|
|
44
|
+
};
|
|
45
|
+
const element = (_jsx(Region, { priority: 0, children: _jsx(Summary, { id: "test-3", priority: 1, store: store, summarize: summarize, children: "Content ".repeat(100) }) }));
|
|
46
|
+
await render(element, { tokenizer, budget: 20 });
|
|
47
|
+
expect(receivedExisting).toBe("Previous summary");
|
|
48
|
+
});
|
|
49
|
+
test("Summary: does not trigger when under budget", async () => {
|
|
50
|
+
const store = new InMemoryStore();
|
|
51
|
+
let summarizeCalled = false;
|
|
52
|
+
const summarize = () => {
|
|
53
|
+
summarizeCalled = true;
|
|
54
|
+
return "Summary";
|
|
55
|
+
};
|
|
56
|
+
const element = (_jsx(Region, { priority: 0, children: _jsx(Summary, { id: "test-4", priority: 1, store: store, summarize: summarize, children: "Short" }) }));
|
|
57
|
+
// Large budget - no need to summarize
|
|
58
|
+
await render(element, { tokenizer, budget: 1000 });
|
|
59
|
+
expect(summarizeCalled).toBe(false);
|
|
60
|
+
});
|
|
61
|
+
test("Last: keeps only last N children", async () => {
|
|
62
|
+
const messages = ["First", "Second", "Third", "Fourth", "Fifth"];
|
|
63
|
+
const element = (_jsx(Region, { priority: 0, children: _jsx(Last, { N: 2, children: messages }) }));
|
|
64
|
+
const result = await render(element, { tokenizer, budget: 1000 });
|
|
65
|
+
expect(result).not.toContain("First");
|
|
66
|
+
expect(result).not.toContain("Second");
|
|
67
|
+
expect(result).not.toContain("Third");
|
|
68
|
+
expect(result).toContain("Fourth");
|
|
69
|
+
expect(result).toContain("Fifth");
|
|
70
|
+
});
|
|
71
|
+
test("Last: handles N larger than children count", async () => {
|
|
72
|
+
const messages = ["One", "Two"];
|
|
73
|
+
const element = (_jsx(Region, { priority: 0, children: _jsx(Last, { N: 10, children: messages }) }));
|
|
74
|
+
const result = await render(element, { tokenizer, budget: 1000 });
|
|
75
|
+
expect(result).toContain("One");
|
|
76
|
+
expect(result).toContain("Two");
|
|
77
|
+
});
|
|
78
|
+
test("Summary + Last: typical usage pattern", async () => {
|
|
79
|
+
const store = new InMemoryStore();
|
|
80
|
+
// Summarizer produces a short fixed-length output
|
|
81
|
+
const summarize = () => "Discussed greetings";
|
|
82
|
+
// Use longer messages so the summary provides real compression
|
|
83
|
+
const messages = [
|
|
84
|
+
"Message 1: Hello there, how are you doing today?",
|
|
85
|
+
"Message 2: I am doing great, thanks for asking!",
|
|
86
|
+
"Message 3: That is wonderful to hear from you.",
|
|
87
|
+
"Message 4: Recent message here",
|
|
88
|
+
"Message 5: Final message",
|
|
89
|
+
];
|
|
90
|
+
const element = (_jsxs(Region, { priority: 0, children: [_jsx(Summary, { id: "conv", priority: 2, store: store, summarize: summarize, children: messages.slice(0, -2) }), _jsx(Last, { N: 2, children: messages })] }));
|
|
91
|
+
// Full content: ~180 chars = 45 tokens
|
|
92
|
+
// Summarized: prefix (34) + summary (19) + last 2 msgs (~50) = ~103 chars = 26 tokens
|
|
93
|
+
const result = await render(element, { tokenizer, budget: 30 });
|
|
94
|
+
// Should have summary of older messages (wrapped with prefix)
|
|
95
|
+
expect(result).toContain("[Summary of earlier conversation]");
|
|
96
|
+
expect(result).toContain("Discussed greetings");
|
|
97
|
+
// Should have recent messages in full
|
|
98
|
+
expect(result).toContain("Message 4: Recent message here");
|
|
99
|
+
expect(result).toContain("Message 5: Final message");
|
|
100
|
+
});
|
|
101
|
+
//# sourceMappingURL=summary.test.js.map
|