@cortexkit/opencode-magic-context 0.22.5 → 0.23.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/dist/agents/magic-context-prompt.d.ts +1 -1
- package/dist/agents/magic-context-prompt.d.ts.map +1 -1
- package/dist/agents/permissions.d.ts +4 -4
- package/dist/agents/permissions.d.ts.map +1 -1
- package/dist/config/project-security.d.ts +5 -0
- package/dist/config/project-security.d.ts.map +1 -1
- package/dist/config/schema/magic-context.d.ts +0 -13
- package/dist/config/schema/magic-context.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/task-prompts.d.ts +1 -1
- package/dist/features/magic-context/dreamer/task-prompts.d.ts.map +1 -1
- package/dist/features/magic-context/memory/constants.d.ts +7 -0
- package/dist/features/magic-context/memory/constants.d.ts.map +1 -1
- package/dist/features/magic-context/migrations.d.ts.map +1 -1
- package/dist/features/magic-context/storage-db.d.ts +1 -1
- package/dist/features/magic-context/storage-db.d.ts.map +1 -1
- package/dist/features/magic-context/storage-meta-persisted.d.ts +83 -15
- package/dist/features/magic-context/storage-meta-persisted.d.ts.map +1 -1
- package/dist/features/magic-context/storage-meta-shared.d.ts +9 -2
- package/dist/features/magic-context/storage-meta-shared.d.ts.map +1 -1
- package/dist/features/magic-context/storage-meta.d.ts +1 -1
- package/dist/features/magic-context/storage-meta.d.ts.map +1 -1
- package/dist/features/magic-context/storage-notes.d.ts.map +1 -1
- package/dist/features/magic-context/storage-tags.d.ts +118 -1
- package/dist/features/magic-context/storage-tags.d.ts.map +1 -1
- package/dist/features/magic-context/storage.d.ts +2 -2
- package/dist/features/magic-context/storage.d.ts.map +1 -1
- package/dist/features/magic-context/tagger.d.ts +12 -2
- package/dist/features/magic-context/tagger.d.ts.map +1 -1
- package/dist/features/magic-context/tool-definition-tokens.d.ts +0 -21
- package/dist/features/magic-context/tool-definition-tokens.d.ts.map +1 -1
- package/dist/features/magic-context/tool-owner-backfill.d.ts +2 -1
- package/dist/features/magic-context/tool-owner-backfill.d.ts.map +1 -1
- package/dist/features/magic-context/types.d.ts +8 -0
- package/dist/features/magic-context/types.d.ts.map +1 -1
- package/dist/hooks/magic-context/apply-operations.d.ts.map +1 -1
- package/dist/hooks/magic-context/auto-search-runner.d.ts.map +1 -1
- package/dist/hooks/magic-context/channel2-delivery.d.ts +22 -0
- package/dist/hooks/magic-context/channel2-delivery.d.ts.map +1 -0
- package/dist/hooks/magic-context/command-handler.d.ts +0 -1
- package/dist/hooks/magic-context/command-handler.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner-incremental.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner-partial-recomp.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner-recomp.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner-types.d.ts +5 -0
- package/dist/hooks/magic-context/compartment-runner-types.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-trigger.d.ts +47 -2
- package/dist/hooks/magic-context/compartment-trigger.d.ts.map +1 -1
- package/dist/hooks/magic-context/ctx-reduce-availability.d.ts +18 -0
- package/dist/hooks/magic-context/ctx-reduce-availability.d.ts.map +1 -0
- package/dist/hooks/magic-context/ctx-reduce-nudge.d.ts +117 -0
- package/dist/hooks/magic-context/ctx-reduce-nudge.d.ts.map +1 -0
- package/dist/hooks/magic-context/emergency-drop.d.ts +86 -0
- package/dist/hooks/magic-context/emergency-drop.d.ts.map +1 -0
- package/dist/hooks/magic-context/event-handler.d.ts +6 -4
- package/dist/hooks/magic-context/event-handler.d.ts.map +1 -1
- package/dist/hooks/magic-context/execute-flush.d.ts.map +1 -1
- package/dist/hooks/magic-context/execute-status.d.ts +1 -1
- package/dist/hooks/magic-context/execute-status.d.ts.map +1 -1
- package/dist/hooks/magic-context/heuristic-cleanup.d.ts +10 -3
- package/dist/hooks/magic-context/heuristic-cleanup.d.ts.map +1 -1
- package/dist/hooks/magic-context/hook-handlers.d.ts +3 -9
- package/dist/hooks/magic-context/hook-handlers.d.ts.map +1 -1
- package/dist/hooks/magic-context/hook.d.ts +3 -5
- package/dist/hooks/magic-context/hook.d.ts.map +1 -1
- package/dist/hooks/magic-context/inject-compartments.d.ts +0 -2
- package/dist/hooks/magic-context/inject-compartments.d.ts.map +1 -1
- package/dist/hooks/magic-context/issue-135-wire-fixtures.d.ts +8 -0
- package/dist/hooks/magic-context/issue-135-wire-fixtures.d.ts.map +1 -0
- package/dist/hooks/magic-context/note-visibility.d.ts +1 -1
- package/dist/hooks/magic-context/openai-compat-adjacency.d.ts +38 -0
- package/dist/hooks/magic-context/openai-compat-adjacency.d.ts.map +1 -0
- package/dist/hooks/magic-context/protected-tail-boundary.d.ts +132 -0
- package/dist/hooks/magic-context/protected-tail-boundary.d.ts.map +1 -0
- package/dist/hooks/magic-context/read-session-chunk.d.ts +55 -0
- package/dist/hooks/magic-context/read-session-chunk.d.ts.map +1 -1
- package/dist/hooks/magic-context/read-session-formatting.d.ts.map +1 -1
- package/dist/hooks/magic-context/read-session-raw.d.ts +91 -0
- package/dist/hooks/magic-context/read-session-raw.d.ts.map +1 -1
- package/dist/hooks/magic-context/read-session-true-raw-tokens.d.ts +70 -0
- package/dist/hooks/magic-context/read-session-true-raw-tokens.d.ts.map +1 -0
- package/dist/hooks/magic-context/send-session-notification.d.ts +2 -1
- package/dist/hooks/magic-context/send-session-notification.d.ts.map +1 -1
- package/dist/hooks/magic-context/system-prompt-hash.d.ts +0 -1
- package/dist/hooks/magic-context/system-prompt-hash.d.ts.map +1 -1
- package/dist/hooks/magic-context/tag-messages.d.ts +3 -0
- package/dist/hooks/magic-context/tag-messages.d.ts.map +1 -1
- package/dist/hooks/magic-context/todo-view.d.ts +1 -1
- package/dist/hooks/magic-context/tool-drop-target.d.ts +9 -0
- package/dist/hooks/magic-context/tool-drop-target.d.ts.map +1 -1
- package/dist/hooks/magic-context/transform-compartment-phase.d.ts +15 -0
- package/dist/hooks/magic-context/transform-compartment-phase.d.ts.map +1 -1
- package/dist/hooks/magic-context/transform-postprocess-phase.d.ts +7 -10
- package/dist/hooks/magic-context/transform-postprocess-phase.d.ts.map +1 -1
- package/dist/hooks/magic-context/transform.d.ts +14 -17
- package/dist/hooks/magic-context/transform.d.ts.map +1 -1
- package/dist/hooks/magic-context/upgrade-reminder.d.ts +2 -1
- package/dist/hooks/magic-context/upgrade-reminder.d.ts.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5215 -1140
- package/dist/plugin/conflict-warning-hook.d.ts.map +1 -1
- package/dist/plugin/hooks/create-session-hooks.d.ts +1 -1
- package/dist/plugin/hooks/create-session-hooks.d.ts.map +1 -1
- package/dist/plugin/rpc-handlers.d.ts.map +1 -1
- package/dist/plugin/tool-registry.d.ts.map +1 -1
- package/dist/shared/announcement.d.ts +4 -6
- package/dist/shared/announcement.d.ts.map +1 -1
- package/dist/shared/live-server-client.d.ts +50 -0
- package/dist/shared/live-server-client.d.ts.map +1 -0
- package/dist/shared/prompt-context.d.ts +31 -0
- package/dist/shared/prompt-context.d.ts.map +1 -0
- package/dist/shared/rpc-types.d.ts +0 -3
- package/dist/shared/rpc-types.d.ts.map +1 -1
- package/dist/shared/safe-notification-target.d.ts +23 -0
- package/dist/shared/safe-notification-target.d.ts.map +1 -0
- package/dist/shared/tag-transcript.d.ts.map +1 -1
- package/dist/shared/transcript-opencode.d.ts.map +1 -1
- package/dist/shared/transcript.d.ts +15 -1
- package/dist/shared/transcript.d.ts.map +1 -1
- package/dist/tools/ctx-expand/constants.d.ts +1 -1
- package/dist/tools/ctx-expand/constants.d.ts.map +1 -1
- package/dist/tools/ctx-expand/tools.d.ts.map +1 -1
- package/dist/tools/ctx-memory/constants.d.ts +1 -1
- package/dist/tools/ctx-memory/constants.d.ts.map +1 -1
- package/dist/tools/ctx-memory/tools.d.ts.map +1 -1
- package/dist/tools/ctx-memory/types.d.ts +7 -3
- package/dist/tools/ctx-memory/types.d.ts.map +1 -1
- package/dist/tools/ctx-note/constants.d.ts +1 -1
- package/dist/tools/ctx-note/constants.d.ts.map +1 -1
- package/dist/tools/ctx-note/tools.d.ts.map +1 -1
- package/dist/tools/ctx-note/types.d.ts +4 -0
- package/dist/tools/ctx-note/types.d.ts.map +1 -1
- package/dist/tools/ctx-search/constants.d.ts +1 -1
- package/dist/tools/ctx-search/constants.d.ts.map +1 -1
- package/dist/tui/data/context-db.d.ts.map +1 -1
- package/package.json +2 -1
- package/src/shared/announcement.test.ts +18 -0
- package/src/shared/announcement.ts +35 -20
- package/src/shared/live-server-client.ts +152 -0
- package/src/shared/prompt-context.ts +135 -0
- package/src/shared/rpc-types.ts +0 -3
- package/src/shared/safe-notification-target.test.ts +97 -0
- package/src/shared/safe-notification-target.ts +102 -0
- package/src/shared/tag-transcript.test.ts +34 -8
- package/src/shared/tag-transcript.ts +110 -8
- package/src/shared/transcript-opencode.ts +15 -5
- package/src/shared/transcript.ts +20 -2
- package/src/tui/data/context-db.ts +0 -3
- package/src/tui/index.tsx +2 -5
- package/src/tui/slots/sidebar-content.tsx +1 -26
- package/dist/hooks/magic-context/apply-context-nudge.d.ts +0 -5
- package/dist/hooks/magic-context/apply-context-nudge.d.ts.map +0 -1
- package/dist/hooks/magic-context/nudge-bands.d.ts +0 -6
- package/dist/hooks/magic-context/nudge-bands.d.ts.map +0 -1
- package/dist/hooks/magic-context/nudge-injection.d.ts +0 -7
- package/dist/hooks/magic-context/nudge-injection.d.ts.map +0 -1
- package/dist/hooks/magic-context/nudge-placement-store.d.ts +0 -15
- package/dist/hooks/magic-context/nudge-placement-store.d.ts.map +0 -1
- package/dist/hooks/magic-context/nudger.d.ts +0 -21
- package/dist/hooks/magic-context/nudger.d.ts.map +0 -1
|
@@ -47,8 +47,15 @@
|
|
|
47
47
|
|
|
48
48
|
import type { ContextDatabase } from "../features/magic-context/storage";
|
|
49
49
|
import { saveSourceContent } from "../features/magic-context/storage-source";
|
|
50
|
-
import {
|
|
50
|
+
import {
|
|
51
|
+
updateTagByteSize,
|
|
52
|
+
updateTagInputByteSize,
|
|
53
|
+
updateTagInputTokenCount,
|
|
54
|
+
updateTagTokenCount,
|
|
55
|
+
} from "../features/magic-context/storage-tags";
|
|
51
56
|
import { makeToolCompositeKey, type Tagger } from "../features/magic-context/tagger";
|
|
57
|
+
import { estimateImageTokensFromDataUrl } from "../hooks/magic-context/image-token-estimate";
|
|
58
|
+
import { estimateTokens } from "../hooks/magic-context/read-session-formatting";
|
|
52
59
|
import {
|
|
53
60
|
byteSize,
|
|
54
61
|
prependTag,
|
|
@@ -112,10 +119,11 @@ export interface TagTranscriptResult {
|
|
|
112
119
|
/**
|
|
113
120
|
* Per-callId aggregation of tool occurrences across the transcript.
|
|
114
121
|
* Built up during the walk and used to:
|
|
115
|
-
* 1. Assign one tag per call_id with byte_size
|
|
116
|
-
*
|
|
117
|
-
* (
|
|
118
|
-
*
|
|
122
|
+
* 1. Assign one tag per call_id with byte_size = the tool_RESULT (output)
|
|
123
|
+
* size, and inputByteSize = the tool_use (args) size, tracked SEPARATELY
|
|
124
|
+
* (mirrors OpenCode tag-messages.ts). Reclaim accounting sums them
|
|
125
|
+
* (byteSize + inputByteSize + reasoning); folding args into byte_size too
|
|
126
|
+
* would double-count the args for a large-input/small-output tool.
|
|
119
127
|
* 2. Build a single aggregate TagTarget that mutates BOTH the
|
|
120
128
|
* invocation and result occurrences atomically, so a queued drop
|
|
121
129
|
* replaces both halves with a sentinel instead of last-write-wins.
|
|
@@ -131,10 +139,14 @@ interface ToolAggregate {
|
|
|
131
139
|
occurrences: ToolOccurrence[];
|
|
132
140
|
/** Largest byteSize seen across occurrences — used as the tag size. */
|
|
133
141
|
maxByteSize: number;
|
|
142
|
+
/** Token count paired with maxByteSize (the same output occurrence). */
|
|
143
|
+
maxTokenCount: number;
|
|
134
144
|
/** Tool name from the first occurrence we see one on. */
|
|
135
145
|
toolName: string | null;
|
|
136
146
|
/** Input byte size from the invocation occurrence (for storage projection). */
|
|
137
147
|
inputByteSize: number;
|
|
148
|
+
/** Whether input_token_count has been persisted (from the tool_use occurrence). */
|
|
149
|
+
inputTokenStored: boolean;
|
|
138
150
|
}
|
|
139
151
|
|
|
140
152
|
export function tagTranscript(
|
|
@@ -215,7 +227,9 @@ export function tagTranscript(
|
|
|
215
227
|
const callId = part.id;
|
|
216
228
|
const text = part.getText() ?? "";
|
|
217
229
|
const toolByteSize = getToolPartByteSize(part, text);
|
|
230
|
+
const toolTokenCount = getToolPartTokenCount(part, text);
|
|
218
231
|
const meta = part.getToolMetadata();
|
|
232
|
+
const inputTokenCount = meta.inputTokenCount;
|
|
219
233
|
|
|
220
234
|
if (typeof callId !== "string" || callId.length === 0) {
|
|
221
235
|
activeToolResultRun = undefined;
|
|
@@ -261,9 +275,19 @@ export function tagTranscript(
|
|
|
261
275
|
part,
|
|
262
276
|
kind: part.kind,
|
|
263
277
|
});
|
|
264
|
-
|
|
278
|
+
// byte_size tracks OUTPUT bytes only (the tool_result
|
|
279
|
+
// occurrence). The invocation args are captured separately in
|
|
280
|
+
// inputByteSize below; counting tool_use bytes here too would
|
|
281
|
+
// double-count args in the emergency-drop reclaim formula
|
|
282
|
+
// (byteSize + inputByteSize + reasoning). Mirrors OpenCode,
|
|
283
|
+
// which assigns the tool tag on the result path.
|
|
284
|
+
if (part.kind === "tool_result" && toolByteSize > existing.maxByteSize) {
|
|
265
285
|
existing.maxByteSize = toolByteSize;
|
|
286
|
+
existing.maxTokenCount = toolTokenCount;
|
|
266
287
|
updateTagByteSize(db, sessionId, existing.tagId, toolByteSize);
|
|
288
|
+
// Keep token_count in lockstep with the byte bump so the
|
|
289
|
+
// grown output's tokens aren't undercounted by readers.
|
|
290
|
+
updateTagTokenCount(db, sessionId, existing.tagId, toolTokenCount);
|
|
267
291
|
}
|
|
268
292
|
if (existing.toolName === null && meta.toolName) {
|
|
269
293
|
existing.toolName = meta.toolName;
|
|
@@ -276,6 +300,14 @@ export function tagTranscript(
|
|
|
276
300
|
existing.inputByteSize = meta.inputByteSize;
|
|
277
301
|
updateTagInputByteSize(db, sessionId, existing.tagId, meta.inputByteSize);
|
|
278
302
|
}
|
|
303
|
+
if (
|
|
304
|
+
!existing.inputTokenStored &&
|
|
305
|
+
part.kind === "tool_use" &&
|
|
306
|
+
inputTokenCount > 0
|
|
307
|
+
) {
|
|
308
|
+
existing.inputTokenStored = true;
|
|
309
|
+
updateTagInputTokenCount(db, sessionId, existing.tagId, inputTokenCount);
|
|
310
|
+
}
|
|
279
311
|
// Inject §N§ prefix into this tool_result occurrence
|
|
280
312
|
// (matches OpenCode behavior — only result gets the prefix).
|
|
281
313
|
if (!skipPrefixInjection && part.kind === "tool_result") {
|
|
@@ -299,15 +331,28 @@ export function tagTranscript(
|
|
|
299
331
|
// First occurrence for this owner+callId identity — reserve
|
|
300
332
|
// the tag number. Owner stays stable across passes because
|
|
301
333
|
// transcript message ids are durable.
|
|
334
|
+
// byte_size is OUTPUT-only (0 until the tool_result occurrence
|
|
335
|
+
// is seen); the invocation args live in inputByteSize. This
|
|
336
|
+
// keeps the emergency-drop reclaim formula (byteSize +
|
|
337
|
+
// inputByteSize + reasoning) from double-counting args when the
|
|
338
|
+
// first occurrence is a large tool_use. Mirrors OpenCode.
|
|
339
|
+
const outputByteSize = part.kind === "tool_result" ? toolByteSize : 0;
|
|
340
|
+
const outputTokenCount = part.kind === "tool_result" ? toolTokenCount : 0;
|
|
341
|
+
const firstInputTokenCount = part.kind === "tool_use" ? inputTokenCount : 0;
|
|
302
342
|
const tagId = tagger.assignToolTag(
|
|
303
343
|
sessionId,
|
|
304
344
|
callId,
|
|
305
345
|
messageId,
|
|
306
|
-
|
|
346
|
+
outputByteSize,
|
|
307
347
|
db,
|
|
308
348
|
0,
|
|
309
349
|
meta.toolName ?? null,
|
|
310
350
|
meta.inputByteSize,
|
|
351
|
+
() => ({
|
|
352
|
+
tokenCount: outputTokenCount,
|
|
353
|
+
inputTokenCount: firstInputTokenCount,
|
|
354
|
+
reasoningTokenCount: null,
|
|
355
|
+
}),
|
|
311
356
|
);
|
|
312
357
|
const aggregate = {
|
|
313
358
|
callId,
|
|
@@ -319,9 +364,11 @@ export function tagTranscript(
|
|
|
319
364
|
kind: part.kind,
|
|
320
365
|
},
|
|
321
366
|
],
|
|
322
|
-
maxByteSize:
|
|
367
|
+
maxByteSize: outputByteSize,
|
|
368
|
+
maxTokenCount: outputTokenCount,
|
|
323
369
|
toolName: meta.toolName ?? null,
|
|
324
370
|
inputByteSize: part.kind === "tool_use" ? meta.inputByteSize : 0,
|
|
371
|
+
inputTokenStored: part.kind === "tool_use" && firstInputTokenCount > 0,
|
|
325
372
|
};
|
|
326
373
|
toolAggregates.set(aggregateKey, aggregate);
|
|
327
374
|
if (part.kind === "tool_use") {
|
|
@@ -382,13 +429,48 @@ function markToolAggregateResolved(
|
|
|
382
429
|
openToolAggregateKeysByCallId.set(callId, nextPendingKeys);
|
|
383
430
|
}
|
|
384
431
|
|
|
432
|
+
/** Real-tokenizer count for tagged text (images bill by visual tokens). */
|
|
433
|
+
function estimateTagTextTokens(text: string): number {
|
|
434
|
+
if (!text) return 0;
|
|
435
|
+
if (text.startsWith("data:image/")) return estimateImageTokensFromDataUrl(text);
|
|
436
|
+
return estimateTokens(text);
|
|
437
|
+
}
|
|
438
|
+
|
|
385
439
|
function getToolPartByteSize(part: TranscriptPart, text: string): number {
|
|
386
440
|
const textByteSize = byteSize(text);
|
|
387
441
|
if (textByteSize > 0 || part.kind !== "tool_result") return textByteSize;
|
|
388
442
|
return getNonTextToolResultByteSize(part);
|
|
389
443
|
}
|
|
390
444
|
|
|
445
|
+
/**
|
|
446
|
+
* Real-tokenizer mirror of {@link getToolPartByteSize}: token count of a tool
|
|
447
|
+
* part's output text (falling back to the raw payload for non-text results,
|
|
448
|
+
* matching the byte path so token_count stays consistent with byte_size).
|
|
449
|
+
*/
|
|
450
|
+
function getToolPartTokenCount(part: TranscriptPart, text: string): number {
|
|
451
|
+
if (text.length > 0 || part.kind !== "tool_result") return estimateTokens(text);
|
|
452
|
+
const raw = part.rawByteSize?.();
|
|
453
|
+
if (typeof raw === "number" && raw > 0) {
|
|
454
|
+
const record = isRecord(part) ? part : undefined;
|
|
455
|
+
const content =
|
|
456
|
+
record?.content ??
|
|
457
|
+
record?.rawContent ??
|
|
458
|
+
record?.rawPart ??
|
|
459
|
+
record?.part ??
|
|
460
|
+
record?.data ??
|
|
461
|
+
record?.image ??
|
|
462
|
+
record?.source;
|
|
463
|
+
const serialized = safeJsonStringify(content ?? part);
|
|
464
|
+
return serialized === undefined ? 0 : estimateTokens(serialized);
|
|
465
|
+
}
|
|
466
|
+
return 0;
|
|
467
|
+
}
|
|
468
|
+
|
|
391
469
|
function getNonTextToolResultByteSize(part: TranscriptPart): number {
|
|
470
|
+
// Prefer the adapter's exact raw-payload size when available (Pi's
|
|
471
|
+
// tool_result proxy can serialize the real content array, incl. images).
|
|
472
|
+
const raw = part.rawByteSize?.();
|
|
473
|
+
if (typeof raw === "number" && raw > 0) return raw;
|
|
392
474
|
const record = isRecord(part) ? part : undefined;
|
|
393
475
|
const content =
|
|
394
476
|
record?.content ??
|
|
@@ -441,6 +523,13 @@ function tagTextPart(args: TagTextPartArgs): void {
|
|
|
441
523
|
null,
|
|
442
524
|
0,
|
|
443
525
|
args.entryFingerprint,
|
|
526
|
+
// Lazy: fires only on fresh insert. Strip any §N§ prefix so a re-tag
|
|
527
|
+
// from already-prefixed text still tokenizes the pristine content.
|
|
528
|
+
() => ({
|
|
529
|
+
tokenCount: estimateTagTextTokens(stripTagPrefix(text)),
|
|
530
|
+
inputTokenCount: null,
|
|
531
|
+
reasoningTokenCount: null,
|
|
532
|
+
}),
|
|
444
533
|
);
|
|
445
534
|
|
|
446
535
|
// Persist the original (pre-tagged) source content so caveman
|
|
@@ -490,6 +579,7 @@ function tagToolPart(args: TagToolPartArgs): void {
|
|
|
490
579
|
const contentId = stableId ?? `${args.messageId}:t${args.partIndex}`;
|
|
491
580
|
const text = args.part.getText() ?? "";
|
|
492
581
|
const toolByteSize = getToolPartByteSize(args.part, text);
|
|
582
|
+
const toolTokenCount = getToolPartTokenCount(args.part, text);
|
|
493
583
|
const meta = args.part.getToolMetadata();
|
|
494
584
|
// v3.3.1 Layer C: synthetic ownership for the no-callId Pi
|
|
495
585
|
// fallback. Owner == callId == contentId. The composite key
|
|
@@ -506,6 +596,11 @@ function tagToolPart(args: TagToolPartArgs): void {
|
|
|
506
596
|
0,
|
|
507
597
|
meta.toolName ?? null,
|
|
508
598
|
meta.inputByteSize,
|
|
599
|
+
() => ({
|
|
600
|
+
tokenCount: toolTokenCount,
|
|
601
|
+
inputTokenCount: meta.inputTokenCount,
|
|
602
|
+
reasoningTokenCount: null,
|
|
603
|
+
}),
|
|
509
604
|
);
|
|
510
605
|
|
|
511
606
|
// For tool parts, the visible payload is the tool result text. We
|
|
@@ -596,6 +691,13 @@ function buildAggregateTarget(tagId: number, occurrences: ToolOccurrence[]): Tag
|
|
|
596
691
|
}
|
|
597
692
|
return any ? "truncated" : "absent";
|
|
598
693
|
},
|
|
694
|
+
// Non-mutating reclaim predicate (Pi parity with OpenCode's canDrop).
|
|
695
|
+
// Pi sentinelizes BOTH halves, so unlike OpenCode there's no
|
|
696
|
+
// result-part requirement — a target reclaims as long as it still has
|
|
697
|
+
// at least one live occurrence to sentinelize.
|
|
698
|
+
canDrop(): boolean {
|
|
699
|
+
return occurrences.length > 0;
|
|
700
|
+
},
|
|
599
701
|
message: {
|
|
600
702
|
info: { id: messageId, role },
|
|
601
703
|
parts: [],
|
|
@@ -43,6 +43,7 @@
|
|
|
43
43
|
* tagging+drops layer to use Transcript instances.
|
|
44
44
|
*/
|
|
45
45
|
|
|
46
|
+
import { estimateTokens } from "../hooks/magic-context/read-session-formatting";
|
|
46
47
|
import { isRecord } from "./record-type-guard";
|
|
47
48
|
import type {
|
|
48
49
|
Transcript,
|
|
@@ -129,7 +130,11 @@ function createOpenCodePart(
|
|
|
129
130
|
setToolOutput(newText: string): boolean {
|
|
130
131
|
return writeOpenCodeToolOutput(rawPart, newText);
|
|
131
132
|
},
|
|
132
|
-
getToolMetadata(): {
|
|
133
|
+
getToolMetadata(): {
|
|
134
|
+
toolName: string | undefined;
|
|
135
|
+
inputByteSize: number;
|
|
136
|
+
inputTokenCount: number;
|
|
137
|
+
} {
|
|
133
138
|
return readOpenCodeToolMetadata(rawPart);
|
|
134
139
|
},
|
|
135
140
|
replaceWithSentinel(sentinelText: string): boolean {
|
|
@@ -227,9 +232,10 @@ function writeOpenCodeToolOutput(part: unknown, newText: string): boolean {
|
|
|
227
232
|
function readOpenCodeToolMetadata(part: unknown): {
|
|
228
233
|
toolName: string | undefined;
|
|
229
234
|
inputByteSize: number;
|
|
235
|
+
inputTokenCount: number;
|
|
230
236
|
} {
|
|
231
|
-
if (!isRecord(part)) return { toolName: undefined, inputByteSize: 0 };
|
|
232
|
-
if (part.type !== "tool") return { toolName: undefined, inputByteSize: 0 };
|
|
237
|
+
if (!isRecord(part)) return { toolName: undefined, inputByteSize: 0, inputTokenCount: 0 };
|
|
238
|
+
if (part.type !== "tool") return { toolName: undefined, inputByteSize: 0, inputTokenCount: 0 };
|
|
233
239
|
|
|
234
240
|
// OpenCode parts use `tool` as the tool name field; some legacy
|
|
235
241
|
// shapes use `toolName` or `name`. Match all three for forward
|
|
@@ -247,13 +253,17 @@ function readOpenCodeToolMetadata(part: unknown): {
|
|
|
247
253
|
const input = state?.input ?? part.args ?? part.input;
|
|
248
254
|
|
|
249
255
|
let inputByteSize = 0;
|
|
256
|
+
let inputTokenCount = 0;
|
|
250
257
|
if (input !== undefined && input !== null) {
|
|
251
258
|
try {
|
|
252
|
-
|
|
259
|
+
const serialized = typeof input === "string" ? input : JSON.stringify(input);
|
|
260
|
+
inputByteSize = serialized.length;
|
|
261
|
+
inputTokenCount = serialized ? estimateTokens(serialized) : 0;
|
|
253
262
|
} catch {
|
|
254
263
|
inputByteSize = 0;
|
|
264
|
+
inputTokenCount = 0;
|
|
255
265
|
}
|
|
256
266
|
}
|
|
257
267
|
|
|
258
|
-
return { toolName, inputByteSize };
|
|
268
|
+
return { toolName, inputByteSize, inputTokenCount };
|
|
259
269
|
}
|
package/src/shared/transcript.ts
CHANGED
|
@@ -121,10 +121,17 @@ export interface TranscriptPart {
|
|
|
121
121
|
* for non-tool parts.
|
|
122
122
|
* - inputByteSize: serialized argument size; used by historian
|
|
123
123
|
* pressure projection to estimate post-drop savings.
|
|
124
|
+
* - inputTokenCount: real-tokenizer count of the same serialized
|
|
125
|
+
* argument, stored on the tag so token-budget consumers SUM stored
|
|
126
|
+
* counts instead of re-tokenizing. 0 for non-tool parts.
|
|
124
127
|
*
|
|
125
|
-
* For non-tool parts both fields are undefined.
|
|
128
|
+
* For non-tool parts both byte fields are undefined/0.
|
|
126
129
|
*/
|
|
127
|
-
getToolMetadata(): {
|
|
130
|
+
getToolMetadata(): {
|
|
131
|
+
toolName: string | undefined;
|
|
132
|
+
inputByteSize: number;
|
|
133
|
+
inputTokenCount: number;
|
|
134
|
+
};
|
|
128
135
|
|
|
129
136
|
/**
|
|
130
137
|
* Replace this part with a sentinel placeholder. Sentinels look like
|
|
@@ -140,6 +147,17 @@ export interface TranscriptPart {
|
|
|
140
147
|
* replaced (e.g. it's already a sentinel, or it's an image part).
|
|
141
148
|
*/
|
|
142
149
|
replaceWithSentinel(sentinelText: string): boolean;
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Optional: serialized byte size of the part's REAL payload, including
|
|
153
|
+
* non-text content (images, structured data) that `getText()` can't
|
|
154
|
+
* surface. Used by emergency-drop reclaim accounting so an image-only
|
|
155
|
+
* tool result is sized by its actual payload, not treated as ~0 bytes.
|
|
156
|
+
* Adapters that can compute this (e.g. Pi's tool_result proxy, which
|
|
157
|
+
* closes over the raw content array) should implement it; callers fall
|
|
158
|
+
* back to the text/JSON estimate when it's absent.
|
|
159
|
+
*/
|
|
160
|
+
rawByteSize?(): number;
|
|
143
161
|
}
|
|
144
162
|
|
|
145
163
|
/**
|
|
@@ -186,7 +186,6 @@ export async function loadStatusDetail(
|
|
|
186
186
|
activeBytes: 0,
|
|
187
187
|
lastResponseTime: 0,
|
|
188
188
|
lastNudgeTokens: 0,
|
|
189
|
-
lastNudgeBand: "",
|
|
190
189
|
lastTransformError: null,
|
|
191
190
|
isSubagent: false,
|
|
192
191
|
pendingOps: [],
|
|
@@ -197,9 +196,7 @@ export async function loadStatusDetail(
|
|
|
197
196
|
executeThreshold: 65,
|
|
198
197
|
executeThresholdMode: "percentage",
|
|
199
198
|
protectedTagCount: 20,
|
|
200
|
-
nudgeInterval: 20000,
|
|
201
199
|
historyBudgetPercentage: 0.15,
|
|
202
|
-
nextNudgeAfter: 0,
|
|
203
200
|
historyBlockTokens: 0,
|
|
204
201
|
compressionBudget: null,
|
|
205
202
|
compressionUsage: null,
|
package/src/tui/index.tsx
CHANGED
|
@@ -385,12 +385,9 @@ const StatusDialog = (props: { api: TuiPluginApi; s: StatusDetail }) => {
|
|
|
385
385
|
</box>
|
|
386
386
|
{/* Right column */}
|
|
387
387
|
<box flexDirection="column" flexGrow={1} flexBasis={0}>
|
|
388
|
-
<text fg={t().text}><b>
|
|
388
|
+
<text fg={t().text}><b>Reductions</b></text>
|
|
389
389
|
<R t={t()} l="Execute threshold" v={`${formatThresholdPercent(s().executeThreshold)}%`} />
|
|
390
|
-
<R t={t()} l="
|
|
391
|
-
<R t={t()} l="Interval" v={`${fmt(s().nudgeInterval)} tok`} fg={t().textMuted} />
|
|
392
|
-
<R t={t()} l="Next nudge after" v={`${fmt(s().nextNudgeAfter)} tok`} />
|
|
393
|
-
{s().lastNudgeBand ? <R t={t()} l="Current band" v={s().lastNudgeBand} /> : null}
|
|
390
|
+
<R t={t()} l="Last reduce anchor" v={`${fmt(s().lastNudgeTokens)} tok`} />
|
|
394
391
|
<box marginTop={1}>
|
|
395
392
|
<text fg={t().text}><b>Context Details</b></text>
|
|
396
393
|
</box>
|
|
@@ -1,32 +1,16 @@
|
|
|
1
1
|
/** @jsxImportSource @opentui/solid */
|
|
2
|
-
import { appendFileSync } from "node:fs"
|
|
3
|
-
import { tmpdir } from "node:os"
|
|
4
|
-
import { join } from "node:path"
|
|
5
2
|
import { createEffect, createMemo, createSignal, on, onCleanup } from "solid-js"
|
|
6
3
|
import type { TuiSlotPlugin, TuiPluginApi, TuiThemeCurrent } from "@opencode-ai/plugin/tui"
|
|
7
4
|
import packageJson from "../../../package.json"
|
|
8
5
|
import { loadSidebarSnapshot, type SidebarSnapshot } from "../data/context-db"
|
|
9
6
|
import { formatThresholdPercent } from "../../shared/format-threshold"
|
|
10
7
|
|
|
11
|
-
// TEMP recomp-poll instrumentation (dogfood 2026-05-30). Writes to a dedicated
|
|
12
|
-
// file so we can trace the client poll loop the server log can't see. Remove
|
|
13
|
-
// once the freeze is diagnosed.
|
|
14
|
-
const RECOMP_TRACE = join(tmpdir(), "mc-recomp-trace.log")
|
|
15
|
-
function rtrace(msg: string): void {
|
|
16
|
-
try {
|
|
17
|
-
appendFileSync(RECOMP_TRACE, `[${new Date().toISOString()}] ${msg}\n`)
|
|
18
|
-
} catch {
|
|
19
|
-
// ignore
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
|
|
23
8
|
// Module-level hook so the upgrade/recomp dialog can kick the sidebar into its
|
|
24
9
|
// fast recomp self-poll the INSTANT the user confirms — without waiting for a
|
|
25
10
|
// parent-session message event (the RPC upgrade/recomp call fires none). The
|
|
26
|
-
// mounted SidebarContent registers its refresh here
|
|
11
|
+
// mounted SidebarContent registers its refresh here.
|
|
27
12
|
let activeRecompPollKick: (() => void) | null = null
|
|
28
13
|
export function kickRecompProgressRefresh(): void {
|
|
29
|
-
rtrace(`kickRecompProgressRefresh called; activeKick=${activeRecompPollKick ? "set" : "NULL"}`)
|
|
30
14
|
activeRecompPollKick?.()
|
|
31
15
|
}
|
|
32
16
|
|
|
@@ -473,9 +457,6 @@ const SidebarContent = (props: {
|
|
|
473
457
|
void loadSidebarSnapshot(sid, directory)
|
|
474
458
|
.then((data) => {
|
|
475
459
|
const phase = data?.recompProgress?.phase
|
|
476
|
-
rtrace(
|
|
477
|
-
`poll#${recompPollCount} phase=${phase ?? "ABSENT"} passCount=${data?.recompProgress?.passCount ?? "-"} note=${data?.recompProgress?.note ?? "-"} sawPhase=${recompSawPhase} absent=${recompConsecutiveAbsent}`,
|
|
478
|
-
)
|
|
479
460
|
// While a recomp is known-active, a transient snapshot that lost
|
|
480
461
|
// recompProgress (sticky cache / busy-DB empty) must NOT wipe the
|
|
481
462
|
// visible bar — carry the last good progress forward so it stays
|
|
@@ -499,7 +480,6 @@ const SidebarContent = (props: {
|
|
|
499
480
|
// Terminal state rendered — stop. The server keeps "done"/
|
|
500
481
|
// "skipped" for a grace window and "failed" until the next run,
|
|
501
482
|
// so the outcome stays visible without further polling.
|
|
502
|
-
rtrace(`STOP: terminal phase=${phase}`)
|
|
503
483
|
recompActive = false
|
|
504
484
|
} else {
|
|
505
485
|
// Phase absent this poll.
|
|
@@ -508,7 +488,6 @@ const SidebarContent = (props: {
|
|
|
508
488
|
// Still waiting for the server's first "Starting…".
|
|
509
489
|
if (recompPollCount < RECOMP_PROBE_MAX) scheduleRecompTick()
|
|
510
490
|
else {
|
|
511
|
-
rtrace("STOP: probe window exhausted, never saw phase")
|
|
512
491
|
recompActive = false
|
|
513
492
|
}
|
|
514
493
|
} else if (recompConsecutiveAbsent < RECOMP_ABSENT_GIVEUP) {
|
|
@@ -519,7 +498,6 @@ const SidebarContent = (props: {
|
|
|
519
498
|
scheduleRecompTick()
|
|
520
499
|
} else {
|
|
521
500
|
// Long continuous absence — the entry is genuinely gone.
|
|
522
|
-
rtrace("STOP: absent giveup")
|
|
523
501
|
recompActive = false
|
|
524
502
|
}
|
|
525
503
|
}
|
|
@@ -527,7 +505,6 @@ const SidebarContent = (props: {
|
|
|
527
505
|
.catch((err) => {
|
|
528
506
|
// CRITICAL: a failed/slow fetch must NOT kill the loop — keep
|
|
529
507
|
// polling while active so we still catch the terminal state.
|
|
530
|
-
rtrace(`poll#${recompPollCount} FETCH ERROR: ${String(err)}`)
|
|
531
508
|
scheduleRecompTick()
|
|
532
509
|
})
|
|
533
510
|
}
|
|
@@ -536,7 +513,6 @@ const SidebarContent = (props: {
|
|
|
536
513
|
// first detects an active recomp). The server emits an immediate "Starting…"
|
|
537
514
|
// entry; the probe window covers the brief RPC race before it lands.
|
|
538
515
|
function kickRecompPoll(): void {
|
|
539
|
-
rtrace(`kickRecompPoll: recompActive=${recompActive} (${recompActive ? "SKIP" : "starting"})`)
|
|
540
516
|
if (recompActive) return // already running
|
|
541
517
|
recompActive = true
|
|
542
518
|
recompSawPhase = false
|
|
@@ -546,7 +522,6 @@ const SidebarContent = (props: {
|
|
|
546
522
|
}
|
|
547
523
|
|
|
548
524
|
activeRecompPollKick = kickRecompPoll
|
|
549
|
-
rtrace("SidebarContent mounted; registered activeRecompPollKick")
|
|
550
525
|
|
|
551
526
|
onCleanup(() => {
|
|
552
527
|
if (refreshTimer) clearTimeout(refreshTimer)
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
import type { NudgePlacementStore } from "./nudge-placement-store";
|
|
2
|
-
import type { ContextNudge } from "./nudger";
|
|
3
|
-
import type { MessageLike } from "./tag-messages";
|
|
4
|
-
export declare function applyContextNudge(messages: MessageLike[], nudge: ContextNudge | null, nudgePlacements: NudgePlacementStore, sessionId: string): void;
|
|
5
|
-
//# sourceMappingURL=apply-context-nudge.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"apply-context-nudge.d.ts","sourceRoot":"","sources":["../../../src/hooks/magic-context/apply-context-nudge.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AACnE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAC7C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAElD,wBAAgB,iBAAiB,CAC7B,QAAQ,EAAE,WAAW,EAAE,EACvB,KAAK,EAAE,YAAY,GAAG,IAAI,EAC1B,eAAe,EAAE,mBAAmB,EACpC,SAAS,EAAE,MAAM,GAClB,IAAI,CAgCN"}
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
export type RollingNudgeBand = "far" | "near" | "urgent" | "critical";
|
|
2
|
-
export declare function getRollingNudgeBand(percentage: number, executeThresholdPercentage: number): RollingNudgeBand;
|
|
3
|
-
export declare function getRollingNudgeBandPriority(band: RollingNudgeBand | null): number;
|
|
4
|
-
export declare function formatRollingNudgeBand(band: RollingNudgeBand | null): string;
|
|
5
|
-
export declare function getRollingNudgeIntervalTokens(baseIntervalTokens: number, band: RollingNudgeBand): number;
|
|
6
|
-
//# sourceMappingURL=nudge-bands.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"nudge-bands.d.ts","sourceRoot":"","sources":["../../../src/hooks/magic-context/nudge-bands.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,gBAAgB,GAAG,KAAK,GAAG,MAAM,GAAG,QAAQ,GAAG,UAAU,CAAC;AAEtE,wBAAgB,mBAAmB,CAC/B,UAAU,EAAE,MAAM,EAClB,0BAA0B,EAAE,MAAM,GACnC,gBAAgB,CAWlB;AAED,wBAAgB,2BAA2B,CAAC,IAAI,EAAE,gBAAgB,GAAG,IAAI,GAAG,MAAM,CAajF;AAED,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,gBAAgB,GAAG,IAAI,GAAG,MAAM,CAE5E;AAED,wBAAgB,6BAA6B,CACzC,kBAAkB,EAAE,MAAM,EAC1B,IAAI,EAAE,gBAAgB,GACvB,MAAM,CAWR"}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import type { NudgePlacementStore } from "./nudge-placement-store";
|
|
2
|
-
import type { MessageLike } from "./tag-messages";
|
|
3
|
-
export declare function reinjectNudgeAtAnchor(messages: MessageLike[], nudgeText: string, nudgePlacements: NudgePlacementStore, sessionId: string): boolean;
|
|
4
|
-
export declare function appendNudgeToAssistant(messages: MessageLike[], nudge: string, nudgePlacements: NudgePlacementStore, sessionId: string): void;
|
|
5
|
-
export declare function appendSupplementalNudgeToAssistant(messages: MessageLike[], nudge: string, nudgePlacements: NudgePlacementStore, sessionId: string): boolean;
|
|
6
|
-
export declare function canAppendSupplementalNudgeToAssistant(messages: MessageLike[], nudgePlacements: NudgePlacementStore, sessionId: string): boolean;
|
|
7
|
-
//# sourceMappingURL=nudge-injection.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"nudge-injection.d.ts","sourceRoot":"","sources":["../../../src/hooks/magic-context/nudge-injection.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AACnE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AA6ElD,wBAAgB,qBAAqB,CACjC,QAAQ,EAAE,WAAW,EAAE,EACvB,SAAS,EAAE,MAAM,EACjB,eAAe,EAAE,mBAAmB,EACpC,SAAS,EAAE,MAAM,GAClB,OAAO,CA+CT;AAED,wBAAgB,sBAAsB,CAClC,QAAQ,EAAE,WAAW,EAAE,EACvB,KAAK,EAAE,MAAM,EACb,eAAe,EAAE,mBAAmB,EACpC,SAAS,EAAE,MAAM,GAClB,IAAI,CAmDN;AAED,wBAAgB,kCAAkC,CAC9C,QAAQ,EAAE,WAAW,EAAE,EACvB,KAAK,EAAE,MAAM,EACb,eAAe,EAAE,mBAAmB,EACpC,SAAS,EAAE,MAAM,GAClB,OAAO,CA4BT;AAED,wBAAgB,qCAAqC,CACjD,QAAQ,EAAE,WAAW,EAAE,EACvB,eAAe,EAAE,mBAAmB,EACpC,SAAS,EAAE,MAAM,GAClB,OAAO,CAMT"}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import type { Database } from "../../shared/sqlite";
|
|
2
|
-
interface NudgePlacement {
|
|
3
|
-
messageId: string;
|
|
4
|
-
nudgeText: string;
|
|
5
|
-
}
|
|
6
|
-
export interface NudgePlacementStore {
|
|
7
|
-
set(sessionId: string, messageId: string, nudgeText: string): void;
|
|
8
|
-
get(sessionId: string): NudgePlacement | null;
|
|
9
|
-
clear(sessionId: string, options?: {
|
|
10
|
-
persist?: boolean;
|
|
11
|
-
}): void;
|
|
12
|
-
}
|
|
13
|
-
export declare function createNudgePlacementStore(db?: Database): NudgePlacementStore;
|
|
14
|
-
export {};
|
|
15
|
-
//# sourceMappingURL=nudge-placement-store.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"nudge-placement-store.d.ts","sourceRoot":"","sources":["../../../src/hooks/magic-context/nudge-placement-store.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAEpD,UAAU,cAAc;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,mBAAmB;IAChC,GAAG,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACnE,GAAG,CAAC,SAAS,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI,CAAC;IAC9C,KAAK,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI,CAAC;CACnE;AAED,wBAAgB,yBAAyB,CAAC,EAAE,CAAC,EAAE,QAAQ,GAAG,mBAAmB,CAgC5E"}
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import { getOrCreateSessionMeta, type getTopNBySize } from "../../features/magic-context/storage";
|
|
2
|
-
import type { ContextUsage, SessionMeta, TagEntry } from "../../features/magic-context/types";
|
|
3
|
-
type ContextDatabase = Parameters<typeof getOrCreateSessionMeta>[0];
|
|
4
|
-
export type ContextNudge = {
|
|
5
|
-
type: "assistant";
|
|
6
|
-
text: string;
|
|
7
|
-
};
|
|
8
|
-
export declare const RECENT_CTX_REDUCE_WINDOW_MS: number;
|
|
9
|
-
export declare function createNudger(config: {
|
|
10
|
-
protected_tags: number;
|
|
11
|
-
nudge_interval_tokens: number;
|
|
12
|
-
iteration_nudge_threshold: number;
|
|
13
|
-
execute_threshold_percentage: number | {
|
|
14
|
-
default: number;
|
|
15
|
-
[modelKey: string]: number;
|
|
16
|
-
};
|
|
17
|
-
now?: () => number;
|
|
18
|
-
recentReduceBySession?: Map<string, number>;
|
|
19
|
-
}): (sessionId: string, contextUsage: ContextUsage, db: ContextDatabase, topNFn: typeof getTopNBySize, preloadedTags?: TagEntry[], messagesSinceLastUser?: number, preloadedSessionMeta?: SessionMeta) => ContextNudge | null;
|
|
20
|
-
export {};
|
|
21
|
-
//# sourceMappingURL=nudger.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"nudger.d.ts","sourceRoot":"","sources":["../../../src/hooks/magic-context/nudger.ts"],"names":[],"mappings":"AAAA,OAAO,EAEH,sBAAsB,EAEtB,KAAK,aAAa,EAErB,MAAM,sCAAsC,CAAC;AAC9C,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,oCAAoC,CAAC;AAY9F,KAAK,eAAe,GAAG,UAAU,CAAC,OAAO,sBAAsB,CAAC,CAAC,CAAC,CAAC,CAAC;AACpE,MAAM,MAAM,YAAY,GAAG;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAC/D,eAAO,MAAM,2BAA2B,QAAgB,CAAC;AA+BzD,wBAAgB,YAAY,CAAC,MAAM,EAAE;IACjC,cAAc,EAAE,MAAM,CAAC;IACvB,qBAAqB,EAAE,MAAM,CAAC;IAC9B,yBAAyB,EAAE,MAAM,CAAC;IAClC,4BAA4B,EAAE,MAAM,GAAG;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAC;IACvF,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB,qBAAqB,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC/C,IAIO,WAAW,MAAM,EACjB,cAAc,YAAY,EAC1B,IAAI,eAAe,EACnB,QAAQ,OAAO,aAAa,EAC5B,gBAAgB,QAAQ,EAAE,EAC1B,wBAAwB,MAAM,EAC9B,uBAAuB,WAAW,KACnC,YAAY,GAAG,IAAI,CA2IzB"}
|