@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,255 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ContextView: Immutable, deterministically-ordered snapshot of context blocks.
|
|
3
|
+
*
|
|
4
|
+
* Views provide stable ordering (KIND_ORDER + lexicographic) and token estimation.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { createHash } from 'crypto';
|
|
8
|
+
import type { ContextBlock } from '../types/block.js';
|
|
9
|
+
import type { ContextGraph } from './context-graph.js';
|
|
10
|
+
import type { BlockQuery } from './queries.js';
|
|
11
|
+
import type { TokenEstimator } from '../adapters/token-estimator.js';
|
|
12
|
+
import { compareKinds } from './kind-order.js';
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* View options for creating a ContextView.
|
|
16
|
+
*/
|
|
17
|
+
export interface ViewOptions {
|
|
18
|
+
/** Query to filter blocks (default: all blocks) */
|
|
19
|
+
query?: BlockQuery;
|
|
20
|
+
|
|
21
|
+
/** Token estimator for budget enforcement (optional) */
|
|
22
|
+
tokenEstimator?: TokenEstimator;
|
|
23
|
+
|
|
24
|
+
/** Maximum token budget (requires tokenEstimator) */
|
|
25
|
+
maxTokens?: number;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Token estimation result for a view.
|
|
30
|
+
*/
|
|
31
|
+
export interface ViewTokenEstimate {
|
|
32
|
+
/** Estimated token count */
|
|
33
|
+
tokens: number;
|
|
34
|
+
|
|
35
|
+
/** Confidence level */
|
|
36
|
+
confidence: 'exact' | 'high' | 'low';
|
|
37
|
+
|
|
38
|
+
/** Whether token budget was exceeded (blocks were truncated) */
|
|
39
|
+
truncated: boolean;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* ContextView: Immutable snapshot of blocks with deterministic ordering.
|
|
44
|
+
*
|
|
45
|
+
* Ordering rules:
|
|
46
|
+
* 1. Primary: KIND_ORDER (pinned → reference → memory → state → tool_output → history → turn)
|
|
47
|
+
* 2. Secondary: Lexicographic by blockHash within same kind
|
|
48
|
+
*/
|
|
49
|
+
export interface ContextView {
|
|
50
|
+
/** Ordered blocks (immutable) */
|
|
51
|
+
readonly blocks: ReadonlyArray<ContextBlock<unknown>>;
|
|
52
|
+
|
|
53
|
+
/** Token estimation (if estimator provided) */
|
|
54
|
+
readonly tokenEstimate?: ViewTokenEstimate;
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Stable prefix hash (computed from ordered block hashes).
|
|
58
|
+
* Two views with identical ordered blocks have identical prefix hashes.
|
|
59
|
+
*/
|
|
60
|
+
readonly stablePrefixHash: string;
|
|
61
|
+
|
|
62
|
+
/** View creation timestamp */
|
|
63
|
+
readonly createdAt: number;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Sort blocks deterministically by KIND_ORDER + lexicographic.
|
|
68
|
+
*
|
|
69
|
+
* @param blocks - Blocks to sort
|
|
70
|
+
* @returns Sorted blocks (new array)
|
|
71
|
+
*/
|
|
72
|
+
export function sortBlocksDeterministic(
|
|
73
|
+
blocks: ContextBlock<unknown>[]
|
|
74
|
+
): ContextBlock<unknown>[] {
|
|
75
|
+
return [...blocks].sort((a, b) => {
|
|
76
|
+
// Primary: KIND_ORDER
|
|
77
|
+
const kindCmp = compareKinds(a.meta.kind, b.meta.kind);
|
|
78
|
+
if (kindCmp !== 0) {
|
|
79
|
+
return kindCmp;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// Secondary: Lexicographic by blockHash
|
|
83
|
+
return a.blockHash.localeCompare(b.blockHash);
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Compute stable prefix hash from ordered block hashes.
|
|
89
|
+
*
|
|
90
|
+
* @param blocks - Ordered blocks
|
|
91
|
+
* @returns Hex-encoded SHA-256 hash
|
|
92
|
+
*/
|
|
93
|
+
export function computeStablePrefixHash(blocks: ReadonlyArray<ContextBlock<unknown>>): string {
|
|
94
|
+
// Concatenate block hashes in order
|
|
95
|
+
const concatenated = blocks.map((b) => b.blockHash).join('|');
|
|
96
|
+
|
|
97
|
+
// Compute SHA-256 hash
|
|
98
|
+
const hash = createHash('sha256')
|
|
99
|
+
.update(concatenated)
|
|
100
|
+
.digest('hex');
|
|
101
|
+
|
|
102
|
+
return hash;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Apply token budget to blocks (truncate if needed).
|
|
107
|
+
* Returns blocks that fit within budget + estimation metadata.
|
|
108
|
+
*
|
|
109
|
+
* @param blocks - Ordered blocks
|
|
110
|
+
* @param estimator - Token estimator
|
|
111
|
+
* @param maxTokens - Maximum token budget
|
|
112
|
+
* @returns Truncated blocks + estimation result
|
|
113
|
+
*/
|
|
114
|
+
async function applyTokenBudget(
|
|
115
|
+
blocks: ContextBlock<unknown>[],
|
|
116
|
+
estimator: TokenEstimator,
|
|
117
|
+
maxTokens: number
|
|
118
|
+
): Promise<{ blocks: ContextBlock<unknown>[]; estimate: ViewTokenEstimate }> {
|
|
119
|
+
let totalTokens = 0;
|
|
120
|
+
let lowestConfidence: 'exact' | 'high' | 'low' = 'exact';
|
|
121
|
+
const includedBlocks: ContextBlock<unknown>[] = [];
|
|
122
|
+
|
|
123
|
+
for (const block of blocks) {
|
|
124
|
+
// Estimate tokens for this block
|
|
125
|
+
const blockEstimate = await estimator.estimateBlock(block);
|
|
126
|
+
const projectedTotal = totalTokens + blockEstimate.tokens;
|
|
127
|
+
|
|
128
|
+
// Check if adding this block would exceed budget
|
|
129
|
+
if (projectedTotal > maxTokens) {
|
|
130
|
+
// Budget exceeded - stop here
|
|
131
|
+
return {
|
|
132
|
+
blocks: includedBlocks,
|
|
133
|
+
estimate: {
|
|
134
|
+
tokens: totalTokens,
|
|
135
|
+
confidence: lowestConfidence,
|
|
136
|
+
truncated: true,
|
|
137
|
+
},
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// Include block
|
|
142
|
+
includedBlocks.push(block);
|
|
143
|
+
totalTokens += blockEstimate.tokens;
|
|
144
|
+
|
|
145
|
+
// Track lowest confidence
|
|
146
|
+
if (blockEstimate.confidence === 'low') {
|
|
147
|
+
lowestConfidence = 'low';
|
|
148
|
+
} else if (blockEstimate.confidence === 'high' && lowestConfidence === 'exact') {
|
|
149
|
+
lowestConfidence = 'high';
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// All blocks fit within budget
|
|
154
|
+
return {
|
|
155
|
+
blocks: includedBlocks,
|
|
156
|
+
estimate: {
|
|
157
|
+
tokens: totalTokens,
|
|
158
|
+
confidence: lowestConfidence,
|
|
159
|
+
truncated: false,
|
|
160
|
+
},
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Create a ContextView from a graph and options.
|
|
166
|
+
*
|
|
167
|
+
* @param graph - Context graph
|
|
168
|
+
* @param options - View options
|
|
169
|
+
* @returns ContextView
|
|
170
|
+
*/
|
|
171
|
+
export async function createContextView(
|
|
172
|
+
graph: ContextGraph,
|
|
173
|
+
options: ViewOptions
|
|
174
|
+
): Promise<ContextView> {
|
|
175
|
+
// Select blocks matching query
|
|
176
|
+
const query = options.query ?? {};
|
|
177
|
+
let selectedBlocks = graph.select(query);
|
|
178
|
+
|
|
179
|
+
// Sort blocks deterministically
|
|
180
|
+
selectedBlocks = sortBlocksDeterministic(selectedBlocks);
|
|
181
|
+
|
|
182
|
+
// Apply token budget if provided
|
|
183
|
+
let tokenEstimate: ViewTokenEstimate | undefined;
|
|
184
|
+
if (options.tokenEstimator && options.maxTokens !== undefined) {
|
|
185
|
+
const result = await applyTokenBudget(
|
|
186
|
+
selectedBlocks,
|
|
187
|
+
options.tokenEstimator,
|
|
188
|
+
options.maxTokens
|
|
189
|
+
);
|
|
190
|
+
selectedBlocks = result.blocks;
|
|
191
|
+
tokenEstimate = result.estimate;
|
|
192
|
+
} else if (options.tokenEstimator) {
|
|
193
|
+
// Estimate without budget enforcement
|
|
194
|
+
const estimate = await options.tokenEstimator.estimate(selectedBlocks);
|
|
195
|
+
tokenEstimate = {
|
|
196
|
+
tokens: estimate.tokens,
|
|
197
|
+
confidence: estimate.confidence,
|
|
198
|
+
truncated: false,
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
// Compute stable prefix hash
|
|
203
|
+
const stablePrefixHash = computeStablePrefixHash(selectedBlocks);
|
|
204
|
+
|
|
205
|
+
return {
|
|
206
|
+
blocks: selectedBlocks,
|
|
207
|
+
tokenEstimate,
|
|
208
|
+
stablePrefixHash,
|
|
209
|
+
createdAt: Math.floor(Date.now() / 1000),
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* Check if two views have identical content (same blocks in same order).
|
|
215
|
+
*
|
|
216
|
+
* @param a - First view
|
|
217
|
+
* @param b - Second view
|
|
218
|
+
* @returns True if views have identical content
|
|
219
|
+
*/
|
|
220
|
+
export function viewsEqual(a: ContextView, b: ContextView): boolean {
|
|
221
|
+
return a.stablePrefixHash === b.stablePrefixHash;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* Merge multiple views into a single view (preserves ordering).
|
|
226
|
+
* Deduplicates blocks by hash.
|
|
227
|
+
*
|
|
228
|
+
* @param views - Views to merge
|
|
229
|
+
* @returns Merged view
|
|
230
|
+
*/
|
|
231
|
+
export function mergeViews(...views: ContextView[]): ContextView {
|
|
232
|
+
const seenHashes = new Set<string>();
|
|
233
|
+
const mergedBlocks: ContextBlock<unknown>[] = [];
|
|
234
|
+
|
|
235
|
+
for (const view of views) {
|
|
236
|
+
for (const block of view.blocks) {
|
|
237
|
+
if (!seenHashes.has(block.blockHash)) {
|
|
238
|
+
seenHashes.add(block.blockHash);
|
|
239
|
+
mergedBlocks.push(block);
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
// Re-sort merged blocks
|
|
245
|
+
const sortedBlocks = sortBlocksDeterministic(mergedBlocks);
|
|
246
|
+
|
|
247
|
+
// Compute new prefix hash
|
|
248
|
+
const stablePrefixHash = computeStablePrefixHash(sortedBlocks);
|
|
249
|
+
|
|
250
|
+
return {
|
|
251
|
+
blocks: sortedBlocks,
|
|
252
|
+
stablePrefixHash,
|
|
253
|
+
createdAt: Math.floor(Date.now() / 1000),
|
|
254
|
+
};
|
|
255
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @foundry/context - Context management library for LLM conversations
|
|
3
|
+
*
|
|
4
|
+
* Phase 1: Core Types & Codecs
|
|
5
|
+
* Phase 2: Context Graph & Token Estimation
|
|
6
|
+
* Phase 3: Builder & Compilation Pipeline
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
// Core types
|
|
10
|
+
export * from './types/index.js';
|
|
11
|
+
|
|
12
|
+
// Graph utilities (KIND_ORDER, ContextGraph, queries, views)
|
|
13
|
+
export * from './graph/index.js';
|
|
14
|
+
|
|
15
|
+
// Built-in codecs
|
|
16
|
+
export * from './codecs/index.js';
|
|
17
|
+
|
|
18
|
+
// Token estimators
|
|
19
|
+
export * from './adapters/index.js';
|
|
20
|
+
|
|
21
|
+
// Context builder (Phase 3)
|
|
22
|
+
export * from './builder/index.js';
|
|
23
|
+
|
|
24
|
+
// Pipeline utilities (compaction, fork)
|
|
25
|
+
export * from './pipeline/index.js';
|
|
26
|
+
|
|
27
|
+
// Provider compilers
|
|
28
|
+
export * from './providers/index.js';
|
|
29
|
+
|
|
30
|
+
// Policy configurations
|
|
31
|
+
export * from './policies/index.js';
|