@diyor28/context 1.0.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.
- package/README.md +270 -0
- package/dist/__tests__/attachment-selector.test.d.ts +11 -0
- package/dist/__tests__/attachment-selector.test.d.ts.map +1 -0
- package/dist/__tests__/attachment-selector.test.js +449 -0
- package/dist/__tests__/attachment-selector.test.js.map +1 -0
- package/dist/__tests__/cache-breakpoints.test.d.ts +11 -0
- package/dist/__tests__/cache-breakpoints.test.d.ts.map +1 -0
- package/dist/__tests__/cache-breakpoints.test.js +398 -0
- package/dist/__tests__/cache-breakpoints.test.js.map +1 -0
- package/dist/__tests__/codecs.test.d.ts +7 -0
- package/dist/__tests__/codecs.test.d.ts.map +1 -0
- package/dist/__tests__/codecs.test.js +331 -0
- package/dist/__tests__/codecs.test.js.map +1 -0
- package/dist/__tests__/compactor.test.d.ts +11 -0
- package/dist/__tests__/compactor.test.d.ts.map +1 -0
- package/dist/__tests__/compactor.test.js +519 -0
- package/dist/__tests__/compactor.test.js.map +1 -0
- package/dist/__tests__/context-graph.test.d.ts +7 -0
- package/dist/__tests__/context-graph.test.d.ts.map +1 -0
- package/dist/__tests__/context-graph.test.js +262 -0
- package/dist/__tests__/context-graph.test.js.map +1 -0
- package/dist/__tests__/hash.test.d.ts +7 -0
- package/dist/__tests__/hash.test.d.ts.map +1 -0
- package/dist/__tests__/hash.test.js +228 -0
- package/dist/__tests__/hash.test.js.map +1 -0
- package/dist/__tests__/integration.test.d.ts +15 -0
- package/dist/__tests__/integration.test.d.ts.map +1 -0
- package/dist/__tests__/integration.test.js +728 -0
- package/dist/__tests__/integration.test.js.map +1 -0
- package/dist/__tests__/kind-order.test.d.ts +7 -0
- package/dist/__tests__/kind-order.test.d.ts.map +1 -0
- package/dist/__tests__/kind-order.test.js +243 -0
- package/dist/__tests__/kind-order.test.js.map +1 -0
- package/dist/__tests__/phase2-integration.test.d.ts +5 -0
- package/dist/__tests__/phase2-integration.test.d.ts.map +1 -0
- package/dist/__tests__/phase2-integration.test.js +222 -0
- package/dist/__tests__/phase2-integration.test.js.map +1 -0
- package/dist/__tests__/queries.test.d.ts +7 -0
- package/dist/__tests__/queries.test.d.ts.map +1 -0
- package/dist/__tests__/queries.test.js +254 -0
- package/dist/__tests__/queries.test.js.map +1 -0
- package/dist/__tests__/token-estimator.test.d.ts +7 -0
- package/dist/__tests__/token-estimator.test.d.ts.map +1 -0
- package/dist/__tests__/token-estimator.test.js +267 -0
- package/dist/__tests__/token-estimator.test.js.map +1 -0
- package/dist/adapters/anthropic-estimator.d.ts +38 -0
- package/dist/adapters/anthropic-estimator.d.ts.map +1 -0
- package/dist/adapters/anthropic-estimator.js +108 -0
- package/dist/adapters/anthropic-estimator.js.map +1 -0
- package/dist/adapters/attachment-resolver.d.ts +96 -0
- package/dist/adapters/attachment-resolver.d.ts.map +1 -0
- package/dist/adapters/attachment-resolver.js +176 -0
- package/dist/adapters/attachment-resolver.js.map +1 -0
- package/dist/adapters/attachment-selector.d.ts +59 -0
- package/dist/adapters/attachment-selector.d.ts.map +1 -0
- package/dist/adapters/attachment-selector.js +163 -0
- package/dist/adapters/attachment-selector.js.map +1 -0
- package/dist/adapters/gemini-estimator.d.ts +27 -0
- package/dist/adapters/gemini-estimator.d.ts.map +1 -0
- package/dist/adapters/gemini-estimator.js +80 -0
- package/dist/adapters/gemini-estimator.js.map +1 -0
- package/dist/adapters/index.d.ts +12 -0
- package/dist/adapters/index.d.ts.map +1 -0
- package/dist/adapters/index.js +28 -0
- package/dist/adapters/index.js.map +1 -0
- package/dist/adapters/memory-store.d.ts +139 -0
- package/dist/adapters/memory-store.d.ts.map +1 -0
- package/dist/adapters/memory-store.js +187 -0
- package/dist/adapters/memory-store.js.map +1 -0
- package/dist/adapters/openai-estimator.d.ts +35 -0
- package/dist/adapters/openai-estimator.d.ts.map +1 -0
- package/dist/adapters/openai-estimator.js +89 -0
- package/dist/adapters/openai-estimator.js.map +1 -0
- package/dist/adapters/summarizer.d.ts +121 -0
- package/dist/adapters/summarizer.d.ts.map +1 -0
- package/dist/adapters/summarizer.js +121 -0
- package/dist/adapters/summarizer.js.map +1 -0
- package/dist/adapters/token-estimator.d.ts +63 -0
- package/dist/adapters/token-estimator.d.ts.map +1 -0
- package/dist/adapters/token-estimator.js +37 -0
- package/dist/adapters/token-estimator.js.map +1 -0
- package/dist/builder/context-builder.d.ts +186 -0
- package/dist/builder/context-builder.d.ts.map +1 -0
- package/dist/builder/context-builder.js +305 -0
- package/dist/builder/context-builder.js.map +1 -0
- package/dist/builder/context-fork.d.ts +166 -0
- package/dist/builder/context-fork.d.ts.map +1 -0
- package/dist/builder/context-fork.js +282 -0
- package/dist/builder/context-fork.js.map +1 -0
- package/dist/builder/index.d.ts +6 -0
- package/dist/builder/index.d.ts.map +1 -0
- package/dist/builder/index.js +22 -0
- package/dist/builder/index.js.map +1 -0
- package/dist/codecs/base.d.ts +18 -0
- package/dist/codecs/base.d.ts.map +1 -0
- package/dist/codecs/base.js +39 -0
- package/dist/codecs/base.js.map +1 -0
- package/dist/codecs/conversation-history.codec.d.ts +81 -0
- package/dist/codecs/conversation-history.codec.d.ts.map +1 -0
- package/dist/codecs/conversation-history.codec.js +89 -0
- package/dist/codecs/conversation-history.codec.js.map +1 -0
- package/dist/codecs/index.d.ts +31 -0
- package/dist/codecs/index.d.ts.map +1 -0
- package/dist/codecs/index.js +71 -0
- package/dist/codecs/index.js.map +1 -0
- package/dist/codecs/redacted-stub.codec.d.ts +32 -0
- package/dist/codecs/redacted-stub.codec.d.ts.map +1 -0
- package/dist/codecs/redacted-stub.codec.js +64 -0
- package/dist/codecs/redacted-stub.codec.js.map +1 -0
- package/dist/codecs/structured-reference.codec.d.ts +40 -0
- package/dist/codecs/structured-reference.codec.d.ts.map +1 -0
- package/dist/codecs/structured-reference.codec.js +81 -0
- package/dist/codecs/structured-reference.codec.js.map +1 -0
- package/dist/codecs/system-rules.codec.d.ts +32 -0
- package/dist/codecs/system-rules.codec.d.ts.map +1 -0
- package/dist/codecs/system-rules.codec.js +62 -0
- package/dist/codecs/system-rules.codec.js.map +1 -0
- package/dist/codecs/tool-output.codec.d.ts +66 -0
- package/dist/codecs/tool-output.codec.d.ts.map +1 -0
- package/dist/codecs/tool-output.codec.js +95 -0
- package/dist/codecs/tool-output.codec.js.map +1 -0
- package/dist/codecs/tool-schema.codec.d.ts +36 -0
- package/dist/codecs/tool-schema.codec.d.ts.map +1 -0
- package/dist/codecs/tool-schema.codec.js +74 -0
- package/dist/codecs/tool-schema.codec.js.map +1 -0
- package/dist/codecs/unsafe-text.codec.d.ts +28 -0
- package/dist/codecs/unsafe-text.codec.d.ts.map +1 -0
- package/dist/codecs/unsafe-text.codec.js +63 -0
- package/dist/codecs/unsafe-text.codec.js.map +1 -0
- package/dist/graph/context-graph.d.ts +121 -0
- package/dist/graph/context-graph.d.ts.map +1 -0
- package/dist/graph/context-graph.js +166 -0
- package/dist/graph/context-graph.js.map +1 -0
- package/dist/graph/index.d.ts +8 -0
- package/dist/graph/index.d.ts.map +1 -0
- package/dist/graph/index.js +24 -0
- package/dist/graph/index.js.map +1 -0
- package/dist/graph/kind-order.d.ts +60 -0
- package/dist/graph/kind-order.d.ts.map +1 -0
- package/dist/graph/kind-order.js +113 -0
- package/dist/graph/kind-order.js.map +1 -0
- package/dist/graph/queries.d.ts +68 -0
- package/dist/graph/queries.d.ts.map +1 -0
- package/dist/graph/queries.js +240 -0
- package/dist/graph/queries.js.map +1 -0
- package/dist/graph/views.d.ts +90 -0
- package/dist/graph/views.d.ts.map +1 -0
- package/dist/graph/views.js +173 -0
- package/dist/graph/views.js.map +1 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +40 -0
- package/dist/index.js.map +1 -0
- package/dist/pipeline/compactor.d.ts +128 -0
- package/dist/pipeline/compactor.d.ts.map +1 -0
- package/dist/pipeline/compactor.js +346 -0
- package/dist/pipeline/compactor.js.map +1 -0
- package/dist/pipeline/index.d.ts +6 -0
- package/dist/pipeline/index.d.ts.map +1 -0
- package/dist/pipeline/index.js +22 -0
- package/dist/pipeline/index.js.map +1 -0
- package/dist/pipeline/summarizer.d.ts +18 -0
- package/dist/pipeline/summarizer.d.ts.map +1 -0
- package/dist/pipeline/summarizer.js +68 -0
- package/dist/pipeline/summarizer.js.map +1 -0
- package/dist/policies/default-policy.d.ts +29 -0
- package/dist/policies/default-policy.d.ts.map +1 -0
- package/dist/policies/default-policy.js +58 -0
- package/dist/policies/default-policy.js.map +1 -0
- package/dist/policies/index.d.ts +5 -0
- package/dist/policies/index.d.ts.map +1 -0
- package/dist/policies/index.js +21 -0
- package/dist/policies/index.js.map +1 -0
- package/dist/providers/anthropic-compiler.d.ts +58 -0
- package/dist/providers/anthropic-compiler.d.ts.map +1 -0
- package/dist/providers/anthropic-compiler.js +182 -0
- package/dist/providers/anthropic-compiler.js.map +1 -0
- package/dist/providers/capabilities.d.ts +54 -0
- package/dist/providers/capabilities.d.ts.map +1 -0
- package/dist/providers/capabilities.js +87 -0
- package/dist/providers/capabilities.js.map +1 -0
- package/dist/providers/gemini-compiler.d.ts +51 -0
- package/dist/providers/gemini-compiler.d.ts.map +1 -0
- package/dist/providers/gemini-compiler.js +206 -0
- package/dist/providers/gemini-compiler.js.map +1 -0
- package/dist/providers/index.d.ts +8 -0
- package/dist/providers/index.d.ts.map +1 -0
- package/dist/providers/index.js +24 -0
- package/dist/providers/index.js.map +1 -0
- package/dist/providers/openai-compiler.d.ts +46 -0
- package/dist/providers/openai-compiler.d.ts.map +1 -0
- package/dist/providers/openai-compiler.js +149 -0
- package/dist/providers/openai-compiler.js.map +1 -0
- package/dist/types/attachment.d.ts +62 -0
- package/dist/types/attachment.d.ts.map +1 -0
- package/dist/types/attachment.js +6 -0
- package/dist/types/attachment.js.map +1 -0
- package/dist/types/block.d.ts +61 -0
- package/dist/types/block.d.ts.map +1 -0
- package/dist/types/block.js +8 -0
- package/dist/types/block.js.map +1 -0
- package/dist/types/codec.d.ts +58 -0
- package/dist/types/codec.d.ts.map +1 -0
- package/dist/types/codec.js +6 -0
- package/dist/types/codec.js.map +1 -0
- package/dist/types/compiled.d.ts +91 -0
- package/dist/types/compiled.d.ts.map +1 -0
- package/dist/types/compiled.js +6 -0
- package/dist/types/compiled.js.map +1 -0
- package/dist/types/hash.d.ts +24 -0
- package/dist/types/hash.d.ts.map +1 -0
- package/dist/types/hash.js +49 -0
- package/dist/types/hash.js.map +1 -0
- package/dist/types/index.d.ts +10 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +26 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/policy.d.ts +128 -0
- package/dist/types/policy.d.ts.map +1 -0
- package/dist/types/policy.js +55 -0
- package/dist/types/policy.js.map +1 -0
- package/package.json +55 -0
- package/postcss.config.js +4 -0
- package/src/__tests__/attachment-selector.test.ts +559 -0
- package/src/__tests__/cache-breakpoints.test.ts +566 -0
- package/src/__tests__/codecs.test.ts +417 -0
- package/src/__tests__/compactor.test.ts +608 -0
- package/src/__tests__/context-graph.test.ts +383 -0
- package/src/__tests__/hash.test.ts +274 -0
- package/src/__tests__/integration.test.ts +866 -0
- package/src/__tests__/kind-order.test.ts +312 -0
- package/src/__tests__/phase2-integration.test.ts +253 -0
- package/src/__tests__/queries.test.ts +387 -0
- package/src/__tests__/token-estimator.test.ts +326 -0
- package/src/adapters/anthropic-estimator.ts +125 -0
- package/src/adapters/attachment-resolver.ts +295 -0
- package/src/adapters/attachment-selector.ts +218 -0
- package/src/adapters/gemini-estimator.ts +93 -0
- package/src/adapters/index.ts +12 -0
- package/src/adapters/memory-store.ts +299 -0
- package/src/adapters/openai-estimator.ts +105 -0
- package/src/adapters/summarizer.ts +250 -0
- package/src/adapters/token-estimator.ts +74 -0
- package/src/builder/context-builder.ts +467 -0
- package/src/builder/context-fork.ts +471 -0
- package/src/builder/index.ts +6 -0
- package/src/codecs/base.ts +36 -0
- package/src/codecs/conversation-history.codec.ts +108 -0
- package/src/codecs/index.ts +57 -0
- package/src/codecs/redacted-stub.codec.ts +76 -0
- package/src/codecs/structured-reference.codec.ts +96 -0
- package/src/codecs/system-rules.codec.ts +74 -0
- package/src/codecs/tool-output.codec.ts +109 -0
- package/src/codecs/tool-schema.codec.ts +87 -0
- package/src/codecs/unsafe-text.codec.ts +74 -0
- package/src/graph/context-graph.ts +205 -0
- package/src/graph/index.ts +8 -0
- package/src/graph/kind-order.ts +125 -0
- package/src/graph/queries.ts +306 -0
- package/src/graph/views.ts +255 -0
- package/src/index.ts +31 -0
- package/src/pipeline/compactor.ts +563 -0
- package/src/pipeline/index.ts +6 -0
- package/src/pipeline/summarizer.ts +76 -0
- package/src/policies/default-policy.ts +69 -0
- package/src/policies/index.ts +5 -0
- package/src/providers/anthropic-compiler.ts +294 -0
- package/src/providers/capabilities.ts +144 -0
- package/src/providers/gemini-compiler.ts +272 -0
- package/src/providers/index.ts +8 -0
- package/src/providers/openai-compiler.ts +191 -0
- package/src/types/attachment.ts +86 -0
- package/src/types/block.ts +84 -0
- package/src/types/codec.ts +68 -0
- package/src/types/compiled.ts +109 -0
- package/src/types/hash.ts +58 -0
- package/src/types/index.ts +10 -0
- package/src/types/policy.ts +194 -0
- package/tsconfig.json +21 -0
- package/vitest.config.ts +21 -0
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Summarizer: Generate summaries with sensitivity filtering.
|
|
3
|
+
*
|
|
4
|
+
* Provides schema-enforced summarization with forbidden field validation.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { createHash } from 'crypto';
|
|
8
|
+
import type { ZodSchema } from 'zod';
|
|
9
|
+
import type { ContextBlock, SensitivityLevel } from '../types/block.js';
|
|
10
|
+
import type { ModelRef } from '../types/policy.js';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Summarization provenance.
|
|
14
|
+
*/
|
|
15
|
+
export interface SummaryProvenance {
|
|
16
|
+
/** Source block hashes */
|
|
17
|
+
derivedFrom: string[];
|
|
18
|
+
|
|
19
|
+
/** Summarization method */
|
|
20
|
+
method: 'summarize';
|
|
21
|
+
|
|
22
|
+
/** Summarizer version */
|
|
23
|
+
version: string;
|
|
24
|
+
|
|
25
|
+
/** Source content snapshot hash */
|
|
26
|
+
snapshotHash: string;
|
|
27
|
+
|
|
28
|
+
/** Creation timestamp */
|
|
29
|
+
createdAt: number;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Summary block result.
|
|
34
|
+
*/
|
|
35
|
+
export interface SummaryBlock<TOutput = unknown> {
|
|
36
|
+
/** Validated summary output */
|
|
37
|
+
summary: TOutput;
|
|
38
|
+
|
|
39
|
+
/** Provenance information */
|
|
40
|
+
provenance: SummaryProvenance;
|
|
41
|
+
|
|
42
|
+
/** Token usage */
|
|
43
|
+
usage: {
|
|
44
|
+
inputTokens: number;
|
|
45
|
+
outputTokens: number;
|
|
46
|
+
totalTokens: number;
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Summarizer interface.
|
|
52
|
+
*/
|
|
53
|
+
export interface Summarizer {
|
|
54
|
+
/**
|
|
55
|
+
* Generate a summary of blocks with schema validation.
|
|
56
|
+
*
|
|
57
|
+
* @param blocks - Blocks to summarize
|
|
58
|
+
* @param schema - Expected output schema
|
|
59
|
+
* @param options - Summarization options
|
|
60
|
+
* @returns Summary block
|
|
61
|
+
*/
|
|
62
|
+
summarize<TOutput>(
|
|
63
|
+
blocks: ContextBlock<unknown>[],
|
|
64
|
+
schema: ZodSchema<TOutput>,
|
|
65
|
+
options?: SummarizationOptions
|
|
66
|
+
): Promise<SummaryBlock<TOutput>>;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Summarization options.
|
|
71
|
+
*/
|
|
72
|
+
export interface SummarizationOptions {
|
|
73
|
+
/** Instruction/prompt for summarization */
|
|
74
|
+
instruction?: string;
|
|
75
|
+
|
|
76
|
+
/** Maximum output tokens */
|
|
77
|
+
maxOutputTokens?: number;
|
|
78
|
+
|
|
79
|
+
/** Forbidden fields that must not appear in summary */
|
|
80
|
+
forbiddenFields?: string[];
|
|
81
|
+
|
|
82
|
+
/** Allowed sensitivity levels for summarization */
|
|
83
|
+
allowedForSummarization?: SensitivityLevel[];
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Default summarization options.
|
|
88
|
+
*/
|
|
89
|
+
export const DEFAULT_SUMMARIZATION_OPTIONS: Required<
|
|
90
|
+
Omit<SummarizationOptions, 'instruction' | 'maxOutputTokens'>
|
|
91
|
+
> = {
|
|
92
|
+
forbiddenFields: ['raw_messages', 'full_transcript', 'raw_history'],
|
|
93
|
+
allowedForSummarization: ['public'],
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Default summarizer using gpt-5-nano.
|
|
98
|
+
*/
|
|
99
|
+
export class DefaultSummarizer implements Summarizer {
|
|
100
|
+
private readonly version = '1.0.0';
|
|
101
|
+
|
|
102
|
+
constructor(
|
|
103
|
+
private readonly modelRef: ModelRef = {
|
|
104
|
+
provider: 'openai',
|
|
105
|
+
model: 'gpt-5-nano',
|
|
106
|
+
},
|
|
107
|
+
private readonly executor?: (
|
|
108
|
+
instruction: string,
|
|
109
|
+
content: string,
|
|
110
|
+
schema: ZodSchema
|
|
111
|
+
) => Promise<{
|
|
112
|
+
output: unknown;
|
|
113
|
+
usage: { inputTokens: number; outputTokens: number; totalTokens: number };
|
|
114
|
+
}>
|
|
115
|
+
) {}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Filter blocks by sensitivity level.
|
|
119
|
+
*
|
|
120
|
+
* @param blocks - Blocks to filter
|
|
121
|
+
* @param allowedLevels - Allowed sensitivity levels
|
|
122
|
+
* @returns Filtered blocks
|
|
123
|
+
*/
|
|
124
|
+
private filterBySensitivity(
|
|
125
|
+
blocks: ContextBlock<unknown>[],
|
|
126
|
+
allowedLevels: SensitivityLevel[]
|
|
127
|
+
): ContextBlock<unknown>[] {
|
|
128
|
+
return blocks.filter((block) => allowedLevels.includes(block.meta.sensitivity));
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Compute snapshot hash from block hashes.
|
|
133
|
+
*
|
|
134
|
+
* @param blocks - Blocks to hash
|
|
135
|
+
* @returns Hex-encoded SHA-256 hash
|
|
136
|
+
*/
|
|
137
|
+
private computeSnapshotHash(blocks: ContextBlock<unknown>[]): string {
|
|
138
|
+
const concatenated = blocks.map((b) => b.blockHash).join('|');
|
|
139
|
+
return createHash('sha256').update(concatenated).digest('hex');
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Default executor (throws error - must be provided).
|
|
144
|
+
*/
|
|
145
|
+
private async defaultExecutor(
|
|
146
|
+
instruction: string,
|
|
147
|
+
content: string,
|
|
148
|
+
schema: ZodSchema
|
|
149
|
+
): Promise<{
|
|
150
|
+
output: unknown;
|
|
151
|
+
usage: { inputTokens: number; outputTokens: number; totalTokens: number };
|
|
152
|
+
}> {
|
|
153
|
+
throw new Error(
|
|
154
|
+
'Summarizer executor not provided. Please provide an executor function in constructor.'
|
|
155
|
+
);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
async summarize<TOutput>(
|
|
159
|
+
blocks: ContextBlock<unknown>[],
|
|
160
|
+
schema: ZodSchema<TOutput>,
|
|
161
|
+
options?: SummarizationOptions
|
|
162
|
+
): Promise<SummaryBlock<TOutput>> {
|
|
163
|
+
const opts = {
|
|
164
|
+
...DEFAULT_SUMMARIZATION_OPTIONS,
|
|
165
|
+
...options,
|
|
166
|
+
};
|
|
167
|
+
|
|
168
|
+
// Filter blocks by sensitivity
|
|
169
|
+
const filteredBlocks = this.filterBySensitivity(
|
|
170
|
+
blocks,
|
|
171
|
+
opts.allowedForSummarization ?? DEFAULT_SUMMARIZATION_OPTIONS.allowedForSummarization
|
|
172
|
+
);
|
|
173
|
+
|
|
174
|
+
if (filteredBlocks.length === 0) {
|
|
175
|
+
throw new Error('No blocks available for summarization after sensitivity filtering');
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// Build content string from blocks
|
|
179
|
+
const content = filteredBlocks
|
|
180
|
+
.map((block, idx) => {
|
|
181
|
+
return `[Block ${idx + 1}/${filteredBlocks.length}]\nKind: ${block.meta.kind}\nPayload: ${JSON.stringify(block.payload, null, 2)}`;
|
|
182
|
+
})
|
|
183
|
+
.join('\n\n---\n\n');
|
|
184
|
+
|
|
185
|
+
// Build instruction
|
|
186
|
+
const instruction =
|
|
187
|
+
opts.instruction ??
|
|
188
|
+
'Summarize the following context blocks concisely. Focus on key information and maintain accuracy.';
|
|
189
|
+
|
|
190
|
+
// Add forbidden fields note if specified
|
|
191
|
+
const enhancedInstruction = opts.forbiddenFields
|
|
192
|
+
? `${instruction}\n\nIMPORTANT: Your summary MUST NOT include these fields: ${opts.forbiddenFields.join(', ')}`
|
|
193
|
+
: instruction;
|
|
194
|
+
|
|
195
|
+
// Execute summarization
|
|
196
|
+
const executor = this.executor ?? this.defaultExecutor.bind(this);
|
|
197
|
+
const result = await executor(enhancedInstruction, content, schema);
|
|
198
|
+
|
|
199
|
+
// Validate output against schema
|
|
200
|
+
const validatedOutput = schema.parse(result.output);
|
|
201
|
+
|
|
202
|
+
// Check for forbidden fields
|
|
203
|
+
if (opts.forbiddenFields && opts.forbiddenFields.length > 0) {
|
|
204
|
+
const outputStr = JSON.stringify(validatedOutput);
|
|
205
|
+
for (const field of opts.forbiddenFields) {
|
|
206
|
+
if (outputStr.includes(field)) {
|
|
207
|
+
throw new Error(
|
|
208
|
+
`Summarization failed: Output contains forbidden field '${field}'`
|
|
209
|
+
);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
// Compute snapshot hash
|
|
215
|
+
const snapshotHash = this.computeSnapshotHash(filteredBlocks);
|
|
216
|
+
|
|
217
|
+
return {
|
|
218
|
+
summary: validatedOutput,
|
|
219
|
+
provenance: {
|
|
220
|
+
derivedFrom: filteredBlocks.map((b) => b.blockHash),
|
|
221
|
+
method: 'summarize',
|
|
222
|
+
version: this.version,
|
|
223
|
+
snapshotHash,
|
|
224
|
+
createdAt: Math.floor(Date.now() / 1000),
|
|
225
|
+
},
|
|
226
|
+
usage: result.usage,
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* Create a summarizer with custom model.
|
|
233
|
+
*
|
|
234
|
+
* @param modelRef - Model reference
|
|
235
|
+
* @param executor - Executor function
|
|
236
|
+
* @returns Summarizer instance
|
|
237
|
+
*/
|
|
238
|
+
export function createSummarizer(
|
|
239
|
+
modelRef: ModelRef,
|
|
240
|
+
executor: (
|
|
241
|
+
instruction: string,
|
|
242
|
+
content: string,
|
|
243
|
+
schema: ZodSchema
|
|
244
|
+
) => Promise<{
|
|
245
|
+
output: unknown;
|
|
246
|
+
usage: { inputTokens: number; outputTokens: number; totalTokens: number };
|
|
247
|
+
}>
|
|
248
|
+
): Summarizer {
|
|
249
|
+
return new DefaultSummarizer(modelRef, executor);
|
|
250
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TokenEstimator: Single source of truth for token counting.
|
|
3
|
+
*
|
|
4
|
+
* Provides provider-specific token estimation for context blocks.
|
|
5
|
+
* NOT implemented by codecs - this is the only place token counting happens.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import type { ContextBlock } from '../types/block.js';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Token estimation result.
|
|
12
|
+
*/
|
|
13
|
+
export interface TokenEstimate {
|
|
14
|
+
/** Estimated token count */
|
|
15
|
+
tokens: number;
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Confidence level:
|
|
19
|
+
* - 'exact': API-provided count (Anthropic)
|
|
20
|
+
* - 'high': tiktoken-based (OpenAI/Gemini)
|
|
21
|
+
* - 'low': Heuristic fallback (chars / 4)
|
|
22
|
+
*/
|
|
23
|
+
confidence: 'exact' | 'high' | 'low';
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* TokenEstimator interface.
|
|
28
|
+
* All implementations must be async (Anthropic uses API calls).
|
|
29
|
+
*/
|
|
30
|
+
export interface TokenEstimator {
|
|
31
|
+
/**
|
|
32
|
+
* Estimate tokens for a list of blocks.
|
|
33
|
+
*
|
|
34
|
+
* @param blocks - Blocks to estimate
|
|
35
|
+
* @returns Token estimate
|
|
36
|
+
*/
|
|
37
|
+
estimate(blocks: ContextBlock<unknown>[]): Promise<TokenEstimate>;
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Estimate tokens for a single block.
|
|
41
|
+
*
|
|
42
|
+
* @param block - Block to estimate
|
|
43
|
+
* @returns Token estimate
|
|
44
|
+
*/
|
|
45
|
+
estimateBlock(block: ContextBlock<unknown>): Promise<TokenEstimate>;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Safety multiplier for low-confidence estimates.
|
|
50
|
+
* Applies 1.2x multiplier to heuristic estimates to avoid budget overruns.
|
|
51
|
+
*/
|
|
52
|
+
export const LOW_CONFIDENCE_MULTIPLIER = 1.2;
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Heuristic token estimation (chars / 4).
|
|
56
|
+
* Used as fallback when tiktoken/API is unavailable.
|
|
57
|
+
*
|
|
58
|
+
* @param text - Text to estimate
|
|
59
|
+
* @returns Token count
|
|
60
|
+
*/
|
|
61
|
+
export function heuristicTokenCount(text: string): number {
|
|
62
|
+
return Math.ceil((text.length / 4) * LOW_CONFIDENCE_MULTIPLIER);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Serialize a block to text for token estimation.
|
|
67
|
+
* Uses JSON.stringify as a reasonable approximation of rendered content.
|
|
68
|
+
*
|
|
69
|
+
* @param block - Block to serialize
|
|
70
|
+
* @returns Serialized text
|
|
71
|
+
*/
|
|
72
|
+
export function serializeBlockForEstimation(block: ContextBlock<unknown>): string {
|
|
73
|
+
return JSON.stringify(block.payload);
|
|
74
|
+
}
|