pi-fold 0.0.1 → 0.1.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/LICENSE +21 -0
- package/README.md +135 -11
- package/extensions/active-context.ts +2157 -0
- package/extensions/evidence.js +673 -0
- package/extensions/index.js +32 -0
- package/extensions/json.ts +228 -0
- package/extensions/lib/advisory.ts +238 -0
- package/extensions/lib/canonical.ts +171 -0
- package/extensions/lib/folding.ts +1091 -0
- package/extensions/lib/measurement.ts +429 -0
- package/extensions/lib/persistence.ts +814 -0
- package/extensions/lib/policy.ts +296 -0
- package/extensions/lib/selection.ts +501 -0
- package/extensions/lib/surfacing.ts +332 -0
- package/extensions/lib/tool-surface.ts +69 -0
- package/extensions/lib/transcript.ts +479 -0
- package/extensions/summarizer.js +95 -0
- package/package.json +48 -11
- package/index.js +0 -4
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+
import type { EvidenceRef } from "../json.ts";
|
|
2
|
+
|
|
3
|
+
export const DEFAULT_ACTIVE_CONTEXT_TOOL_NAME = "active_context";
|
|
4
|
+
export const DEFAULT_ACTIVE_CONTEXT_ENTRY_TYPE_PREFIX = "pi-fold-active-context";
|
|
5
|
+
export const DEFAULT_ACTIVE_CONTEXT_TOOL_LABEL = "Active Context";
|
|
6
|
+
export const DEFAULT_ACTIVE_CONTEXT_BRAND_NOUN = "active-context";
|
|
7
|
+
export const DEFAULT_ACTIVE_CONTEXT_COMMAND_NAMES = Object.freeze({
|
|
8
|
+
status: "context",
|
|
9
|
+
fold: "fold-context",
|
|
10
|
+
});
|
|
11
|
+
export const GUIDANCE_PROFILES = Object.freeze(["pressure", "curation", "minimal"] as const);
|
|
12
|
+
export type GuidanceProfile = typeof GUIDANCE_PROFILES[number];
|
|
13
|
+
export const DEFAULT_GUIDANCE_PROFILE: GuidanceProfile = "pressure";
|
|
14
|
+
|
|
15
|
+
export function entryTypeNamespace(entryTypePrefix: string): string {
|
|
16
|
+
const suffix = "-active-context";
|
|
17
|
+
return entryTypePrefix.endsWith(suffix) && entryTypePrefix.length > suffix.length
|
|
18
|
+
? entryTypePrefix.slice(0, -suffix.length)
|
|
19
|
+
: entryTypePrefix;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export function activeContextSource(entryTypePrefix: string): string {
|
|
23
|
+
const namespace = entryTypeNamespace(entryTypePrefix);
|
|
24
|
+
return namespace === entryTypePrefix ? entryTypePrefix : `${namespace}/active-context`;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function activeContextBrand(brandNoun: string): string {
|
|
28
|
+
return /active-context$/i.test(brandNoun) ? brandNoun : `${brandNoun} active-context`;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export function contextBrand(brandNoun: string): string {
|
|
32
|
+
return /context$/i.test(brandNoun) ? brandNoun : `${brandNoun} context`;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const DEFAULT_ENTRY_NAMESPACE = entryTypeNamespace(DEFAULT_ACTIVE_CONTEXT_ENTRY_TYPE_PREFIX);
|
|
36
|
+
export const ACTIVE_CONTEXT_STATE_ENTRY = `${DEFAULT_ACTIVE_CONTEXT_ENTRY_TYPE_PREFIX}-state`;
|
|
37
|
+
export const ACTIVE_CONTEXT_FOLD_RECORD_ENTRY = `${DEFAULT_ACTIVE_CONTEXT_ENTRY_TYPE_PREFIX}-fold-record`;
|
|
38
|
+
export const NATIVE_COMPACTION_RECEIPT_ENTRY = `${DEFAULT_ENTRY_NAMESPACE}-native-compaction-receipt`;
|
|
39
|
+
export const NATIVE_COMPACTION_DECISION_ENTRY = `${DEFAULT_ENTRY_NAMESPACE}-native-compaction-decision`;
|
|
40
|
+
export const PROVIDER_CONTEXT_MEASUREMENT_ENTRY = `${DEFAULT_ENTRY_NAMESPACE}-provider-context-measurement`;
|
|
41
|
+
export const ACTIVE_CONTEXT_STATUS_KEY = DEFAULT_ACTIVE_CONTEXT_ENTRY_TYPE_PREFIX;
|
|
42
|
+
export const ACTIVE_CONTEXT_TOOL_ACTIONS = Object.freeze([
|
|
43
|
+
"status", "peek", "fold", "expand", "refold", "protect", "unprotect",
|
|
44
|
+
] as const);
|
|
45
|
+
export type ActiveContextToolAction = typeof ACTIVE_CONTEXT_TOOL_ACTIONS[number];
|
|
46
|
+
export const USER_RESCUE_MAX_SOURCE_CHARS = 512_000;
|
|
47
|
+
export const DEFAULT_CONTEXT_WINDOW = 272_000;
|
|
48
|
+
export const TOOL_FOLD_CADENCE_MIN_TOKENS = 12_000;
|
|
49
|
+
export const TOOL_FOLD_CADENCE_WINDOW_FRACTION = 0.06;
|
|
50
|
+
export const EXPAND_LEASE_GENERATIONS = 8;
|
|
51
|
+
export const MAX_EXPAND_LEASES = 64;
|
|
52
|
+
export const CONSOLIDATION_WIDTH_THRESHOLD = 10;
|
|
53
|
+
export const MAX_ADVISORY_DELIVERIES_PER_MILESTONE = 16;
|
|
54
|
+
|
|
55
|
+
// Ephemeral surfacing structure. These stay INTERNAL constants rather than public
|
|
56
|
+
// options: they are the knobs the surfacing experiment is meant to settle, and an
|
|
57
|
+
// option surface fixed before the accept/reject data exists would freeze a guess.
|
|
58
|
+
export const DEFAULT_SURFACING_ENABLED = true;
|
|
59
|
+
export const SURFACING_TOP_K = 3;
|
|
60
|
+
export const SURFACING_MIN_SCORE = 0.30;
|
|
61
|
+
export const SURFACING_CHAR_BUDGET = 1_000;
|
|
62
|
+
export const SURFACING_COOLDOWN_ORDINALS = 8;
|
|
63
|
+
export const SURFACING_OUTCOME_WINDOW_ORDINALS = 12;
|
|
64
|
+
export const SURFACING_RECENT_TASK_SPANS = 6;
|
|
65
|
+
export const SURFACING_MAX_TASK_CHARS = 12_000;
|
|
66
|
+
export const SURFACING_MAX_LOG_RECORDS = 128;
|
|
67
|
+
export const SURFACING_LEXICAL_WEIGHT = 0.80;
|
|
68
|
+
export const SURFACING_RECENCY_WEIGHT = 0.14;
|
|
69
|
+
export const SURFACING_DEPTH_WEIGHT = 0.06;
|
|
70
|
+
export const SURFACING_MAX_DEPTH = 4;
|
|
71
|
+
export const SURFACING_MAX_TEXT_CHARS = 220;
|
|
72
|
+
export const SURFACING_SOURCE_ID = "fold-brief";
|
|
73
|
+
|
|
74
|
+
// Conservative LOWER bound on UTF-8 bytes per provider token, used only to cap
|
|
75
|
+
// the protected byte tail as a share of a small window; never to estimate usage.
|
|
76
|
+
export const BYTES_PER_TOKEN_FLOOR = 2;
|
|
77
|
+
|
|
78
|
+
export const ACTIVE_CONTEXT_POLICY = Object.freeze({
|
|
79
|
+
freshTurns: 3,
|
|
80
|
+
freshBytes: 24_000,
|
|
81
|
+
freshWindowShare: 0.25,
|
|
82
|
+
warningRatio: 0.65,
|
|
83
|
+
toolFoldRatio: 0.75,
|
|
84
|
+
refoldRatio: 0.85,
|
|
85
|
+
prepareRatio: 0.90,
|
|
86
|
+
warmRatio: 0.55,
|
|
87
|
+
responseReserve: 16_384,
|
|
88
|
+
consolidationRatio: 0.85,
|
|
89
|
+
consolidationChildren: 5,
|
|
90
|
+
maxConsolidationChildren: 8,
|
|
91
|
+
minToolChars: 2_000,
|
|
92
|
+
minChapterChars: 4_000,
|
|
93
|
+
maxChapterChars: 128_000,
|
|
94
|
+
maxChapterTurns: 4,
|
|
95
|
+
maxSourceChars: 200_000,
|
|
96
|
+
maxFoldSourceRefs: 256,
|
|
97
|
+
maxBriefChars: 1_200,
|
|
98
|
+
briefTimeoutMs: 120_000,
|
|
99
|
+
orientationMessages: 2,
|
|
100
|
+
maxOrientationChars: 12_000,
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
export type FoldKind = "tool-result" | "chapter" | "consolidation";
|
|
104
|
+
export type FoldPart = { kind: "raw"; ref: EvidenceRef } | { kind: "fold"; foldId: string };
|
|
105
|
+
export type BriefProvenance =
|
|
106
|
+
| { kind: "supplied" }
|
|
107
|
+
| { kind: "deterministic" }
|
|
108
|
+
| {
|
|
109
|
+
kind: "model" | "luna";
|
|
110
|
+
provider: string;
|
|
111
|
+
model: string;
|
|
112
|
+
effort: string;
|
|
113
|
+
launchContractDigest?: string;
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
export interface ActiveFold {
|
|
117
|
+
id: string;
|
|
118
|
+
kind: FoldKind;
|
|
119
|
+
parentId: string | null;
|
|
120
|
+
parts: FoldPart[];
|
|
121
|
+
brief: string;
|
|
122
|
+
provenance: BriefProvenance;
|
|
123
|
+
sourceSha256: string;
|
|
124
|
+
sourceChars: number;
|
|
125
|
+
placeholderChars: number;
|
|
126
|
+
createdAt: number;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
export interface PreparedFold {
|
|
130
|
+
id: string;
|
|
131
|
+
sessionId: string;
|
|
132
|
+
generation: number;
|
|
133
|
+
branchSha256: string;
|
|
134
|
+
topologySha256: string;
|
|
135
|
+
protectionSha256: string;
|
|
136
|
+
sourceRefs: EvidenceRef[];
|
|
137
|
+
sourceSha256: string;
|
|
138
|
+
beforeRefs: EvidenceRef[];
|
|
139
|
+
beforeSha256: string;
|
|
140
|
+
afterRefs: EvidenceRef[];
|
|
141
|
+
afterSha256: string;
|
|
142
|
+
fold: ActiveFold;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
export type SurfacingOutcome = "shown" | "accept" | "reject";
|
|
146
|
+
|
|
147
|
+
/** One durable surfacing observation: what was shown, how it scored, and what the agent did. */
|
|
148
|
+
export interface SurfacingRecord {
|
|
149
|
+
source: string;
|
|
150
|
+
id: string;
|
|
151
|
+
score: number;
|
|
152
|
+
ordinal: number;
|
|
153
|
+
outcome: SurfacingOutcome;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/** One item a suggestion source offers for the shared carrier. */
|
|
157
|
+
export interface SurfacingCandidate {
|
|
158
|
+
source: string;
|
|
159
|
+
id: string;
|
|
160
|
+
text: string;
|
|
161
|
+
route: string;
|
|
162
|
+
alternateRoute?: string;
|
|
163
|
+
/** Transcript position used for recency; higher is more recent. Never a wall clock. */
|
|
164
|
+
position?: number;
|
|
165
|
+
depth?: number;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
export interface SurfacingSuggestion extends SurfacingCandidate {
|
|
169
|
+
score: number;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
export interface SuggestionSourceInput {
|
|
173
|
+
state: ActiveContextState;
|
|
174
|
+
snapshot: ActiveContextSnapshot;
|
|
175
|
+
toolName: string;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
export interface SuggestionSource {
|
|
179
|
+
id: string;
|
|
180
|
+
candidates: (input: SuggestionSourceInput) => SurfacingCandidate[];
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
export interface ActiveContextState {
|
|
184
|
+
version: 1;
|
|
185
|
+
sessionId: string;
|
|
186
|
+
revision: number;
|
|
187
|
+
folds: ActiveFold[];
|
|
188
|
+
expanded: string[];
|
|
189
|
+
protected: EvidenceRef[];
|
|
190
|
+
tokensSinceToolFold: number;
|
|
191
|
+
leases: Record<string, number>;
|
|
192
|
+
surfacing?: SurfacingRecord[];
|
|
193
|
+
prepared?: PreparedFold;
|
|
194
|
+
advisory?: {
|
|
195
|
+
highWater: number;
|
|
196
|
+
delivered: Record<string, number>;
|
|
197
|
+
armed?: { milestone: AdvisoryMilestone; threshold: number; scheduleKey: string };
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
export interface FoldRecordRef {
|
|
202
|
+
id: string;
|
|
203
|
+
sha256: string;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
export interface FoldRecordEntry {
|
|
207
|
+
version: 1;
|
|
208
|
+
sessionId: string;
|
|
209
|
+
foldId: string;
|
|
210
|
+
recordSha256: string;
|
|
211
|
+
fold: ActiveFold;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
export interface ActiveContextCheckpointV2 {
|
|
215
|
+
version: 2;
|
|
216
|
+
kind: "checkpoint";
|
|
217
|
+
sessionId: string;
|
|
218
|
+
revision: number;
|
|
219
|
+
foldRefs: FoldRecordRef[];
|
|
220
|
+
expanded: string[];
|
|
221
|
+
protected: EvidenceRef[];
|
|
222
|
+
prepared: PreparedFold | null;
|
|
223
|
+
tokensSinceToolFold?: number;
|
|
224
|
+
leases?: Record<string, number>;
|
|
225
|
+
surfacing?: SurfacingRecord[];
|
|
226
|
+
advisory?: NonNullable<ActiveContextState["advisory"]>;
|
|
227
|
+
stateSha256: string;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
export interface ActiveContextDeltaV2 {
|
|
231
|
+
version: 2;
|
|
232
|
+
kind: "delta";
|
|
233
|
+
sessionId: string;
|
|
234
|
+
revision: number;
|
|
235
|
+
baseRevision: number;
|
|
236
|
+
baseStateSha256: string;
|
|
237
|
+
addFoldRefs: FoldRecordRef[];
|
|
238
|
+
removeFoldIds: string[];
|
|
239
|
+
expanded: string[];
|
|
240
|
+
protected: EvidenceRef[];
|
|
241
|
+
prepared: PreparedFold | null;
|
|
242
|
+
tokensSinceToolFold?: number;
|
|
243
|
+
leases?: Record<string, number>;
|
|
244
|
+
surfacing?: SurfacingRecord[];
|
|
245
|
+
advisory?: NonNullable<ActiveContextState["advisory"]>;
|
|
246
|
+
stateSha256: string;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
export type ActiveContextStateWireV2 = ActiveContextCheckpointV2 | ActiveContextDeltaV2;
|
|
250
|
+
|
|
251
|
+
export interface MappedMessage {
|
|
252
|
+
index: number;
|
|
253
|
+
message: unknown;
|
|
254
|
+
ref: EvidenceRef | null;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
export interface BranchObject {
|
|
258
|
+
branchIndex: number;
|
|
259
|
+
message: unknown;
|
|
260
|
+
ref: EvidenceRef;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
export interface CompleteTurn {
|
|
264
|
+
start: number;
|
|
265
|
+
end: number;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
export interface ActiveContextSnapshot {
|
|
269
|
+
sessionId: string;
|
|
270
|
+
messages: unknown[];
|
|
271
|
+
mapped: MappedMessage[];
|
|
272
|
+
branchObjects: BranchObject[];
|
|
273
|
+
completeTurns: CompleteTurn[];
|
|
274
|
+
freshBoundary: number;
|
|
275
|
+
protectedIndices: Set<number>;
|
|
276
|
+
toolProtectedIndices: Set<number>;
|
|
277
|
+
policy: typeof ACTIVE_CONTEXT_POLICY;
|
|
278
|
+
toolName: string;
|
|
279
|
+
brandNoun: string;
|
|
280
|
+
entryTypePrefix: string;
|
|
281
|
+
readOnlyTools: ReadonlySet<string>;
|
|
282
|
+
contextWindow: number;
|
|
283
|
+
windowSource: "reported" | "fallback";
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
export interface FoldCandidate {
|
|
287
|
+
kind: FoldKind;
|
|
288
|
+
parts: FoldPart[];
|
|
289
|
+
sourceRefs: EvidenceRef[];
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
export const READ_ONLY_TOOLS_DEFAULT = new Set([
|
|
293
|
+
"read", "grep", "find", "ls",
|
|
294
|
+
]);
|
|
295
|
+
|
|
296
|
+
export type AdvisoryMilestone = "orientation" | "notice" | "tools" | "chapters" | "urgent";
|