@gajae-code/coding-agent 0.12.18 → 0.12.20
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/CHANGELOG.md +26 -9
- package/dist/types/commands/gc.d.ts +4 -0
- package/dist/types/commands/sdk.d.ts +66 -0
- package/dist/types/config/settings-schema.d.ts +34 -0
- package/dist/types/gjc-runtime/gc-runtime.d.ts +97 -1
- package/dist/types/modes/acp/acp-agent.d.ts +33 -1
- package/dist/types/modes/components/bash-execution.d.ts +7 -0
- package/dist/types/modes/components/eval-execution.d.ts +7 -0
- package/dist/types/modes/utils/ui-helpers.d.ts +10 -1
- package/dist/types/sdk/acp/adapter.d.ts +9 -17
- package/dist/types/sdk/acp/index.d.ts +1 -1
- package/dist/types/sdk/broker/broker.d.ts +93 -1
- package/dist/types/sdk/broker/ensure.d.ts +17 -0
- package/dist/types/sdk/broker/index.d.ts +1 -0
- package/dist/types/sdk/broker/lifecycle-ledger.d.ts +10 -1
- package/dist/types/sdk/broker/lifecycle.d.ts +81 -2
- package/dist/types/sdk/broker/startup-budget.d.ts +44 -0
- package/dist/types/sdk/bus/chat-daemon-control.d.ts +7 -1
- package/dist/types/sdk/bus/chat-daemon-runtime.d.ts +11 -1
- package/dist/types/sdk/bus/discord-daemon.d.ts +1 -0
- package/dist/types/sdk/bus/index.d.ts +20 -9
- package/dist/types/sdk/bus/prompt-reconciliation.d.ts +2 -6
- package/dist/types/sdk/bus/slack-daemon.d.ts +2 -2
- package/dist/types/sdk/bus/telegram-daemon-contract.d.ts +4 -2
- package/dist/types/sdk/host/query/revision-store.d.ts +5 -0
- package/dist/types/sdk/host/session-runtime.d.ts +4 -0
- package/dist/types/sdk/lifecycle-session.d.ts +13 -2
- package/dist/types/sdk/prompt-failure.d.ts +13 -0
- package/dist/types/sdk/prompt-watchdog.d.ts +82 -0
- package/dist/types/sdk/session-reconnect.d.ts +20 -0
- package/dist/types/sdk/startup-capability.d.ts +1 -1
- package/dist/types/session/agent-session.d.ts +14 -4
- package/dist/types/session/blob-store.d.ts +32 -0
- package/dist/types/session/internal/managed-session-storage.d.ts +40 -2
- package/dist/types/session/internal/session-memory-sidecar.d.ts +881 -0
- package/dist/types/session/session-manager.d.ts +301 -27
- package/dist/types/session/session-storage.d.ts +170 -0
- package/dist/types/task/executor.d.ts +2 -1
- package/dist/types/tools/bash.d.ts +1 -0
- package/dist/types/tui/output-block.d.ts +6 -0
- package/package.json +8 -8
- package/src/cli/args.ts +75 -34
- package/src/commands/acp.ts +7 -1
- package/src/commands/gc.ts +31 -2
- package/src/commands/sdk.ts +141 -7
- package/src/config/settings-schema.ts +43 -0
- package/src/coordinator-mcp/server.ts +6 -1
- package/src/export/html/index.ts +83 -39
- package/src/gjc-runtime/gc-runtime.ts +1283 -4
- package/src/internal-urls/docs-index.generated.ts +1 -1
- package/src/internal-urls/local-protocol.ts +14 -0
- package/src/main.ts +40 -9
- package/src/modes/acp/acp-agent.ts +564 -37
- package/src/modes/acp/terminal-auth.ts +2 -2
- package/src/modes/components/bash-execution.ts +14 -0
- package/src/modes/components/eval-execution.ts +14 -0
- package/src/modes/controllers/command-controller.ts +63 -8
- package/src/modes/utils/ui-helpers.ts +81 -11
- package/src/sdk/acp/adapter.ts +46 -45
- package/src/sdk/acp/index.ts +1 -1
- package/src/sdk/broker/broker.ts +392 -11
- package/src/sdk/broker/ensure.ts +131 -61
- package/src/sdk/broker/index.ts +1 -0
- package/src/sdk/broker/lifecycle-ledger.ts +59 -5
- package/src/sdk/broker/lifecycle.ts +278 -63
- package/src/sdk/broker/startup-budget.ts +103 -0
- package/src/sdk/bus/chat-daemon-control.ts +9 -3
- package/src/sdk/bus/chat-daemon-runtime.ts +565 -29
- package/src/sdk/bus/conversation-store.ts +1 -1
- package/src/sdk/bus/discord-daemon.ts +2 -1
- package/src/sdk/bus/discord-live-provider.ts +34 -6
- package/src/sdk/bus/index.ts +118 -20
- package/src/sdk/bus/kind-aware-reconciliation.ts +2 -1
- package/src/sdk/bus/prompt-reconciliation.ts +4 -9
- package/src/sdk/bus/slack-daemon.ts +91 -18
- package/src/sdk/bus/telegram-daemon-contract.ts +4 -2
- package/src/sdk/bus/topic-registry.ts +7 -1
- package/src/sdk/cli/session-cli.ts +8 -1
- package/src/sdk/host/query/handlers.ts +1 -1
- package/src/sdk/host/query/revision-store.ts +48 -12
- package/src/sdk/host/session-runtime.test.ts +50 -0
- package/src/sdk/host/session-runtime.ts +12 -2
- package/src/sdk/lifecycle-session.ts +26 -3
- package/src/sdk/mcp/server.ts +6 -1
- package/src/sdk/prompt-failure.ts +42 -0
- package/src/sdk/prompt-watchdog.ts +162 -0
- package/src/sdk/session-reconnect.ts +43 -0
- package/src/sdk/startup-capability.ts +13 -4
- package/src/session/agent-session.ts +525 -222
- package/src/session/blob-store.ts +89 -0
- package/src/session/internal/managed-session-scope.ts +36 -26
- package/src/session/internal/managed-session-storage.ts +303 -32
- package/src/session/internal/session-memory-sidecar.ts +2160 -0
- package/src/session/session-manager.ts +7027 -394
- package/src/session/session-storage.ts +1134 -11
- package/src/task/executor.ts +17 -4
- package/src/tools/bash.ts +109 -7
- package/src/tools/find.ts +55 -26
- package/src/tools/todo-contract.ts +40 -8
- package/src/tui/output-block.ts +11 -1
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import * as crypto from "node:crypto";
|
|
1
2
|
import { type AgentMessage } from "@gajae-code/agent-core";
|
|
2
3
|
import type { ConfiguredModelChainEntry as SharedConfiguredModelChainEntry } from "@gajae-code/agent-core/compaction";
|
|
3
4
|
import type { ImageContent, Message, MessageAttribution, ServiceTier, TextContent } from "@gajae-code/ai/core";
|
|
@@ -7,7 +8,8 @@ import type { ManagedLegacyLocalMigrationSource } from "../internal-urls/local-p
|
|
|
7
8
|
import { ArtifactManager } from "./artifacts";
|
|
8
9
|
import { type BlobPutResult, BlobStore } from "./blob-store";
|
|
9
10
|
import { type ManagedMigrationPolicy } from "./internal/managed-session-scope";
|
|
10
|
-
import { type ManagedDirectoryRoot, ManagedSessionDescendantStore } from "./internal/managed-session-storage";
|
|
11
|
+
import { type ManagedBoundedAppendExpectation, type ManagedDirectoryRoot, ManagedSessionDescendantStore } from "./internal/managed-session-storage";
|
|
12
|
+
import { type BaseAnchor, BoundedLabelsPinsStore, type CommittedTail, type DescriptorSnapshot, type DictionaryPartitionCommit, FixedCacheAccount, type MetadataDeltaValue, type ParentBucketCommit, type ReducerState, type ReopenClassification, SessionMemoryAccountant } from "./internal/session-memory-sidecar";
|
|
11
13
|
import { type MemoryGuardCreateCheckpointInput, type MemoryGuardParticipantIngressLease, type MemoryGuardRestoreInput, type MemoryGuardRestoreResult, type MemoryGuardSessionManagerCheckpointV1 } from "./memory-guard-checkpoint-participant";
|
|
12
14
|
import { type BashExecutionMessage, type CustomMessage, type FileMentionMessage, type HookMessage, type PythonExecutionMessage } from "./messages";
|
|
13
15
|
import { type SessionManagerReadAccess, sessionManagerReadCapability } from "./session-manager-internal";
|
|
@@ -84,6 +86,48 @@ export interface SessionManagerObservabilityStats {
|
|
|
84
86
|
materializedCacheDemotedCount: number;
|
|
85
87
|
pathOnlyContextBuildCount: number;
|
|
86
88
|
}
|
|
89
|
+
export interface SessionMemoryStats {
|
|
90
|
+
sidecarEnabled: boolean;
|
|
91
|
+
coldRetirementActive: boolean;
|
|
92
|
+
sidecarIneligible: boolean;
|
|
93
|
+
hotRegionBytes: number;
|
|
94
|
+
metaDescriptorBytes: number;
|
|
95
|
+
totalAccountedBytes: number;
|
|
96
|
+
lastReopenTransition: ReopenClassification | undefined;
|
|
97
|
+
currentCommitTransition: ReopenClassification | undefined;
|
|
98
|
+
lazyReopenAttempted: boolean;
|
|
99
|
+
lazyReopenSucceeded: boolean;
|
|
100
|
+
lazyReopenFallbackReason: string | undefined;
|
|
101
|
+
retirementFallbackReason: string | undefined;
|
|
102
|
+
autoDisabledReason: string | undefined;
|
|
103
|
+
consecutiveBuildFailures: number;
|
|
104
|
+
/** Persistent bounded parent→children artifact is adopted and usable. */
|
|
105
|
+
parentArtifactEnabled: boolean;
|
|
106
|
+
/** Persistent bounded dictionary artifact is adopted and usable. */
|
|
107
|
+
dictionaryArtifactEnabled: boolean;
|
|
108
|
+
/** Reducer-bucket bytes retained by metadata-delta descriptors (fixed accounting). */
|
|
109
|
+
metadataDeltaDescriptorBytes: number;
|
|
110
|
+
/** Live cold index bytes (descriptor size when proven, else 0). */
|
|
111
|
+
coldIndexBytes: number;
|
|
112
|
+
/** Live cold block-cache allocated bytes. */
|
|
113
|
+
coldIndexBlockCacheBytes: number;
|
|
114
|
+
/** Live cold entry-cache allocated bytes. */
|
|
115
|
+
coldEntryCacheBytes: number;
|
|
116
|
+
/** Live observability counters (P7 contract). */
|
|
117
|
+
coldEntriesRetired: number;
|
|
118
|
+
coldEntriesReloaded: number;
|
|
119
|
+
rangeReadCount: number;
|
|
120
|
+
rangeReadGenerationMismatchCount: number;
|
|
121
|
+
sidecarRebuildCount: number;
|
|
122
|
+
coldMutationPromotions: number;
|
|
123
|
+
hotOverflowTransitions: number;
|
|
124
|
+
labelDiskFallbackCount: number;
|
|
125
|
+
/** Shadow-mode eager-vs-sidecar parity mismatches observed at build time (AC10 telemetry). */
|
|
126
|
+
shadowParityMismatchCount: number;
|
|
127
|
+
/** Shadow-mode parity comparisons performed at build time (AC10 telemetry). */
|
|
128
|
+
shadowParityCheckCount: number;
|
|
129
|
+
transcriptGeneration: number;
|
|
130
|
+
}
|
|
87
131
|
export interface SessionMessageEntry extends SessionEntryBase {
|
|
88
132
|
type: "message";
|
|
89
133
|
message: AgentMessage;
|
|
@@ -256,14 +300,179 @@ export interface EntryPatchRecord {
|
|
|
256
300
|
export type SessionPatchRecord = HeaderPatchRecord | EntryPatchRecord;
|
|
257
301
|
/** Resolved file entries; patch records are applied by parseSessionEntries(). */
|
|
258
302
|
export type FileEntry = SessionHeader | SessionEntry;
|
|
303
|
+
/**
|
|
304
|
+
* Cold-region placeholder envelope for a retired entry. The heavy payload was moved
|
|
305
|
+
* out of RAM into the disposable `.spill.idx`/`.spill.tail` cold region; the exact
|
|
306
|
+
* transcript byte range is recorded so the entry can be lazily resolved by
|
|
307
|
+
* `ordinal`/`id`. Never persisted; used only while a cold sidecar region is active.
|
|
308
|
+
*/
|
|
309
|
+
export interface SessionColdRefEntry extends SessionEntryBase {
|
|
310
|
+
type: "session_cold_ref";
|
|
311
|
+
ordinal: number;
|
|
312
|
+
seq: number;
|
|
313
|
+
byteOffset: number;
|
|
314
|
+
byteLength: number;
|
|
315
|
+
}
|
|
316
|
+
/** One cold entry's transcript location, keyed by entry id. */
|
|
317
|
+
export interface ColdEntryIndex {
|
|
318
|
+
ordinal: number;
|
|
319
|
+
seq: number;
|
|
320
|
+
byteOffset: number;
|
|
321
|
+
byteLength: number;
|
|
322
|
+
recordDigest: string;
|
|
323
|
+
parentId?: string | null;
|
|
324
|
+
entryType?: string;
|
|
325
|
+
}
|
|
326
|
+
export interface SessionMemorySidecarRuntime {
|
|
327
|
+
/** Transcript v5 remains authoritative; sidecars are disposable/rebuildable. */
|
|
328
|
+
enabled: boolean;
|
|
329
|
+
/** Set when duplicate record IDs were detected; session stays eager. */
|
|
330
|
+
sidecarIneligible: boolean;
|
|
331
|
+
base: BaseAnchor;
|
|
332
|
+
tail: CommittedTail;
|
|
333
|
+
/** Bounded hot index cache; authoritative lookup falls back to the disk index. */
|
|
334
|
+
coldEntries: Map<string, ColdEntryIndex>;
|
|
335
|
+
indexPath: string;
|
|
336
|
+
tailPath: string;
|
|
337
|
+
commitPath: string;
|
|
338
|
+
/** Directory prefix of the persistent `.spill.parent-<bucket>` bucket files. */
|
|
339
|
+
parentPathPrefix: string;
|
|
340
|
+
/** Directory prefix of the persistent `.spill.dict-part-<partition>` partition files. */
|
|
341
|
+
dictionaryPathPrefix: string;
|
|
342
|
+
/** Path of the persistent `.spill.dict-meta` finalization file. */
|
|
343
|
+
dictionaryMetaPath: string;
|
|
344
|
+
/** Path of the persistent `.spill.metadata-delta` section. */
|
|
345
|
+
metadataDeltaPath: string;
|
|
346
|
+
retirementFirstKeptEntryId: string | undefined;
|
|
347
|
+
/** Hot-suffix byte total (accountant-bounded to ≤ 16 MiB). */
|
|
348
|
+
hotSuffixBytes: number;
|
|
349
|
+
accountant: SessionMemoryAccountant;
|
|
350
|
+
reducer: ReducerState;
|
|
351
|
+
/** Resident inline provider-affecting entries (merged order minus demoted slots). */
|
|
352
|
+
providerStateEntries: SessionEntry[];
|
|
353
|
+
/** Merged provider-list order as keys (inline + demoted); reopened/appended slots stay exact. */
|
|
354
|
+
providerStateOrder: string[];
|
|
355
|
+
blockCache: FixedCacheAccount;
|
|
356
|
+
parentChildrenCache: Map<string, {
|
|
357
|
+
ids: readonly string[];
|
|
358
|
+
bytes: number;
|
|
359
|
+
descriptor: SessionStorageStat;
|
|
360
|
+
bucketDescriptor?: SessionStorageStat;
|
|
361
|
+
bucketIndex?: number;
|
|
362
|
+
}>;
|
|
363
|
+
entryCache: FixedCacheAccount;
|
|
364
|
+
tailCache: FixedCacheAccount;
|
|
365
|
+
labelsPins: BoundedLabelsPinsStore;
|
|
366
|
+
terminalTransition: ReopenClassification | undefined;
|
|
367
|
+
reopenTransition: ReopenClassification | undefined;
|
|
368
|
+
/** SHA-256 over the exact `.spill.idx` bytes this runtime has written/adopted ("" until proven). */
|
|
369
|
+
indexDigest: string;
|
|
370
|
+
/** Descriptor of the exact index bytes whose digest was validated for cache use. */
|
|
371
|
+
validatedIndexDescriptor?: SessionStorageStat;
|
|
372
|
+
/** Live running hash of the index bytes; updated on every index append. */
|
|
373
|
+
indexHash: crypto.Hash;
|
|
374
|
+
/** Persistent bounded parent→children artifact state; absent = parent lookups fail closed. */
|
|
375
|
+
parentArtifact?: ParentArtifactRuntimeState;
|
|
376
|
+
/** Persistent bounded dictionary artifact state; absent = dictionary lookups fail closed to the cold scan. */
|
|
377
|
+
dictionary?: DictionaryArtifactRuntimeState;
|
|
378
|
+
/** Persistent metadata-delta section state; absent = no demoted provider values. */
|
|
379
|
+
metadataDelta?: MetadataDeltaArtifactRuntimeState;
|
|
380
|
+
/** Lazily built 24-bit fingerprints for O(1) fail-closed ID generation when no persistent dictionary exists. */
|
|
381
|
+
coldIdHashes?: BoundedColdIdHashSet;
|
|
382
|
+
coldIdHashesDescriptor?: SessionStorageStat;
|
|
383
|
+
/** Live observability counters (P7 live-only contract). */
|
|
384
|
+
coldEntriesRetired: number;
|
|
385
|
+
coldEntriesReloaded: number;
|
|
386
|
+
rangeReadCount: number;
|
|
387
|
+
rangeReadGenerationMismatchCount: number;
|
|
388
|
+
sidecarRebuildCount: number;
|
|
389
|
+
coldMutationPromotions: number;
|
|
390
|
+
hotOverflowTransitions: number;
|
|
391
|
+
labelDiskFallbackCount: number;
|
|
392
|
+
/** Shadow-mode eager-vs-sidecar parity mismatches observed at build time (AC10 telemetry). */
|
|
393
|
+
shadowParityMismatchCount: number;
|
|
394
|
+
/** Shadow-mode parity comparisons performed at build time (AC10 telemetry). */
|
|
395
|
+
shadowParityCheckCount: number;
|
|
396
|
+
transcriptGeneration: number;
|
|
397
|
+
}
|
|
398
|
+
/** Retained runtime state of the disposable parent→children artifact (block-cache charged). */
|
|
399
|
+
interface ParentArtifactRuntimeState {
|
|
400
|
+
/** Exact `.spill.idx` digest the artifact covers; artifact lookups require `indexDigest === runtime.indexDigest`. */
|
|
401
|
+
indexDigest: string;
|
|
402
|
+
/** Committed per-bucket exact-byte size + sha256, updated incrementally on append. */
|
|
403
|
+
buckets: ParentBucketCommit[];
|
|
404
|
+
/** Total artifact bytes (sum of bucket sizes). */
|
|
405
|
+
totalBytes: number;
|
|
406
|
+
/** Block-cache bytes charged for this retained state; released on invalidation/wholesale release. */
|
|
407
|
+
chargedBytes: number;
|
|
408
|
+
/** On-disk byte cap enforced on append; fixed at `PARENT_CHILDREN_BUDGET_BYTES` unless a test shrinks it. */
|
|
409
|
+
budgetBytes: number;
|
|
410
|
+
}
|
|
411
|
+
/** Retained runtime state of the disposable dictionary artifact (block-cache charged). */
|
|
412
|
+
interface DictionaryArtifactRuntimeState {
|
|
413
|
+
/** Exact `.spill.idx` digest the artifact covers; lookups require `indexDigest === runtime.indexDigest`. */
|
|
414
|
+
indexDigest: string;
|
|
415
|
+
/** Committed per-partition exact-byte size + sha256, updated incrementally on append. */
|
|
416
|
+
partitions: DictionaryPartitionCommit[];
|
|
417
|
+
/** Exact `.spill.dict-meta` bytes (size + digest). */
|
|
418
|
+
metaSize: number;
|
|
419
|
+
metaDigest: string;
|
|
420
|
+
recordCount: number;
|
|
421
|
+
uniqueTerms: number;
|
|
422
|
+
totalBytes: number;
|
|
423
|
+
/** Bounded duplicate-id diagnostics; non-empty ⇒ the artifact is never adopted. */
|
|
424
|
+
duplicateIds: readonly string[];
|
|
425
|
+
sidecarIneligible: boolean;
|
|
426
|
+
/** Block-cache bytes charged for this retained state; released on invalidation. */
|
|
427
|
+
chargedBytes: number;
|
|
428
|
+
/** On-disk byte cap for a single partition append; fixed unless a test shrinks it. */
|
|
429
|
+
budgetBytes: number;
|
|
430
|
+
/** Running per-partition hashes/sizes/records for append-time rebinding. */
|
|
431
|
+
partitionHashes: crypto.Hash[];
|
|
432
|
+
partitionSizes: number[];
|
|
433
|
+
partitionRecords: number[];
|
|
434
|
+
/** Descriptor of the exact meta bytes whose digest was validated for artifact use. */
|
|
435
|
+
validatedDescriptor?: SessionStorageStat;
|
|
436
|
+
}
|
|
437
|
+
/** Retained runtime state of the disposable metadata-delta section (reducer-bucket accounting). */
|
|
438
|
+
interface MetadataDeltaArtifactRuntimeState {
|
|
439
|
+
/** Exact `.spill.idx` digest the sidecar set was built with. */
|
|
440
|
+
indexDigest: string;
|
|
441
|
+
/** Exact bytes of the `.spill.metadata-delta` file. */
|
|
442
|
+
size: number;
|
|
443
|
+
sha256: string;
|
|
444
|
+
/** Live running hash of the delta bytes; updated on every value append. */
|
|
445
|
+
hash: crypto.Hash;
|
|
446
|
+
/** Demoted value descriptors keyed by provider key (positions derived at marker time). */
|
|
447
|
+
byKey: Map<string, Omit<MetadataDeltaValue, "key" | "position">>;
|
|
448
|
+
/** Reducer-bucket bytes retained by the descriptors (fixed accounting, reported in stats). */
|
|
449
|
+
descriptorBytes: number;
|
|
450
|
+
/** Fixed on-disk byte cap for the section. */
|
|
451
|
+
budgetBytes: number;
|
|
452
|
+
/** Descriptor of the exact delta bytes whose digest was validated. */
|
|
453
|
+
validatedDescriptor?: SessionStorageStat;
|
|
454
|
+
}
|
|
455
|
+
declare class BoundedColdIdHashSet {
|
|
456
|
+
#private;
|
|
457
|
+
has(value: string): boolean;
|
|
458
|
+
add(value: string): boolean;
|
|
459
|
+
addUnique(value: string): boolean;
|
|
460
|
+
}
|
|
259
461
|
export type DefaultModelSelectionStage = {
|
|
260
462
|
readonly entryRevision: number;
|
|
463
|
+
readonly leafRevision: number;
|
|
261
464
|
readonly headerExportRevision: number;
|
|
262
465
|
readonly sessionId: string;
|
|
263
466
|
readonly sessionFile: string | undefined;
|
|
264
467
|
readonly entries: readonly FileEntry[];
|
|
265
468
|
readonly tempPath: string | undefined;
|
|
266
469
|
readonly persistsToExistingFile: boolean;
|
|
470
|
+
readonly boundedCold: boolean;
|
|
471
|
+
readonly appendEntries: readonly SessionEntry[];
|
|
472
|
+
readonly sourceDescriptor: DescriptorSnapshot | undefined;
|
|
473
|
+
readonly sourceStat: SessionStorageStat | undefined;
|
|
474
|
+
readonly sourceSha256: string | undefined;
|
|
475
|
+
readonly managedAppendExpectation: ManagedBoundedAppendExpectation | undefined;
|
|
267
476
|
};
|
|
268
477
|
export interface SessionManagerRevisionSnapshot {
|
|
269
478
|
entry: number;
|
|
@@ -346,18 +555,12 @@ export interface ResumeTailTerminal {
|
|
|
346
555
|
}
|
|
347
556
|
export interface ResumeTailError {
|
|
348
557
|
kind: "error";
|
|
349
|
-
reason: "missing" | "malformed" | "unstable" | "read-failed" | "legacy_migration_disabled" | "oversized";
|
|
558
|
+
reason: "missing" | "malformed" | "unstable" | "read-failed" | "legacy_migration_disabled" | "oversized" | "context_too_large";
|
|
350
559
|
size?: number;
|
|
351
560
|
}
|
|
352
561
|
export type SessionDirectoryMigrationPolicy = ManagedMigrationPolicy;
|
|
353
562
|
export type SessionAppendPersistenceFailurePhase = "current_append" | "prior_failure";
|
|
354
|
-
/**
|
|
355
|
-
* Safety bound for resuming a single transcript file. Matches the managed-storage
|
|
356
|
-
* per-file artifact limit (`MANAGED_ARTIFACT_MAX_FILE_BYTES`): transcripts at or above
|
|
357
|
-
* this size are not loaded into memory wholesale because the decode + per-line JSON
|
|
358
|
-
* parse + identity hash would OOM or stall the process (#3851). The bound is a
|
|
359
|
-
* load-time guard only; it does not raise the on-disk managed-storage limit.
|
|
360
|
-
*/
|
|
563
|
+
/** Safety bound for eager resume compatibility and managed per-file artifacts. */
|
|
361
564
|
export declare const RESUME_TRANSCRIPT_MAX_BYTES: number;
|
|
362
565
|
export declare const SESSION_OVERSIZED_RECOVERY_MESSAGE = "The selected session transcript is too large to resume safely. Use `gjc export <session-file>` to export its content into a new session, or remove/archive it after confirming its content is no longer needed.";
|
|
363
566
|
export declare class SessionAppendPersistenceError extends Error {
|
|
@@ -383,6 +586,21 @@ export declare class SessionTranscriptOversizedError extends Error {
|
|
|
383
586
|
readonly size: number;
|
|
384
587
|
constructor(size: number);
|
|
385
588
|
}
|
|
589
|
+
/** Operation-peak budget for one synchronous session-context materialization. */
|
|
590
|
+
export declare const SESSION_CONTEXT_MATERIALIZATION_BUDGET_BYTES: number;
|
|
591
|
+
/**
|
|
592
|
+
* Thrown by the synchronous session-context builders when the materialized graph
|
|
593
|
+
* exceeds the operation budget. `instanceof`-stable across module boundaries:
|
|
594
|
+
* consumers map with `error instanceof SessionContextTooLargeError`, never by name
|
|
595
|
+
* string. The over-budget graph is never retained — the builder releases scratch
|
|
596
|
+
* before throwing and public synchronous signatures are unchanged.
|
|
597
|
+
*/
|
|
598
|
+
export declare class SessionContextTooLargeError extends Error {
|
|
599
|
+
readonly code: "context_too_large";
|
|
600
|
+
readonly measuredBytes: number;
|
|
601
|
+
readonly budgetBytes: number;
|
|
602
|
+
constructor(measuredBytes: number, budgetBytes?: number, options?: ErrorOptions);
|
|
603
|
+
}
|
|
386
604
|
export type ResumeTailInspection = ResumeTailResumable | ResumeTailTerminal | ResumeTailError;
|
|
387
605
|
export interface StrictSessionOpenSuccess {
|
|
388
606
|
kind: "opened";
|
|
@@ -394,16 +612,42 @@ export interface StrictSessionOpenFailure {
|
|
|
394
612
|
message?: string;
|
|
395
613
|
size?: number;
|
|
396
614
|
}
|
|
397
|
-
/**
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
615
|
+
/**
|
|
616
|
+
* Descriptor-bound strict-capture handle. Bounded recorded-length range reads
|
|
617
|
+
* revalidate the live source against the captured identity on every pass; no
|
|
618
|
+
* whole-transcript buffer is ever materialized by capture or fork.
|
|
619
|
+
*/
|
|
620
|
+
export interface TranscriptSnapshotHandle {
|
|
621
|
+
readonly sourcePath: string;
|
|
622
|
+
readonly identity: ResumeSessionIdentity;
|
|
623
|
+
readonly storage: SessionStorage;
|
|
624
|
+
/**
|
|
625
|
+
* Iterate every transcript line in bounded recorded-length reads. Each line
|
|
626
|
+
* is delivered without its trailing newline; returning `false` aborts the
|
|
627
|
+
* pass. A completed pass re-validates the running content hash against the
|
|
628
|
+
* captured identity and throws `identity-mismatch` on divergence.
|
|
629
|
+
*/
|
|
630
|
+
forEachLine(callback: (line: Uint8Array) => boolean | undefined): boolean;
|
|
631
|
+
/** Descriptor captured after the most recent complete line pass, when supported. */
|
|
632
|
+
getLastReadStat(): SessionStorageStat | undefined;
|
|
633
|
+
/** Revalidate the live source against the captured identity (bounded). */
|
|
634
|
+
revalidate(): {
|
|
635
|
+
kind: "valid";
|
|
636
|
+
} | StrictSessionOpenFailure;
|
|
637
|
+
/** Idempotent close; subsequent reads throw. */
|
|
638
|
+
close(): void;
|
|
639
|
+
/**
|
|
640
|
+
* Rehydrate the full transcript bytes for bounded-full-return consumers.
|
|
641
|
+
* This is an explicit compatibility escape hatch, never used by fork/capture
|
|
642
|
+
* publication itself.
|
|
643
|
+
*/
|
|
644
|
+
materialize(): Uint8Array;
|
|
403
645
|
}
|
|
646
|
+
/** @deprecated Use {@link TranscriptSnapshotHandle}; retained for call-site compatibility. */
|
|
647
|
+
export type CapturedSessionTranscriptSnapshot = TranscriptSnapshotHandle;
|
|
404
648
|
export type StrictSessionCaptureResult = {
|
|
405
649
|
kind: "captured";
|
|
406
|
-
snapshot:
|
|
650
|
+
snapshot: TranscriptSnapshotHandle;
|
|
407
651
|
} | ResumeTailError;
|
|
408
652
|
export type StrictSessionForkResult = {
|
|
409
653
|
kind: "forked";
|
|
@@ -521,11 +765,6 @@ export declare function migrateSessionEntries(entries: FileEntry[]): void;
|
|
|
521
765
|
/** Exported for compaction.test.ts */
|
|
522
766
|
export declare function parseSessionEntries(content: string): FileEntry[];
|
|
523
767
|
export declare function getLatestCompactionEntry(entries: SessionEntry[]): CompactionEntry | null;
|
|
524
|
-
/**
|
|
525
|
-
* Build the session context from entries using tree traversal.
|
|
526
|
-
* If leafId is provided, walks from that entry to root.
|
|
527
|
-
* Handles compaction and branch summaries along the path.
|
|
528
|
-
*/
|
|
529
768
|
export declare function buildSessionContext(entries: SessionEntry[], leafId?: string | null, byId?: Map<string, SessionEntry>, sessionIdentityNamespace?: string): SessionContext;
|
|
530
769
|
/** A session directory's authority is distinct from its string path. */
|
|
531
770
|
export type SessionDestination = {
|
|
@@ -550,6 +789,7 @@ type ForkArtifactPublication = {
|
|
|
550
789
|
};
|
|
551
790
|
/** Exported for testing */
|
|
552
791
|
export declare function loadEntriesFromFile(filePath: string, storage?: SessionStorage): Promise<FileEntry[]>;
|
|
792
|
+
export declare const TRANSCRIPT_CAPTURE_CHUNK_BYTES: number;
|
|
553
793
|
declare class RecentSessionInfo {
|
|
554
794
|
#private;
|
|
555
795
|
readonly path: string;
|
|
@@ -641,7 +881,27 @@ export declare const SessionManagerTestHooks: {
|
|
|
641
881
|
beforeResidentTransitionIndexBuild?: () => void;
|
|
642
882
|
afterForkSnapshot?: () => void | Promise<void>;
|
|
643
883
|
beforeEphemeralArtifactManagerInstall?: (dir: string) => void | Promise<void>;
|
|
884
|
+
beforePersistPatchFence?: (attempt: number) => void;
|
|
644
885
|
};
|
|
886
|
+
/**
|
|
887
|
+
* Freshness snapshot captured with every async whole-session persistence
|
|
888
|
+
* preparation. Immediately before the synchronous persistence transaction, the
|
|
889
|
+
* live values are compared: a `sessionFile`/`lifecycleId` change aborts (lifecycle
|
|
890
|
+
* switch); a revision change discards the prepared bytes and re-prepares (bounded),
|
|
891
|
+
* so a stale snapshot is never published.
|
|
892
|
+
*/
|
|
893
|
+
export interface PersistenceInputToken {
|
|
894
|
+
/** Canonical session file path the prepared bytes target. */
|
|
895
|
+
sessionFile: string;
|
|
896
|
+
/** Per-manager lifecycle identity (`sessionId@sessionFile`); changes on switch/open/reset. */
|
|
897
|
+
lifecycleId: string;
|
|
898
|
+
/** Revision of #fileEntries affecting persisted bytes. */
|
|
899
|
+
entryRevision: number;
|
|
900
|
+
/** Header/version revision affecting persisted bytes. */
|
|
901
|
+
headerRevision: number;
|
|
902
|
+
/** Resident/blob store revision affecting persisted bytes. */
|
|
903
|
+
residentBlobRevision: number;
|
|
904
|
+
}
|
|
645
905
|
export declare class SessionManager {
|
|
646
906
|
#private;
|
|
647
907
|
private cwd;
|
|
@@ -753,6 +1013,8 @@ export declare class SessionManager {
|
|
|
753
1013
|
listForResumePickerReadOnly(): Promise<SessionInfo[]>;
|
|
754
1014
|
getSessionId(): string;
|
|
755
1015
|
getSessionFile(): string | undefined;
|
|
1016
|
+
getSessionMemoryStats(): SessionMemoryStats;
|
|
1017
|
+
setSessionMemoryMode(mode: "off" | "shadow" | "enabled"): void;
|
|
756
1018
|
acquireMemoryGuardParticipantIngressLease(): MemoryGuardParticipantIngressLease;
|
|
757
1019
|
createMemoryGuardCheckpoint(input: MemoryGuardCreateCheckpointInput): Promise<MemoryGuardSessionManagerCheckpointV1>;
|
|
758
1020
|
/**
|
|
@@ -938,10 +1200,21 @@ export declare class SessionManager {
|
|
|
938
1200
|
/**
|
|
939
1201
|
* Get the most recent model role from the current session path.
|
|
940
1202
|
* Returns undefined if no model change has been recorded.
|
|
1203
|
+
*
|
|
1204
|
+
* R1: keyed ONLY on the nearest `model_change` on the leaf→root path — never on
|
|
1205
|
+
* `hasExplicitDefaultModel`, which gates only legacy assistant inference into
|
|
1206
|
+
* `models.default` inside `buildSessionContext`. Six parity cases (D1): reviewer-
|
|
1207
|
+
* only → "reviewer"; temporary-only → "temporary"; interleaved → nearest;
|
|
1208
|
+
* no model_change → undefined; legacy-only inference → undefined; explicit
|
|
1209
|
+
* default then legacy inference → "default".
|
|
941
1210
|
*/
|
|
942
1211
|
getLastModelChangeRole(): string | undefined;
|
|
943
1212
|
evictCompactedContent(firstKeptEntryId: string, compactionEntryId: string): EvictCompactedContentResult;
|
|
944
1213
|
getObservabilityStatsForTests(): SessionManagerObservabilityStats;
|
|
1214
|
+
setSidecarHotSuffixBudgetForTests(bytes: number): void;
|
|
1215
|
+
parentChildrenCacheKeysForTests(): string[];
|
|
1216
|
+
parentArtifactEnabledForTests(): boolean;
|
|
1217
|
+
setParentArtifactBudgetForTests(bytes: number): void;
|
|
945
1218
|
hotRetainedMessageCharsForTests(): number;
|
|
946
1219
|
getCanonicalEntryForTests(id: string): SessionEntry | undefined;
|
|
947
1220
|
getEntryForFidelity(id: string): SessionEntry | undefined;
|
|
@@ -952,6 +1225,7 @@ export declare class SessionManager {
|
|
|
952
1225
|
* sync; callers must not mutate returned entries.
|
|
953
1226
|
*/
|
|
954
1227
|
getActivePathEntriesCanonical(fromId?: string): SessionEntry[];
|
|
1228
|
+
visitEntriesForExport(visitor: (entry: SessionEntry) => void): void;
|
|
955
1229
|
getEntriesForExport(): SessionEntry[];
|
|
956
1230
|
getEntry(id: string): SessionEntry | undefined;
|
|
957
1231
|
/**
|
|
@@ -1046,14 +1320,14 @@ export declare class SessionManager {
|
|
|
1046
1320
|
* Fork a session into the current project directory.
|
|
1047
1321
|
* Copies history from another session file while creating a new session file in the current sessionDir.
|
|
1048
1322
|
*/
|
|
1049
|
-
static forkFrom(sourcePath: string, cwd: string, destinationInput?: SessionDestinationInput, storage?: SessionStorage, migrationPolicy?: SessionDirectoryMigrationPolicy): Promise<SessionManager>;
|
|
1323
|
+
static forkFrom(sourcePath: string, cwd: string, destinationInput?: SessionDestinationInput, storage?: SessionStorage, migrationPolicy?: SessionDirectoryMigrationPolicy, sessionMemoryMode?: "off" | "shadow" | "enabled"): Promise<SessionManager>;
|
|
1050
1324
|
/**
|
|
1051
1325
|
* Open a specific session file.
|
|
1052
1326
|
* @param path Path to session file
|
|
1053
1327
|
* @param sessionDir Optional session directory for /new or /branch. If omitted, derives from file's parent.
|
|
1054
1328
|
*/
|
|
1055
|
-
static open(filePath: string, destinationInput?: SessionDestinationInput, storage?: SessionStorage, migrationPolicy?: SessionDirectoryMigrationPolicy): Promise<SessionManager>;
|
|
1056
|
-
static openNestedManaged(filePath: string, destination: SessionDestination, store: ManagedSessionDescendantStore, storage?: SessionStorage, cwdOverride?: string): Promise<SessionManager>;
|
|
1329
|
+
static open(filePath: string, destinationInput?: SessionDestinationInput, storage?: SessionStorage, migrationPolicy?: SessionDirectoryMigrationPolicy, sessionMemoryMode?: "off" | "shadow" | "enabled"): Promise<SessionManager>;
|
|
1330
|
+
static openNestedManaged(filePath: string, destination: SessionDestination, store: ManagedSessionDescendantStore, storage?: SessionStorage, cwdOverride?: string, sessionMemoryMode?: "off" | "shadow" | "enabled"): Promise<SessionManager>;
|
|
1057
1331
|
/**
|
|
1058
1332
|
* List default-managed sessions for the resume picker without recovery or other
|
|
1059
1333
|
* maintenance writes. This is the only picker inventory that includes legacy
|
|
@@ -1075,7 +1349,7 @@ export declare class SessionManager {
|
|
|
1075
1349
|
* revalidate captured authority before destination initialization and transcript
|
|
1076
1350
|
* persistence; destination history always comes from the captured bytes.
|
|
1077
1351
|
*/
|
|
1078
|
-
static forkFromCaptured(snapshot: CapturedSessionTranscriptSnapshot, cwd: string, destinationInput?: SessionDestinationInput, _migrationPolicy?: SessionDirectoryMigrationPolicy): Promise<StrictSessionForkResult>;
|
|
1352
|
+
static forkFromCaptured(snapshot: CapturedSessionTranscriptSnapshot, cwd: string, destinationInput?: SessionDestinationInput, _migrationPolicy?: SessionDirectoryMigrationPolicy, sessionMemoryMode?: "off" | "shadow" | "enabled"): Promise<StrictSessionForkResult>;
|
|
1079
1353
|
static restoreMemoryGuardCheckpoint(input: MemoryGuardRestoreInput): Promise<MemoryGuardRestoreResult>;
|
|
1080
1354
|
/** Inspect a selected session without acquiring write-capable ownership. */
|
|
1081
1355
|
static inspectSessionTailReadOnly(filePath: string, storage?: SessionStorage): Promise<ResumeTailInspection>;
|
|
@@ -1096,13 +1370,13 @@ export declare class SessionManager {
|
|
|
1096
1370
|
* the returned discriminant; an error result never creates, rewrites, or adopts
|
|
1097
1371
|
* the selected path. Breadcrumb ownership begins only after `kind: "opened"`.
|
|
1098
1372
|
*/
|
|
1099
|
-
static openExistingStrict(identity: ResumeSessionIdentity, destinationInput?: SessionDestinationInput, storage?: SessionStorage, migrationPolicy?: SessionDirectoryMigrationPolicy): Promise<StrictSessionOpenResult>;
|
|
1373
|
+
static openExistingStrict(identity: ResumeSessionIdentity, destinationInput?: SessionDestinationInput, storage?: SessionStorage, migrationPolicy?: SessionDirectoryMigrationPolicy, sessionMemoryMode?: "off" | "shadow" | "enabled"): Promise<StrictSessionOpenResult>;
|
|
1100
1374
|
/**
|
|
1101
1375
|
* Continue the most recent session, or create new if none.
|
|
1102
1376
|
* @param cwd Working directory
|
|
1103
1377
|
* @param sessionDir Optional session directory. If omitted, uses default (~/.gjc/agent/sessions/<encoded-cwd>/).
|
|
1104
1378
|
*/
|
|
1105
|
-
static continueRecent(cwd: string, destinationInput?: SessionDestinationInput, storage?: SessionStorage, migrationPolicy?: SessionDirectoryMigrationPolicy): Promise<SessionManager>;
|
|
1379
|
+
static continueRecent(cwd: string, destinationInput?: SessionDestinationInput, storage?: SessionStorage, migrationPolicy?: SessionDirectoryMigrationPolicy, sessionMemoryMode?: "off" | "shadow" | "enabled"): Promise<SessionManager>;
|
|
1106
1380
|
/** Create an in-memory session (no file persistence) */
|
|
1107
1381
|
static inMemory(cwd?: string, storage?: SessionStorage): SessionManager;
|
|
1108
1382
|
/**
|