memorix 1.2.0 → 1.2.2
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 +30 -1
- package/README.md +18 -4
- package/README.zh-CN.md +18 -4
- package/TEAM.md +86 -86
- package/dist/cli/index.js +15919 -14055
- package/dist/cli/index.js.map +1 -1
- package/dist/index.js +1997 -1021
- package/dist/index.js.map +1 -1
- package/dist/maintenance-runner.d.ts +1 -1
- package/dist/maintenance-runner.js +8481 -8005
- package/dist/maintenance-runner.js.map +1 -1
- package/dist/memcode-runtime/CHANGELOG.md +30 -1
- package/dist/sdk.d.ts +7 -2
- package/dist/sdk.js +2022 -1024
- package/dist/sdk.js.map +1 -1
- package/dist/types.d.ts +49 -1
- package/dist/types.js.map +1 -1
- package/docs/1.2.2-MEMORY-CONTROL-PLANE.md +434 -0
- package/docs/AGENT_OPERATOR_PLAYBOOK.md +4 -0
- package/docs/API_REFERENCE.md +27 -5
- package/docs/DESIGN_DECISIONS.md +357 -357
- package/docs/DEVELOPMENT.md +4 -0
- package/docs/README.md +1 -1
- package/docs/SETUP.md +7 -1
- package/docs/dev-log/progress.txt +91 -11
- package/docs/knowledge/workflows/memorix-release.md +57 -0
- package/package.json +1 -1
- package/plugins/codex/memorix/.codex-plugin/plugin.json +1 -1
- package/src/audit/index.ts +156 -156
- package/src/cli/command-guide.ts +192 -0
- package/src/cli/commands/audit-list.ts +89 -89
- package/src/cli/commands/audit.ts +9 -4
- package/src/cli/commands/background.ts +659 -659
- package/src/cli/commands/cleanup.ts +5 -1
- package/src/cli/commands/codegraph.ts +17 -8
- package/src/cli/commands/context.ts +3 -2
- package/src/cli/commands/doctor.ts +4 -2
- package/src/cli/commands/explain.ts +9 -3
- package/src/cli/commands/formation.ts +48 -48
- package/src/cli/commands/git-hook-install.ts +111 -111
- package/src/cli/commands/handoff.ts +75 -61
- package/src/cli/commands/hooks-status.ts +63 -63
- package/src/cli/commands/identity.ts +116 -0
- package/src/cli/commands/ingest-commit.ts +153 -153
- package/src/cli/commands/ingest-image.ts +71 -69
- package/src/cli/commands/ingest-log.ts +180 -180
- package/src/cli/commands/ingest.ts +44 -44
- package/src/cli/commands/integrate-shared.ts +15 -15
- package/src/cli/commands/knowledge.ts +40 -0
- package/src/cli/commands/lock.ts +93 -92
- package/src/cli/commands/memory.ts +58 -21
- package/src/cli/commands/message.ts +123 -118
- package/src/cli/commands/operator-shared.ts +98 -3
- package/src/cli/commands/poll.ts +74 -64
- package/src/cli/commands/purge-all-memory.ts +85 -85
- package/src/cli/commands/purge-project-memory.ts +83 -83
- package/src/cli/commands/reasoning.ts +135 -121
- package/src/cli/commands/retention.ts +9 -4
- package/src/cli/commands/serve-http.ts +22 -43
- package/src/cli/commands/serve-shared.ts +118 -118
- package/src/cli/commands/session.ts +29 -3
- package/src/cli/commands/setup.ts +9 -3
- package/src/cli/commands/skills.ts +124 -119
- package/src/cli/commands/status.ts +4 -3
- package/src/cli/commands/task.ts +193 -184
- package/src/cli/commands/team.ts +14 -10
- package/src/cli/commands/transfer.ts +108 -55
- package/src/cli/commands/uninstall-project-artifacts.ts +85 -85
- package/src/cli/identity.ts +89 -0
- package/src/cli/index.ts +96 -19
- package/src/cli/invocation.ts +115 -0
- package/src/cli/tui/ChatView.tsx +234 -234
- package/src/cli/tui/CommandBar.tsx +312 -312
- package/src/cli/tui/ContextRail.tsx +118 -118
- package/src/cli/tui/HeaderBar.tsx +72 -72
- package/src/cli/tui/LogoBanner.tsx +51 -51
- package/src/cli/tui/Sidebar.tsx +179 -179
- package/src/cli/tui/chat-service.ts +41 -18
- package/src/cli/tui/data.ts +23 -44
- package/src/cli/tui/index.ts +41 -41
- package/src/cli/tui/markdown-render.tsx +371 -371
- package/src/cli/tui/operator-context.ts +60 -0
- package/src/cli/tui/use-mouse.ts +157 -157
- package/src/cli/tui/useNavigation.ts +56 -56
- package/src/cli/tui/views/MemoryView.tsx +10 -8
- package/src/cli/update-checker.ts +211 -211
- package/src/cli/version.ts +7 -7
- package/src/cli/workbench.ts +1 -1
- package/src/codegraph/auto-context.ts +34 -17
- package/src/codegraph/context-pack.ts +1 -0
- package/src/codegraph/current-facts.ts +19 -1
- package/src/codegraph/project-context.ts +2 -0
- package/src/codegraph/task-lens.ts +49 -5
- package/src/compact/engine.ts +26 -10
- package/src/compact/index-format.ts +25 -2
- package/src/compact/token-budget.ts +74 -74
- package/src/dashboard/project-classification.ts +64 -64
- package/src/dashboard/server.ts +58 -52
- package/src/embedding/fastembed-provider.ts +142 -142
- package/src/embedding/transformers-provider.ts +111 -111
- package/src/git/extractor.ts +209 -209
- package/src/git/hooks-path.ts +85 -85
- package/src/hooks/admission.ts +117 -0
- package/src/hooks/handler.ts +98 -91
- package/src/hooks/pattern-detector.ts +173 -173
- package/src/hooks/significance-filter.ts +250 -250
- package/src/knowledge/claims.ts +51 -1
- package/src/knowledge/context-assembly.ts +97 -0
- package/src/knowledge/types.ts +1 -0
- package/src/knowledge/workflows.ts +34 -3
- package/src/knowledge/workset.ts +179 -10
- package/src/llm/memory-manager.ts +328 -328
- package/src/llm/provider.ts +885 -885
- package/src/llm/quality.ts +248 -248
- package/src/memory/admission.ts +57 -0
- package/src/memory/attribution-guard.ts +249 -249
- package/src/memory/auto-relations.ts +21 -0
- package/src/memory/consolidation.ts +13 -2
- package/src/memory/disclosure-policy.ts +140 -135
- package/src/memory/entity-extractor.ts +197 -197
- package/src/memory/export-import.ts +11 -3
- package/src/memory/formation/evaluate.ts +217 -217
- package/src/memory/formation/extract.ts +361 -361
- package/src/memory/formation/index.ts +417 -417
- package/src/memory/formation/resolve.ts +344 -344
- package/src/memory/formation/types.ts +315 -315
- package/src/memory/freshness.ts +122 -122
- package/src/memory/graph-context.ts +8 -2
- package/src/memory/graph-scope.ts +46 -0
- package/src/memory/graph.ts +197 -197
- package/src/memory/observations.ts +162 -4
- package/src/memory/quality-audit.ts +2 -0
- package/src/memory/refs.ts +94 -94
- package/src/memory/retention.ts +22 -2
- package/src/memory/secret-filter.ts +79 -79
- package/src/memory/session.ts +5 -2
- package/src/memory/visibility.ts +80 -0
- package/src/multimodal/image-loader.ts +143 -143
- package/src/orchestrate/adapters/claude-stream.ts +192 -192
- package/src/orchestrate/adapters/claude.ts +111 -111
- package/src/orchestrate/adapters/codex-stream.ts +134 -134
- package/src/orchestrate/adapters/codex.ts +41 -41
- package/src/orchestrate/adapters/gemini-stream.ts +166 -166
- package/src/orchestrate/adapters/gemini.ts +42 -42
- package/src/orchestrate/adapters/index.ts +73 -73
- package/src/orchestrate/adapters/opencode-stream.ts +143 -143
- package/src/orchestrate/adapters/opencode.ts +47 -47
- package/src/orchestrate/adapters/spawn-helper.ts +286 -286
- package/src/orchestrate/adapters/types.ts +77 -77
- package/src/orchestrate/capability-router.ts +284 -284
- package/src/orchestrate/context-compact.ts +188 -188
- package/src/orchestrate/cost-tracker.ts +219 -219
- package/src/orchestrate/error-recovery.ts +191 -191
- package/src/orchestrate/evidence.ts +140 -140
- package/src/orchestrate/ledger.ts +110 -110
- package/src/orchestrate/memorix-bridge.ts +378 -340
- package/src/orchestrate/output-budget.ts +80 -80
- package/src/orchestrate/permission.ts +152 -152
- package/src/orchestrate/pipeline-trace.ts +131 -131
- package/src/orchestrate/prompt-builder.ts +155 -155
- package/src/orchestrate/ring-buffer.ts +37 -37
- package/src/orchestrate/task-graph.ts +389 -389
- package/src/orchestrate/verify-gate.ts +33 -10
- package/src/orchestrate/worktree.ts +232 -232
- package/src/project/aliases.ts +374 -374
- package/src/project/detector.ts +268 -268
- package/src/rules/adapters/claude-code.ts +99 -99
- package/src/rules/adapters/codex.ts +97 -97
- package/src/rules/adapters/copilot.ts +124 -124
- package/src/rules/adapters/cursor.ts +114 -114
- package/src/rules/adapters/kiro.ts +126 -126
- package/src/rules/adapters/trae.ts +56 -56
- package/src/rules/adapters/windsurf.ts +83 -83
- package/src/rules/syncer.ts +235 -235
- package/src/runtime/control-plane-maintenance.ts +1 -0
- package/src/runtime/isolated-maintenance.ts +1 -0
- package/src/runtime/lifecycle.ts +18 -0
- package/src/runtime/maintenance-jobs.ts +1 -0
- package/src/runtime/maintenance-runner.ts +2 -0
- package/src/runtime/project-maintenance.ts +89 -0
- package/src/sdk.ts +334 -304
- package/src/search/intent-detector.ts +289 -289
- package/src/search/query-expansion.ts +52 -52
- package/src/server/formation-timeout.ts +27 -27
- package/src/server.ts +334 -93
- package/src/skills/mini-skills.ts +386 -386
- package/src/store/chat-store.ts +119 -119
- package/src/store/graph-store.ts +249 -249
- package/src/store/mini-skill-store.ts +349 -349
- package/src/store/orama-store.ts +61 -6
- package/src/store/persistence-json.ts +212 -212
- package/src/store/persistence.ts +291 -291
- package/src/store/project-affinity.ts +195 -195
- package/src/store/sqlite-db.ts +23 -1
- package/src/store/sqlite-store.ts +12 -2
- package/src/team/event-bus.ts +76 -76
- package/src/team/file-locks.ts +173 -173
- package/src/team/handoff.ts +168 -161
- package/src/team/messages.ts +203 -203
- package/src/team/poll.ts +132 -132
- package/src/team/tasks.ts +211 -211
- package/src/types.ts +51 -0
- package/src/wiki/generator.ts +2 -0
- package/src/workspace/mcp-adapters/codex.ts +191 -191
- package/src/workspace/mcp-adapters/copilot.ts +105 -105
- package/src/workspace/mcp-adapters/cursor.ts +53 -53
- package/src/workspace/mcp-adapters/kiro.ts +64 -64
- package/src/workspace/mcp-adapters/opencode.ts +123 -123
- package/src/workspace/mcp-adapters/trae.ts +134 -134
- package/src/workspace/mcp-adapters/windsurf.ts +91 -91
- package/src/workspace/sanitizer.ts +60 -60
- package/src/workspace/workflow-sync.ts +131 -131
package/src/knowledge/types.ts
CHANGED
|
@@ -7,6 +7,7 @@ import { atomicWriteFile, withFileLock } from '../store/file-lock.js';
|
|
|
7
7
|
import { WorkflowSyncer } from '../workspace/workflow-sync.js';
|
|
8
8
|
import { getKnowledgeWorkspacePaths, resolveKnowledgeWorkspaceFile } from './workspace.js';
|
|
9
9
|
import { WorkflowStore } from './workflow-store.js';
|
|
10
|
+
import { containsTaskKeyword } from '../codegraph/task-lens.js';
|
|
10
11
|
import type {
|
|
11
12
|
WorkflowAdapterPreview,
|
|
12
13
|
WorkflowAdapterTarget,
|
|
@@ -414,6 +415,9 @@ const LENS_TERMS: Record<string, string[]> = {
|
|
|
414
415
|
test: ['test', 'verify', 'smoke', '测试', '验证'],
|
|
415
416
|
};
|
|
416
417
|
|
|
418
|
+
const GENERIC_WORKFLOW_LENSES = new Set(['review', 'test']);
|
|
419
|
+
const GENERIC_WORKFLOW_TERMS = new Set(['review', 'audit', 'test', 'verify', 'smoke']);
|
|
420
|
+
|
|
417
421
|
function inferTaskLenses(value: string): string[] {
|
|
418
422
|
const text = value.toLowerCase();
|
|
419
423
|
return Object.entries(LENS_TERMS)
|
|
@@ -425,20 +429,28 @@ function taskScore(workflow: WorkflowSpec, task: string): { score: number; reaso
|
|
|
425
429
|
const text = task.toLowerCase();
|
|
426
430
|
let score = 0;
|
|
427
431
|
const reasons: string[] = [];
|
|
432
|
+
const matchedLenses = new Set<string>();
|
|
433
|
+
const matchedTriggers = new Set<string>();
|
|
428
434
|
for (const lens of workflow.taskLenses) {
|
|
429
435
|
const terms = LENS_TERMS[lens.toLowerCase()] ?? [lens.toLowerCase()];
|
|
430
|
-
if (terms.some(term =>
|
|
436
|
+
if (terms.some(term => containsTaskKeyword(task, term))) {
|
|
431
437
|
score += 20;
|
|
432
438
|
reasons.push('matches ' + lens + ' workflow');
|
|
439
|
+
matchedLenses.add(lens.toLowerCase());
|
|
433
440
|
}
|
|
434
441
|
}
|
|
435
442
|
for (const trigger of workflow.triggers) {
|
|
436
443
|
const term = trigger.toLowerCase().trim();
|
|
437
|
-
if (term.length >= 2 &&
|
|
444
|
+
if (term.length >= 2 && containsTaskKeyword(task, term)) {
|
|
438
445
|
score += 8;
|
|
439
446
|
reasons.push('matches trigger "' + trigger + '"');
|
|
447
|
+
matchedTriggers.add(term);
|
|
440
448
|
}
|
|
441
449
|
}
|
|
450
|
+
const hasSpecificLens = workflow.taskLenses.some(lens => !GENERIC_WORKFLOW_LENSES.has(lens.toLowerCase()));
|
|
451
|
+
const hasSpecificMatch = [...matchedLenses].some(lens => !GENERIC_WORKFLOW_LENSES.has(lens))
|
|
452
|
+
|| [...matchedTriggers].some(trigger => !GENERIC_WORKFLOW_TERMS.has(trigger));
|
|
453
|
+
if (hasSpecificLens && !hasSpecificMatch) return { score: 0, reasons: [] };
|
|
442
454
|
return { score, reasons: [...new Set(reasons)] };
|
|
443
455
|
}
|
|
444
456
|
|
|
@@ -475,9 +487,28 @@ function importedWorkflowSpec(input: {
|
|
|
475
487
|
sourcePath: string;
|
|
476
488
|
raw: string;
|
|
477
489
|
}): WorkflowSpec {
|
|
490
|
+
let sourceMatter: matter.GrayMatterFile<string>;
|
|
491
|
+
try {
|
|
492
|
+
sourceMatter = matter(input.raw);
|
|
493
|
+
} catch (error) {
|
|
494
|
+
throw new Error('Malformed Windsurf workflow Markdown: ' + (error instanceof Error ? error.message : String(error)));
|
|
495
|
+
}
|
|
496
|
+
if (sourceMatter.data.id !== undefined) {
|
|
497
|
+
const id = requiredText(sourceMatter.data as Record<string, unknown>, 'id');
|
|
498
|
+
const sourcePath = 'workflows/' + slug(id) + '.md';
|
|
499
|
+
const canonical = parsedWorkflow(sourceMatter.data as Record<string, unknown>, sourceMatter.content, {
|
|
500
|
+
workspaceId: input.workspace.id,
|
|
501
|
+
sourcePath,
|
|
502
|
+
contentHash: hash(input.raw),
|
|
503
|
+
});
|
|
504
|
+
return materializeWorkflow({
|
|
505
|
+
...canonical,
|
|
506
|
+
importedFrom: input.sourcePath.replace(/\\/g, '/'),
|
|
507
|
+
});
|
|
508
|
+
}
|
|
478
509
|
const entry = new WorkflowSyncer().parseWindsurfWorkflow(input.sourceName, input.raw);
|
|
479
510
|
const content = entry.content.trim() || '## Execute\n\nFollow the imported workflow.';
|
|
480
|
-
const lenses = inferTaskLenses(entry.name + '\n' + entry.description
|
|
511
|
+
const lenses = inferTaskLenses(entry.name + '\n' + entry.description);
|
|
481
512
|
const createdAt = now();
|
|
482
513
|
const sourcePath = 'workflows/' + slug(entry.name) + '.md';
|
|
483
514
|
const spec: WorkflowSpec = {
|
package/src/knowledge/workset.ts
CHANGED
|
@@ -6,6 +6,14 @@ import { KnowledgeWorkspaceStore } from './workspace-store.js';
|
|
|
6
6
|
import { loadKnowledgeWorkspace } from './workspace.js';
|
|
7
7
|
import { WorkflowStore } from './workflow-store.js';
|
|
8
8
|
import { selectWorkflows } from './workflows.js';
|
|
9
|
+
import type {
|
|
10
|
+
ContextCandidateFreshness,
|
|
11
|
+
ContextCandidateKind,
|
|
12
|
+
ContextDeliveryTarget,
|
|
13
|
+
ContextReceipt,
|
|
14
|
+
ContextReceiptOmission,
|
|
15
|
+
ContextReceiptSelection,
|
|
16
|
+
} from './context-assembly.js';
|
|
9
17
|
import type { CodeGraphProviderQuality, ExternalCodeGraphOutline } from '../codegraph/types.js';
|
|
10
18
|
import type { KnowledgeClaim, ClaimEvidenceRef } from './types.js';
|
|
11
19
|
import type { KnowledgePageRecord, KnowledgeWorkspace } from './workspace-types.js';
|
|
@@ -98,6 +106,8 @@ export interface TaskWorkset {
|
|
|
98
106
|
tokenCount: number;
|
|
99
107
|
omitted: string[];
|
|
100
108
|
};
|
|
109
|
+
/** Privacy-safe selection metadata for diagnostics, never appended to the prompt. */
|
|
110
|
+
receipt: ContextReceipt;
|
|
101
111
|
prompt: string;
|
|
102
112
|
}
|
|
103
113
|
|
|
@@ -128,6 +138,8 @@ export interface BuildTaskWorksetInput {
|
|
|
128
138
|
};
|
|
129
139
|
runtimeCautions?: WorksetCaution[];
|
|
130
140
|
maxTokens?: number;
|
|
141
|
+
/** Delivery surface controls receipt semantics without changing prompt shape. */
|
|
142
|
+
deliveryTarget?: ContextDeliveryTarget;
|
|
131
143
|
}
|
|
132
144
|
|
|
133
145
|
function unique(values: string[]): string[] {
|
|
@@ -228,35 +240,104 @@ function appendLine(
|
|
|
228
240
|
maxTokens: number,
|
|
229
241
|
omitted: string[],
|
|
230
242
|
omittedKind: string,
|
|
243
|
+
selected?: ContextReceiptSelection[],
|
|
244
|
+
receiptSelection?: ContextReceiptSelection,
|
|
231
245
|
): boolean {
|
|
232
246
|
const next = lines.length ? lines.join('\n') + '\n' + candidate : candidate;
|
|
233
247
|
if (countTextTokens(next) <= maxTokens) {
|
|
234
248
|
lines.push(candidate);
|
|
249
|
+
if (receiptSelection) selected?.push(receiptSelection);
|
|
235
250
|
return true;
|
|
236
251
|
}
|
|
237
252
|
omitted.push(omittedKind);
|
|
238
253
|
return false;
|
|
239
254
|
}
|
|
240
255
|
|
|
256
|
+
function freshnessForMemory(status: WorksetMemorySource['status']): ContextCandidateFreshness {
|
|
257
|
+
if (status === 'current' || status === 'suspect' || status === 'stale') return status;
|
|
258
|
+
return 'unknown';
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
function receiptOmissionKind(raw: string): ContextCandidateKind | undefined {
|
|
262
|
+
if (raw.includes('task')) return 'task';
|
|
263
|
+
if (raw.includes('fact')) return 'current-fact';
|
|
264
|
+
if (raw.includes('state')) return 'code-state';
|
|
265
|
+
if (raw.includes('semantic')) return 'semantic-code';
|
|
266
|
+
if (raw.includes('start')) return 'start-here';
|
|
267
|
+
if (raw.includes('memory')) return 'memory';
|
|
268
|
+
if (raw.includes('claim')) return 'claim';
|
|
269
|
+
if (raw.includes('knowledge-page')) return 'knowledge-page';
|
|
270
|
+
if (raw.includes('workflow')) return 'workflow';
|
|
271
|
+
if (raw.includes('verification')) return 'verification';
|
|
272
|
+
if (raw.includes('caution')) return 'caution';
|
|
273
|
+
return undefined;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
function receiptOmissions(omitted: string[], hiddenCautionMemoryCount: number): ContextReceiptOmission[] {
|
|
277
|
+
const counts = new Map<ContextCandidateKind, number>();
|
|
278
|
+
for (const raw of omitted) {
|
|
279
|
+
const kind = receiptOmissionKind(raw);
|
|
280
|
+
if (!kind || raw.endsWith('-heading')) continue;
|
|
281
|
+
counts.set(kind, (counts.get(kind) ?? 0) + 1);
|
|
282
|
+
}
|
|
283
|
+
const receipt: ContextReceiptOmission[] = [...counts.entries()].map(([kind, count]) => ({
|
|
284
|
+
kind,
|
|
285
|
+
reason: 'token-budget',
|
|
286
|
+
count,
|
|
287
|
+
}));
|
|
288
|
+
if (hiddenCautionMemoryCount > 0) {
|
|
289
|
+
receipt.push({
|
|
290
|
+
kind: 'caution',
|
|
291
|
+
reason: 'hidden-by-task-lens',
|
|
292
|
+
count: hiddenCautionMemoryCount,
|
|
293
|
+
});
|
|
294
|
+
}
|
|
295
|
+
return receipt;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
function scheduledActions(cautions: WorksetCaution[]): string[] {
|
|
299
|
+
return cautions
|
|
300
|
+
.filter(caution => caution.kind === 'codegraph-refresh-queued')
|
|
301
|
+
.map(caution => short(caution.message, 28));
|
|
302
|
+
}
|
|
303
|
+
|
|
241
304
|
/**
|
|
242
305
|
* Render a bounded prompt from whole evidence items. It never cuts a page,
|
|
243
306
|
* workflow, or claim body into an untraceable partial fragment.
|
|
244
307
|
*/
|
|
245
|
-
export function renderTaskWorksetPrompt(input: Omit<TaskWorkset, 'prompt' | 'budget'> & {
|
|
308
|
+
export function renderTaskWorksetPrompt(input: Omit<TaskWorkset, 'prompt' | 'budget' | 'receipt'> & {
|
|
246
309
|
budget?: Partial<TaskWorkset['budget']>;
|
|
247
|
-
}): {
|
|
310
|
+
}): {
|
|
311
|
+
prompt: string;
|
|
312
|
+
tokenCount: number;
|
|
313
|
+
/** Compatibility summary: unique omission categories. */
|
|
314
|
+
omitted: string[];
|
|
315
|
+
/** Internal receipt input: one entry per candidate that did not fit. */
|
|
316
|
+
omittedItems: string[];
|
|
317
|
+
selected: ContextReceiptSelection[];
|
|
318
|
+
} {
|
|
248
319
|
const maxTokens = input.budget?.maxTokens ?? 180;
|
|
249
320
|
const omitted: string[] = [];
|
|
321
|
+
const selected: ContextReceiptSelection[] = [];
|
|
250
322
|
const lines: string[] = ['Memorix Autopilot Brief'];
|
|
251
323
|
const task = short(input.task || 'Continue the current task.', 34);
|
|
252
|
-
appendLine(lines, 'Task: ' + task, maxTokens, omitted, 'task-detail'
|
|
324
|
+
appendLine(lines, 'Task: ' + task, maxTokens, omitted, 'task-detail', selected, {
|
|
325
|
+
kind: 'task',
|
|
326
|
+
reason: 'current task supplied by the caller',
|
|
327
|
+
trust: 'source-backed',
|
|
328
|
+
});
|
|
253
329
|
appendLine(lines, 'Task lens: ' + input.lens, maxTokens, omitted, 'lens');
|
|
254
330
|
|
|
255
331
|
if (input.cautions.length > 0 || input.cautionMemory.length > 0) {
|
|
256
332
|
appendLine(lines, '', maxTokens, omitted, 'caution-heading');
|
|
257
333
|
appendLine(lines, 'Cautions', maxTokens, omitted, 'caution-heading');
|
|
258
334
|
for (const caution of input.cautions.slice(0, 6)) {
|
|
259
|
-
appendLine(lines, '- ' + short(caution.message, 22), maxTokens, omitted, 'caution'
|
|
335
|
+
appendLine(lines, '- ' + short(caution.message, 22), maxTokens, omitted, 'caution', selected, {
|
|
336
|
+
kind: 'caution',
|
|
337
|
+
id: 'caution:' + caution.kind,
|
|
338
|
+
reason: 'current project caution',
|
|
339
|
+
trust: 'source-backed',
|
|
340
|
+
});
|
|
260
341
|
}
|
|
261
342
|
for (const memory of input.cautionMemory.slice(0, 3)) {
|
|
262
343
|
const location = memory.path
|
|
@@ -269,6 +350,14 @@ export function renderTaskWorksetPrompt(input: Omit<TaskWorkset, 'prompt' | 'bud
|
|
|
269
350
|
maxTokens,
|
|
270
351
|
omitted,
|
|
271
352
|
'caution-memory',
|
|
353
|
+
selected,
|
|
354
|
+
{
|
|
355
|
+
kind: 'memory',
|
|
356
|
+
id: 'memory:' + memory.id,
|
|
357
|
+
reason: 'task-relevant memory requiring source verification',
|
|
358
|
+
freshness: freshnessForMemory(memory.status),
|
|
359
|
+
trust: 'historical',
|
|
360
|
+
},
|
|
272
361
|
);
|
|
273
362
|
}
|
|
274
363
|
if (input.hiddenCautionMemoryCount > 0) {
|
|
@@ -280,14 +369,23 @@ export function renderTaskWorksetPrompt(input: Omit<TaskWorkset, 'prompt' | 'bud
|
|
|
280
369
|
appendLine(lines, '', maxTokens, omitted, 'facts-heading');
|
|
281
370
|
appendLine(lines, 'Current project facts', maxTokens, omitted, 'facts-heading');
|
|
282
371
|
for (const fact of input.currentFacts.slice(0, 4)) {
|
|
283
|
-
appendLine(lines, '- ' + short(fact, 40), maxTokens, omitted, 'current-fact'
|
|
372
|
+
appendLine(lines, '- ' + short(fact, 40), maxTokens, omitted, 'current-fact', selected, {
|
|
373
|
+
kind: 'current-fact',
|
|
374
|
+
reason: 'current project state',
|
|
375
|
+
trust: 'source-backed',
|
|
376
|
+
});
|
|
284
377
|
}
|
|
285
378
|
}
|
|
286
379
|
|
|
287
380
|
if (input.codeState) {
|
|
288
381
|
appendLine(lines, '', maxTokens, omitted, 'state-heading');
|
|
289
382
|
appendLine(lines, 'Project state', maxTokens, omitted, 'state-heading');
|
|
290
|
-
appendLine(lines, input.codeState, maxTokens, omitted, 'code-state'
|
|
383
|
+
appendLine(lines, input.codeState, maxTokens, omitted, 'code-state', selected, {
|
|
384
|
+
kind: 'code-state',
|
|
385
|
+
...(input.provenance.snapshotId ? { id: 'snapshot:' + input.provenance.snapshotId } : {}),
|
|
386
|
+
reason: 'latest available Code State snapshot',
|
|
387
|
+
trust: 'source-backed',
|
|
388
|
+
});
|
|
291
389
|
}
|
|
292
390
|
|
|
293
391
|
if (input.semanticCode && (input.semanticCode.entryPoints.length > 0 || input.semanticCode.relations.length > 0)) {
|
|
@@ -301,6 +399,13 @@ export function renderTaskWorksetPrompt(input: Omit<TaskWorkset, 'prompt' | 'bud
|
|
|
301
399
|
maxTokens,
|
|
302
400
|
omitted,
|
|
303
401
|
'semantic-relation',
|
|
402
|
+
selected,
|
|
403
|
+
{
|
|
404
|
+
kind: 'semantic-code',
|
|
405
|
+
id: 'code:' + location,
|
|
406
|
+
reason: 'validated optional semantic code relation',
|
|
407
|
+
trust: 'derived',
|
|
408
|
+
},
|
|
304
409
|
);
|
|
305
410
|
}
|
|
306
411
|
if (input.semanticCode.relations.length === 0) {
|
|
@@ -312,6 +417,13 @@ export function renderTaskWorksetPrompt(input: Omit<TaskWorkset, 'prompt' | 'bud
|
|
|
312
417
|
maxTokens,
|
|
313
418
|
omitted,
|
|
314
419
|
'semantic-entry',
|
|
420
|
+
selected,
|
|
421
|
+
{
|
|
422
|
+
kind: 'semantic-code',
|
|
423
|
+
id: 'code:' + location,
|
|
424
|
+
reason: 'validated optional semantic code entry point',
|
|
425
|
+
trust: 'derived',
|
|
426
|
+
},
|
|
315
427
|
);
|
|
316
428
|
}
|
|
317
429
|
}
|
|
@@ -321,7 +433,12 @@ export function renderTaskWorksetPrompt(input: Omit<TaskWorkset, 'prompt' | 'bud
|
|
|
321
433
|
appendLine(lines, '', maxTokens, omitted, 'start-heading');
|
|
322
434
|
appendLine(lines, 'Start here', maxTokens, omitted, 'start-heading');
|
|
323
435
|
for (const source of input.startHere.slice(0, 5)) {
|
|
324
|
-
appendLine(lines, '- ' + source, maxTokens, omitted, 'start-here'
|
|
436
|
+
appendLine(lines, '- ' + source, maxTokens, omitted, 'start-here', selected, {
|
|
437
|
+
kind: 'start-here',
|
|
438
|
+
id: 'path:' + source,
|
|
439
|
+
reason: 'task-lensed starting point',
|
|
440
|
+
trust: 'derived',
|
|
441
|
+
});
|
|
325
442
|
}
|
|
326
443
|
}
|
|
327
444
|
|
|
@@ -338,6 +455,14 @@ export function renderTaskWorksetPrompt(input: Omit<TaskWorkset, 'prompt' | 'bud
|
|
|
338
455
|
maxTokens,
|
|
339
456
|
omitted,
|
|
340
457
|
'reliable-memory',
|
|
458
|
+
selected,
|
|
459
|
+
{
|
|
460
|
+
kind: 'memory',
|
|
461
|
+
id: 'memory:' + memory.id,
|
|
462
|
+
reason: 'current code-bound memory',
|
|
463
|
+
freshness: freshnessForMemory(memory.status),
|
|
464
|
+
trust: 'historical',
|
|
465
|
+
},
|
|
341
466
|
);
|
|
342
467
|
}
|
|
343
468
|
}
|
|
@@ -346,10 +471,27 @@ export function renderTaskWorksetPrompt(input: Omit<TaskWorkset, 'prompt' | 'bud
|
|
|
346
471
|
appendLine(lines, '', maxTokens, omitted, 'knowledge-heading');
|
|
347
472
|
appendLine(lines, 'Project knowledge', maxTokens, omitted, 'knowledge-heading');
|
|
348
473
|
for (const claim of input.claims.slice(0, 3)) {
|
|
349
|
-
appendLine(lines, '- ' + claim.assertion + ' [' + claim.id + ']', maxTokens, omitted, 'claim'
|
|
474
|
+
appendLine(lines, '- ' + claim.assertion + ' [' + claim.id + ']', maxTokens, omitted, 'claim', selected, {
|
|
475
|
+
kind: 'claim',
|
|
476
|
+
id: 'claim:' + claim.id,
|
|
477
|
+
reason: 'source-qualified task match',
|
|
478
|
+
trust: 'source-backed',
|
|
479
|
+
});
|
|
350
480
|
}
|
|
351
481
|
for (const page of input.pages.slice(0, 2)) {
|
|
352
|
-
|
|
482
|
+
const supportsDeliveredClaim = page.claimIds.some(claimId => selected.some(item => (
|
|
483
|
+
item.kind === 'claim' && item.id === 'claim:' + claimId
|
|
484
|
+
)));
|
|
485
|
+
if (!supportsDeliveredClaim) {
|
|
486
|
+
omitted.push('knowledge-page-dependency');
|
|
487
|
+
continue;
|
|
488
|
+
}
|
|
489
|
+
appendLine(lines, '- page: ' + page.relativePath, maxTokens, omitted, 'knowledge-page', selected, {
|
|
490
|
+
kind: 'knowledge-page',
|
|
491
|
+
id: 'page:' + page.id,
|
|
492
|
+
reason: 'approved page linked to a selected claim',
|
|
493
|
+
trust: 'source-backed',
|
|
494
|
+
});
|
|
353
495
|
}
|
|
354
496
|
}
|
|
355
497
|
|
|
@@ -363,6 +505,13 @@ export function renderTaskWorksetPrompt(input: Omit<TaskWorkset, 'prompt' | 'bud
|
|
|
363
505
|
maxTokens,
|
|
364
506
|
omitted,
|
|
365
507
|
'workflow',
|
|
508
|
+
selected,
|
|
509
|
+
{
|
|
510
|
+
kind: 'workflow',
|
|
511
|
+
id: 'workflow:' + workflow.id,
|
|
512
|
+
reason: 'task-matching project workflow',
|
|
513
|
+
trust: 'source-backed',
|
|
514
|
+
},
|
|
366
515
|
);
|
|
367
516
|
}
|
|
368
517
|
}
|
|
@@ -371,7 +520,11 @@ export function renderTaskWorksetPrompt(input: Omit<TaskWorkset, 'prompt' | 'bud
|
|
|
371
520
|
appendLine(lines, '', maxTokens, omitted, 'verification-heading');
|
|
372
521
|
appendLine(lines, 'Verify', maxTokens, omitted, 'verification-heading');
|
|
373
522
|
for (const check of input.verification.slice(0, 4)) {
|
|
374
|
-
appendLine(lines, '- ' + short(check, 20), maxTokens, omitted, 'verification'
|
|
523
|
+
appendLine(lines, '- ' + short(check, 20), maxTokens, omitted, 'verification', selected, {
|
|
524
|
+
kind: 'verification',
|
|
525
|
+
reason: 'task-lensed verification guidance',
|
|
526
|
+
trust: 'derived',
|
|
527
|
+
});
|
|
375
528
|
}
|
|
376
529
|
}
|
|
377
530
|
|
|
@@ -379,6 +532,8 @@ export function renderTaskWorksetPrompt(input: Omit<TaskWorkset, 'prompt' | 'bud
|
|
|
379
532
|
prompt: lines.join('\n'),
|
|
380
533
|
tokenCount: countTextTokens(lines.join('\n')),
|
|
381
534
|
omitted: unique(omitted),
|
|
535
|
+
omittedItems: omitted,
|
|
536
|
+
selected,
|
|
382
537
|
};
|
|
383
538
|
}
|
|
384
539
|
|
|
@@ -388,6 +543,7 @@ export function renderTaskWorksetPrompt(input: Omit<TaskWorkset, 'prompt' | 'bud
|
|
|
388
543
|
* context response.
|
|
389
544
|
*/
|
|
390
545
|
export async function buildTaskWorkset(input: BuildTaskWorksetInput): Promise<TaskWorkset> {
|
|
546
|
+
const startedAt = Date.now();
|
|
391
547
|
const task = input.task?.trim() ?? '';
|
|
392
548
|
const maxTokens = Math.max(96, Math.min(Math.floor(input.maxTokens ?? 180), 320));
|
|
393
549
|
const cautions = [...(input.runtimeCautions ?? []), ...snapshotCautions(input)];
|
|
@@ -503,6 +659,18 @@ export async function buildTaskWorkset(input: BuildTaskWorksetInput): Promise<Ta
|
|
|
503
659
|
...base,
|
|
504
660
|
budget: { maxTokens },
|
|
505
661
|
});
|
|
662
|
+
const receipt: ContextReceipt = {
|
|
663
|
+
version: '1.2.2',
|
|
664
|
+
target: input.deliveryTarget ?? 'project-context',
|
|
665
|
+
elapsedMs: Math.max(0, Date.now() - startedAt),
|
|
666
|
+
budget: {
|
|
667
|
+
maxTokens,
|
|
668
|
+
tokenCount: rendered.tokenCount,
|
|
669
|
+
},
|
|
670
|
+
selected: rendered.selected,
|
|
671
|
+
omitted: receiptOmissions(rendered.omittedItems, base.hiddenCautionMemoryCount),
|
|
672
|
+
scheduledActions: scheduledActions(normalizedCautions),
|
|
673
|
+
};
|
|
506
674
|
return {
|
|
507
675
|
...base,
|
|
508
676
|
budget: {
|
|
@@ -510,6 +678,7 @@ export async function buildTaskWorkset(input: BuildTaskWorksetInput): Promise<Ta
|
|
|
510
678
|
tokenCount: rendered.tokenCount,
|
|
511
679
|
omitted: rendered.omitted,
|
|
512
680
|
},
|
|
681
|
+
receipt,
|
|
513
682
|
prompt: rendered.prompt,
|
|
514
683
|
};
|
|
515
684
|
}
|