qlogicagent 2.16.6 → 2.16.7

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.
Files changed (56) hide show
  1. package/dist/agent.js +16 -16
  2. package/dist/cli.js +372 -373
  3. package/dist/index.js +371 -372
  4. package/dist/protocol.js +1 -1
  5. package/dist/types/cli/base-tool-bootstrap.d.ts +1 -0
  6. package/dist/types/cli/handlers/files-handler.d.ts +5 -0
  7. package/dist/types/cli/handlers/message-feedback-handler.d.ts +29 -0
  8. package/dist/types/cli/handlers/project-handler.d.ts +1 -0
  9. package/dist/types/cli/handlers/turn-baseline-handler.d.ts +8 -0
  10. package/dist/types/cli/handlers/turn-handler.d.ts +5 -0
  11. package/dist/types/cli/handlers/working-materials-handler.d.ts +9 -0
  12. package/dist/types/cli/idle-dream-coordinator.d.ts +6 -0
  13. package/dist/types/cli/mcp-bootstrap.d.ts +1 -0
  14. package/dist/types/cli/rpc-registry.d.ts +6 -0
  15. package/dist/types/cli/stdio-rpc-handler-hosts.d.ts +1 -0
  16. package/dist/types/cli/stdio-runtime-bootstrap.d.ts +1 -0
  17. package/dist/types/cli/tool-bootstrap-core-registration.d.ts +1 -0
  18. package/dist/types/cli/tool-bootstrap.d.ts +1 -0
  19. package/dist/types/protocol/methods.d.ts +24 -0
  20. package/dist/types/protocol/wire/agent-events.d.ts +2 -2
  21. package/dist/types/protocol/wire/gateway-rpc.d.ts +160 -0
  22. package/dist/types/protocol/wire/notification-payloads.d.ts +27 -0
  23. package/dist/types/runtime/infra/feedback-distillation-worker.d.ts +20 -0
  24. package/dist/types/runtime/infra/feedback-distillation.d.ts +30 -0
  25. package/dist/types/runtime/infra/feedback-event-store.d.ts +160 -0
  26. package/dist/types/runtime/infra/feedback-outbox.d.ts +26 -0
  27. package/dist/types/runtime/infra/feedback-redaction.d.ts +71 -0
  28. package/dist/types/runtime/infra/feedback-upload-client.d.ts +39 -0
  29. package/dist/types/runtime/infra/feedback-upload-worker.d.ts +11 -0
  30. package/dist/types/runtime/infra/turn-baseline-store.d.ts +102 -0
  31. package/dist/types/runtime/infra/turn-telemetry-store.d.ts +59 -0
  32. package/dist/types/runtime/infra/working-materials-store.d.ts +35 -0
  33. package/dist/types/runtime/ports/memory-provider.d.ts +6 -0
  34. package/dist/types/runtime/ports/tool-contracts.d.ts +1 -0
  35. package/dist/types/runtime/prompt/fresh-workspace-evidence.d.ts +14 -0
  36. package/dist/types/skills/mcp/mcp-manager.d.ts +11 -0
  37. package/dist/types/skills/memory/local-memory-provider.d.ts +3 -3
  38. package/dist/types/skills/memory/local-store-records.d.ts +18 -1
  39. package/dist/types/skills/memory/local-store.d.ts +8 -195
  40. package/dist/types/skills/memory/memory-consolidation.d.ts +14 -0
  41. package/dist/types/skills/memory/sqlite-memory-schema.d.ts +1 -1
  42. package/dist/types/skills/tools/skill-tool.d.ts +1 -1
  43. package/dist/vendor/hatch-pet/LICENSE.txt +201 -201
  44. package/dist/vendor/hatch-pet/NOTICE.md +25 -25
  45. package/dist/vendor/hatch-pet/references/animation-rows.md +29 -29
  46. package/dist/vendor/hatch-pet/references/codex-pet-contract.md +35 -35
  47. package/dist/vendor/hatch-pet/references/qa-rubric.md +66 -66
  48. package/dist/vendor/hatch-pet/scripts/compose_atlas.py +169 -169
  49. package/dist/vendor/hatch-pet/scripts/derive_running_left_from_running_right.py +150 -150
  50. package/dist/vendor/hatch-pet/scripts/extract_strip_frames.py +408 -408
  51. package/dist/vendor/hatch-pet/scripts/inspect_frames.py +256 -256
  52. package/dist/vendor/hatch-pet/scripts/make_contact_sheet.py +96 -96
  53. package/dist/vendor/hatch-pet/scripts/prepare_pet_run.py +834 -834
  54. package/dist/vendor/hatch-pet/scripts/render_animation_previews.py +78 -78
  55. package/dist/vendor/hatch-pet/scripts/validate_atlas.py +157 -157
  56. package/package.json +1 -1
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Feedback distillation worker (design §11; mini-design 2026-06-28 v2) — the idle-triggered sweep
3
+ * that turns a project's accumulated feedback into memory proposals. Scheduling mirrors the upload
4
+ * worker + dream: a pure work unit, callers serialize per project (§9.1 rule 9). It is append-only
5
+ * into the SHARED memory pipeline (proposeExtracted, source="feedback") — it never promotes; dream /
6
+ * consolidator own merge + promote (§11.2). The store-level idempotency key (§10) makes the sweep
7
+ * safe to re-run: a retried sweep, or a worker restart mid-sweep, never duplicates a proposal.
8
+ */
9
+ import type { MemoryDreamProvider } from "../ports/memory-provider.js";
10
+ export interface FeedbackDistillationResult {
11
+ candidates: number;
12
+ proposed: number;
13
+ }
14
+ /**
15
+ * One distillation sweep for a project: cluster active feedback into candidates, append each as a
16
+ * memory proposal. Fail-soft per candidate — one rejected proposal never aborts the rest of the
17
+ * sweep. Returns counts for logging. The memory provider must expose proposeExtracted (the dream
18
+ * provider does); if it doesn't, the sweep is a no-op.
19
+ */
20
+ export declare function runFeedbackDistillationSweep(projectId: string, sink: Pick<MemoryDreamProvider, "proposeExtracted">, userId: string): Promise<FeedbackDistillationResult>;
@@ -0,0 +1,30 @@
1
+ import type { FeedbackEvent } from "./feedback-event-store.js";
2
+ /** Minimum corroborating active events before a cluster becomes a proposal (mini-design §3.4). */
3
+ export declare const MIN_EVIDENCE = 2;
4
+ export interface FeedbackDistillationCandidate {
5
+ clusterKey: string;
6
+ /** Template preference sentence (dream LLM refines later — mini-design §9.3). */
7
+ text: string;
8
+ category: string;
9
+ importance: number;
10
+ confidence: number;
11
+ /** Audit trail + crash-safe idempotency, consumed by the extended proposeExtracted (§10). */
12
+ evidence: {
13
+ kind: "feedback";
14
+ refs: string[];
15
+ idempotencyKey: string;
16
+ };
17
+ /** Cluster diagnostics — not persisted as-is; surfaced for tests + logging. */
18
+ stats: {
19
+ evidence: number;
20
+ crossSession: boolean;
21
+ feedbackIds: string[];
22
+ turnIds: string[];
23
+ };
24
+ }
25
+ /**
26
+ * Cluster a project's feedback events into proposal candidates. Only active events count
27
+ * (retracted / replaced are filtered — §11.1). Clusters below MIN_EVIDENCE are dropped. Output is
28
+ * sorted by clusterKey for deterministic ordering across runs.
29
+ */
30
+ export declare function distillFeedback(events: FeedbackEvent[]): FeedbackDistillationCandidate[];
@@ -0,0 +1,160 @@
1
+ export type FeedbackRating = "up" | "down";
2
+ export type FeedbackState = "active" | "retracted" | "replaced";
3
+ export type TelemetryStatus = "complete" | "partial" | "missing";
4
+ export type FeedbackReason = "missed_requirement" | "incomplete" | "broken_file_link_or_panel" | "code_or_test_failed" | "factually_wrong" | "too_verbose" | "too_short" | "wrong_style" | "other";
5
+ export interface FeedbackUsage {
6
+ inputTokens?: number;
7
+ outputTokens?: number;
8
+ totalTokens?: number;
9
+ }
10
+ export interface FeedbackToolSummary {
11
+ calledTools: string[];
12
+ failedTools: string[];
13
+ blockedTools: string[];
14
+ }
15
+ export interface FeedbackFileContext {
16
+ changedFileCount?: number;
17
+ changedPathsPreview?: string[];
18
+ hasTurnFileChanges?: boolean;
19
+ diffOpenState?: "not_applicable" | "opened" | "failed" | "unknown";
20
+ }
21
+ export interface FeedbackBrowserContext {
22
+ url?: string;
23
+ hadToastError?: boolean;
24
+ visiblePanel?: "chat" | "artifact" | "diff" | "unknown";
25
+ }
26
+ export interface FeedbackEvent {
27
+ feedbackId: string;
28
+ rating: FeedbackRating;
29
+ reason?: FeedbackReason;
30
+ comment?: string;
31
+ state: FeedbackState;
32
+ projectId?: string;
33
+ sessionId: string;
34
+ turnId: string;
35
+ assistantMessageId: string;
36
+ userId?: string;
37
+ telemetryStatus: TelemetryStatus;
38
+ messageRole: "assistant";
39
+ messagePreview: string;
40
+ messageHash: string;
41
+ model?: string;
42
+ provider?: string;
43
+ agentMode?: "chat" | "solo" | "product" | "workflow" | "unknown";
44
+ sourceChannel?: string;
45
+ usage?: FeedbackUsage;
46
+ toolSummary?: FeedbackToolSummary;
47
+ fileContext?: FeedbackFileContext;
48
+ browserContext?: FeedbackBrowserContext;
49
+ upload?: {
50
+ eligible: boolean;
51
+ uploadedAt?: string;
52
+ uploadBatchId?: string;
53
+ redactionVersion?: string;
54
+ };
55
+ /**
56
+ * Local distillation bookkeeping (mini-design §6): records that this event was folded into a
57
+ * memory proposal, and under which cluster + idempotency key. Observability only — the crash-safe
58
+ * dedup guard is the store-level idempotency key on the proposal, not this field.
59
+ */
60
+ distill?: {
61
+ proposedAt: string;
62
+ clusterKey: string;
63
+ idempotencyKey: string;
64
+ };
65
+ createdAt: string;
66
+ updatedAt: string;
67
+ }
68
+ /** Telemetry-joined + click-time context the handler assembles before persisting. */
69
+ export interface FeedbackContext {
70
+ telemetryStatus: TelemetryStatus;
71
+ messagePreview: string;
72
+ messageHash: string;
73
+ userId?: string;
74
+ model?: string;
75
+ provider?: string;
76
+ agentMode?: FeedbackEvent["agentMode"];
77
+ sourceChannel?: string;
78
+ usage?: FeedbackUsage;
79
+ toolSummary?: FeedbackToolSummary;
80
+ fileContext?: FeedbackFileContext;
81
+ browserContext?: FeedbackBrowserContext;
82
+ }
83
+ export interface FeedbackSubmitInput {
84
+ rating: FeedbackRating;
85
+ reason?: FeedbackReason;
86
+ comment?: string;
87
+ projectId: string;
88
+ sessionId: string;
89
+ turnId: string;
90
+ assistantMessageId: string;
91
+ context: FeedbackContext;
92
+ }
93
+ export interface FeedbackStateEntry {
94
+ turnId: string;
95
+ assistantMessageId: string;
96
+ feedbackId: string;
97
+ rating: FeedbackRating;
98
+ reason?: FeedbackReason;
99
+ state: FeedbackState;
100
+ updatedAt: string;
101
+ }
102
+ export declare function hashMessageContent(content: string): string;
103
+ /**
104
+ * Create / switch / re-activate the feedback for a turn. Returns the stable feedbackId and the
105
+ * resulting state. Submitting the SAME rating while already active is a no-op (idempotent retry).
106
+ */
107
+ export declare function submitFeedback(input: FeedbackSubmitInput): Promise<{
108
+ feedbackId: string;
109
+ state: FeedbackState;
110
+ }>;
111
+ /**
112
+ * Retract the active feedback for a turn (the frontend calls this when the user re-clicks the
113
+ * already-selected button). Idempotent: retracting when there is nothing active is a no-op.
114
+ */
115
+ export declare function retractFeedback(input: {
116
+ projectId: string;
117
+ turnId: string;
118
+ feedbackId?: string;
119
+ }): Promise<{
120
+ ok: boolean;
121
+ feedbackId?: string;
122
+ state: FeedbackState | null;
123
+ }>;
124
+ /**
125
+ * Hydrate feedback state for a session's messages (initial render / refresh). Returns only ACTIVE
126
+ * feedback (absent = not rated) — the fixed contract per design §8.3, so the UI never has to
127
+ * interpret retracted/replaced records.
128
+ */
129
+ export declare function getFeedbackState(input: {
130
+ projectId: string;
131
+ sessionId: string;
132
+ turnIds?: string[];
133
+ assistantMessageIds?: string[];
134
+ }): Promise<{
135
+ states: FeedbackStateEntry[];
136
+ }>;
137
+ /**
138
+ * Events eligible for cloud upload that have not yet been assigned to a batch (design §10). The
139
+ * worker redacts + ships these; once assigned a batchId (delivered or queued for retry) they are
140
+ * skipped until a state change resets the upload marks.
141
+ */
142
+ export declare function listUploadableFeedback(projectId: string): Promise<FeedbackEvent[]>;
143
+ /** Mark an event as assigned to an in-flight upload batch (queued for retry, not yet delivered). */
144
+ export declare function assignFeedbackBatch(projectId: string, turnId: string, uploadBatchId: string): Promise<void>;
145
+ /** Mark an event as successfully uploaded (stamps uploadedAt + batch + redactionVersion). */
146
+ export declare function markFeedbackUploaded(projectId: string, turnId: string, uploadBatchId: string, redactionVersion: string): Promise<void>;
147
+ /**
148
+ * Active feedback eligible for memory distillation (mini-design §3.1). Distillation re-clusters the
149
+ * full active set every sweep; the store-level idempotency key (not a per-event flag) prevents
150
+ * duplicate proposals, so this intentionally returns ALL active events — already distilled or not.
151
+ * A newly added active event simply changes a cluster's id set and yields a fresh proposal.
152
+ */
153
+ export declare function listDistillableFeedback(projectId: string): Promise<FeedbackEvent[]>;
154
+ /** Stamp local distillation bookkeeping on an event (which cluster + idempotency key folded it in). */
155
+ export declare function markFeedbackDistilled(projectId: string, turnId: string, info: {
156
+ clusterKey: string;
157
+ idempotencyKey: string;
158
+ }): Promise<void>;
159
+ /** Test helper: read the raw stored event for a turn (including retracted), or null. */
160
+ export declare function __getFeedbackEventForTest(projectId: string, turnId: string): Promise<FeedbackEvent | null>;
@@ -0,0 +1,26 @@
1
+ export type OutboxOp = "uploadBatch";
2
+ export interface OutboxEntry {
3
+ entryId: string;
4
+ /** Dedup key — re-enqueuing the same logical op is a no-op (no double upload). */
5
+ idempotencyKey: string;
6
+ op: OutboxOp;
7
+ payload: unknown;
8
+ attempts: number;
9
+ createdAt: string;
10
+ nextAttemptAt: string;
11
+ lastError?: string;
12
+ }
13
+ /** Enqueue a failed op for retry. Idempotent: an existing entry with the same key is kept as-is. */
14
+ export declare function enqueueOutbox(projectId: string, input: {
15
+ idempotencyKey: string;
16
+ op: OutboxOp;
17
+ payload: unknown;
18
+ }, now?: Date): Promise<OutboxEntry>;
19
+ /** Entries whose backoff window has elapsed and that have not exhausted their retry budget. */
20
+ export declare function listDueOutbox(projectId: string, now?: Date): Promise<OutboxEntry[]>;
21
+ /** Drop a successfully-delivered entry. */
22
+ export declare function removeOutbox(projectId: string, entryId: string): Promise<void>;
23
+ /** Record a failed attempt: bump attempts + schedule the next retry with exponential backoff. */
24
+ export declare function markOutboxFailure(projectId: string, entryId: string, error: string, now?: Date): Promise<void>;
25
+ /** Entries that have exhausted their retry budget — kept for local audit, never re-sent. */
26
+ export declare function listExhaustedOutbox(projectId: string): Promise<OutboxEntry[]>;
@@ -0,0 +1,71 @@
1
+ import type { FeedbackEvent, FeedbackRating, FeedbackReason, FeedbackState, FeedbackToolSummary, FeedbackUsage, TelemetryStatus } from "./feedback-event-store.js";
2
+ /** Bump when the redaction rules change so uploaded samples stay traceable (§8.6/§13). */
3
+ export declare const REDACTION_VERSION = "feedback-redaction-v1";
4
+ export interface RedactedFeedbackEvent {
5
+ feedbackId: string;
6
+ rating: FeedbackRating;
7
+ reason?: FeedbackReason;
8
+ state: FeedbackState;
9
+ /** Hashed identity — correlate without exposing local ids (§8.6). */
10
+ messageHash: string;
11
+ sessionIdHash: string;
12
+ projectIdHash?: string;
13
+ turnIdHash: string;
14
+ /** ≤500 chars, secrets/emails/absolute-paths scrubbed (§13). */
15
+ messagePreview: string;
16
+ model?: string;
17
+ provider?: string;
18
+ agentMode?: FeedbackEvent["agentMode"];
19
+ sourceChannel?: string;
20
+ usage?: FeedbackUsage;
21
+ /** Tool names only (never args). */
22
+ toolSummary?: FeedbackToolSummary;
23
+ fileContext?: {
24
+ changedFileCount?: number;
25
+ hasTurnFileChanges?: boolean;
26
+ diffOpenState?: "not_applicable" | "opened" | "failed" | "unknown";
27
+ };
28
+ browserContext?: {
29
+ hadToastError?: boolean;
30
+ visiblePanel?: "chat" | "artifact" | "diff" | "unknown";
31
+ };
32
+ telemetryStatus: TelemetryStatus;
33
+ redactionVersion: string;
34
+ createdAt: string;
35
+ }
36
+ export interface FeedbackRollup {
37
+ rollupId: string;
38
+ periodStart: string;
39
+ periodEnd: string;
40
+ total: number;
41
+ upCount: number;
42
+ downCount: number;
43
+ /** Down-vote reason → count. */
44
+ byReason: Record<string, number>;
45
+ byModel: Record<string, {
46
+ up: number;
47
+ down: number;
48
+ }>;
49
+ byAgentMode: Record<string, {
50
+ up: number;
51
+ down: number;
52
+ }>;
53
+ telemetryStatusCounts: {
54
+ complete: number;
55
+ partial: number;
56
+ missing: number;
57
+ };
58
+ redactionVersion: string;
59
+ createdAt: string;
60
+ }
61
+ /** Truncate to the preview limit and scrub api keys / emails / absolute paths (§13). */
62
+ export declare function sanitizePreview(text: string): string;
63
+ /** Map a local feedback event to its upload-safe redacted form (§8.6/§13). */
64
+ export declare function redactFeedbackEvent(event: FeedbackEvent, redactionVersion?: string): RedactedFeedbackEvent;
65
+ /** Pre-aggregate a batch of local events into a rollup for low-cost trend upload (§10). */
66
+ export declare function aggregateFeedbackRollup(events: FeedbackEvent[], input: {
67
+ rollupId: string;
68
+ periodStart: string;
69
+ periodEnd: string;
70
+ redactionVersion?: string;
71
+ }): FeedbackRollup;
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Feedback upload client — the single HTTP exit that ships redacted feedback to the llmrouter
3
+ * feedback backend (design §8.6, §9.1 rule 4). The redaction worker calls this directly; the
4
+ * messageFeedback.uploadBatch RPC wraps it for manual/test triggers.
5
+ *
6
+ * Transport mirrors the usage client: append the route to the llmrouter base already injected into
7
+ * the agent (QLOGIC_LLMROUTER_BASE_URL, e.g. https://www.qlogicagent.com/api) and authenticate with
8
+ * the injected Bearer QLOGIC_LLMROUTER_ACCESS_TOKEN. Feedback lands at <base>/client/feedback, so a
9
+ * batch POSTs to <base>/client/feedback/uploadBatch — the contract the llmrouter ingest endpoint
10
+ * (Phase 3b) implements. No dedicated feedback env: one llmrouter base, like /client/usage.
11
+ */
12
+ import type { FeedbackRollup, RedactedFeedbackEvent } from "./feedback-redaction.js";
13
+ export interface UploadBatchInput {
14
+ batchId: string;
15
+ events: RedactedFeedbackEvent[];
16
+ rollups: FeedbackRollup[];
17
+ redactionVersion: string;
18
+ clientBuild?: string;
19
+ runtimeVersion?: string;
20
+ qlogicagentVersion?: string;
21
+ }
22
+ export interface UploadBatchResult {
23
+ ok: boolean;
24
+ accepted?: number;
25
+ status?: number;
26
+ error?: string;
27
+ }
28
+ /**
29
+ * Resolve the feedback ingest base, derived from the llmrouter base already injected into the agent
30
+ * (QLOGIC_LLMROUTER_BASE_URL), mirroring how the usage client reaches /client/usage. Returns
31
+ * undefined when llmrouter is not configured.
32
+ */
33
+ export declare function resolveFeedbackUploadBaseUrl(): string | undefined;
34
+ /**
35
+ * Ship one redacted batch to llmrouter. Fail-soft: an unconfigured base or a transport/HTTP error
36
+ * returns { ok: false }, so the caller (worker) keeps the events eligible and queues a retry rather
37
+ * than dropping feedback. Idempotent at the server by batchId + event id (§9.1 rule 5).
38
+ */
39
+ export declare function uploadFeedbackBatch(input: UploadBatchInput, signal?: AbortSignal): Promise<UploadBatchResult>;
@@ -0,0 +1,11 @@
1
+ export interface FeedbackSweepResult {
2
+ uploaded: number;
3
+ queued: number;
4
+ retried: number;
5
+ }
6
+ /**
7
+ * One feedback upload sweep for a project. Retries due outbox batches, then redacts + ships any
8
+ * newly uploadable events. Fail-soft: a failed upload is queued in the outbox (its events assigned
9
+ * the batchId so they are not re-picked) and retried on a later sweep with backoff.
10
+ */
11
+ export declare function runFeedbackUploadSweep(projectId: string, now?: Date): Promise<FeedbackSweepResult>;
@@ -0,0 +1,102 @@
1
+ export type TurnBaselineState = "running" | "completed" | "failed" | "cancelled";
2
+ export type FileChangeStatus = "added" | "modified" | "deleted" | "renamed" | "moved" | "copied" | "unchanged";
3
+ export type SnapshotKind = "missing" | "text" | "binary" | "directory" | "too-large";
4
+ export interface FileSnapshot {
5
+ exists: boolean;
6
+ kind: SnapshotKind;
7
+ sizeBytes?: number;
8
+ sha256?: string;
9
+ inlineContent?: string;
10
+ contentRef?: string;
11
+ }
12
+ export interface TurnFileChange {
13
+ path: string;
14
+ previousPath?: string;
15
+ status: FileChangeStatus;
16
+ additions?: number;
17
+ deletions?: number;
18
+ before?: FileSnapshot;
19
+ after?: FileSnapshot;
20
+ }
21
+ export interface TurnChangeSummary {
22
+ turnId: string;
23
+ sessionId: string;
24
+ projectId: string;
25
+ state: TurnBaselineState;
26
+ startedAt: string;
27
+ completedAt?: string;
28
+ filesChanged: number;
29
+ files: TurnFileChange[];
30
+ truncated?: boolean;
31
+ }
32
+ export declare function resolveProjectRelativePath(projectRoot: string, input: string): string | null;
33
+ export declare function startTurnBaseline(input: {
34
+ turnId: string;
35
+ sessionId: string;
36
+ projectId?: string;
37
+ workspaceDir?: string;
38
+ seedPaths?: unknown;
39
+ }): Promise<void>;
40
+ export declare function captureFileBefore(input: {
41
+ turnId?: string;
42
+ projectId?: string;
43
+ workspaceDir?: string;
44
+ path: string;
45
+ entryPath?: string;
46
+ previousPath?: string;
47
+ }): Promise<void>;
48
+ export declare function captureFileAfter(input: {
49
+ turnId?: string;
50
+ projectId?: string;
51
+ workspaceDir?: string;
52
+ path: string;
53
+ entryPath?: string;
54
+ previousPath?: string;
55
+ status?: FileChangeStatus;
56
+ }): Promise<void>;
57
+ export declare function captureAbsoluteBefore(input: {
58
+ turnId?: string;
59
+ workspaceDir: string;
60
+ absolutePath: string;
61
+ }): Promise<void>;
62
+ export declare function captureAbsoluteAfter(input: {
63
+ turnId?: string;
64
+ workspaceDir: string;
65
+ absolutePath: string;
66
+ status?: FileChangeStatus;
67
+ }): Promise<void>;
68
+ export declare function finalizeTurnBaseline(input: {
69
+ turnId: string;
70
+ state: TurnBaselineState;
71
+ }): Promise<TurnChangeSummary | null>;
72
+ export declare function getTurnBaselineSummary(projectId: string, turnId: string): Promise<TurnChangeSummary | null>;
73
+ export declare function listRecentTurnBaselines(input: {
74
+ projectId: string;
75
+ sessionId?: string;
76
+ limit?: number;
77
+ }): Promise<{
78
+ summaries: TurnChangeSummary[];
79
+ }>;
80
+ export declare function getTurnBaselineFileBaseline(input: {
81
+ projectId: string;
82
+ turnId: string;
83
+ path: string;
84
+ }): Promise<{
85
+ path: string;
86
+ content: string | null;
87
+ snapshot: FileSnapshot | null;
88
+ }>;
89
+ export declare function getTurnBaselineFileDiff(input: {
90
+ projectId: string;
91
+ turnId: string;
92
+ path: string;
93
+ }): Promise<{
94
+ path: string;
95
+ previousPath?: string;
96
+ status: FileChangeStatus;
97
+ original: string;
98
+ modified: string;
99
+ language?: string;
100
+ additions?: number;
101
+ deletions?: number;
102
+ }>;
@@ -0,0 +1,59 @@
1
+ export type AgentMode = "chat" | "solo" | "product" | "workflow" | "unknown";
2
+ export interface TurnTelemetryUsage {
3
+ inputTokens?: number;
4
+ outputTokens?: number;
5
+ totalTokens?: number;
6
+ }
7
+ export interface TurnTelemetryToolSummary {
8
+ calledTools: string[];
9
+ failedTools: string[];
10
+ blockedTools: string[];
11
+ }
12
+ export interface TurnTelemetryFileContext {
13
+ changedFileCount?: number;
14
+ changedPathsPreview?: string[];
15
+ hasTurnFileChanges?: boolean;
16
+ }
17
+ export interface TurnTelemetrySnapshot {
18
+ turnId: string;
19
+ sessionId: string;
20
+ projectId?: string;
21
+ /** Gateway-stamped alias; v1 MUST equal turnId (design §7.3). Set at finalize. */
22
+ assistantMessageId?: string;
23
+ model?: string;
24
+ provider?: string;
25
+ agentMode?: AgentMode;
26
+ sourceChannel?: string;
27
+ usage?: TurnTelemetryUsage;
28
+ toolSummary?: TurnTelemetryToolSummary;
29
+ fileContext?: TurnTelemetryFileContext;
30
+ createdAt: string;
31
+ finalizedAt?: string;
32
+ }
33
+ /** Fields that can be merged into a turn's telemetry record as the turn progresses. */
34
+ export type TurnTelemetryPatch = Partial<Omit<TurnTelemetrySnapshot, "turnId" | "createdAt" | "finalizedAt" | "assistantMessageId">>;
35
+ /**
36
+ * Merge a telemetry fragment into the in-memory record for a turn. Pieces (tool summary,
37
+ * usage/model, file context) arrive at different points in the pipeline and upsert into the
38
+ * same turnId record. Safe to call before the projectId is known; the first call seeds it.
39
+ */
40
+ export declare function recordTurnTelemetry(turnId: string, patch: TurnTelemetryPatch): void;
41
+ /**
42
+ * Flush the accumulated telemetry for a turn to disk and drop it from memory. Returns null
43
+ * (after dropping the in-memory record) when no projectId resolved — telemetry, like the turn
44
+ * baseline, is only persisted for turns that belong to a registered project.
45
+ */
46
+ export declare function finalizeTurnTelemetry(input: {
47
+ turnId: string;
48
+ projectId?: string;
49
+ }): Promise<TurnTelemetrySnapshot | null>;
50
+ export declare function getTurnTelemetryRecord(projectId: string, turnId: string): Promise<TurnTelemetrySnapshot | null>;
51
+ export declare function listTurnTelemetryBySession(input: {
52
+ projectId: string;
53
+ sessionId?: string;
54
+ limit?: number;
55
+ }): Promise<{
56
+ records: TurnTelemetrySnapshot[];
57
+ }>;
58
+ /** Test/maintenance helper: drop any in-memory telemetry not yet finalized. */
59
+ export declare function __resetActiveTurnTelemetryForTest(): void;
@@ -0,0 +1,35 @@
1
+ export type WorkingMaterialKind = "workspace" | "instructions" | "generated" | "url";
2
+ export interface WorkingMaterialItem {
3
+ id: string;
4
+ projectId: string;
5
+ sessionId: string;
6
+ sourceKind: WorkingMaterialKind;
7
+ path?: string;
8
+ title: string;
9
+ viewerHint?: string;
10
+ pinned: boolean;
11
+ order: number;
12
+ addedAt: string;
13
+ updatedAt: string;
14
+ missing?: boolean;
15
+ }
16
+ export declare function getWorkingMaterials(projectId: string, sessionId: string): Promise<{
17
+ items: WorkingMaterialItem[];
18
+ missing: WorkingMaterialItem[];
19
+ }>;
20
+ export declare function replaceWorkingMaterials(projectId: string, sessionId: string, items: unknown[]): Promise<{
21
+ ok: true;
22
+ items: WorkingMaterialItem[];
23
+ }>;
24
+ export declare function upsertWorkingMaterial(projectId: string, sessionId: string, item: unknown): Promise<{
25
+ ok: true;
26
+ items: WorkingMaterialItem[];
27
+ }>;
28
+ export declare function removeWorkingMaterial(projectId: string, sessionId: string, id: string): Promise<{
29
+ ok: true;
30
+ items: WorkingMaterialItem[];
31
+ }>;
32
+ export declare function reorderWorkingMaterials(projectId: string, sessionId: string, ids: string[]): Promise<{
33
+ ok: true;
34
+ items: WorkingMaterialItem[];
35
+ }>;
@@ -35,6 +35,12 @@ export interface MemoryExtractionItem {
35
35
  tags?: string[];
36
36
  /** Ids of already-uploaded attachments to link to this memory on commit. */
37
37
  attachmentIds?: string[];
38
+ /** Evidence trail for distillation-style sources (feedback — §10): audit refs + crash-safe dedup key. */
39
+ evidence?: {
40
+ kind: string;
41
+ refs: string[];
42
+ idempotencyKey: string;
43
+ };
38
44
  }
39
45
  export interface MemoryConsolidationWriteResult {
40
46
  memoriesAdded?: number;
@@ -64,6 +64,7 @@ export interface ToolBootstrapConfig {
64
64
  debug(message: string): void;
65
65
  };
66
66
  getTaskScopeKey?(): string | undefined;
67
+ getCurrentTurnId?(): string | undefined;
67
68
  onExecProgress?(progress: ToolBootstrapProgress): void;
68
69
  }
69
70
  export interface ToolBootstrap {
@@ -21,5 +21,19 @@ export declare function getFreshWorkspaceEvidencePolicy(messages: readonly Promp
21
21
  export declare function looksLikeBuildIntent(messages: readonly PromptMessageLike[] | string): boolean;
22
22
  export declare function isLightweightChatTurn(messages: readonly PromptMessageLike[] | string): boolean;
23
23
  export declare function isExplicitNoToolTurn(messages: readonly PromptMessageLike[] | string): boolean;
24
+ /**
25
+ * Orchestration / capability primitives that survive every evidence filter.
26
+ * The policy's job is to FORCE fresh-evidence tools into the turn, not to
27
+ * strip the coordination layer — removing task/agent here silently breaks
28
+ * sub-agent delegation and background-task tracking on any turn whose text
29
+ * happens to match an evidence pattern (e.g. "write reports/x.json").
30
+ * `skill_view` belongs here for the same reason: it is the capability-invocation
31
+ * primitive, and the `# Available Skills` section tells the model to call it.
32
+ * Stripping `skill_view` on a file/mutation/shell turn (i.e. almost every real task)
33
+ * makes that instruction impossible to follow — the model cannot call a tool it
34
+ * was never given — which was the entire "skills never self-activate" bug.
35
+ * (skills_list / skill_manage are not load-bearing for self-activation, so they
36
+ * stay subject to the normal evidence filter.)
37
+ */
24
38
  export declare function selectFreshWorkspaceEvidenceTools<TTool extends ToolNameLike>(tools: readonly TTool[], policy: FreshWorkspaceEvidencePolicy): TTool[];
25
39
  export declare function createFreshWorkspaceEvidenceSection(policy: FreshWorkspaceEvidencePolicy): SystemPromptSection | null;
@@ -46,6 +46,17 @@ export interface McpManagerConfig {
46
46
  /** Runtime-owned catalog used for dynamic MCP tool injection. */
47
47
  toolCatalog?: ToolRegistryLike;
48
48
  }
49
+ /**
50
+ * Run `attempt` up to `options.attempts` times, backing off `baseDelayMs * n`
51
+ * between tries. Returns the first success; rethrows the last error if every
52
+ * attempt fails. `sleep` is injectable so callers (and tests) control timing.
53
+ */
54
+ export declare function connectWithRetry<T>(attempt: () => Promise<T>, options: {
55
+ attempts: number;
56
+ baseDelayMs: number;
57
+ sleep?: (ms: number) => Promise<void>;
58
+ onRetry?: (attemptNumber: number, err: unknown) => void;
59
+ }): Promise<T>;
49
60
  export declare class McpManager {
50
61
  private runtime;
51
62
  private definitions;
@@ -162,7 +162,7 @@ export declare class LocalMemoryProvider implements MemoryProvider {
162
162
  page?: number;
163
163
  pageSize?: number;
164
164
  activeOnly?: boolean;
165
- }): import("./local-store.js").MemoryRecord[];
165
+ }): import("./local-store-records.js").MemoryRecord[];
166
166
  /**
167
167
  * Find memories by event date (+/- tolerance). For temporal context retrieval.
168
168
  */
@@ -178,8 +178,8 @@ export declare class LocalMemoryProvider implements MemoryProvider {
178
178
  bucketCount?: number;
179
179
  clusterLimit?: number;
180
180
  activeOnly?: boolean;
181
- }): import("./local-store.js").MemoryAtlasResult;
182
- findByEventDate(userId: string, targetDate: string, toleranceDays?: number): import("./local-store.js").MemorySearchHit[];
181
+ }): import("./local-store-records.js").MemoryAtlasResult;
182
+ findByEventDate(userId: string, targetDate: string, toleranceDays?: number): import("./local-store-records.js").MemorySearchHit[];
183
183
  /**
184
184
  * Find related memories (event continuity detection).
185
185
  * Given a new memory, finds existing memories that are semantically related