[codex] Add research memory project extension#40
Closed
ASIWU wants to merge 1 commit into
Closed
Conversation
There was a problem hiding this comment.
Pull request overview
Adds a new project-scoped, headless “Research Memory” extension and extends the local runtime to discover project extensions, expose their tools/skills, report extension capability diagnostics, and package the extension for distribution.
Changes:
- Introduces project-extension discovery (manifests + skill roots) and wires it into GUI-managed local runtime config generation.
- Adds a new Kun tool-provider for loading headless project-extension tools directly from a runtime module (no MCP transport) and reports extension diagnostics/capabilities.
- Adds the
extensions/research-memoryproject extension (SQLite-backed store, evidence gating, context resolution, snapshotting) plus showcase fixtures and tests.
Reviewed changes
Copilot reviewed 50 out of 50 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| vitest.config.ts | Runs extension tests as part of Vitest suite. |
| tsconfig.node.json | Includes extension TS sources in node-side typechecking. |
| src/shared/agent-runtime-contract.ts | Extends runtime capability contract to include extension counts/tool totals. |
| src/main/services/skill-service.ts | Adds extension-provided skill roots into GUI skill discovery. |
| src/main/services/skill-service.test.ts | Tests discovery of skills contributed via workspace extensions. |
| src/main/services/project-extension-service.ts | New service to discover headless project extensions and their skill roots/manifests. |
| src/main/runtime/local-runtime-agent-runtime-adapter.ts | Maps runtime “extensions” capability fields into GUI-facing capabilities. |
| src/main/local-runtime-process.ts | Writes extension manifests + extension skill roots into GUI-managed local runtime config. |
| src/main/local-runtime-process.test.ts | Tests config sync: adds extension manifests/skill roots and prunes stale entries. |
| src/main/local-runtime-package-contract.ts | Exposes ProjectExtensionCapabilityConfig to the packaged runtime contract exports. |
| scripts/local-runtime-package.cjs | Ensures the research-memory extension is built and packaged with the local runtime. |
| kun/tests/project-extension-tool-provider.test.ts | Tests loading tools from a project extension module and diagnostics for failure cases. |
| kun/tests/http-server.test.ts | Updates runtime diagnostics payload shape to include extensions. |
| kun/src/server/runtime-factory.ts | Loads project-extension tool providers and includes them in runtime capabilities/diagnostics. |
| kun/src/server/routes/server-runtime.ts | Extends RuntimeToolDiagnostics contract to include extension diagnostics. |
| kun/src/server/routes/runtime-info.ts | Adds empty extensions list to runtime diagnostics JSON response baseline. |
| kun/src/ports/tool-host.ts | Adds extension as a ToolProviderKind. |
| kun/src/contracts/capabilities.ts | Adds ProjectExtensionCapabilityConfig and reports extension capability counts in manifest. |
| kun/src/adapters/tool/project-extension-tool-provider.ts | New provider to load headless extension tools from runtime modules. |
| kun/src/adapters/tool/index.ts | Exports the new project-extension tool provider module. |
| extensions/research-memory/tsconfig.json | TypeScript build config for the extension package. |
| extensions/research-memory/tests/research-memory.test.ts | End-to-end tests for store/service/tools, including evidence gating and showcase acceptance. |
| extensions/research-memory/src/types.ts | Defines Research Memory domain types and tool names. |
| extensions/research-memory/src/tool-types.ts | Defines the minimal ToolHostContext shape used by the extension tools. |
| extensions/research-memory/src/store.ts | SQLite-backed persistence layer for experiment runs, memory items, and review/reflection events. |
| extensions/research-memory/src/snapshot.ts | Snapshot writer for markdown/JSON artifacts. |
| extensions/research-memory/src/service.ts | High-level service API for recording runs, reflecting, resolving context, reviews, and snapshots. |
| extensions/research-memory/src/reflection.ts | Reflection logic to infer method choices/insights/negative results/hypotheses from run metrics. |
| extensions/research-memory/src/index.ts | Exposes the extension API and defines the exported tool implementations with input/path-policy validation. |
| extensions/research-memory/src/evidence-gate.ts | Evidence gating rules to decide status/evidence level/confidence. |
| extensions/research-memory/src/context-resolver.ts | Query-based memory selection and budget-based trimming for resolve_context. |
| extensions/research-memory/src/artifact-parser.ts | Reads metrics/logs/artifacts from workspace paths with workspace-boundary enforcement. |
| extensions/research-memory/skill/SKILL.md | Documents the skill protocol and evidence-boundary guidelines. |
| extensions/research-memory/skill/skill.json | Skill metadata and trigger patterns (EN + ZH). |
| extensions/research-memory/showcase/ai4ai-model-iteration/notes/sciforge_product_notes.md | Showcase notes describing intended user-facing behavior. |
| extensions/research-memory/showcase/ai4ai-model-iteration/notes/research_log.md | Showcase research log fixture narrative. |
| extensions/research-memory/showcase/ai4ai-model-iteration/artifacts/runs/v5/metrics.json | Showcase run v5 metrics fixture. |
| extensions/research-memory/showcase/ai4ai-model-iteration/artifacts/runs/v5/manifest.json | Showcase run v5 artifact manifest fixture. |
| extensions/research-memory/showcase/ai4ai-model-iteration/artifacts/runs/v4/metrics.json | Showcase run v4 metrics fixture. |
| extensions/research-memory/showcase/ai4ai-model-iteration/artifacts/runs/v4/manifest.json | Showcase run v4 artifact manifest fixture. |
| extensions/research-memory/showcase/ai4ai-model-iteration/artifacts/runs/v3/metrics.json | Showcase run v3 metrics fixture. |
| extensions/research-memory/showcase/ai4ai-model-iteration/artifacts/runs/v3/manifest.json | Showcase run v3 artifact manifest fixture. |
| extensions/research-memory/showcase/ai4ai-model-iteration/artifacts/runs/v2/metrics.json | Showcase run v2 metrics fixture. |
| extensions/research-memory/showcase/ai4ai-model-iteration/artifacts/runs/v2/manifest.json | Showcase run v2 artifact manifest fixture. |
| extensions/research-memory/showcase/ai4ai-model-iteration/artifacts/runs/v1/metrics.json | Showcase run v1 metrics fixture. |
| extensions/research-memory/showcase/ai4ai-model-iteration/artifacts/runs/v1/manifest.json | Showcase run v1 artifact manifest fixture. |
| extensions/research-memory/showcase/ai4ai-model-iteration/artifacts/research_memory_snapshot.md | Placeholder documenting expected snapshot artifact path for the showcase. |
| extensions/research-memory/package.json | Declares the extension package, build scripts, and better-sqlite3 dependency. |
| extensions/research-memory/extension.json | Defines the extension manifest (kind/headless/runtime module/tool + skill contributions). |
| electron-builder.config.cjs | Packages the extension into Electron builds and ensures extension assets are included. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+52
to
+70
| const run: ExperimentRun = { | ||
| id: draft.id?.trim() || existing?.id || this.idGenerator('run'), | ||
| projectId: draft.projectId?.trim() || this.workspaceRoot, | ||
| title: draft.title.trim(), | ||
| status: draft.status ?? 'completed', | ||
| ...(draft.command ? { command: draft.command } : {}), | ||
| ...(draft.scriptPath ? { scriptPath: draft.scriptPath } : {}), | ||
| ...(draft.datasetVersion ? { datasetVersion: draft.datasetVersion } : {}), | ||
| ...(draft.environment ? { environment: draft.environment } : {}), | ||
| ...(draft.parameters ? { parameters: draft.parameters } : {}), | ||
| ...(draft.seed !== undefined ? { seed: draft.seed } : {}), | ||
| ...(draft.metrics ? { metrics: draft.metrics } : {}), | ||
| ...(draft.logsExcerpt ? { logsExcerpt: draft.logsExcerpt } : {}), | ||
| artifactRefs: uniqueStrings(draft.artifactRefs ?? []), | ||
| ...(draft.threadRef ? { threadRef: draft.threadRef } : {}), | ||
| ...(draft.turnRef ? { turnRef: draft.turnRef } : {}), | ||
| createdAt: existing?.createdAt ?? now, | ||
| updatedAt: now | ||
| } |
Comment on lines
+273
to
+279
| db.prepare('DELETE FROM memory_evidence_ref WHERE memory_id = ?').run(item.id) | ||
| for (const ref of item.evidenceRefs) { | ||
| db.prepare(` | ||
| INSERT INTO memory_evidence_ref (memory_id, project_id, evidence_ref, created_at) | ||
| VALUES (?, ?, ?, ?) | ||
| `).run(item.id, item.projectId, ref, item.createdAt) | ||
| } |
Comment on lines
+35
to
+39
| const trimmed = path.trim() | ||
| if (!trimmed) return '' | ||
| if (trimmed.includes(':')) return trimmed | ||
| const absolute = resolvePath(workspaceRoot, trimmed) | ||
| const rel = relative(workspaceRoot, absolute).replace(/\\/g, '/') |
Comment on lines
+91
to
+93
| const manifest = parseManifest(JSON.parse(readFileSync(resolvedManifestPath, 'utf8')) as unknown) | ||
| const extensionRoot = dirname(resolvedManifestPath) | ||
| const modulePath = resolve(extensionRoot, manifest.runtimeModule ?? 'dist/index.js') |
Comment on lines
+167
to
+181
| function normalizeTools(rawTools: unknown[], manifest: ProjectExtensionManifest): LocalTool[] { | ||
| const tools = rawTools.filter(isLocalTool) | ||
| const contributed = new Set(manifest.contributes?.agentTools ?? []) | ||
| if (contributed.size > 0) { | ||
| const missing = [...contributed].filter((name) => !tools.some((tool) => tool.name === name)) | ||
| if (missing.length > 0) { | ||
| throw new Error(`extension module did not provide contributed tool(s): ${missing.join(', ')}`) | ||
| } | ||
| } | ||
| return tools.map((tool) => ({ | ||
| ...tool, | ||
| shouldAdvertise: (context: ToolHostContext) => Boolean(context.workspace) && | ||
| (tool.shouldAdvertise ? tool.shouldAdvertise(context) : true) | ||
| })) | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a project-scoped Research Memory extension and wires the local runtime to discover headless project extensions, expose their tools, include extension skill roots, report extension capabilities, and package the extension with the local runtime.
Scope
This PR contains the research memory extension, project-extension runtime loader, GUI runtime config discovery, capability contract updates, packaging hooks, and related tests. It intentionally excludes the workspace preview bugfix.
Validation
npm --prefix extensions/research-memory run typechecknpx vitest run extensions/research-memory/tests/research-memory.test.ts src/main/local-runtime-process.test.ts src/main/services/skill-service.test.tsnpm run local-runtime:testnpm run local-runtime:typechecknpm run typechecknpm run buildSplit Audit
codex/preview-bugfix.codex/preview-bugfix, this covers the original WIP tracked changes.out/,kun/dist/,extensions/research-memory/dist/, and showcaserun.logfiles were not committed or pushed.