diff --git a/apps/example/README.md b/apps/example/README.md index 02f10c661d..89e3fa27c6 100644 --- a/apps/example/README.md +++ b/apps/example/README.md @@ -7,7 +7,7 @@ It demonstrates: - one local skill (`/example-local`) - one plugin-bundled skill (`/example-bundle-help`) - one bundle-only plugin (`app/plugins/example-bundle/plugin.yaml`) with no credential broker config -- installed plugin packages (`@sentry/junior-agent-browser`, `@sentry/junior-datadog`, `@sentry/junior-github`, `@sentry/junior-hex`, `@sentry/junior-linear`, `@sentry/junior-memory`, `@sentry/junior-notion`, `@sentry/junior-sentry`, `@sentry/junior-vercel`) +- installed plugin packages (`@sentry/junior-agent-browser`, `@sentry/junior-datadog`, `@sentry/junior-github`, `@sentry/junior-hex`, `@sentry/junior-linear`, `@sentry/junior-notion`, `@sentry/junior-sentry`, `@sentry/junior-vercel`) ## Run diff --git a/apps/example/app/skills/example-local/SKILL.md b/apps/example/app/skills/example-local/SKILL.md index 6fae336fc1..bef4c7c611 100644 --- a/apps/example/app/skills/example-local/SKILL.md +++ b/apps/example/app/skills/example-local/SKILL.md @@ -7,7 +7,9 @@ description: Provide a compact local example response. Use when users invoke /ex 1. Confirm the request in one sentence. 2. Return three bullets: + - what this app demonstrates - what plugin-bundled skills add - one practical next action + 3. Keep the reply under 120 words. diff --git a/apps/example/package.json b/apps/example/package.json index a7d17be6ce..8e63a11f35 100644 --- a/apps/example/package.json +++ b/apps/example/package.json @@ -3,9 +3,9 @@ "private": true, "type": "module", "scripts": { - "predev": "pnpm --filter @sentry/junior build && pnpm --filter @sentry/junior-dashboard build && pnpm --filter @sentry/junior-memory build", + "predev": "pnpm --filter @sentry/junior build && pnpm --filter @sentry/junior-dashboard build", "dev": "cross-env NODE_OPTIONS=--import=./instrument.mjs nitro dev", - "prebuild": "pnpm --filter @sentry/junior build && pnpm --filter @sentry/junior-dashboard build && pnpm --filter @sentry/junior-memory build", + "prebuild": "pnpm --filter @sentry/junior build && pnpm --filter @sentry/junior-dashboard build", "build": "junior snapshot create && nitro build", "postbuild": "node scripts/check-vercel-output.mjs", "preview": "cross-env NODE_OPTIONS=--import=./instrument.mjs nitro preview", @@ -22,7 +22,6 @@ "@sentry/junior-github": "workspace:*", "@sentry/junior-hex": "workspace:*", "@sentry/junior-linear": "workspace:*", - "@sentry/junior-memory": "workspace:*", "@sentry/junior-notion": "workspace:*", "@sentry/junior-sentry": "workspace:*", "@sentry/junior-vercel": "workspace:*", diff --git a/apps/example/plugins.ts b/apps/example/plugins.ts index a23bb71c52..27708d7a8c 100644 --- a/apps/example/plugins.ts +++ b/apps/example/plugins.ts @@ -1,7 +1,6 @@ import { defineJuniorPlugins } from "@sentry/junior"; import { githubPlugin } from "@sentry/junior-github"; import { linearPlugin } from "@sentry/junior-linear"; -import { memoryPlugin } from "@sentry/junior-memory"; import { sentryPlugin } from "@sentry/junior-sentry"; import { vercelPlugin } from "@sentry/junior-vercel"; @@ -19,7 +18,6 @@ export const plugins = defineJuniorPlugins([ }), "@sentry/junior-hex", linearPlugin(), - memoryPlugin(), "@sentry/junior-notion", sentryPlugin(), vercelPlugin(), diff --git a/ast-grep/rules/no-memory-semantic-regex.yml b/ast-grep/rules/no-memory-semantic-regex.yml index a1c8d50d93..6787f4ffc1 100644 --- a/ast-grep/rules/no-memory-semantic-regex.yml +++ b/ast-grep/rules/no-memory-semantic-regex.yml @@ -3,10 +3,10 @@ language: TypeScript severity: error message: Memory semantic decisions must stay agentic. Do not use regex classifiers in memory tools, policy, extraction, or agent modules. files: - - packages/junior-memory/src/tools.ts - - packages/junior-memory/src/agent.ts - - packages/junior-memory/src/**/*policy*.ts - - packages/junior-memory/src/**/*extraction*.ts + - packages/junior/src/chat/memory/tools.ts + - packages/junior/src/chat/memory/agent.ts + - packages/junior/src/chat/memory/**/*policy*.ts + - packages/junior/src/chat/memory/**/*extraction*.ts rule: any: - pattern: /$R/ diff --git a/packages/docs/src/content/docs/cli/init.md b/packages/docs/src/content/docs/cli/init.md index edffd967e4..2fb63d5172 100644 --- a/packages/docs/src/content/docs/cli/init.md +++ b/packages/docs/src/content/docs/cli/init.md @@ -25,9 +25,9 @@ The command requires exactly one argument: the target directory. The scaffold includes: -- `package.json` with `@sentry/junior`, `@sentry/junior-maintenance`, `@sentry/junior-memory`, `hono`, `nitro`, `typescript`, `jiti`, and `@types/node` +- `package.json` with `@sentry/junior`, `@sentry/junior-maintenance`, `hono`, `nitro`, `typescript`, `jiti`, and `@types/node` - `pnpm-workspace.yaml` with a 24-hour dependency release delay and an immediate exception for the `@sentry/*` package scope -- `plugins.ts` with `@sentry/junior-maintenance` and `memoryPlugin()` enabled +- `plugins.ts` with `@sentry/junior-maintenance` enabled - `server.ts` - `nitro.config.ts` pointing at `./plugins` - `tsconfig.json` extending Nitro's TypeScript config @@ -43,7 +43,7 @@ The scaffold includes: `SOUL.md` sets Junior's default voice, `WORLD.md` holds operational context, and `DESCRIPTION.md` powers the user-facing app description. Add other `app/*.md` files only when you want optional reference material available to the agent at runtime. -The generated `plugins.ts` enables `@sentry/junior-maintenance` and `memoryPlugin()` by default. Maintenance provides the `self-update` skill for keeping Junior packages current, and memory provides long-term recall once you configure Postgres with pgvector. `plugins.ts` is also the place to add other packaged plugins later. +The generated app includes core Memory by default. The generated `plugins.ts` enables `@sentry/junior-maintenance`, which provides the `self-update` skill. Add other packaged plugins in this file. This gives you the supported app shape needed to run Junior locally, keep the app updated, and continue with plugin or skill setup. diff --git a/packages/docs/src/content/docs/extend/memory-plugin.md b/packages/docs/src/content/docs/extend/memory-plugin.md index bdb3617c42..7ea5e6a073 100644 --- a/packages/docs/src/content/docs/extend/memory-plugin.md +++ b/packages/docs/src/content/docs/extend/memory-plugin.md @@ -1,6 +1,6 @@ --- -title: Memory Plugin -description: Configure the memory plugin for persistent long-term memory storage and recall. +title: Memory +description: Configure core Memory for persistent long-term memory storage and recall. type: tutorial summary: Set up pgvector-backed memory storage so Junior can recall preferences and context across conversations. prerequisites: @@ -10,50 +10,29 @@ related: - /start-here/quickstart/ --- -The memory plugin uses a Postgres database with the pgvector extension to store and retrieve long-term memories across conversations. Before each user turn, Junior combines semantic and full-text matches and includes only memories that directly help with the current request. The plugin also exposes explicit memory tools (remember, list, search, remove) and passively extracts memories from completed public-channel and local sessions. +Memory uses a Postgres database with the pgvector extension to store and retrieve long-term memories across conversations. Before each user turn, Junior combines semantic and full-text matches and includes only memories that directly help with the current request. Memory also exposes explicit memory tools (remember, list, search, remove) and passively extracts memories from completed public-channel and local sessions. -New apps created with `junior init` include `memoryPlugin()` in `plugins.ts` by default. +Memory is part of `@sentry/junior`. New apps created with `junior init` do not install or register a separate Memory package. ## Prerequisites -Provision a Postgres database with pgvector support before running migrations. The memory plugin migrations create the `vector` and `btree_gin` extensions, store 1536-dimensional embeddings, maintain a scope-aware full-text search index, and create an HNSW cosine index on embeddings for hybrid recall. Most managed Postgres providers — Neon, Supabase, Railway, and AWS RDS/Aurora PostgreSQL with pgvector enabled — support this out of the box. - -## Install - -Install the plugin package alongside `@sentry/junior`: - -```bash -pnpm add @sentry/junior @sentry/junior-memory -``` - -## Runtime setup - -The memory plugin requires a factory function call to register its tools and session hooks. Add `memoryPlugin()` to the plugin set exported from `plugins.ts`: - -```ts title="plugins.ts" -import { defineJuniorPlugins } from "@sentry/junior"; -import { memoryPlugin } from "@sentry/junior-memory"; - -export const plugins = defineJuniorPlugins([memoryPlugin()]); -``` - -Do not register `@sentry/junior-memory` as a bare package-name string. The memory plugin uses `defineJuniorPlugin` with runtime hooks for tool registration and session processing; a bare string skips those hooks and the plugin will not activate its runtime behavior. +Provision a Postgres database with pgvector support before running migrations. Core migrations create the `vector` and `btree_gin` extensions, store 1536-dimensional embeddings, maintain a scope-aware full-text search index, and create an HNSW cosine index on embeddings for hybrid recall. Most managed Postgres providers — Neon, Supabase, Railway, and AWS RDS/Aurora PostgreSQL with pgvector enabled — support this out of the box. ## Config -Pass plugin options to `memoryPlugin({ ... })` in `plugins.ts`. Set deployment variables in the Junior environment, then redeploy. +Pass Memory options to `createApp({ memory: { ... } })`. Set deployment variables in the Junior environment, then redeploy. -### Plugin options +### Memory options
modelId Model used for memory classification, consolidation, and automatic recall relevance. -- **Define:** `memoryPlugin({ modelId: "anthropic/claude-sonnet-4-5" })` in `plugins.ts` +- **Define:** `createApp({ memory: { modelId: "anthropic/claude-sonnet-4-5" } })` - **Default:** The app's structured model - **Required:** No -- **Environment override:** `AI_MEMORY_MODEL`; the plugin option takes precedence +- **Environment override:** `AI_MEMORY_MODEL`; the app option takes precedence
@@ -62,7 +41,7 @@ Model used for memory classification, consolidation, and automatic recall releva Disables automatic prompt recall while keeping explicit memory tools available. -- **Define:** `memoryPlugin({ disableRecall: true })` in `plugins.ts` +- **Define:** `createApp({ memory: { disableRecall: true } })` - **Default:** `false` - **Required:** No - **Environment override:** None @@ -74,7 +53,7 @@ Disables automatic prompt recall while keeping explicit memory tools available. Disables passive memory extraction from completed sessions while keeping explicit memory tools available. -- **Define:** `memoryPlugin({ disableExtraction: true })` in `plugins.ts` +- **Define:** `createApp({ memory: { disableExtraction: true } })` - **Default:** `false` - **Required:** No - **Environment override:** None @@ -147,7 +126,7 @@ explains whether Junior learned it automatically or saved it because the user asked. Overview groups the viewer's active memories by type and how they were added. Forgetting archives the memory so Junior no longer recalls it. -The plugin also exposes authenticated REST resources: +Memory also exposes authenticated REST resources: | Method | Path | Purpose | | -------- | ---------------------------------- | --------------------------------------------- | @@ -161,7 +140,7 @@ authenticated dashboard browser session. ## Run migrations -After setting `DATABASE_URL`, run the upgrade command to apply the memory plugin schema: +After setting `DATABASE_URL`, run the upgrade command to apply the Memory schema: ```bash pnpm junior upgrade @@ -195,7 +174,6 @@ Public Slack channel memories are workspace-visible. A durable fact remembered i ## Failure modes -- **Plugin not active after registration**: `@sentry/junior-memory` was registered as a bare string instead of `memoryPlugin()`. Switch to the factory call and redeploy. - **Migration error — extension "vector" does not exist**: the Postgres database does not have pgvector available. Use a provider that supports pgvector or install it manually with `CREATE EXTENSION vector`. - **Migration error — extension "btree_gin" does not exist**: the Postgres database does not include the standard `btree_gin` extension. Enable it with your provider or install it manually with `CREATE EXTENSION btree_gin`. - **`DATABASE_URL` is required**: no database URL is configured. Set it in the deployment environment. diff --git a/packages/docs/src/content/docs/reference/config-and-env.md b/packages/docs/src/content/docs/reference/config-and-env.md index 9b92b330cf..4c04810e88 100644 --- a/packages/docs/src/content/docs/reference/config-and-env.md +++ b/packages/docs/src/content/docs/reference/config-and-env.md @@ -221,7 +221,7 @@ Each profile value may be a model id string or an object with `modelId` and opti Set `profiles` and `defaultProfile` together. Pass auxiliary model ids on the same `createApp()` options object. App config replaces profiles from env settings and overrides auxiliary model env settings. If app config omits both profile options, the deprecated env settings create `standard` and `handoff` profiles with default task-fit descriptions. `AI_MODEL_PROFILES` can add or replace those profiles and may use the same string or object shape. -The memory model belongs to the memory plugin. Set it with `memoryPlugin({ modelId })` in the plugin set. +Set the Memory model with `createApp({ memory: { modelId } })`. `AI_MEMORY_MODEL` remains the environment fallback. ## Install-wide config defaults diff --git a/packages/docs/src/content/docs/start-here/quickstart.mdx b/packages/docs/src/content/docs/start-here/quickstart.mdx index 8825f61298..d55cd6be8d 100644 --- a/packages/docs/src/content/docs/start-here/quickstart.mdx +++ b/packages/docs/src/content/docs/start-here/quickstart.mdx @@ -28,7 +28,7 @@ Use the same baseline that the scaffolded CI workflow uses: - Node.js 24 - pnpm -- A Postgres database for Junior SQL records and the default memory plugin +- A Postgres database for Junior SQL records and the core Memory - A Redis URL for runtime state, locks, and durable automation records Slack credentials are needed before the bot can reply in Slack. You can scaffold and verify the local health route first, then finish [Slack App Setup](/start-here/slack-app-setup/). @@ -65,27 +65,27 @@ node -e "console.log(require('node:crypto').randomBytes(32).toString('base64url' Set these values before running real turns: -| Variable | Required | Purpose | -| ------------------------- | ---------------------- | ------------------------------------------------------------- | -| `SLACK_SIGNING_SECRET` | Yes, for Slack traffic | Verifies Slack requests. | -| `SLACK_BOT_TOKEN` | Yes, for Slack replies | Posts thread replies and calls Slack APIs. | -| `DATABASE_URL` | Yes | Postgres connection string for Junior SQL records and memory. | -| `JUNIOR_DATABASE_DRIVER` | No | SQL client driver: `neon` or `postgres`. | -| `REDIS_URL` | Yes | Runtime state, locks, and durable background automation records. | -| `JUNIOR_SECRET` | Yes | Signs internal resume callbacks and sandbox actor context. | -| `JUNIOR_BOT_NAME` | No | Bot display/config name. | -| `JUNIOR_SLASH_COMMAND` | No | Slack slash command name. Defaults to `/jr`. | -| `AI_MODEL` | No | Deprecated default model setting. | -| `AI_FAST_MODEL` | No | Lightweight routing/classification model override. | -| `AI_HANDOFF_MODEL` | No | Deprecated handoff model setting. | -| `AI_MODEL_PROFILES` | No | Deprecated JSON map of named profiles. | -| `AI_EMBEDDING_MODEL` | No | Embedding model override for plugin vector retrieval. | -| `AI_VISION_MODEL` | No | Enables image understanding when set. | -| `AI_WEB_SEARCH_MODEL` | No | Search model override. | -| `JUNIOR_STATE_KEY_PREFIX` | No | Redis key namespace for this local app/environment. | +| Variable | Required | Purpose | +| ------------------------- | ---------------------- | ---------------------------------------------------------------- | +| `SLACK_SIGNING_SECRET` | Yes, for Slack traffic | Verifies Slack requests. | +| `SLACK_BOT_TOKEN` | Yes, for Slack replies | Posts thread replies and calls Slack APIs. | +| `DATABASE_URL` | Yes | Postgres connection string for Junior SQL records and memory. | +| `JUNIOR_DATABASE_DRIVER` | No | SQL client driver: `neon` or `postgres`. | +| `REDIS_URL` | Yes | Runtime state, locks, and durable background automation records. | +| `JUNIOR_SECRET` | Yes | Signs internal resume callbacks and sandbox actor context. | +| `JUNIOR_BOT_NAME` | No | Bot display/config name. | +| `JUNIOR_SLASH_COMMAND` | No | Slack slash command name. Defaults to `/jr`. | +| `AI_MODEL` | No | Deprecated default model setting. | +| `AI_FAST_MODEL` | No | Lightweight routing/classification model override. | +| `AI_HANDOFF_MODEL` | No | Deprecated handoff model setting. | +| `AI_MODEL_PROFILES` | No | Deprecated JSON map of named profiles. | +| `AI_EMBEDDING_MODEL` | No | Embedding model override for plugin vector retrieval. | +| `AI_VISION_MODEL` | No | Enables image understanding when set. | +| `AI_WEB_SEARCH_MODEL` | No | Search model override. | +| `JUNIOR_STATE_KEY_PREFIX` | No | Redis key namespace for this local app/environment. | See [Config & Environment](/reference/config-and-env/) for the full reference. -If you keep the default memory plugin enabled, use a Postgres database with +If you keep the core Memory enabled, use a Postgres database with pgvector support before running migrations. Local Postgres URLs automatically use the `postgres` driver; set `JUNIOR_DATABASE_DRIVER=postgres` for other non-Neon Postgres providers. @@ -119,24 +119,22 @@ New apps created with `junior init` already have a `plugins.ts` file with mainte For an existing app created without a `plugins.ts`, create one as shown below. Install only the plugins you plan to enable. If you are creating `plugins.ts` -for an existing app, include the default maintenance and memory packages too: +for an existing app, include the default maintenance package too: ```bash -pnpm add @sentry/junior-maintenance @sentry/junior-memory @sentry/junior-agent-browser @sentry/junior-amplitude @sentry/junior-cloudflare @sentry/junior-datadog @sentry/junior-github @sentry/junior-hex @sentry/junior-linear @sentry/junior-notion @sentry/junior-sentry @sentry/junior-vercel +pnpm add @sentry/junior-maintenance @sentry/junior-agent-browser @sentry/junior-amplitude @sentry/junior-cloudflare @sentry/junior-datadog @sentry/junior-github @sentry/junior-hex @sentry/junior-linear @sentry/junior-notion @sentry/junior-sentry @sentry/junior-vercel ``` Add them to the plugin set in `plugins.ts`: ```ts title="plugins.ts" import { defineJuniorPlugins } from "@sentry/junior"; -import { memoryPlugin } from "@sentry/junior-memory"; import { githubPlugin } from "@sentry/junior-github"; import { linearPlugin } from "@sentry/junior-linear"; import { sentryPlugin } from "@sentry/junior-sentry"; import { vercelPlugin } from "@sentry/junior-vercel"; export const plugins = defineJuniorPlugins([ - memoryPlugin(), "@sentry/junior-maintenance", "@sentry/junior-agent-browser", "@sentry/junior-amplitude", diff --git a/packages/junior-dashboard/tests/dashboard-plugin-routes.test.ts b/packages/junior-dashboard/tests/dashboard-plugin-routes.test.ts index d367e3e9be..f7fa08969b 100644 --- a/packages/junior-dashboard/tests/dashboard-plugin-routes.test.ts +++ b/packages/junior-dashboard/tests/dashboard-plugin-routes.test.ts @@ -96,9 +96,9 @@ describe("dashboard plugin routes", () => { plugins: defineJuniorPlugins([ defineJuniorPlugin({ manifest: { - name: "memory", - displayName: "Memory", - description: "Memory plugin", + name: "demo", + displayName: "Demo", + description: "Demo plugin", }, hooks: { apiRoutes() { @@ -110,7 +110,7 @@ describe("dashboard plugin routes", () => { }); const response = await app.fetch( - new Request("http://localhost/api/plugins/memory/memories"), + new Request("http://localhost/api/plugins/demo/memories"), ); expect(response.status).toBe(200); await expect(response.json()).resolves.toEqual({ diff --git a/packages/junior-evals/evals/integration/conversation/delivery.eval.ts b/packages/junior-evals/evals/integration/conversation/delivery.eval.ts index 6f850086d2..f679c176d1 100644 --- a/packages/junior-evals/evals/integration/conversation/delivery.eval.ts +++ b/packages/junior-evals/evals/integration/conversation/delivery.eval.ts @@ -21,9 +21,7 @@ describeEval("Slack Message Delivery", slackEvals, (it) => { it("when asked for no visible reply, complete silently", async ({ run }) => { const result = await run({ initialEvents: [ - mention( - "please just mark that this has been seen — no need to reply", - ), + mention("please just mark that this has been seen — no need to reply"), ], }); diff --git a/packages/junior-evals/evals/memory/actors.eval.ts b/packages/junior-evals/evals/memory/actors.eval.ts index e4aa97178a..812bb8dde7 100644 --- a/packages/junior-evals/evals/memory/actors.eval.ts +++ b/packages/junior-evals/evals/memory/actors.eval.ts @@ -2,11 +2,11 @@ import { expect } from "vitest"; import { describeEval } from "vitest-evals"; import { getDb } from "@/chat/db"; import { readActorIdentity } from "@/chat/plugins/viewer"; -import type { MemoryDb } from "@sentry/junior-memory"; import { juniorMemoryEmbeddings, juniorMemoryMemories, -} from "../../../junior-memory/src/db/schema"; + type MemoryDb, +} from "@sentry/junior/memory"; import { mention, rubric, @@ -23,9 +23,7 @@ import { * more than one Actor does not store any preference. */ -const memoryPluginOverrides = { - plugin_packages: ["@sentry/junior-memory"], -}; +const memoryPluginOverrides = { memory: {} }; const memoryTeamId = "TEVAL"; const ALICE = { diff --git a/packages/junior-evals/evals/memory/helpers.ts b/packages/junior-evals/evals/memory/helpers.ts index a18747db98..3ab976648e 100644 --- a/packages/junior-evals/evals/memory/helpers.ts +++ b/packages/junior-evals/evals/memory/helpers.ts @@ -4,17 +4,16 @@ import { getDb, getSqlExecutor } from "@/chat/db"; import { upsertIdentity } from "@/chat/identities/sql"; import { completeText, resolveGatewayModel } from "@/chat/pi/client"; import { createPluginEmbedder } from "@/chat/plugins/model"; -import { createMemoryStore, type MemoryDb } from "@sentry/junior-memory"; import { createSlackSource } from "@sentry/junior-plugin-api"; import { + createMemoryStore, juniorMemoryEmbeddings, juniorMemoryMemories, -} from "../../../junior-memory/src/db/schema"; + type MemoryDb, +} from "@sentry/junior/memory"; import { TEST_USER_ID } from "@junior-tests/fixtures/slack/factories/ids"; -export const memoryPluginOverrides = { - plugin_packages: ["@sentry/junior-memory"], -}; +export const memoryPluginOverrides = { memory: {} }; const memoryTeamId = "TEVAL"; const actorUserId = TEST_USER_ID; const memoryJudgeModelId = resolveGatewayModel("openai/gpt-5.4").id; diff --git a/packages/junior-evals/package.json b/packages/junior-evals/package.json index 129bebcf99..89a17c8e74 100644 --- a/packages/junior-evals/package.json +++ b/packages/junior-evals/package.json @@ -17,7 +17,6 @@ "@earendil-works/pi-ai": "catalog:", "@sentry/junior": "workspace:*", "@sentry/junior-github": "workspace:*", - "@sentry/junior-memory": "workspace:*", "@sentry/junior-plugin-api": "workspace:*", "@sentry/junior-sentry": "workspace:*", "@sentry/junior-testing": "workspace:*", diff --git a/packages/junior-evals/postgres-global-setup.ts b/packages/junior-evals/postgres-global-setup.ts index 65b2b164cc..453155ba0f 100644 --- a/packages/junior-evals/postgres-global-setup.ts +++ b/packages/junior-evals/postgres-global-setup.ts @@ -1,19 +1,11 @@ -import path from "node:path"; -import { fileURLToPath } from "node:url"; import { cleanupPostgresHarness, setupPostgresTemplate, type PostgresHarnessConfig, } from "@sentry/junior-testing/postgres"; import { migrateSchema } from "@/chat/conversations/sql/migrations"; -import { migratePluginSchemas } from "@/chat/plugins/migrations"; import { createPostgresJuniorSqlExecutor } from "@/db/postgres"; -const workspaceRoot = path.resolve( - path.dirname(fileURLToPath(import.meta.url)), - "../..", -); - interface EvalTestProject { provide(key: "juniorPostgresHarness", value: PostgresHarnessConfig): void; } @@ -44,15 +36,6 @@ export default async function setup( const executor = createPostgresJuniorSqlExecutor({ connectionString }); try { await migrateSchema(executor); - await migratePluginSchemas(executor, [ - { - dir: path.resolve( - workspaceRoot, - "packages/junior-memory/migrations", - ), - pluginName: "memory", - }, - ]); } finally { await executor.close(); } diff --git a/packages/junior-evals/src/behavior-harness.ts b/packages/junior-evals/src/behavior-harness.ts index 7d2fc5f743..0ceb5ef139 100644 --- a/packages/junior-evals/src/behavior-harness.ts +++ b/packages/junior-evals/src/behavior-harness.ts @@ -40,6 +40,8 @@ import { getMcpStoredOAuthCredentials, } from "@/chat/mcp/auth-store"; import { getPlugins, setPlugins } from "@/chat/plugins/agent-hooks"; +import type { MemoryOptions } from "@/chat/memory/registration"; +import { memoryRuntimeRegistrations } from "@/chat/memory/runtime"; import { pluginCatalogRuntime } from "@/chat/plugins/catalog-runtime"; import { defineJuniorPlugins, @@ -66,7 +68,6 @@ import { } from "@/chat/scheduled-automations/tasks"; import type { ScheduledAutomation } from "@/chat/scheduled-automations/types"; import { githubPlugin } from "@sentry/junior-github"; -import { memoryPlugin } from "@sentry/junior-memory"; import { sentryPlugin } from "@sentry/junior-sentry"; import { runPluginHeartbeats } from "@/chat/agent-dispatch/heartbeat"; import { runScheduledAutomationHeartbeat } from "@/chat/scheduled-automations/heartbeat"; @@ -351,6 +352,7 @@ export interface EvalOverrides { expired_oauth_tokens?: string[]; github_events?: boolean; mock_image_generation?: boolean; + memory?: MemoryOptions; plugin_dirs?: string[]; plugin_packages?: string[]; reply_timeout_ms?: number; @@ -1545,13 +1547,14 @@ function runtimePluginsForScenario( scenario: EvalScenario, ): PluginRegistration[] { const packages = new Set(scenario.overrides?.plugin_packages ?? []); - return [ + const plugins = [ ...(packages.has("@sentry/junior-github") ? [githubPlugin({ appPermissions: { deployments: "read" } })] : []), - ...(packages.has("@sentry/junior-memory") ? [memoryPlugin()] : []), ...(packages.has("@sentry/junior-sentry") ? [sentryPlugin()] : []), ]; + const memory = scenario.overrides?.memory; + return memory ? memoryRuntimeRegistrations(plugins, memory) : plugins; } async function setupHarnessEnvironment( diff --git a/packages/junior-evals/tests/unit/harness/behavior-harness.test.ts b/packages/junior-evals/tests/unit/harness/behavior-harness.test.ts index f4248b5fd7..a30acbd91e 100644 --- a/packages/junior-evals/tests/unit/harness/behavior-harness.test.ts +++ b/packages/junior-evals/tests/unit/harness/behavior-harness.test.ts @@ -593,7 +593,7 @@ describe("behavior harness", () => { expect(process.cwd()).toBe(cwd); }); - it("registers GitHub runtime and egress ownership when an eval requests its package", async () => { + it("registers core Memory and requested plugin runtimes", async () => { let pluginNames: string[] = []; let apiProvider: string | undefined; handleNewMentionMock.mockImplementationOnce( @@ -627,11 +627,12 @@ describe("behavior harness", () => { }, ], overrides: { + memory: {}, plugin_packages: ["@sentry/junior-github"], }, }); - expect(pluginNames).toContain("github"); + expect(pluginNames).toEqual(["github", "memory"]); expect(apiProvider).toBe("github"); }); diff --git a/packages/junior-evals/tsconfig.json b/packages/junior-evals/tsconfig.json index 87d62a0ec4..ff2ced87c8 100644 --- a/packages/junior-evals/tsconfig.json +++ b/packages/junior-evals/tsconfig.json @@ -13,7 +13,6 @@ "paths": { "@/*": ["../junior/src/*"], "@junior-tests/*": ["../junior/tests/*"], - "@sentry/junior-memory": ["../junior-memory/src/index.ts"], "@sentry/junior-plugin-api": ["../junior-plugin-api/src/index.ts"] } }, diff --git a/packages/junior-evals/vitest.config.ts b/packages/junior-evals/vitest.config.ts index c658732eee..1997c0473d 100644 --- a/packages/junior-evals/vitest.config.ts +++ b/packages/junior-evals/vitest.config.ts @@ -5,7 +5,6 @@ import { loadJuniorTestEnvFiles } from "../junior/tests/fixtures/env"; const juniorPackageRoot = path.resolve(__dirname, "../junior"); const workspaceRoot = path.resolve(__dirname, "../.."); const pluginApiPackageRoot = path.resolve(__dirname, "../junior-plugin-api"); -const memoryPackageRoot = path.resolve(__dirname, "../junior-memory"); loadJuniorTestEnvFiles({ workspaceRoot, @@ -16,7 +15,10 @@ export default defineConfig({ resolve: { alias: { "@": path.resolve(juniorPackageRoot, "src"), - "@sentry/junior-memory": path.resolve(memoryPackageRoot, "src/index.ts"), + "@sentry/junior/memory": path.resolve( + juniorPackageRoot, + "src/chat/memory/index.ts", + ), "@sentry/junior-plugin-api": path.resolve( pluginApiPackageRoot, "src/index.ts", diff --git a/packages/junior-evals/vitest.evals.behavioral.config.ts b/packages/junior-evals/vitest.evals.behavioral.config.ts index f53a802d15..cb395f0852 100644 --- a/packages/junior-evals/vitest.evals.behavioral.config.ts +++ b/packages/junior-evals/vitest.evals.behavioral.config.ts @@ -8,7 +8,6 @@ const juniorPackageRoot = path.resolve(__dirname, "../junior"); const workspaceRoot = path.resolve(__dirname, "../.."); const evalsPackageRoot = __dirname; const pluginApiPackageRoot = path.resolve(__dirname, "../junior-plugin-api"); -const memoryPackageRoot = path.resolve(__dirname, "../junior-memory"); // Leave room for harness cleanup and rubric judging after a reply reaches its // separate 60-second behavior budget. const EVAL_TEST_TIMEOUT_MS = 120_000; @@ -47,7 +46,10 @@ export default defineConfig({ resolve: { alias: { "@": path.resolve(juniorPackageRoot, "src"), - "@sentry/junior-memory": path.resolve(memoryPackageRoot, "src/index.ts"), + "@sentry/junior/memory": path.resolve( + juniorPackageRoot, + "src/chat/memory/index.ts", + ), "@sentry/junior-plugin-api": path.resolve( pluginApiPackageRoot, "src/index.ts", diff --git a/packages/junior-evals/vitest.evals.guardian.config.ts b/packages/junior-evals/vitest.evals.guardian.config.ts index 2550a313e2..474b0e3bb4 100644 --- a/packages/junior-evals/vitest.evals.guardian.config.ts +++ b/packages/junior-evals/vitest.evals.guardian.config.ts @@ -8,7 +8,6 @@ const juniorPackageRoot = path.resolve(__dirname, "../junior"); const workspaceRoot = path.resolve(__dirname, "../.."); const evalsPackageRoot = __dirname; const pluginApiPackageRoot = path.resolve(__dirname, "../junior-plugin-api"); -const memoryPackageRoot = path.resolve(__dirname, "../junior-memory"); // Leave room for provider retry inside the separate 60-second review budget. const GUARDIAN_EVAL_TEST_TIMEOUT_MS = 90_000; const evalReportPath = path.resolve( @@ -35,7 +34,10 @@ export default defineConfig({ resolve: { alias: { "@": path.resolve(juniorPackageRoot, "src"), - "@sentry/junior-memory": path.resolve(memoryPackageRoot, "src/index.ts"), + "@sentry/junior/memory": path.resolve( + juniorPackageRoot, + "src/chat/memory/index.ts", + ), "@sentry/junior-plugin-api": path.resolve( pluginApiPackageRoot, "src/index.ts", diff --git a/packages/junior-evals/vitest.evals.integration.config.ts b/packages/junior-evals/vitest.evals.integration.config.ts index 904c987fba..bcedf1c597 100644 --- a/packages/junior-evals/vitest.evals.integration.config.ts +++ b/packages/junior-evals/vitest.evals.integration.config.ts @@ -8,7 +8,6 @@ const juniorPackageRoot = path.resolve(__dirname, "../junior"); const workspaceRoot = path.resolve(__dirname, "../.."); const evalsPackageRoot = __dirname; const pluginApiPackageRoot = path.resolve(__dirname, "../junior-plugin-api"); -const memoryPackageRoot = path.resolve(__dirname, "../junior-memory"); // Leave room for harness cleanup and rubric judging after a reply reaches its // separate 60-second behavior budget. const EVAL_TEST_TIMEOUT_MS = 120_000; @@ -47,7 +46,10 @@ export default defineConfig({ resolve: { alias: { "@": path.resolve(juniorPackageRoot, "src"), - "@sentry/junior-memory": path.resolve(memoryPackageRoot, "src/index.ts"), + "@sentry/junior/memory": path.resolve( + juniorPackageRoot, + "src/chat/memory/index.ts", + ), "@sentry/junior-plugin-api": path.resolve( pluginApiPackageRoot, "src/index.ts", diff --git a/packages/junior-memory/README.md b/packages/junior-memory/README.md index 6a69d06d10..621e043ea1 100644 --- a/packages/junior-memory/README.md +++ b/packages/junior-memory/README.md @@ -1,104 +1,7 @@ # @sentry/junior-memory -The memory plugin stores durable facts, recalls relevant facts -into prompts, and learns candidates from completed sessions. SQL schemas, -exported types, tools, and tests are authoritative. +This package keeps old Junior app configuration valid while Memory moves into `@sentry/junior`. -## Surfaces +New apps do not need this package. Memory is part of `@sentry/junior` and is enabled by default. Configure it with `createApp({ memory: { ... } })`. -- `createMemory`, `archiveMemory`, `listMemories`, and `searchMemories` are - model-visible tools registered by `src/plugin.ts`. `archiveMemory` can forget - public memory or private memory owned by the current User. -- `userPrompt` recall contributes bounded memory context before a run. -- `processSession` reviews completed sessions asynchronously for passive - learning. -- The `memory` CLI namespace provides explicit administrative search and - inspection. -- The dashboard exposes a searchable, paginated **Memories** user page. It - includes public memory and private memory owned by the authenticated user. - The overview charts global passive-extraction cost from the durable - `memory/memories_captured` events. The System plugin report uses the same - event-cost feed. -- Authenticated REST clients can list and search authorized memories through - `GET /api/plugins/memory/memories`, read one through - `GET /api/plugins/memory/memories/:id`, and forget an authorized private - memory through `DELETE /api/plugins/memory/memories/:id`. Public memory is - read-only in the dashboard and REST API. - -## Scope And Visibility - -- The Source sets memory visibility. Model output cannot set it. -- Public memory is visible everywhere. -- Private memory belongs to one User. Every Identity linked to that User can - access it. -- Junior records the optional Location where it learned a memory. Location is - a record of where Junior learned it. It does not grant access. -- The subject says what a memory is about. It does not set access. A user - preference can be public or private based on its Source. -- Recall filters candidates by visibility, status, and relevance before content - reaches the model. -- Administrative reads require explicit selectors and safe output defaults. -- Memory content, embeddings, source excerpts, and review prompts must not be - logged or traced. - -## Storage - -- The Drizzle schema in `src/db/schema.ts` and generated migrations define the - database contract. -- Records retain provenance, the optional origin `conversation_id`, lifecycle - status, supersession relationships, and timestamps needed for review and deletion. -- Embeddings are derived indexes, not independent memory authority. -- Embedding distance never decides that two memories are duplicates. Exact - content and preference review own duplicate and supersession decisions. -- Writes are idempotent where a completed session or tool retry can repeat. -- Removal and supersession preserve enough lifecycle information to prevent - deleted facts from being recalled or silently recreated. - -## Learning And Recall - -- Explicit user requests to remember or forget take priority over passive - learning. -- Passive extraction creates only durable, reusable facts—not transient tasks, - conversation summaries, secrets, or speculative interpretation. -- Every completed passive extraction emits the namespaced - `memory/memories_captured` conversation event with its best-effort model cost. - Empty extraction outcomes remain durable for reporting but do not produce a - transcript row. -- Candidate review resolves duplicates and supersession before activation. -- Search combines independently ranked vector and PostgreSQL full-text matches - with reciprocal rank fusion; provider-specific raw scores are never added - together. -- Both retrieval legs always run in parallel as bounded top-k probes. Each leg - fetches at least the caller's requested limit (and never more than the store - limit ceiling). Recall keeps a smaller overfetch window than explicit search - and slightly prefers lexical ranks so exact tokens survive soft semantic - neighbors. Vector recall also applies the cosine distance cutoff in SQL, and - embeddings use an HNSW cosine index (`vector_cosine_ops`). -- Automatic recall also searches private memory by itself. This keeps newer - public memory with common words from hiding older private memory. On equal - RRF scores, private memory ranks first. -- Automatic recall retrieves a bounded candidate window, then uses the - memory relevance model and prompt limit to select useful memories. An empty - result adds no prompt text. -- Every completed automatic recall attempt emits an invisible, namespaced - `memory/memories_recalled` conversation event with the admitted memory IDs - and best-effort embedding and relevance-model cost, including retrievals that - find no candidates and decisions that admit no memories. -- Automatic recall degrades to no prompt contribution when relevance selection - fails. Review, extraction, and write failures still fail their owning - hook/task without corrupting existing memory state. - -## Configuration - -- `AI_MEMORY_MODEL` or `memoryPlugin({ modelId })` selects the structured - review model. -- `memoryPlugin({ disableRecall: true })` disables automatic prompt recall. -- `memoryPlugin({ disableExtraction: true })` disables passive session - extraction. The two flags are independent and do not disable explicit memory - tools. -- Automatic recall uses a fixed cosine distance cutoff of `0.45` (for - `text-embedding-3-small`). Explicit search does not apply that cutoff. -- Generate schema changes with `pnpm --filter @sentry/junior-memory db:generate`. - -Follow `../../policies/data-redaction.md`, `../../policies/security.md`, and the -plugin contract in `../junior-plugin-api/README.md`. +`memoryPlugin()` is deprecated. It returns a compatibility marker. Current `@sentry/junior` versions accept this marker and use its `modelId`, `disableRecall`, and `disableExtraction` settings. The package re-exports the supported API from `@sentry/junior/memory`. diff --git a/packages/junior-memory/drizzle.config.ts b/packages/junior-memory/drizzle.config.ts deleted file mode 100644 index 15a62b834c..0000000000 --- a/packages/junior-memory/drizzle.config.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { defineConfig } from "drizzle-kit"; - -export default defineConfig({ - dialect: "postgresql", - out: "./migrations", - schema: "./src/db/schema.ts", -}); diff --git a/packages/junior-memory/migrations/0000_dizzy_millenium_guard.sql b/packages/junior-memory/migrations/0000_dizzy_millenium_guard.sql deleted file mode 100644 index be2c9ea601..0000000000 --- a/packages/junior-memory/migrations/0000_dizzy_millenium_guard.sql +++ /dev/null @@ -1,37 +0,0 @@ -CREATE TABLE "junior_memory_memories" ( - "id" text PRIMARY KEY NOT NULL, - "scope" text NOT NULL, - "scope_key" text NOT NULL, - "type" text NOT NULL, - "subject_type" text NOT NULL, - "subject_key" text, - "content" text NOT NULL, - "source_platform" text NOT NULL, - "source_key" text NOT NULL, - "idempotency_key" text, - "observed_at_ms" bigint NOT NULL, - "created_at_ms" bigint NOT NULL, - "expires_at_ms" bigint, - "superseded_at_ms" bigint, - "superseded_by_id" text, - "archived_at_ms" bigint, - "archive_reason" text, - CONSTRAINT "junior_memory_memories_scope_check" CHECK ("junior_memory_memories"."scope" IN ('personal', 'conversation')), - CONSTRAINT "junior_memory_memories_type_check" CHECK ("junior_memory_memories"."type" IN ( - 'preference', - 'identity', - 'relationship', - 'knowledge', - 'context', - 'event', - 'task', - 'observation' - )), - CONSTRAINT "junior_memory_memories_subject_type_check" CHECK ("junior_memory_memories"."subject_type" IN ('user', 'conversation', 'general')), - CONSTRAINT "junior_memory_memories_subject_key_check" CHECK (("junior_memory_memories"."subject_type" = 'general' AND "junior_memory_memories"."subject_key" IS NULL) OR ("junior_memory_memories"."subject_type" IN ('user', 'conversation') AND "junior_memory_memories"."subject_key" IS NOT NULL AND length("junior_memory_memories"."subject_key") > 0)), - CONSTRAINT "junior_memory_memories_source_platform_check" CHECK ("junior_memory_memories"."source_platform" IN ('slack', 'local')) -); ---> statement-breakpoint -CREATE INDEX "junior_memory_memories_visible_idx" ON "junior_memory_memories" USING btree ("scope","scope_key","created_at_ms" DESC NULLS LAST,"id") WHERE "junior_memory_memories"."archived_at_ms" IS NULL AND "junior_memory_memories"."superseded_at_ms" IS NULL AND "junior_memory_memories"."superseded_by_id" IS NULL;--> statement-breakpoint -CREATE INDEX "junior_memory_memories_expiration_idx" ON "junior_memory_memories" USING btree ("expires_at_ms") WHERE "junior_memory_memories"."archived_at_ms" IS NULL AND "junior_memory_memories"."expires_at_ms" IS NOT NULL;--> statement-breakpoint -CREATE UNIQUE INDEX "junior_memory_memories_idempotency_idx" ON "junior_memory_memories" USING btree ("scope","scope_key","idempotency_key") WHERE "junior_memory_memories"."idempotency_key" IS NOT NULL; \ No newline at end of file diff --git a/packages/junior-memory/migrations/0001_closed_madrox.sql b/packages/junior-memory/migrations/0001_closed_madrox.sql deleted file mode 100644 index f2b970a138..0000000000 --- a/packages/junior-memory/migrations/0001_closed_madrox.sql +++ /dev/null @@ -1,2 +0,0 @@ -DROP INDEX "junior_memory_memories_idempotency_idx";--> statement-breakpoint -CREATE UNIQUE INDEX "junior_memory_memories_idempotency_idx" ON "junior_memory_memories" USING btree ("scope","scope_key","idempotency_key") WHERE "junior_memory_memories"."idempotency_key" IS NOT NULL AND "junior_memory_memories"."archived_at_ms" IS NULL AND "junior_memory_memories"."superseded_at_ms" IS NULL AND "junior_memory_memories"."superseded_by_id" IS NULL; \ No newline at end of file diff --git a/packages/junior-memory/migrations/0002_light_silver_centurion.sql b/packages/junior-memory/migrations/0002_light_silver_centurion.sql deleted file mode 100644 index 4c9061fd4a..0000000000 --- a/packages/junior-memory/migrations/0002_light_silver_centurion.sql +++ /dev/null @@ -1,17 +0,0 @@ -CREATE EXTENSION IF NOT EXISTS vector; ---> statement-breakpoint -CREATE TABLE "junior_memory_embeddings" ( - "memory_id" text PRIMARY KEY NOT NULL, - "provider" text NOT NULL, - "model" text NOT NULL, - "dimensions" integer NOT NULL, - "metric" text NOT NULL, - "content_hash" text NOT NULL, - "embedding" vector(1536) NOT NULL, - "created_at_ms" bigint NOT NULL, - CONSTRAINT "junior_memory_embeddings_metric_check" CHECK ("junior_memory_embeddings"."metric" IN ('cosine')), - CONSTRAINT "junior_memory_embeddings_dimensions_check" CHECK ("junior_memory_embeddings"."dimensions" = 1536) -); ---> statement-breakpoint -ALTER TABLE "junior_memory_embeddings" ADD CONSTRAINT "junior_memory_embeddings_memory_id_junior_memory_memories_id_fk" FOREIGN KEY ("memory_id") REFERENCES "public"."junior_memory_memories"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint -CREATE INDEX "junior_memory_embeddings_model_idx" ON "junior_memory_embeddings" USING btree ("provider","model","dimensions","metric"); diff --git a/packages/junior-memory/migrations/0003_public_slack_workspace_memory.sql b/packages/junior-memory/migrations/0003_public_slack_workspace_memory.sql deleted file mode 100644 index f0e5f8dfaf..0000000000 --- a/packages/junior-memory/migrations/0003_public_slack_workspace_memory.sql +++ /dev/null @@ -1,55 +0,0 @@ -WITH ranked_active_rows AS ( - SELECT - id, - is_legacy_public, - row_number() OVER ( - PARTITION BY target_scope_key, idempotency_key - ORDER BY CASE WHEN is_legacy_public THEN 1 ELSE 0 END, id - ) AS duplicate_rank - FROM ( - SELECT - id, - idempotency_key, - CASE - WHEN split_part(scope_key, ':', 1) = 'slack' - AND split_part(scope_key, ':', 3) LIKE 'C%' - AND split_part(scope_key, ':', 4) <> '' - THEN 'slack:' || split_part(scope_key, ':', 2) - ELSE scope_key - END AS target_scope_key, - split_part(scope_key, ':', 1) = 'slack' - AND split_part(scope_key, ':', 3) LIKE 'C%' - AND split_part(scope_key, ':', 4) <> '' AS is_legacy_public - FROM junior_memory_memories - WHERE scope = 'conversation' - AND source_platform = 'slack' - AND idempotency_key IS NOT NULL - AND archived_at_ms IS NULL - AND superseded_at_ms IS NULL - AND superseded_by_id IS NULL - ) active_rows -) -UPDATE junior_memory_memories -SET idempotency_key = 'legacy-public-slack:' || junior_memory_memories.id -FROM ranked_active_rows -WHERE junior_memory_memories.id = ranked_active_rows.id - AND ranked_active_rows.is_legacy_public - AND ranked_active_rows.duplicate_rank > 1; ---> statement-breakpoint -UPDATE junior_memory_memories -SET - scope_key = 'slack:' || split_part(scope_key, ':', 2), - subject_key = CASE - WHEN subject_type = 'conversation' - AND subject_key IS NOT NULL - AND split_part(subject_key, ':', 1) = 'slack' - AND split_part(subject_key, ':', 3) LIKE 'C%' - AND split_part(subject_key, ':', 4) <> '' - THEN 'slack:' || split_part(subject_key, ':', 2) - ELSE subject_key - END -WHERE scope = 'conversation' - AND source_platform = 'slack' - AND split_part(scope_key, ':', 1) = 'slack' - AND split_part(scope_key, ':', 3) LIKE 'C%' - AND split_part(scope_key, ':', 4) <> ''; diff --git a/packages/junior-memory/migrations/0004_gigantic_celestials.sql b/packages/junior-memory/migrations/0004_gigantic_celestials.sql deleted file mode 100644 index afd33e2441..0000000000 --- a/packages/junior-memory/migrations/0004_gigantic_celestials.sql +++ /dev/null @@ -1,12 +0,0 @@ -ALTER TABLE "junior_memory_memories" DROP CONSTRAINT "junior_memory_memories_type_check";--> statement-breakpoint -UPDATE "junior_memory_memories" -SET "type" = CASE - WHEN "type" = 'task' THEN 'procedure' - WHEN "type" IN ('identity', 'relationship', 'context', 'event', 'observation') THEN 'knowledge' - ELSE "type" -END;--> statement-breakpoint -ALTER TABLE "junior_memory_memories" ADD CONSTRAINT "junior_memory_memories_kind_check" CHECK ("junior_memory_memories"."type" IN ( - 'preference', - 'procedure', - 'knowledge' - )); diff --git a/packages/junior-memory/migrations/0005_short_jamie_braddock.sql b/packages/junior-memory/migrations/0005_short_jamie_braddock.sql deleted file mode 100644 index f0e6fc6625..0000000000 --- a/packages/junior-memory/migrations/0005_short_jamie_braddock.sql +++ /dev/null @@ -1 +0,0 @@ -CREATE INDEX "junior_memory_memories_search_idx" ON "junior_memory_memories" USING gin (to_tsvector('english', "content")) WHERE "junior_memory_memories"."archived_at_ms" IS NULL AND "junior_memory_memories"."superseded_at_ms" IS NULL AND "junior_memory_memories"."superseded_by_id" IS NULL; \ No newline at end of file diff --git a/packages/junior-memory/migrations/0006_friendly_hydra.sql b/packages/junior-memory/migrations/0006_friendly_hydra.sql deleted file mode 100644 index cc9dee4b6f..0000000000 --- a/packages/junior-memory/migrations/0006_friendly_hydra.sql +++ /dev/null @@ -1,4 +0,0 @@ -CREATE EXTENSION IF NOT EXISTS btree_gin;--> statement-breakpoint -DROP INDEX "junior_memory_memories_search_idx";--> statement-breakpoint -ALTER TABLE "junior_memory_memories" ADD COLUMN "search_vector" "tsvector" GENERATED ALWAYS AS (to_tsvector('english', "content")) STORED;--> statement-breakpoint -CREATE INDEX "junior_memory_memories_search_idx" ON "junior_memory_memories" USING gin ("scope","scope_key","search_vector") WHERE "junior_memory_memories"."archived_at_ms" IS NULL AND "junior_memory_memories"."superseded_at_ms" IS NULL AND "junior_memory_memories"."superseded_by_id" IS NULL; diff --git a/packages/junior-memory/migrations/0007_military_tyger_tiger.sql b/packages/junior-memory/migrations/0007_military_tyger_tiger.sql deleted file mode 100644 index 81b572bdde..0000000000 --- a/packages/junior-memory/migrations/0007_military_tyger_tiger.sql +++ /dev/null @@ -1 +0,0 @@ -CREATE INDEX "junior_memory_embeddings_embedding_hnsw_idx" ON "junior_memory_embeddings" USING hnsw ("embedding" vector_cosine_ops) WITH (m=16,ef_construction=64); diff --git a/packages/junior-memory/migrations/0008_web_memory_source_platform.sql b/packages/junior-memory/migrations/0008_web_memory_source_platform.sql deleted file mode 100644 index 3bdbfa5474..0000000000 --- a/packages/junior-memory/migrations/0008_web_memory_source_platform.sql +++ /dev/null @@ -1,2 +0,0 @@ -ALTER TABLE "junior_memory_memories" DROP CONSTRAINT "junior_memory_memories_source_platform_check";--> statement-breakpoint -ALTER TABLE "junior_memory_memories" ADD CONSTRAINT "junior_memory_memories_source_platform_check" CHECK ("junior_memory_memories"."source_platform" IN ('slack', 'local', 'web')); diff --git a/packages/junior-memory/migrations/0009_faithful_whizzer.sql b/packages/junior-memory/migrations/0009_faithful_whizzer.sql deleted file mode 100644 index 6e0800a7a3..0000000000 --- a/packages/junior-memory/migrations/0009_faithful_whizzer.sql +++ /dev/null @@ -1,114 +0,0 @@ -ALTER TABLE "junior_memory_memories" DROP CONSTRAINT "junior_memory_memories_scope_check";--> statement-breakpoint -ALTER TABLE "junior_memory_memories" ADD COLUMN "location_id" text;--> statement-breakpoint -CREATE TEMP TABLE junior_memory_legacy_owners ( - id text PRIMARY KEY, - user_id text NOT NULL -) ON COMMIT DROP;--> statement-breakpoint -DO $$ -BEGIN - IF to_regclass('junior_identities') IS NOT NULL THEN - EXECUTE $migration$ - INSERT INTO junior_memory_legacy_owners (id, user_id) - SELECT memory.id, owner.user_id - FROM junior_memory_memories AS memory - INNER JOIN LATERAL ( - SELECT identity.user_id - FROM junior_identities AS identity - WHERE identity.user_id IS NOT NULL - AND ( - ( - memory.scope_key LIKE 'slack:%' - AND identity.provider = 'slack' - AND identity.provider_tenant_id = split_part(memory.scope_key, ':', 2) - AND identity.provider_subject_id = split_part(memory.scope_key, ':', 3) - ) - OR ( - memory.scope_key LIKE 'local:%' - AND identity.provider = 'local' - AND identity.provider_subject_id = substring(memory.scope_key FROM 7) - ) - OR ( - memory.scope_key LIKE 'junior:%' - AND identity.provider = 'junior' - AND identity.provider_subject_id = substring(memory.scope_key FROM 8) - ) - ) - ORDER BY identity.id - LIMIT 1 - ) AS owner ON memory.scope = 'personal' - $migration$; - END IF; -END -$$;--> statement-breakpoint -CREATE TEMP TABLE junior_memory_scope_targets ON COMMIT DROP AS -SELECT - memory.id, - CASE - WHEN memory.scope = 'conversation' - AND memory.source_platform = 'slack' - AND memory.scope_key = 'slack:' || split_part(memory.source_key, ':', 2) - THEN 'public' - ELSE 'private' - END AS target_scope, - CASE - WHEN memory.scope = 'conversation' - AND memory.source_platform = 'slack' - AND memory.scope_key = 'slack:' || split_part(memory.source_key, ':', 2) - THEN 'public' - WHEN memory.scope = 'personal' AND owner.user_id IS NOT NULL - THEN owner.user_id - ELSE 'legacy-unowned:' || memory.id - END AS target_scope_key, - ( - memory.scope <> 'personal' AND NOT ( - memory.scope = 'conversation' - AND memory.source_platform = 'slack' - AND memory.scope_key = 'slack:' || split_part(memory.source_key, ':', 2) - ) - ) OR (memory.scope = 'personal' AND owner.user_id IS NULL) AS archive_unowned -FROM junior_memory_memories AS memory -LEFT JOIN junior_memory_legacy_owners AS owner ON owner.id = memory.id;--> statement-breakpoint -WITH duplicate_targets AS ( - SELECT - memory.id, - row_number() OVER ( - PARTITION BY target.target_scope, target.target_scope_key, memory.idempotency_key - ORDER BY memory.id - ) AS duplicate_rank - FROM junior_memory_memories AS memory - INNER JOIN junior_memory_scope_targets AS target ON target.id = memory.id - WHERE memory.idempotency_key IS NOT NULL - AND memory.archived_at_ms IS NULL - AND memory.superseded_at_ms IS NULL - AND memory.superseded_by_id IS NULL - AND NOT target.archive_unowned -) -UPDATE junior_memory_memories AS memory -SET idempotency_key = 'legacy-scope:' || memory.id -FROM duplicate_targets -WHERE memory.id = duplicate_targets.id - AND duplicate_targets.duplicate_rank > 1;--> statement-breakpoint -UPDATE junior_memory_memories AS memory -SET - scope = target.target_scope, - scope_key = target.target_scope_key, - subject_key = CASE - WHEN memory.subject_type = 'user' AND target.target_scope = 'private' - THEN target.target_scope_key - ELSE memory.subject_key - END, - archived_at_ms = CASE - WHEN target.archive_unowned - THEN coalesce(memory.archived_at_ms, floor(extract(epoch FROM clock_timestamp()) * 1000)::bigint) - ELSE memory.archived_at_ms - END, - archive_reason = CASE - WHEN target.archive_unowned - THEN coalesce(memory.archive_reason, 'legacy_unowned_scope') - ELSE memory.archive_reason - END -FROM junior_memory_scope_targets AS target -WHERE memory.id = target.id;--> statement-breakpoint -DROP TABLE junior_memory_scope_targets;--> statement-breakpoint -DROP TABLE junior_memory_legacy_owners;--> statement-breakpoint -ALTER TABLE "junior_memory_memories" ADD CONSTRAINT "junior_memory_memories_scope_check" CHECK ("junior_memory_memories"."scope" IN ('private', 'public')); diff --git a/packages/junior-memory/migrations/0010_memories_captured_scope_labels.sql b/packages/junior-memory/migrations/0010_memories_captured_scope_labels.sql deleted file mode 100644 index baeb80a897..0000000000 --- a/packages/junior-memory/migrations/0010_memories_captured_scope_labels.sql +++ /dev/null @@ -1,50 +0,0 @@ --- Rewrite pre-rename memories_captured v2 scope labels in conversation history. --- personal -> private, conversation -> public. Leaves v1 rows alone. --- No-op when core events are absent. -DO $$ -BEGIN - IF to_regclass('public.junior_conversation_events') IS NULL THEN - RETURN; - END IF; - - UPDATE junior_conversation_events AS event - SET payload = jsonb_set( - event.payload, - '{content,memories}', - ( - SELECT coalesce( - jsonb_agg( - CASE - WHEN jsonb_typeof(memory.value) = 'object' - AND memory.value->>'scope' = 'personal' - THEN jsonb_set(memory.value, '{scope}', '"private"'::jsonb) - WHEN jsonb_typeof(memory.value) = 'object' - AND memory.value->>'scope' = 'conversation' - THEN jsonb_set(memory.value, '{scope}', '"public"'::jsonb) - ELSE memory.value - END - ORDER BY memory.ordinality - ), - '[]'::jsonb - ) - FROM jsonb_array_elements( - CASE - WHEN jsonb_typeof(event.payload->'content'->'memories') = 'array' - THEN event.payload->'content'->'memories' - ELSE '[]'::jsonb - END - ) WITH ORDINALITY AS memory(value, ordinality) - ) - ) - WHERE event.type = 'structured_event' - AND event.payload->>'namespace' = 'memory' - AND event.payload->>'name' = 'memories_captured' - AND (event.payload->>'version') = '2' - AND jsonb_typeof(event.payload->'content'->'memories') = 'array' - AND EXISTS ( - SELECT 1 - FROM jsonb_array_elements(event.payload->'content'->'memories') AS memory(value) - WHERE memory.value->>'scope' IN ('personal', 'conversation') - ); -END -$$; diff --git a/packages/junior-memory/migrations/0011_memory_conversation_id.sql b/packages/junior-memory/migrations/0011_memory_conversation_id.sql deleted file mode 100644 index b1183b0453..0000000000 --- a/packages/junior-memory/migrations/0011_memory_conversation_id.sql +++ /dev/null @@ -1,11 +0,0 @@ -ALTER TABLE "junior_memory_memories" ADD COLUMN "conversation_id" text; ---> statement-breakpoint -UPDATE "junior_memory_memories" -SET "conversation_id" = "source_key" -WHERE "conversation_id" IS NULL - AND "source_platform" IN ('web', 'local'); ---> statement-breakpoint -UPDATE "junior_memory_memories" -SET "conversation_id" = 'slack:' || split_part("source_key", ':', 3) || ':' || split_part("source_key", ':', 4) -WHERE "conversation_id" IS NULL - AND "source_platform" = 'slack'; diff --git a/packages/junior-memory/migrations/meta/0000_snapshot.json b/packages/junior-memory/migrations/meta/0000_snapshot.json deleted file mode 100644 index 75af75b1d8..0000000000 --- a/packages/junior-memory/migrations/meta/0000_snapshot.json +++ /dev/null @@ -1,234 +0,0 @@ -{ - "id": "57a69a4f-1cc5-4597-a818-fb23e3a5bf17", - "prevId": "00000000-0000-0000-0000-000000000000", - "version": "7", - "dialect": "postgresql", - "tables": { - "public.junior_memory_memories": { - "name": "junior_memory_memories", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "text", - "primaryKey": true, - "notNull": true - }, - "scope": { - "name": "scope", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "scope_key": { - "name": "scope_key", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "type": { - "name": "type", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "subject_type": { - "name": "subject_type", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "subject_key": { - "name": "subject_key", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "content": { - "name": "content", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "source_platform": { - "name": "source_platform", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "source_key": { - "name": "source_key", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "idempotency_key": { - "name": "idempotency_key", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "observed_at_ms": { - "name": "observed_at_ms", - "type": "bigint", - "primaryKey": false, - "notNull": true - }, - "created_at_ms": { - "name": "created_at_ms", - "type": "bigint", - "primaryKey": false, - "notNull": true - }, - "expires_at_ms": { - "name": "expires_at_ms", - "type": "bigint", - "primaryKey": false, - "notNull": false - }, - "superseded_at_ms": { - "name": "superseded_at_ms", - "type": "bigint", - "primaryKey": false, - "notNull": false - }, - "superseded_by_id": { - "name": "superseded_by_id", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "archived_at_ms": { - "name": "archived_at_ms", - "type": "bigint", - "primaryKey": false, - "notNull": false - }, - "archive_reason": { - "name": "archive_reason", - "type": "text", - "primaryKey": false, - "notNull": false - } - }, - "indexes": { - "junior_memory_memories_visible_idx": { - "name": "junior_memory_memories_visible_idx", - "columns": [ - { - "expression": "scope", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "scope_key", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "created_at_ms", - "isExpression": false, - "asc": false, - "nulls": "last" - }, - { - "expression": "id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "where": "\"junior_memory_memories\".\"archived_at_ms\" IS NULL AND \"junior_memory_memories\".\"superseded_at_ms\" IS NULL AND \"junior_memory_memories\".\"superseded_by_id\" IS NULL", - "concurrently": false, - "method": "btree", - "with": {} - }, - "junior_memory_memories_expiration_idx": { - "name": "junior_memory_memories_expiration_idx", - "columns": [ - { - "expression": "expires_at_ms", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "where": "\"junior_memory_memories\".\"archived_at_ms\" IS NULL AND \"junior_memory_memories\".\"expires_at_ms\" IS NOT NULL", - "concurrently": false, - "method": "btree", - "with": {} - }, - "junior_memory_memories_idempotency_idx": { - "name": "junior_memory_memories_idempotency_idx", - "columns": [ - { - "expression": "scope", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "scope_key", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "idempotency_key", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "where": "\"junior_memory_memories\".\"idempotency_key\" IS NOT NULL", - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": { - "junior_memory_memories_scope_check": { - "name": "junior_memory_memories_scope_check", - "value": "\"junior_memory_memories\".\"scope\" IN ('personal', 'conversation')" - }, - "junior_memory_memories_type_check": { - "name": "junior_memory_memories_type_check", - "value": "\"junior_memory_memories\".\"type\" IN (\n 'preference',\n 'identity',\n 'relationship',\n 'knowledge',\n 'context',\n 'event',\n 'task',\n 'observation'\n )" - }, - "junior_memory_memories_subject_type_check": { - "name": "junior_memory_memories_subject_type_check", - "value": "\"junior_memory_memories\".\"subject_type\" IN ('user', 'conversation', 'general')" - }, - "junior_memory_memories_subject_key_check": { - "name": "junior_memory_memories_subject_key_check", - "value": "(\"junior_memory_memories\".\"subject_type\" = 'general' AND \"junior_memory_memories\".\"subject_key\" IS NULL) OR (\"junior_memory_memories\".\"subject_type\" IN ('user', 'conversation') AND \"junior_memory_memories\".\"subject_key\" IS NOT NULL AND length(\"junior_memory_memories\".\"subject_key\") > 0)" - }, - "junior_memory_memories_source_platform_check": { - "name": "junior_memory_memories_source_platform_check", - "value": "\"junior_memory_memories\".\"source_platform\" IN ('slack', 'local')" - } - }, - "isRLSEnabled": false - } - }, - "enums": {}, - "schemas": {}, - "sequences": {}, - "roles": {}, - "policies": {}, - "views": {}, - "_meta": { - "columns": {}, - "schemas": {}, - "tables": {} - } -} diff --git a/packages/junior-memory/migrations/meta/0001_snapshot.json b/packages/junior-memory/migrations/meta/0001_snapshot.json deleted file mode 100644 index f19e5deffa..0000000000 --- a/packages/junior-memory/migrations/meta/0001_snapshot.json +++ /dev/null @@ -1,234 +0,0 @@ -{ - "id": "aef16541-5bbe-4c1b-867d-a19c841cb278", - "prevId": "57a69a4f-1cc5-4597-a818-fb23e3a5bf17", - "version": "7", - "dialect": "postgresql", - "tables": { - "public.junior_memory_memories": { - "name": "junior_memory_memories", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "text", - "primaryKey": true, - "notNull": true - }, - "scope": { - "name": "scope", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "scope_key": { - "name": "scope_key", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "type": { - "name": "type", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "subject_type": { - "name": "subject_type", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "subject_key": { - "name": "subject_key", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "content": { - "name": "content", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "source_platform": { - "name": "source_platform", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "source_key": { - "name": "source_key", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "idempotency_key": { - "name": "idempotency_key", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "observed_at_ms": { - "name": "observed_at_ms", - "type": "bigint", - "primaryKey": false, - "notNull": true - }, - "created_at_ms": { - "name": "created_at_ms", - "type": "bigint", - "primaryKey": false, - "notNull": true - }, - "expires_at_ms": { - "name": "expires_at_ms", - "type": "bigint", - "primaryKey": false, - "notNull": false - }, - "superseded_at_ms": { - "name": "superseded_at_ms", - "type": "bigint", - "primaryKey": false, - "notNull": false - }, - "superseded_by_id": { - "name": "superseded_by_id", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "archived_at_ms": { - "name": "archived_at_ms", - "type": "bigint", - "primaryKey": false, - "notNull": false - }, - "archive_reason": { - "name": "archive_reason", - "type": "text", - "primaryKey": false, - "notNull": false - } - }, - "indexes": { - "junior_memory_memories_visible_idx": { - "name": "junior_memory_memories_visible_idx", - "columns": [ - { - "expression": "scope", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "scope_key", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "created_at_ms", - "isExpression": false, - "asc": false, - "nulls": "last" - }, - { - "expression": "id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "where": "\"junior_memory_memories\".\"archived_at_ms\" IS NULL AND \"junior_memory_memories\".\"superseded_at_ms\" IS NULL AND \"junior_memory_memories\".\"superseded_by_id\" IS NULL", - "concurrently": false, - "method": "btree", - "with": {} - }, - "junior_memory_memories_expiration_idx": { - "name": "junior_memory_memories_expiration_idx", - "columns": [ - { - "expression": "expires_at_ms", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "where": "\"junior_memory_memories\".\"archived_at_ms\" IS NULL AND \"junior_memory_memories\".\"expires_at_ms\" IS NOT NULL", - "concurrently": false, - "method": "btree", - "with": {} - }, - "junior_memory_memories_idempotency_idx": { - "name": "junior_memory_memories_idempotency_idx", - "columns": [ - { - "expression": "scope", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "scope_key", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "idempotency_key", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "where": "\"junior_memory_memories\".\"idempotency_key\" IS NOT NULL AND \"junior_memory_memories\".\"archived_at_ms\" IS NULL AND \"junior_memory_memories\".\"superseded_at_ms\" IS NULL AND \"junior_memory_memories\".\"superseded_by_id\" IS NULL", - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": { - "junior_memory_memories_scope_check": { - "name": "junior_memory_memories_scope_check", - "value": "\"junior_memory_memories\".\"scope\" IN ('personal', 'conversation')" - }, - "junior_memory_memories_type_check": { - "name": "junior_memory_memories_type_check", - "value": "\"junior_memory_memories\".\"type\" IN (\n 'preference',\n 'identity',\n 'relationship',\n 'knowledge',\n 'context',\n 'event',\n 'task',\n 'observation'\n )" - }, - "junior_memory_memories_subject_type_check": { - "name": "junior_memory_memories_subject_type_check", - "value": "\"junior_memory_memories\".\"subject_type\" IN ('user', 'conversation', 'general')" - }, - "junior_memory_memories_subject_key_check": { - "name": "junior_memory_memories_subject_key_check", - "value": "(\"junior_memory_memories\".\"subject_type\" = 'general' AND \"junior_memory_memories\".\"subject_key\" IS NULL) OR (\"junior_memory_memories\".\"subject_type\" IN ('user', 'conversation') AND \"junior_memory_memories\".\"subject_key\" IS NOT NULL AND length(\"junior_memory_memories\".\"subject_key\") > 0)" - }, - "junior_memory_memories_source_platform_check": { - "name": "junior_memory_memories_source_platform_check", - "value": "\"junior_memory_memories\".\"source_platform\" IN ('slack', 'local')" - } - }, - "isRLSEnabled": false - } - }, - "enums": {}, - "schemas": {}, - "sequences": {}, - "roles": {}, - "policies": {}, - "views": {}, - "_meta": { - "columns": {}, - "schemas": {}, - "tables": {} - } -} diff --git a/packages/junior-memory/migrations/meta/0002_snapshot.json b/packages/junior-memory/migrations/meta/0002_snapshot.json deleted file mode 100644 index 6f2bdbffc0..0000000000 --- a/packages/junior-memory/migrations/meta/0002_snapshot.json +++ /dev/null @@ -1,348 +0,0 @@ -{ - "id": "9e9985ce-7ac3-4872-97f3-e4a4d3fe39c9", - "prevId": "aef16541-5bbe-4c1b-867d-a19c841cb278", - "version": "7", - "dialect": "postgresql", - "tables": { - "public.junior_memory_embeddings": { - "name": "junior_memory_embeddings", - "schema": "", - "columns": { - "memory_id": { - "name": "memory_id", - "type": "text", - "primaryKey": true, - "notNull": true - }, - "provider": { - "name": "provider", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "model": { - "name": "model", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "dimensions": { - "name": "dimensions", - "type": "integer", - "primaryKey": false, - "notNull": true - }, - "metric": { - "name": "metric", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "content_hash": { - "name": "content_hash", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "embedding": { - "name": "embedding", - "type": "vector(1536)", - "primaryKey": false, - "notNull": true - }, - "created_at_ms": { - "name": "created_at_ms", - "type": "bigint", - "primaryKey": false, - "notNull": true - } - }, - "indexes": { - "junior_memory_embeddings_model_idx": { - "name": "junior_memory_embeddings_model_idx", - "columns": [ - { - "expression": "provider", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "model", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "dimensions", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "metric", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "junior_memory_embeddings_memory_id_junior_memory_memories_id_fk": { - "name": "junior_memory_embeddings_memory_id_junior_memory_memories_id_fk", - "tableFrom": "junior_memory_embeddings", - "tableTo": "junior_memory_memories", - "columnsFrom": ["memory_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": { - "junior_memory_embeddings_metric_check": { - "name": "junior_memory_embeddings_metric_check", - "value": "\"junior_memory_embeddings\".\"metric\" IN ('cosine')" - }, - "junior_memory_embeddings_dimensions_check": { - "name": "junior_memory_embeddings_dimensions_check", - "value": "\"junior_memory_embeddings\".\"dimensions\" = 1536" - } - }, - "isRLSEnabled": false - }, - "public.junior_memory_memories": { - "name": "junior_memory_memories", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "text", - "primaryKey": true, - "notNull": true - }, - "scope": { - "name": "scope", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "scope_key": { - "name": "scope_key", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "type": { - "name": "type", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "subject_type": { - "name": "subject_type", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "subject_key": { - "name": "subject_key", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "content": { - "name": "content", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "source_platform": { - "name": "source_platform", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "source_key": { - "name": "source_key", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "idempotency_key": { - "name": "idempotency_key", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "observed_at_ms": { - "name": "observed_at_ms", - "type": "bigint", - "primaryKey": false, - "notNull": true - }, - "created_at_ms": { - "name": "created_at_ms", - "type": "bigint", - "primaryKey": false, - "notNull": true - }, - "expires_at_ms": { - "name": "expires_at_ms", - "type": "bigint", - "primaryKey": false, - "notNull": false - }, - "superseded_at_ms": { - "name": "superseded_at_ms", - "type": "bigint", - "primaryKey": false, - "notNull": false - }, - "superseded_by_id": { - "name": "superseded_by_id", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "archived_at_ms": { - "name": "archived_at_ms", - "type": "bigint", - "primaryKey": false, - "notNull": false - }, - "archive_reason": { - "name": "archive_reason", - "type": "text", - "primaryKey": false, - "notNull": false - } - }, - "indexes": { - "junior_memory_memories_visible_idx": { - "name": "junior_memory_memories_visible_idx", - "columns": [ - { - "expression": "scope", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "scope_key", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "created_at_ms", - "isExpression": false, - "asc": false, - "nulls": "last" - }, - { - "expression": "id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "where": "\"junior_memory_memories\".\"archived_at_ms\" IS NULL AND \"junior_memory_memories\".\"superseded_at_ms\" IS NULL AND \"junior_memory_memories\".\"superseded_by_id\" IS NULL", - "concurrently": false, - "method": "btree", - "with": {} - }, - "junior_memory_memories_expiration_idx": { - "name": "junior_memory_memories_expiration_idx", - "columns": [ - { - "expression": "expires_at_ms", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "where": "\"junior_memory_memories\".\"archived_at_ms\" IS NULL AND \"junior_memory_memories\".\"expires_at_ms\" IS NOT NULL", - "concurrently": false, - "method": "btree", - "with": {} - }, - "junior_memory_memories_idempotency_idx": { - "name": "junior_memory_memories_idempotency_idx", - "columns": [ - { - "expression": "scope", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "scope_key", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "idempotency_key", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "where": "\"junior_memory_memories\".\"idempotency_key\" IS NOT NULL AND \"junior_memory_memories\".\"archived_at_ms\" IS NULL AND \"junior_memory_memories\".\"superseded_at_ms\" IS NULL AND \"junior_memory_memories\".\"superseded_by_id\" IS NULL", - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": { - "junior_memory_memories_scope_check": { - "name": "junior_memory_memories_scope_check", - "value": "\"junior_memory_memories\".\"scope\" IN ('personal', 'conversation')" - }, - "junior_memory_memories_type_check": { - "name": "junior_memory_memories_type_check", - "value": "\"junior_memory_memories\".\"type\" IN (\n 'preference',\n 'identity',\n 'relationship',\n 'knowledge',\n 'context',\n 'event',\n 'task',\n 'observation'\n )" - }, - "junior_memory_memories_subject_type_check": { - "name": "junior_memory_memories_subject_type_check", - "value": "\"junior_memory_memories\".\"subject_type\" IN ('user', 'conversation', 'general')" - }, - "junior_memory_memories_subject_key_check": { - "name": "junior_memory_memories_subject_key_check", - "value": "(\"junior_memory_memories\".\"subject_type\" = 'general' AND \"junior_memory_memories\".\"subject_key\" IS NULL) OR (\"junior_memory_memories\".\"subject_type\" IN ('user', 'conversation') AND \"junior_memory_memories\".\"subject_key\" IS NOT NULL AND length(\"junior_memory_memories\".\"subject_key\") > 0)" - }, - "junior_memory_memories_source_platform_check": { - "name": "junior_memory_memories_source_platform_check", - "value": "\"junior_memory_memories\".\"source_platform\" IN ('slack', 'local')" - } - }, - "isRLSEnabled": false - } - }, - "enums": {}, - "schemas": {}, - "sequences": {}, - "roles": {}, - "policies": {}, - "views": {}, - "_meta": { - "columns": {}, - "schemas": {}, - "tables": {} - } -} diff --git a/packages/junior-memory/migrations/meta/0003_snapshot.json b/packages/junior-memory/migrations/meta/0003_snapshot.json deleted file mode 100644 index 0845a395d1..0000000000 --- a/packages/junior-memory/migrations/meta/0003_snapshot.json +++ /dev/null @@ -1,348 +0,0 @@ -{ - "id": "2f78c37c-9c80-4f92-92f8-7eaa1951862b", - "prevId": "9e9985ce-7ac3-4872-97f3-e4a4d3fe39c9", - "version": "7", - "dialect": "postgresql", - "tables": { - "public.junior_memory_embeddings": { - "name": "junior_memory_embeddings", - "schema": "", - "columns": { - "memory_id": { - "name": "memory_id", - "type": "text", - "primaryKey": true, - "notNull": true - }, - "provider": { - "name": "provider", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "model": { - "name": "model", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "dimensions": { - "name": "dimensions", - "type": "integer", - "primaryKey": false, - "notNull": true - }, - "metric": { - "name": "metric", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "content_hash": { - "name": "content_hash", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "embedding": { - "name": "embedding", - "type": "vector(1536)", - "primaryKey": false, - "notNull": true - }, - "created_at_ms": { - "name": "created_at_ms", - "type": "bigint", - "primaryKey": false, - "notNull": true - } - }, - "indexes": { - "junior_memory_embeddings_model_idx": { - "name": "junior_memory_embeddings_model_idx", - "columns": [ - { - "expression": "provider", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "model", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "dimensions", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "metric", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "with": {}, - "method": "btree", - "concurrently": false - } - }, - "foreignKeys": { - "junior_memory_embeddings_memory_id_junior_memory_memories_id_fk": { - "name": "junior_memory_embeddings_memory_id_junior_memory_memories_id_fk", - "tableFrom": "junior_memory_embeddings", - "columnsFrom": ["memory_id"], - "tableTo": "junior_memory_memories", - "columnsTo": ["id"], - "onUpdate": "no action", - "onDelete": "cascade" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": { - "junior_memory_embeddings_metric_check": { - "name": "junior_memory_embeddings_metric_check", - "value": "\"junior_memory_embeddings\".\"metric\" IN ('cosine')" - }, - "junior_memory_embeddings_dimensions_check": { - "name": "junior_memory_embeddings_dimensions_check", - "value": "\"junior_memory_embeddings\".\"dimensions\" = 1536" - } - }, - "isRLSEnabled": false - }, - "public.junior_memory_memories": { - "name": "junior_memory_memories", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "text", - "primaryKey": true, - "notNull": true - }, - "scope": { - "name": "scope", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "scope_key": { - "name": "scope_key", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "type": { - "name": "type", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "subject_type": { - "name": "subject_type", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "subject_key": { - "name": "subject_key", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "content": { - "name": "content", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "source_platform": { - "name": "source_platform", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "source_key": { - "name": "source_key", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "idempotency_key": { - "name": "idempotency_key", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "observed_at_ms": { - "name": "observed_at_ms", - "type": "bigint", - "primaryKey": false, - "notNull": true - }, - "created_at_ms": { - "name": "created_at_ms", - "type": "bigint", - "primaryKey": false, - "notNull": true - }, - "expires_at_ms": { - "name": "expires_at_ms", - "type": "bigint", - "primaryKey": false, - "notNull": false - }, - "superseded_at_ms": { - "name": "superseded_at_ms", - "type": "bigint", - "primaryKey": false, - "notNull": false - }, - "superseded_by_id": { - "name": "superseded_by_id", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "archived_at_ms": { - "name": "archived_at_ms", - "type": "bigint", - "primaryKey": false, - "notNull": false - }, - "archive_reason": { - "name": "archive_reason", - "type": "text", - "primaryKey": false, - "notNull": false - } - }, - "indexes": { - "junior_memory_memories_visible_idx": { - "name": "junior_memory_memories_visible_idx", - "columns": [ - { - "expression": "scope", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "scope_key", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "created_at_ms", - "isExpression": false, - "asc": false, - "nulls": "last" - }, - { - "expression": "id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "with": {}, - "method": "btree", - "where": "\"junior_memory_memories\".\"archived_at_ms\" IS NULL AND \"junior_memory_memories\".\"superseded_at_ms\" IS NULL AND \"junior_memory_memories\".\"superseded_by_id\" IS NULL", - "concurrently": false - }, - "junior_memory_memories_expiration_idx": { - "name": "junior_memory_memories_expiration_idx", - "columns": [ - { - "expression": "expires_at_ms", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "with": {}, - "method": "btree", - "where": "\"junior_memory_memories\".\"archived_at_ms\" IS NULL AND \"junior_memory_memories\".\"expires_at_ms\" IS NOT NULL", - "concurrently": false - }, - "junior_memory_memories_idempotency_idx": { - "name": "junior_memory_memories_idempotency_idx", - "columns": [ - { - "expression": "scope", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "scope_key", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "idempotency_key", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "with": {}, - "method": "btree", - "where": "\"junior_memory_memories\".\"idempotency_key\" IS NOT NULL AND \"junior_memory_memories\".\"archived_at_ms\" IS NULL AND \"junior_memory_memories\".\"superseded_at_ms\" IS NULL AND \"junior_memory_memories\".\"superseded_by_id\" IS NULL", - "concurrently": false - } - }, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": { - "junior_memory_memories_scope_check": { - "name": "junior_memory_memories_scope_check", - "value": "\"junior_memory_memories\".\"scope\" IN ('personal', 'conversation')" - }, - "junior_memory_memories_type_check": { - "name": "junior_memory_memories_type_check", - "value": "\"junior_memory_memories\".\"type\" IN (\n 'preference',\n 'identity',\n 'relationship',\n 'knowledge',\n 'context',\n 'event',\n 'task',\n 'observation'\n )" - }, - "junior_memory_memories_subject_type_check": { - "name": "junior_memory_memories_subject_type_check", - "value": "\"junior_memory_memories\".\"subject_type\" IN ('user', 'conversation', 'general')" - }, - "junior_memory_memories_subject_key_check": { - "name": "junior_memory_memories_subject_key_check", - "value": "(\"junior_memory_memories\".\"subject_type\" = 'general' AND \"junior_memory_memories\".\"subject_key\" IS NULL) OR (\"junior_memory_memories\".\"subject_type\" IN ('user', 'conversation') AND \"junior_memory_memories\".\"subject_key\" IS NOT NULL AND length(\"junior_memory_memories\".\"subject_key\") > 0)" - }, - "junior_memory_memories_source_platform_check": { - "name": "junior_memory_memories_source_platform_check", - "value": "\"junior_memory_memories\".\"source_platform\" IN ('slack', 'local')" - } - }, - "isRLSEnabled": false - } - }, - "enums": {}, - "schemas": {}, - "views": {}, - "sequences": {}, - "roles": {}, - "policies": {}, - "_meta": { - "columns": {}, - "schemas": {}, - "tables": {} - } -} diff --git a/packages/junior-memory/migrations/meta/0004_snapshot.json b/packages/junior-memory/migrations/meta/0004_snapshot.json deleted file mode 100644 index 252285d546..0000000000 --- a/packages/junior-memory/migrations/meta/0004_snapshot.json +++ /dev/null @@ -1,348 +0,0 @@ -{ - "id": "e915b537-996a-488c-a828-7cf4da06be44", - "prevId": "2f78c37c-9c80-4f92-92f8-7eaa1951862b", - "version": "7", - "dialect": "postgresql", - "tables": { - "public.junior_memory_embeddings": { - "name": "junior_memory_embeddings", - "schema": "", - "columns": { - "memory_id": { - "name": "memory_id", - "type": "text", - "primaryKey": true, - "notNull": true - }, - "provider": { - "name": "provider", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "model": { - "name": "model", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "dimensions": { - "name": "dimensions", - "type": "integer", - "primaryKey": false, - "notNull": true - }, - "metric": { - "name": "metric", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "content_hash": { - "name": "content_hash", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "embedding": { - "name": "embedding", - "type": "vector(1536)", - "primaryKey": false, - "notNull": true - }, - "created_at_ms": { - "name": "created_at_ms", - "type": "bigint", - "primaryKey": false, - "notNull": true - } - }, - "indexes": { - "junior_memory_embeddings_model_idx": { - "name": "junior_memory_embeddings_model_idx", - "columns": [ - { - "expression": "provider", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "model", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "dimensions", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "metric", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "junior_memory_embeddings_memory_id_junior_memory_memories_id_fk": { - "name": "junior_memory_embeddings_memory_id_junior_memory_memories_id_fk", - "tableFrom": "junior_memory_embeddings", - "tableTo": "junior_memory_memories", - "columnsFrom": ["memory_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": { - "junior_memory_embeddings_metric_check": { - "name": "junior_memory_embeddings_metric_check", - "value": "\"junior_memory_embeddings\".\"metric\" IN ('cosine')" - }, - "junior_memory_embeddings_dimensions_check": { - "name": "junior_memory_embeddings_dimensions_check", - "value": "\"junior_memory_embeddings\".\"dimensions\" = 1536" - } - }, - "isRLSEnabled": false - }, - "public.junior_memory_memories": { - "name": "junior_memory_memories", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "text", - "primaryKey": true, - "notNull": true - }, - "scope": { - "name": "scope", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "scope_key": { - "name": "scope_key", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "type": { - "name": "type", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "subject_type": { - "name": "subject_type", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "subject_key": { - "name": "subject_key", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "content": { - "name": "content", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "source_platform": { - "name": "source_platform", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "source_key": { - "name": "source_key", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "idempotency_key": { - "name": "idempotency_key", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "observed_at_ms": { - "name": "observed_at_ms", - "type": "bigint", - "primaryKey": false, - "notNull": true - }, - "created_at_ms": { - "name": "created_at_ms", - "type": "bigint", - "primaryKey": false, - "notNull": true - }, - "expires_at_ms": { - "name": "expires_at_ms", - "type": "bigint", - "primaryKey": false, - "notNull": false - }, - "superseded_at_ms": { - "name": "superseded_at_ms", - "type": "bigint", - "primaryKey": false, - "notNull": false - }, - "superseded_by_id": { - "name": "superseded_by_id", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "archived_at_ms": { - "name": "archived_at_ms", - "type": "bigint", - "primaryKey": false, - "notNull": false - }, - "archive_reason": { - "name": "archive_reason", - "type": "text", - "primaryKey": false, - "notNull": false - } - }, - "indexes": { - "junior_memory_memories_visible_idx": { - "name": "junior_memory_memories_visible_idx", - "columns": [ - { - "expression": "scope", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "scope_key", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "created_at_ms", - "isExpression": false, - "asc": false, - "nulls": "last" - }, - { - "expression": "id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "where": "\"junior_memory_memories\".\"archived_at_ms\" IS NULL AND \"junior_memory_memories\".\"superseded_at_ms\" IS NULL AND \"junior_memory_memories\".\"superseded_by_id\" IS NULL", - "concurrently": false, - "method": "btree", - "with": {} - }, - "junior_memory_memories_expiration_idx": { - "name": "junior_memory_memories_expiration_idx", - "columns": [ - { - "expression": "expires_at_ms", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "where": "\"junior_memory_memories\".\"archived_at_ms\" IS NULL AND \"junior_memory_memories\".\"expires_at_ms\" IS NOT NULL", - "concurrently": false, - "method": "btree", - "with": {} - }, - "junior_memory_memories_idempotency_idx": { - "name": "junior_memory_memories_idempotency_idx", - "columns": [ - { - "expression": "scope", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "scope_key", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "idempotency_key", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "where": "\"junior_memory_memories\".\"idempotency_key\" IS NOT NULL AND \"junior_memory_memories\".\"archived_at_ms\" IS NULL AND \"junior_memory_memories\".\"superseded_at_ms\" IS NULL AND \"junior_memory_memories\".\"superseded_by_id\" IS NULL", - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": { - "junior_memory_memories_scope_check": { - "name": "junior_memory_memories_scope_check", - "value": "\"junior_memory_memories\".\"scope\" IN ('personal', 'conversation')" - }, - "junior_memory_memories_kind_check": { - "name": "junior_memory_memories_kind_check", - "value": "\"junior_memory_memories\".\"type\" IN (\n 'preference',\n 'procedure',\n 'knowledge'\n )" - }, - "junior_memory_memories_subject_type_check": { - "name": "junior_memory_memories_subject_type_check", - "value": "\"junior_memory_memories\".\"subject_type\" IN ('user', 'conversation', 'general')" - }, - "junior_memory_memories_subject_key_check": { - "name": "junior_memory_memories_subject_key_check", - "value": "(\"junior_memory_memories\".\"subject_type\" = 'general' AND \"junior_memory_memories\".\"subject_key\" IS NULL) OR (\"junior_memory_memories\".\"subject_type\" IN ('user', 'conversation') AND \"junior_memory_memories\".\"subject_key\" IS NOT NULL AND length(\"junior_memory_memories\".\"subject_key\") > 0)" - }, - "junior_memory_memories_source_platform_check": { - "name": "junior_memory_memories_source_platform_check", - "value": "\"junior_memory_memories\".\"source_platform\" IN ('slack', 'local')" - } - }, - "isRLSEnabled": false - } - }, - "enums": {}, - "schemas": {}, - "sequences": {}, - "roles": {}, - "policies": {}, - "views": {}, - "_meta": { - "columns": {}, - "schemas": {}, - "tables": {} - } -} diff --git a/packages/junior-memory/migrations/meta/0005_snapshot.json b/packages/junior-memory/migrations/meta/0005_snapshot.json deleted file mode 100644 index 7fb0fe5c5f..0000000000 --- a/packages/junior-memory/migrations/meta/0005_snapshot.json +++ /dev/null @@ -1,364 +0,0 @@ -{ - "id": "6948ea3f-2e44-49ce-aa94-8a993ce61cec", - "prevId": "e915b537-996a-488c-a828-7cf4da06be44", - "version": "7", - "dialect": "postgresql", - "tables": { - "public.junior_memory_embeddings": { - "name": "junior_memory_embeddings", - "schema": "", - "columns": { - "memory_id": { - "name": "memory_id", - "type": "text", - "primaryKey": true, - "notNull": true - }, - "provider": { - "name": "provider", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "model": { - "name": "model", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "dimensions": { - "name": "dimensions", - "type": "integer", - "primaryKey": false, - "notNull": true - }, - "metric": { - "name": "metric", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "content_hash": { - "name": "content_hash", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "embedding": { - "name": "embedding", - "type": "vector(1536)", - "primaryKey": false, - "notNull": true - }, - "created_at_ms": { - "name": "created_at_ms", - "type": "bigint", - "primaryKey": false, - "notNull": true - } - }, - "indexes": { - "junior_memory_embeddings_model_idx": { - "name": "junior_memory_embeddings_model_idx", - "columns": [ - { - "expression": "provider", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "model", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "dimensions", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "metric", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "junior_memory_embeddings_memory_id_junior_memory_memories_id_fk": { - "name": "junior_memory_embeddings_memory_id_junior_memory_memories_id_fk", - "tableFrom": "junior_memory_embeddings", - "tableTo": "junior_memory_memories", - "columnsFrom": ["memory_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": { - "junior_memory_embeddings_metric_check": { - "name": "junior_memory_embeddings_metric_check", - "value": "\"junior_memory_embeddings\".\"metric\" IN ('cosine')" - }, - "junior_memory_embeddings_dimensions_check": { - "name": "junior_memory_embeddings_dimensions_check", - "value": "\"junior_memory_embeddings\".\"dimensions\" = 1536" - } - }, - "isRLSEnabled": false - }, - "public.junior_memory_memories": { - "name": "junior_memory_memories", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "text", - "primaryKey": true, - "notNull": true - }, - "scope": { - "name": "scope", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "scope_key": { - "name": "scope_key", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "type": { - "name": "type", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "subject_type": { - "name": "subject_type", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "subject_key": { - "name": "subject_key", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "content": { - "name": "content", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "source_platform": { - "name": "source_platform", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "source_key": { - "name": "source_key", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "idempotency_key": { - "name": "idempotency_key", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "observed_at_ms": { - "name": "observed_at_ms", - "type": "bigint", - "primaryKey": false, - "notNull": true - }, - "created_at_ms": { - "name": "created_at_ms", - "type": "bigint", - "primaryKey": false, - "notNull": true - }, - "expires_at_ms": { - "name": "expires_at_ms", - "type": "bigint", - "primaryKey": false, - "notNull": false - }, - "superseded_at_ms": { - "name": "superseded_at_ms", - "type": "bigint", - "primaryKey": false, - "notNull": false - }, - "superseded_by_id": { - "name": "superseded_by_id", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "archived_at_ms": { - "name": "archived_at_ms", - "type": "bigint", - "primaryKey": false, - "notNull": false - }, - "archive_reason": { - "name": "archive_reason", - "type": "text", - "primaryKey": false, - "notNull": false - } - }, - "indexes": { - "junior_memory_memories_visible_idx": { - "name": "junior_memory_memories_visible_idx", - "columns": [ - { - "expression": "scope", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "scope_key", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "created_at_ms", - "isExpression": false, - "asc": false, - "nulls": "last" - }, - { - "expression": "id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "where": "\"junior_memory_memories\".\"archived_at_ms\" IS NULL AND \"junior_memory_memories\".\"superseded_at_ms\" IS NULL AND \"junior_memory_memories\".\"superseded_by_id\" IS NULL", - "concurrently": false, - "method": "btree", - "with": {} - }, - "junior_memory_memories_expiration_idx": { - "name": "junior_memory_memories_expiration_idx", - "columns": [ - { - "expression": "expires_at_ms", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "where": "\"junior_memory_memories\".\"archived_at_ms\" IS NULL AND \"junior_memory_memories\".\"expires_at_ms\" IS NOT NULL", - "concurrently": false, - "method": "btree", - "with": {} - }, - "junior_memory_memories_search_idx": { - "name": "junior_memory_memories_search_idx", - "columns": [ - { - "expression": "to_tsvector('english', \"content\")", - "asc": true, - "isExpression": true, - "nulls": "last" - } - ], - "isUnique": false, - "where": "\"junior_memory_memories\".\"archived_at_ms\" IS NULL AND \"junior_memory_memories\".\"superseded_at_ms\" IS NULL AND \"junior_memory_memories\".\"superseded_by_id\" IS NULL", - "concurrently": false, - "method": "gin", - "with": {} - }, - "junior_memory_memories_idempotency_idx": { - "name": "junior_memory_memories_idempotency_idx", - "columns": [ - { - "expression": "scope", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "scope_key", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "idempotency_key", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "where": "\"junior_memory_memories\".\"idempotency_key\" IS NOT NULL AND \"junior_memory_memories\".\"archived_at_ms\" IS NULL AND \"junior_memory_memories\".\"superseded_at_ms\" IS NULL AND \"junior_memory_memories\".\"superseded_by_id\" IS NULL", - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": { - "junior_memory_memories_scope_check": { - "name": "junior_memory_memories_scope_check", - "value": "\"junior_memory_memories\".\"scope\" IN ('personal', 'conversation')" - }, - "junior_memory_memories_kind_check": { - "name": "junior_memory_memories_kind_check", - "value": "\"junior_memory_memories\".\"type\" IN (\n 'preference',\n 'procedure',\n 'knowledge'\n )" - }, - "junior_memory_memories_subject_type_check": { - "name": "junior_memory_memories_subject_type_check", - "value": "\"junior_memory_memories\".\"subject_type\" IN ('user', 'conversation', 'general')" - }, - "junior_memory_memories_subject_key_check": { - "name": "junior_memory_memories_subject_key_check", - "value": "(\"junior_memory_memories\".\"subject_type\" = 'general' AND \"junior_memory_memories\".\"subject_key\" IS NULL) OR (\"junior_memory_memories\".\"subject_type\" IN ('user', 'conversation') AND \"junior_memory_memories\".\"subject_key\" IS NOT NULL AND length(\"junior_memory_memories\".\"subject_key\") > 0)" - }, - "junior_memory_memories_source_platform_check": { - "name": "junior_memory_memories_source_platform_check", - "value": "\"junior_memory_memories\".\"source_platform\" IN ('slack', 'local')" - } - }, - "isRLSEnabled": false - } - }, - "enums": {}, - "schemas": {}, - "sequences": {}, - "roles": {}, - "policies": {}, - "views": {}, - "_meta": { - "columns": {}, - "schemas": {}, - "tables": {} - } -} diff --git a/packages/junior-memory/migrations/meta/0006_snapshot.json b/packages/junior-memory/migrations/meta/0006_snapshot.json deleted file mode 100644 index c3916bff56..0000000000 --- a/packages/junior-memory/migrations/meta/0006_snapshot.json +++ /dev/null @@ -1,386 +0,0 @@ -{ - "id": "f18fa309-6485-40f3-921a-5d65552fbdf6", - "prevId": "6948ea3f-2e44-49ce-aa94-8a993ce61cec", - "version": "7", - "dialect": "postgresql", - "tables": { - "public.junior_memory_embeddings": { - "name": "junior_memory_embeddings", - "schema": "", - "columns": { - "memory_id": { - "name": "memory_id", - "type": "text", - "primaryKey": true, - "notNull": true - }, - "provider": { - "name": "provider", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "model": { - "name": "model", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "dimensions": { - "name": "dimensions", - "type": "integer", - "primaryKey": false, - "notNull": true - }, - "metric": { - "name": "metric", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "content_hash": { - "name": "content_hash", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "embedding": { - "name": "embedding", - "type": "vector(1536)", - "primaryKey": false, - "notNull": true - }, - "created_at_ms": { - "name": "created_at_ms", - "type": "bigint", - "primaryKey": false, - "notNull": true - } - }, - "indexes": { - "junior_memory_embeddings_model_idx": { - "name": "junior_memory_embeddings_model_idx", - "columns": [ - { - "expression": "provider", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "model", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "dimensions", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "metric", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "junior_memory_embeddings_memory_id_junior_memory_memories_id_fk": { - "name": "junior_memory_embeddings_memory_id_junior_memory_memories_id_fk", - "tableFrom": "junior_memory_embeddings", - "tableTo": "junior_memory_memories", - "columnsFrom": ["memory_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": { - "junior_memory_embeddings_metric_check": { - "name": "junior_memory_embeddings_metric_check", - "value": "\"junior_memory_embeddings\".\"metric\" IN ('cosine')" - }, - "junior_memory_embeddings_dimensions_check": { - "name": "junior_memory_embeddings_dimensions_check", - "value": "\"junior_memory_embeddings\".\"dimensions\" = 1536" - } - }, - "isRLSEnabled": false - }, - "public.junior_memory_memories": { - "name": "junior_memory_memories", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "text", - "primaryKey": true, - "notNull": true - }, - "scope": { - "name": "scope", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "scope_key": { - "name": "scope_key", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "type": { - "name": "type", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "subject_type": { - "name": "subject_type", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "subject_key": { - "name": "subject_key", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "content": { - "name": "content", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "search_vector": { - "name": "search_vector", - "type": "tsvector", - "primaryKey": false, - "notNull": false, - "generated": { - "as": "to_tsvector('english', \"content\")", - "type": "stored" - } - }, - "source_platform": { - "name": "source_platform", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "source_key": { - "name": "source_key", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "idempotency_key": { - "name": "idempotency_key", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "observed_at_ms": { - "name": "observed_at_ms", - "type": "bigint", - "primaryKey": false, - "notNull": true - }, - "created_at_ms": { - "name": "created_at_ms", - "type": "bigint", - "primaryKey": false, - "notNull": true - }, - "expires_at_ms": { - "name": "expires_at_ms", - "type": "bigint", - "primaryKey": false, - "notNull": false - }, - "superseded_at_ms": { - "name": "superseded_at_ms", - "type": "bigint", - "primaryKey": false, - "notNull": false - }, - "superseded_by_id": { - "name": "superseded_by_id", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "archived_at_ms": { - "name": "archived_at_ms", - "type": "bigint", - "primaryKey": false, - "notNull": false - }, - "archive_reason": { - "name": "archive_reason", - "type": "text", - "primaryKey": false, - "notNull": false - } - }, - "indexes": { - "junior_memory_memories_visible_idx": { - "name": "junior_memory_memories_visible_idx", - "columns": [ - { - "expression": "scope", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "scope_key", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "created_at_ms", - "isExpression": false, - "asc": false, - "nulls": "last" - }, - { - "expression": "id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "where": "\"junior_memory_memories\".\"archived_at_ms\" IS NULL AND \"junior_memory_memories\".\"superseded_at_ms\" IS NULL AND \"junior_memory_memories\".\"superseded_by_id\" IS NULL", - "concurrently": false, - "method": "btree", - "with": {} - }, - "junior_memory_memories_expiration_idx": { - "name": "junior_memory_memories_expiration_idx", - "columns": [ - { - "expression": "expires_at_ms", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "where": "\"junior_memory_memories\".\"archived_at_ms\" IS NULL AND \"junior_memory_memories\".\"expires_at_ms\" IS NOT NULL", - "concurrently": false, - "method": "btree", - "with": {} - }, - "junior_memory_memories_search_idx": { - "name": "junior_memory_memories_search_idx", - "columns": [ - { - "expression": "scope", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "scope_key", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "search_vector", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "where": "\"junior_memory_memories\".\"archived_at_ms\" IS NULL AND \"junior_memory_memories\".\"superseded_at_ms\" IS NULL AND \"junior_memory_memories\".\"superseded_by_id\" IS NULL", - "concurrently": false, - "method": "gin", - "with": {} - }, - "junior_memory_memories_idempotency_idx": { - "name": "junior_memory_memories_idempotency_idx", - "columns": [ - { - "expression": "scope", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "scope_key", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "idempotency_key", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "where": "\"junior_memory_memories\".\"idempotency_key\" IS NOT NULL AND \"junior_memory_memories\".\"archived_at_ms\" IS NULL AND \"junior_memory_memories\".\"superseded_at_ms\" IS NULL AND \"junior_memory_memories\".\"superseded_by_id\" IS NULL", - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": { - "junior_memory_memories_scope_check": { - "name": "junior_memory_memories_scope_check", - "value": "\"junior_memory_memories\".\"scope\" IN ('personal', 'conversation')" - }, - "junior_memory_memories_kind_check": { - "name": "junior_memory_memories_kind_check", - "value": "\"junior_memory_memories\".\"type\" IN (\n 'preference',\n 'procedure',\n 'knowledge'\n )" - }, - "junior_memory_memories_subject_type_check": { - "name": "junior_memory_memories_subject_type_check", - "value": "\"junior_memory_memories\".\"subject_type\" IN ('user', 'conversation', 'general')" - }, - "junior_memory_memories_subject_key_check": { - "name": "junior_memory_memories_subject_key_check", - "value": "(\"junior_memory_memories\".\"subject_type\" = 'general' AND \"junior_memory_memories\".\"subject_key\" IS NULL) OR (\"junior_memory_memories\".\"subject_type\" IN ('user', 'conversation') AND \"junior_memory_memories\".\"subject_key\" IS NOT NULL AND length(\"junior_memory_memories\".\"subject_key\") > 0)" - }, - "junior_memory_memories_source_platform_check": { - "name": "junior_memory_memories_source_platform_check", - "value": "\"junior_memory_memories\".\"source_platform\" IN ('slack', 'local')" - } - }, - "isRLSEnabled": false - } - }, - "enums": {}, - "schemas": {}, - "sequences": {}, - "roles": {}, - "policies": {}, - "views": {}, - "_meta": { - "columns": {}, - "schemas": {}, - "tables": {} - } -} diff --git a/packages/junior-memory/migrations/meta/0007_snapshot.json b/packages/junior-memory/migrations/meta/0007_snapshot.json deleted file mode 100644 index c4de024de3..0000000000 --- a/packages/junior-memory/migrations/meta/0007_snapshot.json +++ /dev/null @@ -1,409 +0,0 @@ -{ - "id": "eeef198b-34d7-4ab8-9e1e-1a238ce8bdd5", - "prevId": "f18fa309-6485-40f3-921a-5d65552fbdf6", - "version": "7", - "dialect": "postgresql", - "tables": { - "public.junior_memory_embeddings": { - "name": "junior_memory_embeddings", - "schema": "", - "columns": { - "memory_id": { - "name": "memory_id", - "type": "text", - "primaryKey": true, - "notNull": true - }, - "provider": { - "name": "provider", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "model": { - "name": "model", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "dimensions": { - "name": "dimensions", - "type": "integer", - "primaryKey": false, - "notNull": true - }, - "metric": { - "name": "metric", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "content_hash": { - "name": "content_hash", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "embedding": { - "name": "embedding", - "type": "vector(1536)", - "primaryKey": false, - "notNull": true - }, - "created_at_ms": { - "name": "created_at_ms", - "type": "bigint", - "primaryKey": false, - "notNull": true - } - }, - "indexes": { - "junior_memory_embeddings_model_idx": { - "name": "junior_memory_embeddings_model_idx", - "columns": [ - { - "expression": "provider", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "model", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "dimensions", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "metric", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "junior_memory_embeddings_embedding_hnsw_idx": { - "name": "junior_memory_embeddings_embedding_hnsw_idx", - "columns": [ - { - "expression": "embedding", - "isExpression": false, - "asc": true, - "nulls": "last", - "opclass": "vector_cosine_ops" - } - ], - "isUnique": false, - "concurrently": false, - "method": "hnsw", - "with": { - "m": 16, - "ef_construction": 64 - } - } - }, - "foreignKeys": { - "junior_memory_embeddings_memory_id_junior_memory_memories_id_fk": { - "name": "junior_memory_embeddings_memory_id_junior_memory_memories_id_fk", - "tableFrom": "junior_memory_embeddings", - "tableTo": "junior_memory_memories", - "columnsFrom": [ - "memory_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": { - "junior_memory_embeddings_metric_check": { - "name": "junior_memory_embeddings_metric_check", - "value": "\"junior_memory_embeddings\".\"metric\" IN ('cosine')" - }, - "junior_memory_embeddings_dimensions_check": { - "name": "junior_memory_embeddings_dimensions_check", - "value": "\"junior_memory_embeddings\".\"dimensions\" = 1536" - } - }, - "isRLSEnabled": false - }, - "public.junior_memory_memories": { - "name": "junior_memory_memories", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "text", - "primaryKey": true, - "notNull": true - }, - "scope": { - "name": "scope", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "scope_key": { - "name": "scope_key", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "type": { - "name": "type", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "subject_type": { - "name": "subject_type", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "subject_key": { - "name": "subject_key", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "content": { - "name": "content", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "search_vector": { - "name": "search_vector", - "type": "tsvector", - "primaryKey": false, - "notNull": false, - "generated": { - "as": "to_tsvector('english', \"content\")", - "type": "stored" - } - }, - "source_platform": { - "name": "source_platform", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "source_key": { - "name": "source_key", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "idempotency_key": { - "name": "idempotency_key", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "observed_at_ms": { - "name": "observed_at_ms", - "type": "bigint", - "primaryKey": false, - "notNull": true - }, - "created_at_ms": { - "name": "created_at_ms", - "type": "bigint", - "primaryKey": false, - "notNull": true - }, - "expires_at_ms": { - "name": "expires_at_ms", - "type": "bigint", - "primaryKey": false, - "notNull": false - }, - "superseded_at_ms": { - "name": "superseded_at_ms", - "type": "bigint", - "primaryKey": false, - "notNull": false - }, - "superseded_by_id": { - "name": "superseded_by_id", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "archived_at_ms": { - "name": "archived_at_ms", - "type": "bigint", - "primaryKey": false, - "notNull": false - }, - "archive_reason": { - "name": "archive_reason", - "type": "text", - "primaryKey": false, - "notNull": false - } - }, - "indexes": { - "junior_memory_memories_visible_idx": { - "name": "junior_memory_memories_visible_idx", - "columns": [ - { - "expression": "scope", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "scope_key", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "created_at_ms", - "isExpression": false, - "asc": false, - "nulls": "last" - }, - { - "expression": "id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "where": "\"junior_memory_memories\".\"archived_at_ms\" IS NULL AND \"junior_memory_memories\".\"superseded_at_ms\" IS NULL AND \"junior_memory_memories\".\"superseded_by_id\" IS NULL", - "concurrently": false, - "method": "btree", - "with": {} - }, - "junior_memory_memories_expiration_idx": { - "name": "junior_memory_memories_expiration_idx", - "columns": [ - { - "expression": "expires_at_ms", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "where": "\"junior_memory_memories\".\"archived_at_ms\" IS NULL AND \"junior_memory_memories\".\"expires_at_ms\" IS NOT NULL", - "concurrently": false, - "method": "btree", - "with": {} - }, - "junior_memory_memories_search_idx": { - "name": "junior_memory_memories_search_idx", - "columns": [ - { - "expression": "scope", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "scope_key", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "search_vector", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "where": "\"junior_memory_memories\".\"archived_at_ms\" IS NULL AND \"junior_memory_memories\".\"superseded_at_ms\" IS NULL AND \"junior_memory_memories\".\"superseded_by_id\" IS NULL", - "concurrently": false, - "method": "gin", - "with": {} - }, - "junior_memory_memories_idempotency_idx": { - "name": "junior_memory_memories_idempotency_idx", - "columns": [ - { - "expression": "scope", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "scope_key", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "idempotency_key", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "where": "\"junior_memory_memories\".\"idempotency_key\" IS NOT NULL AND \"junior_memory_memories\".\"archived_at_ms\" IS NULL AND \"junior_memory_memories\".\"superseded_at_ms\" IS NULL AND \"junior_memory_memories\".\"superseded_by_id\" IS NULL", - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": { - "junior_memory_memories_scope_check": { - "name": "junior_memory_memories_scope_check", - "value": "\"junior_memory_memories\".\"scope\" IN ('personal', 'conversation')" - }, - "junior_memory_memories_kind_check": { - "name": "junior_memory_memories_kind_check", - "value": "\"junior_memory_memories\".\"type\" IN (\n 'preference',\n 'procedure',\n 'knowledge'\n )" - }, - "junior_memory_memories_subject_type_check": { - "name": "junior_memory_memories_subject_type_check", - "value": "\"junior_memory_memories\".\"subject_type\" IN ('user', 'conversation', 'general')" - }, - "junior_memory_memories_subject_key_check": { - "name": "junior_memory_memories_subject_key_check", - "value": "(\"junior_memory_memories\".\"subject_type\" = 'general' AND \"junior_memory_memories\".\"subject_key\" IS NULL) OR (\"junior_memory_memories\".\"subject_type\" IN ('user', 'conversation') AND \"junior_memory_memories\".\"subject_key\" IS NOT NULL AND length(\"junior_memory_memories\".\"subject_key\") > 0)" - }, - "junior_memory_memories_source_platform_check": { - "name": "junior_memory_memories_source_platform_check", - "value": "\"junior_memory_memories\".\"source_platform\" IN ('slack', 'local')" - } - }, - "isRLSEnabled": false - } - }, - "enums": {}, - "schemas": {}, - "sequences": {}, - "roles": {}, - "policies": {}, - "views": {}, - "_meta": { - "columns": {}, - "schemas": {}, - "tables": {} - } -} \ No newline at end of file diff --git a/packages/junior-memory/migrations/meta/0008_snapshot.json b/packages/junior-memory/migrations/meta/0008_snapshot.json deleted file mode 100644 index 917e60f987..0000000000 --- a/packages/junior-memory/migrations/meta/0008_snapshot.json +++ /dev/null @@ -1,409 +0,0 @@ -{ - "id": "030f5fc1-7062-4287-bd0b-14fcfd1c6a65", - "prevId": "eeef198b-34d7-4ab8-9e1e-1a238ce8bdd5", - "version": "7", - "dialect": "postgresql", - "tables": { - "public.junior_memory_embeddings": { - "name": "junior_memory_embeddings", - "schema": "", - "columns": { - "memory_id": { - "name": "memory_id", - "type": "text", - "primaryKey": true, - "notNull": true - }, - "provider": { - "name": "provider", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "model": { - "name": "model", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "dimensions": { - "name": "dimensions", - "type": "integer", - "primaryKey": false, - "notNull": true - }, - "metric": { - "name": "metric", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "content_hash": { - "name": "content_hash", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "embedding": { - "name": "embedding", - "type": "vector(1536)", - "primaryKey": false, - "notNull": true - }, - "created_at_ms": { - "name": "created_at_ms", - "type": "bigint", - "primaryKey": false, - "notNull": true - } - }, - "indexes": { - "junior_memory_embeddings_model_idx": { - "name": "junior_memory_embeddings_model_idx", - "columns": [ - { - "expression": "provider", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "model", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "dimensions", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "metric", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "junior_memory_embeddings_embedding_hnsw_idx": { - "name": "junior_memory_embeddings_embedding_hnsw_idx", - "columns": [ - { - "expression": "embedding", - "isExpression": false, - "asc": true, - "nulls": "last", - "opclass": "vector_cosine_ops" - } - ], - "isUnique": false, - "concurrently": false, - "method": "hnsw", - "with": { - "m": 16, - "ef_construction": 64 - } - } - }, - "foreignKeys": { - "junior_memory_embeddings_memory_id_junior_memory_memories_id_fk": { - "name": "junior_memory_embeddings_memory_id_junior_memory_memories_id_fk", - "tableFrom": "junior_memory_embeddings", - "tableTo": "junior_memory_memories", - "columnsFrom": [ - "memory_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": { - "junior_memory_embeddings_metric_check": { - "name": "junior_memory_embeddings_metric_check", - "value": "\"junior_memory_embeddings\".\"metric\" IN ('cosine')" - }, - "junior_memory_embeddings_dimensions_check": { - "name": "junior_memory_embeddings_dimensions_check", - "value": "\"junior_memory_embeddings\".\"dimensions\" = 1536" - } - }, - "isRLSEnabled": false - }, - "public.junior_memory_memories": { - "name": "junior_memory_memories", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "text", - "primaryKey": true, - "notNull": true - }, - "scope": { - "name": "scope", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "scope_key": { - "name": "scope_key", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "type": { - "name": "type", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "subject_type": { - "name": "subject_type", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "subject_key": { - "name": "subject_key", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "content": { - "name": "content", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "search_vector": { - "name": "search_vector", - "type": "tsvector", - "primaryKey": false, - "notNull": false, - "generated": { - "as": "to_tsvector('english', \"content\")", - "type": "stored" - } - }, - "source_platform": { - "name": "source_platform", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "source_key": { - "name": "source_key", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "idempotency_key": { - "name": "idempotency_key", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "observed_at_ms": { - "name": "observed_at_ms", - "type": "bigint", - "primaryKey": false, - "notNull": true - }, - "created_at_ms": { - "name": "created_at_ms", - "type": "bigint", - "primaryKey": false, - "notNull": true - }, - "expires_at_ms": { - "name": "expires_at_ms", - "type": "bigint", - "primaryKey": false, - "notNull": false - }, - "superseded_at_ms": { - "name": "superseded_at_ms", - "type": "bigint", - "primaryKey": false, - "notNull": false - }, - "superseded_by_id": { - "name": "superseded_by_id", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "archived_at_ms": { - "name": "archived_at_ms", - "type": "bigint", - "primaryKey": false, - "notNull": false - }, - "archive_reason": { - "name": "archive_reason", - "type": "text", - "primaryKey": false, - "notNull": false - } - }, - "indexes": { - "junior_memory_memories_visible_idx": { - "name": "junior_memory_memories_visible_idx", - "columns": [ - { - "expression": "scope", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "scope_key", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "created_at_ms", - "isExpression": false, - "asc": false, - "nulls": "last" - }, - { - "expression": "id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "where": "\"junior_memory_memories\".\"archived_at_ms\" IS NULL AND \"junior_memory_memories\".\"superseded_at_ms\" IS NULL AND \"junior_memory_memories\".\"superseded_by_id\" IS NULL", - "concurrently": false, - "method": "btree", - "with": {} - }, - "junior_memory_memories_expiration_idx": { - "name": "junior_memory_memories_expiration_idx", - "columns": [ - { - "expression": "expires_at_ms", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "where": "\"junior_memory_memories\".\"archived_at_ms\" IS NULL AND \"junior_memory_memories\".\"expires_at_ms\" IS NOT NULL", - "concurrently": false, - "method": "btree", - "with": {} - }, - "junior_memory_memories_search_idx": { - "name": "junior_memory_memories_search_idx", - "columns": [ - { - "expression": "scope", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "scope_key", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "search_vector", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "where": "\"junior_memory_memories\".\"archived_at_ms\" IS NULL AND \"junior_memory_memories\".\"superseded_at_ms\" IS NULL AND \"junior_memory_memories\".\"superseded_by_id\" IS NULL", - "concurrently": false, - "method": "gin", - "with": {} - }, - "junior_memory_memories_idempotency_idx": { - "name": "junior_memory_memories_idempotency_idx", - "columns": [ - { - "expression": "scope", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "scope_key", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "idempotency_key", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "where": "\"junior_memory_memories\".\"idempotency_key\" IS NOT NULL AND \"junior_memory_memories\".\"archived_at_ms\" IS NULL AND \"junior_memory_memories\".\"superseded_at_ms\" IS NULL AND \"junior_memory_memories\".\"superseded_by_id\" IS NULL", - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": { - "junior_memory_memories_scope_check": { - "name": "junior_memory_memories_scope_check", - "value": "\"junior_memory_memories\".\"scope\" IN ('personal', 'conversation')" - }, - "junior_memory_memories_kind_check": { - "name": "junior_memory_memories_kind_check", - "value": "\"junior_memory_memories\".\"type\" IN (\n 'preference',\n 'procedure',\n 'knowledge'\n )" - }, - "junior_memory_memories_subject_type_check": { - "name": "junior_memory_memories_subject_type_check", - "value": "\"junior_memory_memories\".\"subject_type\" IN ('user', 'conversation', 'general')" - }, - "junior_memory_memories_subject_key_check": { - "name": "junior_memory_memories_subject_key_check", - "value": "(\"junior_memory_memories\".\"subject_type\" = 'general' AND \"junior_memory_memories\".\"subject_key\" IS NULL) OR (\"junior_memory_memories\".\"subject_type\" IN ('user', 'conversation') AND \"junior_memory_memories\".\"subject_key\" IS NOT NULL AND length(\"junior_memory_memories\".\"subject_key\") > 0)" - }, - "junior_memory_memories_source_platform_check": { - "name": "junior_memory_memories_source_platform_check", - "value": "\"junior_memory_memories\".\"source_platform\" IN ('slack', 'local', 'web')" - } - }, - "isRLSEnabled": false - } - }, - "enums": {}, - "schemas": {}, - "sequences": {}, - "roles": {}, - "policies": {}, - "views": {}, - "_meta": { - "columns": {}, - "schemas": {}, - "tables": {} - } -} diff --git a/packages/junior-memory/migrations/meta/0009_snapshot.json b/packages/junior-memory/migrations/meta/0009_snapshot.json deleted file mode 100644 index 50ddd075a3..0000000000 --- a/packages/junior-memory/migrations/meta/0009_snapshot.json +++ /dev/null @@ -1,411 +0,0 @@ -{ - "id": "bf82349c-95b3-4edf-b8a0-2bc597b7c8b4", - "prevId": "030f5fc1-7062-4287-bd0b-14fcfd1c6a65", - "version": "7", - "dialect": "postgresql", - "tables": { - "public.junior_memory_embeddings": { - "name": "junior_memory_embeddings", - "schema": "", - "columns": { - "memory_id": { - "name": "memory_id", - "type": "text", - "primaryKey": true, - "notNull": true - }, - "provider": { - "name": "provider", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "model": { - "name": "model", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "dimensions": { - "name": "dimensions", - "type": "integer", - "primaryKey": false, - "notNull": true - }, - "metric": { - "name": "metric", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "content_hash": { - "name": "content_hash", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "embedding": { - "name": "embedding", - "type": "vector(1536)", - "primaryKey": false, - "notNull": true - }, - "created_at_ms": { - "name": "created_at_ms", - "type": "bigint", - "primaryKey": false, - "notNull": true - } - }, - "indexes": { - "junior_memory_embeddings_model_idx": { - "name": "junior_memory_embeddings_model_idx", - "columns": [ - { - "expression": "provider", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "model", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "dimensions", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "metric", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "junior_memory_embeddings_embedding_hnsw_idx": { - "name": "junior_memory_embeddings_embedding_hnsw_idx", - "columns": [ - { - "expression": "embedding", - "isExpression": false, - "asc": true, - "nulls": "last", - "opclass": "vector_cosine_ops" - } - ], - "isUnique": false, - "concurrently": false, - "method": "hnsw", - "with": { - "m": 16, - "ef_construction": 64 - } - } - }, - "foreignKeys": { - "junior_memory_embeddings_memory_id_junior_memory_memories_id_fk": { - "name": "junior_memory_embeddings_memory_id_junior_memory_memories_id_fk", - "tableFrom": "junior_memory_embeddings", - "tableTo": "junior_memory_memories", - "columnsFrom": ["memory_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": { - "junior_memory_embeddings_metric_check": { - "name": "junior_memory_embeddings_metric_check", - "value": "\"junior_memory_embeddings\".\"metric\" IN ('cosine')" - }, - "junior_memory_embeddings_dimensions_check": { - "name": "junior_memory_embeddings_dimensions_check", - "value": "\"junior_memory_embeddings\".\"dimensions\" = 1536" - } - }, - "isRLSEnabled": false - }, - "public.junior_memory_memories": { - "name": "junior_memory_memories", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "text", - "primaryKey": true, - "notNull": true - }, - "scope": { - "name": "scope", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "scope_key": { - "name": "scope_key", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "type": { - "name": "type", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "subject_type": { - "name": "subject_type", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "subject_key": { - "name": "subject_key", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "content": { - "name": "content", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "search_vector": { - "name": "search_vector", - "type": "tsvector", - "primaryKey": false, - "notNull": false, - "generated": { - "as": "to_tsvector('english', \"content\")", - "type": "stored" - } - }, - "source_platform": { - "name": "source_platform", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "source_key": { - "name": "source_key", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "location_id": { - "name": "location_id", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "idempotency_key": { - "name": "idempotency_key", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "observed_at_ms": { - "name": "observed_at_ms", - "type": "bigint", - "primaryKey": false, - "notNull": true - }, - "created_at_ms": { - "name": "created_at_ms", - "type": "bigint", - "primaryKey": false, - "notNull": true - }, - "expires_at_ms": { - "name": "expires_at_ms", - "type": "bigint", - "primaryKey": false, - "notNull": false - }, - "superseded_at_ms": { - "name": "superseded_at_ms", - "type": "bigint", - "primaryKey": false, - "notNull": false - }, - "superseded_by_id": { - "name": "superseded_by_id", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "archived_at_ms": { - "name": "archived_at_ms", - "type": "bigint", - "primaryKey": false, - "notNull": false - }, - "archive_reason": { - "name": "archive_reason", - "type": "text", - "primaryKey": false, - "notNull": false - } - }, - "indexes": { - "junior_memory_memories_visible_idx": { - "name": "junior_memory_memories_visible_idx", - "columns": [ - { - "expression": "scope", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "scope_key", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "created_at_ms", - "isExpression": false, - "asc": false, - "nulls": "last" - }, - { - "expression": "id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "where": "\"junior_memory_memories\".\"archived_at_ms\" IS NULL AND \"junior_memory_memories\".\"superseded_at_ms\" IS NULL AND \"junior_memory_memories\".\"superseded_by_id\" IS NULL", - "concurrently": false, - "method": "btree", - "with": {} - }, - "junior_memory_memories_expiration_idx": { - "name": "junior_memory_memories_expiration_idx", - "columns": [ - { - "expression": "expires_at_ms", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "where": "\"junior_memory_memories\".\"archived_at_ms\" IS NULL AND \"junior_memory_memories\".\"expires_at_ms\" IS NOT NULL", - "concurrently": false, - "method": "btree", - "with": {} - }, - "junior_memory_memories_search_idx": { - "name": "junior_memory_memories_search_idx", - "columns": [ - { - "expression": "scope", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "scope_key", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "search_vector", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "where": "\"junior_memory_memories\".\"archived_at_ms\" IS NULL AND \"junior_memory_memories\".\"superseded_at_ms\" IS NULL AND \"junior_memory_memories\".\"superseded_by_id\" IS NULL", - "concurrently": false, - "method": "gin", - "with": {} - }, - "junior_memory_memories_idempotency_idx": { - "name": "junior_memory_memories_idempotency_idx", - "columns": [ - { - "expression": "scope", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "scope_key", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "idempotency_key", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "where": "\"junior_memory_memories\".\"idempotency_key\" IS NOT NULL AND \"junior_memory_memories\".\"archived_at_ms\" IS NULL AND \"junior_memory_memories\".\"superseded_at_ms\" IS NULL AND \"junior_memory_memories\".\"superseded_by_id\" IS NULL", - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": { - "junior_memory_memories_scope_check": { - "name": "junior_memory_memories_scope_check", - "value": "\"junior_memory_memories\".\"scope\" IN ('private', 'public')" - }, - "junior_memory_memories_kind_check": { - "name": "junior_memory_memories_kind_check", - "value": "\"junior_memory_memories\".\"type\" IN (\n 'preference',\n 'procedure',\n 'knowledge'\n )" - }, - "junior_memory_memories_subject_type_check": { - "name": "junior_memory_memories_subject_type_check", - "value": "\"junior_memory_memories\".\"subject_type\" IN ('user', 'conversation', 'general')" - }, - "junior_memory_memories_subject_key_check": { - "name": "junior_memory_memories_subject_key_check", - "value": "(\"junior_memory_memories\".\"subject_type\" = 'general' AND \"junior_memory_memories\".\"subject_key\" IS NULL) OR (\"junior_memory_memories\".\"subject_type\" IN ('user', 'conversation') AND \"junior_memory_memories\".\"subject_key\" IS NOT NULL AND length(\"junior_memory_memories\".\"subject_key\") > 0)" - }, - "junior_memory_memories_source_platform_check": { - "name": "junior_memory_memories_source_platform_check", - "value": "\"junior_memory_memories\".\"source_platform\" IN ('slack', 'local', 'web')" - } - }, - "isRLSEnabled": false - } - }, - "enums": {}, - "schemas": {}, - "sequences": {}, - "roles": {}, - "policies": {}, - "views": {}, - "_meta": { - "columns": {}, - "schemas": {}, - "tables": {} - } -} diff --git a/packages/junior-memory/migrations/meta/0010_snapshot.json b/packages/junior-memory/migrations/meta/0010_snapshot.json deleted file mode 100644 index f84f41ff9a..0000000000 --- a/packages/junior-memory/migrations/meta/0010_snapshot.json +++ /dev/null @@ -1,415 +0,0 @@ -{ - "id": "3094a78d-54ba-42dc-926d-7563a6a651bd", - "prevId": "bf82349c-95b3-4edf-b8a0-2bc597b7c8b4", - "version": "7", - "dialect": "postgresql", - "tables": { - "public.junior_memory_embeddings": { - "name": "junior_memory_embeddings", - "schema": "", - "columns": { - "memory_id": { - "name": "memory_id", - "type": "text", - "primaryKey": true, - "notNull": true - }, - "provider": { - "name": "provider", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "model": { - "name": "model", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "dimensions": { - "name": "dimensions", - "type": "integer", - "primaryKey": false, - "notNull": true - }, - "metric": { - "name": "metric", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "content_hash": { - "name": "content_hash", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "embedding": { - "name": "embedding", - "type": "vector(1536)", - "primaryKey": false, - "notNull": true - }, - "created_at_ms": { - "name": "created_at_ms", - "type": "bigint", - "primaryKey": false, - "notNull": true - } - }, - "indexes": { - "junior_memory_embeddings_model_idx": { - "name": "junior_memory_embeddings_model_idx", - "columns": [ - { - "expression": "provider", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "model", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "dimensions", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "metric", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "junior_memory_embeddings_embedding_hnsw_idx": { - "name": "junior_memory_embeddings_embedding_hnsw_idx", - "columns": [ - { - "expression": "embedding", - "isExpression": false, - "asc": true, - "nulls": "last", - "opclass": "vector_cosine_ops" - } - ], - "isUnique": false, - "concurrently": false, - "method": "hnsw", - "with": { - "m": 16, - "ef_construction": 64 - } - } - }, - "foreignKeys": { - "junior_memory_embeddings_memory_id_junior_memory_memories_id_fk": { - "name": "junior_memory_embeddings_memory_id_junior_memory_memories_id_fk", - "tableFrom": "junior_memory_embeddings", - "tableTo": "junior_memory_memories", - "columnsFrom": [ - "memory_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": { - "junior_memory_embeddings_metric_check": { - "name": "junior_memory_embeddings_metric_check", - "value": "\"junior_memory_embeddings\".\"metric\" IN ('cosine')" - }, - "junior_memory_embeddings_dimensions_check": { - "name": "junior_memory_embeddings_dimensions_check", - "value": "\"junior_memory_embeddings\".\"dimensions\" = 1536" - } - }, - "isRLSEnabled": false - }, - "public.junior_memory_memories": { - "name": "junior_memory_memories", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "text", - "primaryKey": true, - "notNull": true - }, - "scope": { - "name": "scope", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "scope_key": { - "name": "scope_key", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "type": { - "name": "type", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "subject_type": { - "name": "subject_type", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "subject_key": { - "name": "subject_key", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "content": { - "name": "content", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "search_vector": { - "name": "search_vector", - "type": "tsvector", - "primaryKey": false, - "notNull": false, - "generated": { - "as": "to_tsvector('english', \"content\")", - "type": "stored" - } - }, - "source_platform": { - "name": "source_platform", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "source_key": { - "name": "source_key", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "location_id": { - "name": "location_id", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "idempotency_key": { - "name": "idempotency_key", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "observed_at_ms": { - "name": "observed_at_ms", - "type": "bigint", - "primaryKey": false, - "notNull": true - }, - "created_at_ms": { - "name": "created_at_ms", - "type": "bigint", - "primaryKey": false, - "notNull": true - }, - "expires_at_ms": { - "name": "expires_at_ms", - "type": "bigint", - "primaryKey": false, - "notNull": false - }, - "superseded_at_ms": { - "name": "superseded_at_ms", - "type": "bigint", - "primaryKey": false, - "notNull": false - }, - "superseded_by_id": { - "name": "superseded_by_id", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "archived_at_ms": { - "name": "archived_at_ms", - "type": "bigint", - "primaryKey": false, - "notNull": false - }, - "archive_reason": { - "name": "archive_reason", - "type": "text", - "primaryKey": false, - "notNull": false - } - }, - "indexes": { - "junior_memory_memories_visible_idx": { - "name": "junior_memory_memories_visible_idx", - "columns": [ - { - "expression": "scope", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "scope_key", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "created_at_ms", - "isExpression": false, - "asc": false, - "nulls": "last" - }, - { - "expression": "id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "where": "\"junior_memory_memories\".\"archived_at_ms\" IS NULL AND \"junior_memory_memories\".\"superseded_at_ms\" IS NULL AND \"junior_memory_memories\".\"superseded_by_id\" IS NULL", - "concurrently": false, - "method": "btree", - "with": {} - }, - "junior_memory_memories_expiration_idx": { - "name": "junior_memory_memories_expiration_idx", - "columns": [ - { - "expression": "expires_at_ms", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "where": "\"junior_memory_memories\".\"archived_at_ms\" IS NULL AND \"junior_memory_memories\".\"expires_at_ms\" IS NOT NULL", - "concurrently": false, - "method": "btree", - "with": {} - }, - "junior_memory_memories_search_idx": { - "name": "junior_memory_memories_search_idx", - "columns": [ - { - "expression": "scope", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "scope_key", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "search_vector", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "where": "\"junior_memory_memories\".\"archived_at_ms\" IS NULL AND \"junior_memory_memories\".\"superseded_at_ms\" IS NULL AND \"junior_memory_memories\".\"superseded_by_id\" IS NULL", - "concurrently": false, - "method": "gin", - "with": {} - }, - "junior_memory_memories_idempotency_idx": { - "name": "junior_memory_memories_idempotency_idx", - "columns": [ - { - "expression": "scope", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "scope_key", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "idempotency_key", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "where": "\"junior_memory_memories\".\"idempotency_key\" IS NOT NULL AND \"junior_memory_memories\".\"archived_at_ms\" IS NULL AND \"junior_memory_memories\".\"superseded_at_ms\" IS NULL AND \"junior_memory_memories\".\"superseded_by_id\" IS NULL", - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": { - "junior_memory_memories_scope_check": { - "name": "junior_memory_memories_scope_check", - "value": "\"junior_memory_memories\".\"scope\" IN ('private', 'public')" - }, - "junior_memory_memories_kind_check": { - "name": "junior_memory_memories_kind_check", - "value": "\"junior_memory_memories\".\"type\" IN (\n 'preference',\n 'procedure',\n 'knowledge'\n )" - }, - "junior_memory_memories_subject_type_check": { - "name": "junior_memory_memories_subject_type_check", - "value": "\"junior_memory_memories\".\"subject_type\" IN ('user', 'conversation', 'general')" - }, - "junior_memory_memories_subject_key_check": { - "name": "junior_memory_memories_subject_key_check", - "value": "(\"junior_memory_memories\".\"subject_type\" = 'general' AND \"junior_memory_memories\".\"subject_key\" IS NULL) OR (\"junior_memory_memories\".\"subject_type\" IN ('user', 'conversation') AND \"junior_memory_memories\".\"subject_key\" IS NOT NULL AND length(\"junior_memory_memories\".\"subject_key\") > 0)" - }, - "junior_memory_memories_source_platform_check": { - "name": "junior_memory_memories_source_platform_check", - "value": "\"junior_memory_memories\".\"source_platform\" IN ('slack', 'local', 'web')" - } - }, - "isRLSEnabled": false - } - }, - "enums": {}, - "schemas": {}, - "sequences": {}, - "roles": {}, - "policies": {}, - "views": {}, - "_meta": { - "columns": {}, - "schemas": {}, - "tables": {} - } -} diff --git a/packages/junior-memory/migrations/meta/0011_snapshot.json b/packages/junior-memory/migrations/meta/0011_snapshot.json deleted file mode 100644 index 71dfc203e6..0000000000 --- a/packages/junior-memory/migrations/meta/0011_snapshot.json +++ /dev/null @@ -1,417 +0,0 @@ -{ - "id": "90b7d7a0-b8df-402b-afbd-dcf6dc898261", - "prevId": "3094a78d-54ba-42dc-926d-7563a6a651bd", - "version": "7", - "dialect": "postgresql", - "tables": { - "public.junior_memory_embeddings": { - "name": "junior_memory_embeddings", - "schema": "", - "columns": { - "memory_id": { - "name": "memory_id", - "type": "text", - "primaryKey": true, - "notNull": true - }, - "provider": { - "name": "provider", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "model": { - "name": "model", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "dimensions": { - "name": "dimensions", - "type": "integer", - "primaryKey": false, - "notNull": true - }, - "metric": { - "name": "metric", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "content_hash": { - "name": "content_hash", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "embedding": { - "name": "embedding", - "type": "vector(1536)", - "primaryKey": false, - "notNull": true - }, - "created_at_ms": { - "name": "created_at_ms", - "type": "bigint", - "primaryKey": false, - "notNull": true - } - }, - "indexes": { - "junior_memory_embeddings_model_idx": { - "name": "junior_memory_embeddings_model_idx", - "columns": [ - { - "expression": "provider", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "model", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "dimensions", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "metric", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "junior_memory_embeddings_embedding_hnsw_idx": { - "name": "junior_memory_embeddings_embedding_hnsw_idx", - "columns": [ - { - "expression": "embedding", - "isExpression": false, - "asc": true, - "nulls": "last", - "opclass": "vector_cosine_ops" - } - ], - "isUnique": false, - "concurrently": false, - "method": "hnsw", - "with": { - "m": 16, - "ef_construction": 64 - } - } - }, - "foreignKeys": { - "junior_memory_embeddings_memory_id_junior_memory_memories_id_fk": { - "name": "junior_memory_embeddings_memory_id_junior_memory_memories_id_fk", - "tableFrom": "junior_memory_embeddings", - "tableTo": "junior_memory_memories", - "columnsFrom": ["memory_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": { - "junior_memory_embeddings_metric_check": { - "name": "junior_memory_embeddings_metric_check", - "value": "\"junior_memory_embeddings\".\"metric\" IN ('cosine')" - }, - "junior_memory_embeddings_dimensions_check": { - "name": "junior_memory_embeddings_dimensions_check", - "value": "\"junior_memory_embeddings\".\"dimensions\" = 1536" - } - }, - "isRLSEnabled": false - }, - "public.junior_memory_memories": { - "name": "junior_memory_memories", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "text", - "primaryKey": true, - "notNull": true - }, - "scope": { - "name": "scope", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "scope_key": { - "name": "scope_key", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "type": { - "name": "type", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "subject_type": { - "name": "subject_type", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "subject_key": { - "name": "subject_key", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "content": { - "name": "content", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "search_vector": { - "name": "search_vector", - "type": "tsvector", - "primaryKey": false, - "notNull": false, - "generated": { - "as": "to_tsvector('english', \"content\")", - "type": "stored" - } - }, - "source_platform": { - "name": "source_platform", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "source_key": { - "name": "source_key", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "location_id": { - "name": "location_id", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "conversation_id": { - "name": "conversation_id", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "idempotency_key": { - "name": "idempotency_key", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "observed_at_ms": { - "name": "observed_at_ms", - "type": "bigint", - "primaryKey": false, - "notNull": true - }, - "created_at_ms": { - "name": "created_at_ms", - "type": "bigint", - "primaryKey": false, - "notNull": true - }, - "expires_at_ms": { - "name": "expires_at_ms", - "type": "bigint", - "primaryKey": false, - "notNull": false - }, - "superseded_at_ms": { - "name": "superseded_at_ms", - "type": "bigint", - "primaryKey": false, - "notNull": false - }, - "superseded_by_id": { - "name": "superseded_by_id", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "archived_at_ms": { - "name": "archived_at_ms", - "type": "bigint", - "primaryKey": false, - "notNull": false - }, - "archive_reason": { - "name": "archive_reason", - "type": "text", - "primaryKey": false, - "notNull": false - } - }, - "indexes": { - "junior_memory_memories_visible_idx": { - "name": "junior_memory_memories_visible_idx", - "columns": [ - { - "expression": "scope", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "scope_key", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "created_at_ms", - "isExpression": false, - "asc": false, - "nulls": "last" - }, - { - "expression": "id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "where": "\"junior_memory_memories\".\"archived_at_ms\" IS NULL AND \"junior_memory_memories\".\"superseded_at_ms\" IS NULL AND \"junior_memory_memories\".\"superseded_by_id\" IS NULL", - "concurrently": false, - "method": "btree", - "with": {} - }, - "junior_memory_memories_expiration_idx": { - "name": "junior_memory_memories_expiration_idx", - "columns": [ - { - "expression": "expires_at_ms", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "where": "\"junior_memory_memories\".\"archived_at_ms\" IS NULL AND \"junior_memory_memories\".\"expires_at_ms\" IS NOT NULL", - "concurrently": false, - "method": "btree", - "with": {} - }, - "junior_memory_memories_search_idx": { - "name": "junior_memory_memories_search_idx", - "columns": [ - { - "expression": "scope", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "scope_key", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "search_vector", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "where": "\"junior_memory_memories\".\"archived_at_ms\" IS NULL AND \"junior_memory_memories\".\"superseded_at_ms\" IS NULL AND \"junior_memory_memories\".\"superseded_by_id\" IS NULL", - "concurrently": false, - "method": "gin", - "with": {} - }, - "junior_memory_memories_idempotency_idx": { - "name": "junior_memory_memories_idempotency_idx", - "columns": [ - { - "expression": "scope", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "scope_key", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "idempotency_key", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "where": "\"junior_memory_memories\".\"idempotency_key\" IS NOT NULL AND \"junior_memory_memories\".\"archived_at_ms\" IS NULL AND \"junior_memory_memories\".\"superseded_at_ms\" IS NULL AND \"junior_memory_memories\".\"superseded_by_id\" IS NULL", - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": { - "junior_memory_memories_scope_check": { - "name": "junior_memory_memories_scope_check", - "value": "\"junior_memory_memories\".\"scope\" IN ('private', 'public')" - }, - "junior_memory_memories_kind_check": { - "name": "junior_memory_memories_kind_check", - "value": "\"junior_memory_memories\".\"type\" IN (\n 'preference',\n 'procedure',\n 'knowledge'\n )" - }, - "junior_memory_memories_subject_type_check": { - "name": "junior_memory_memories_subject_type_check", - "value": "\"junior_memory_memories\".\"subject_type\" IN ('user', 'conversation', 'general')" - }, - "junior_memory_memories_subject_key_check": { - "name": "junior_memory_memories_subject_key_check", - "value": "(\"junior_memory_memories\".\"subject_type\" = 'general' AND \"junior_memory_memories\".\"subject_key\" IS NULL) OR (\"junior_memory_memories\".\"subject_type\" IN ('user', 'conversation') AND \"junior_memory_memories\".\"subject_key\" IS NOT NULL AND length(\"junior_memory_memories\".\"subject_key\") > 0)" - }, - "junior_memory_memories_source_platform_check": { - "name": "junior_memory_memories_source_platform_check", - "value": "\"junior_memory_memories\".\"source_platform\" IN ('slack', 'local', 'web')" - } - }, - "isRLSEnabled": false - } - }, - "enums": {}, - "schemas": {}, - "sequences": {}, - "roles": {}, - "policies": {}, - "views": {}, - "_meta": { - "columns": {}, - "schemas": {}, - "tables": {} - } -} diff --git a/packages/junior-memory/migrations/meta/_journal.json b/packages/junior-memory/migrations/meta/_journal.json deleted file mode 100644 index acd03cbda6..0000000000 --- a/packages/junior-memory/migrations/meta/_journal.json +++ /dev/null @@ -1,90 +0,0 @@ -{ - "version": "7", - "dialect": "postgresql", - "entries": [ - { - "idx": 0, - "version": "7", - "when": 1781976138405, - "tag": "0000_dizzy_millenium_guard", - "breakpoints": true - }, - { - "idx": 1, - "version": "7", - "when": 1782149964214, - "tag": "0001_closed_madrox", - "breakpoints": true - }, - { - "idx": 2, - "version": "7", - "when": 1782158974888, - "tag": "0002_light_silver_centurion", - "breakpoints": true - }, - { - "idx": 3, - "version": "7", - "when": 1782582311997, - "tag": "0003_public_slack_workspace_memory", - "breakpoints": true - }, - { - "idx": 4, - "version": "7", - "when": 1782676852768, - "tag": "0004_gigantic_celestials", - "breakpoints": true - }, - { - "idx": 5, - "version": "7", - "when": 1785293874649, - "tag": "0005_short_jamie_braddock", - "breakpoints": true - }, - { - "idx": 6, - "version": "7", - "when": 1785878952301, - "tag": "0006_friendly_hydra", - "breakpoints": true - }, - { - "idx": 7, - "version": "7", - "when": 1785910292191, - "tag": "0007_military_tyger_tiger", - "breakpoints": true - }, - { - "idx": 8, - "version": "7", - "when": 1786345372977, - "tag": "0008_web_memory_source_platform", - "breakpoints": true - }, - { - "idx": 9, - "version": "7", - "when": 1787417688130, - "tag": "0009_faithful_whizzer", - "breakpoints": true - }, - { - "idx": 10, - "version": "7", - "when": 1787458882949, - "tag": "0010_memories_captured_scope_labels", - "breakpoints": true - }, - { - "idx": 11, - "version": "7", - "when": 1789116801128, - "tag": "0011_memory_conversation_id", - "breakpoints": true - } - ] -} diff --git a/packages/junior-memory/package.json b/packages/junior-memory/package.json index 489b0b5a28..8c7fd13a6f 100644 --- a/packages/junior-memory/package.json +++ b/packages/junior-memory/package.json @@ -18,12 +18,10 @@ } }, "files": [ - "dist", - "migrations" + "dist" ], "scripts": { "build": "tsup", - "db:generate": "pnpm exec drizzle-kit generate --config drizzle.config.ts", "lint": "oxlint --config ../junior/.oxlintrc.json --deny-warnings src tests tsup.config.ts", "prepare": "pnpm run build", "prepack": "pnpm run build", @@ -31,20 +29,20 @@ "typecheck": "tsc --noEmit" }, "dependencies": { - "@sentry/junior-plugin-api": "workspace:*", - "@sinclair/typebox": "^0.34.49", - "commander": "^14.0.3", - "drizzle-orm": "catalog:", - "zod": "catalog:" + "@sentry/junior": "workspace:*", + "@sentry/junior-plugin-api": "workspace:*" }, "devDependencies": { "@oxlint/plugins": "1.79.0", "@sentry/junior-testing": "workspace:*", "@types/node": "^25.9.1", - "drizzle-kit": "catalog:", "oxlint": "^1.79.0", "tsup": "^8.5.1", "typescript": "^6.0.3", - "vitest": "^4.1.7" + "vitest": "^4.1.7", + "@sinclair/typebox": "^0.34.49", + "commander": "^14.0.3", + "drizzle-orm": "catalog:", + "zod": "catalog:" } } diff --git a/packages/junior-memory/src/index.ts b/packages/junior-memory/src/index.ts index 96ef0fca86..5c5044d4bb 100644 --- a/packages/junior-memory/src/index.ts +++ b/packages/junior-memory/src/index.ts @@ -1,25 +1,25 @@ -export { memoryPlugin } from "./plugin"; -export { - memoryApiSchema, - memoryDashboardResponseSchema, - memoryListResponseSchema, - type MemoryApi, - type MemoryDashboardResponse, - type MemoryListResponse, -} from "./api"; -export type { MemoryPluginOptions } from "./plugin"; -export { createMemoryStore } from "./store"; -export type { - ArchiveMemoryInput, - CreateMemoryInput, - CreateMemoryResult, - ListMemoriesInput, - MemoryDb, - MemoryEmbeddingProvider, - MemoryRecord, - MemoryStore, - MemoryStoreOptions, - SearchMemoriesInput, -} from "./store"; -export { MEMORY_KINDS } from "./types"; -export type { MemoryKind, MemoryRuntimeContext } from "./types"; +import { defineJuniorPlugin } from "@sentry/junior-plugin-api"; + +export * from "@sentry/junior/memory"; +export type { MemoryOptions as MemoryPluginOptions } from "@sentry/junior/memory"; + +/** + * Keep old app plugin sets valid while Memory runs in core. + * + * @deprecated Remove this registration and configure `createApp({ memory })`. + */ +export function memoryPlugin( + options: import("@sentry/junior/memory").MemoryOptions = {}, +) { + return Object.assign( + defineJuniorPlugin({ + manifest: { + name: "memory", + displayName: "Memory", + description: "Compatibility marker for core Memory", + }, + packageName: "@sentry/junior-memory", + }), + { coreMemoryOptions: { ...options } }, + ); +} diff --git a/packages/junior-memory/tests/events.test.ts b/packages/junior-memory/tests/events.test.ts index eb91722c67..e29d436dda 100644 --- a/packages/junior-memory/tests/events.test.ts +++ b/packages/junior-memory/tests/events.test.ts @@ -3,7 +3,7 @@ import { memoriesCapturedEvent, memoriesCapturedEventV1, memoriesRecalledEvent, -} from "../src/events"; +} from "@sentry/junior/src/chat/memory/events"; describe("memory conversation events", () => { it("renders stored capture events with legacy scope values", () => { diff --git a/packages/junior-memory/tests/operational-report.test.ts b/packages/junior-memory/tests/operational-report.test.ts index 52ffac6e8b..3e41efcda4 100644 --- a/packages/junior-memory/tests/operational-report.test.ts +++ b/packages/junior-memory/tests/operational-report.test.ts @@ -9,10 +9,13 @@ import { } from "@sentry/junior-testing/pglite"; import { createLocalSource } from "@sentry/junior-plugin-api"; import { describe, expect, it } from "vitest"; -import * as memorySqlSchema from "../src/db/schema"; -import { juniorMemoryMemories } from "../src/db/schema"; -import { buildMemoryOperationalReport } from "../src/operational-report"; -import { createMemoryStore, type MemoryDb } from "../src/store"; +import * as memorySqlSchema from "@sentry/junior/src/db/schema/memory"; +import { juniorMemoryMemories } from "@sentry/junior/src/db/schema/memory"; +import { buildMemoryOperationalReport } from "@sentry/junior/src/chat/memory/operational-report"; +import { + createMemoryStore, + type MemoryDb, +} from "@sentry/junior/src/chat/memory/store"; const TEST_NOW_MS = Date.parse("2026-07-28T12:00:00.000Z"); const __dirname = dirname(fileURLToPath(import.meta.url)); @@ -37,15 +40,18 @@ async function createMemoryFixture(): Promise { vector: pgliteVectorExtension, }, }); - const migrations = (await readdir(resolve(__dirname, "../migrations"))) - .filter((filename) => filename.endsWith(".sql")) - .sort(); - for (const migration of migrations) { - await fixture.execute( - await readFile(resolve(__dirname, "../migrations", migration), "utf8"), - ); + const migrationsDir = resolve(__dirname, "../../junior/migrations"); + for (const filename of await readdir(migrationsDir)) { + if (!filename.endsWith(".sql")) { + continue; + } + const migration = await readFile(resolve(migrationsDir, filename), "utf8"); + if (migration.includes("Adopt the former Memory plugin tables")) { + await fixture.execute(migration); + return fixture; + } } - return fixture; + throw new Error("Memory adoption migration not found"); } function localContext() { diff --git a/packages/junior-memory/tests/ranking.test.ts b/packages/junior-memory/tests/ranking.test.ts index cfdbf8ec1b..a290c06a6a 100644 --- a/packages/junior-memory/tests/ranking.test.ts +++ b/packages/junior-memory/tests/ranking.test.ts @@ -1,6 +1,9 @@ import { describe, expect, it } from "vitest"; -import { rankMemoryMatches, type MemoryMatch } from "../src/ranking"; -import type { MemoryRecord } from "../src/store"; +import { + rankMemoryMatches, + type MemoryMatch, +} from "@sentry/junior/src/chat/memory/ranking"; +import type { MemoryRecord } from "@sentry/junior/src/chat/memory/store"; const NOW_MS = Date.parse("2026-07-28T12:00:00.000Z"); diff --git a/packages/junior-memory/tests/retrieval-quality.test.ts b/packages/junior-memory/tests/retrieval-quality.test.ts index d48db07675..48a836988f 100644 --- a/packages/junior-memory/tests/retrieval-quality.test.ts +++ b/packages/junior-memory/tests/retrieval-quality.test.ts @@ -9,12 +9,12 @@ import { } from "@sentry/junior-testing/pglite"; import { createSlackSource } from "@sentry/junior-plugin-api"; import { describe, expect, it } from "vitest"; -import * as memorySqlSchema from "../src/db/schema"; +import * as memorySqlSchema from "@sentry/junior/src/db/schema/memory"; import { createMemoryStore, type MemoryDb, type MemoryEmbeddingProvider, -} from "../src/store"; +} from "@sentry/junior/src/chat/memory/store"; const EMBEDDING_DIMENSIONS = 1536; const NOW_MS = Date.parse("2026-07-29T12:00:00.000Z"); @@ -50,16 +50,18 @@ async function createFixture(): Promise { vector: pgliteVectorExtension, }, }); - const migrationsDir = resolve(__dirname, "../migrations"); - const migrations = (await readdir(migrationsDir)) - .filter((filename) => filename.endsWith(".sql")) - .sort(); - for (const filename of migrations) { - await fixture.execute( - await readFile(resolve(migrationsDir, filename), "utf8"), - ); + const migrationsDir = resolve(__dirname, "../../junior/migrations"); + for (const filename of await readdir(migrationsDir)) { + if (!filename.endsWith(".sql")) { + continue; + } + const migration = await readFile(resolve(migrationsDir, filename), "utf8"); + if (migration.includes("Adopt the former Memory plugin tables")) { + await fixture.execute(migration); + return fixture; + } } - return fixture; + throw new Error("Memory adoption migration not found"); } function runtimeContext() { diff --git a/packages/junior-memory/tests/storage.test.ts b/packages/junior-memory/tests/storage.test.ts index 015195adcc..ee18ee3005 100644 --- a/packages/junior-memory/tests/storage.test.ts +++ b/packages/junior-memory/tests/storage.test.ts @@ -26,31 +26,37 @@ import { import { Command, CommanderError } from "commander"; import { eq } from "drizzle-orm"; import { describe, expect, it, vi } from "vitest"; -import * as memorySqlSchema from "../src/db/schema"; +import * as memorySqlSchema from "@sentry/junior/src/db/schema/memory"; import { conversationMemoryListResponseSchema, createMemoryApi, memoryApiSchema, memoryDashboardResponseSchema, memoryListResponseSchema, -} from "../src/api"; -import { createMemoryAgent, type CreateMemoryRequest } from "../src/agent"; -import { createMemoryCliCommand } from "../src/cli"; -import { memoryPlugin } from "../src/plugin"; -import { processMemorySession } from "../src/process-session"; +} from "@sentry/junior/src/chat/memory/api"; +import { + createMemoryAgent, + type CreateMemoryRequest, +} from "@sentry/junior/src/chat/memory/agent"; +import { createMemoryCliCommand } from "@sentry/junior/src/chat/memory/cli"; +import { createMemoryRegistration as memoryPlugin } from "@sentry/junior/src/chat/memory/registration"; +import { processMemorySession } from "@sentry/junior/src/chat/memory/process-session"; import { createMemoryArchiveTool, createMemoryCreateTool, createMemoryListTool, createMemorySearchTool, type MemoryReviewer, -} from "../src/tools"; -import { listMemories } from "../src/viewer"; -import { createMemoryStore, type MemoryDb } from "../src/store"; +} from "@sentry/junior/src/chat/memory/tools"; +import { listMemories } from "@sentry/junior/src/chat/memory/viewer"; +import { + createMemoryStore, + type MemoryDb, +} from "@sentry/junior/src/chat/memory/store"; import type { MemorySupersessionDecider, MemorySupersessionInput, -} from "../src/store"; +} from "@sentry/junior/src/chat/memory/store"; const TEST_NOW_MS = Date.parse("2026-06-19T12:00:00.000Z"); const TEST_EMBEDDING_DIMENSIONS = 1536; const __dirname = dirname(fileURLToPath(import.meta.url)); @@ -188,17 +194,18 @@ async function createMemoryFixture(): Promise { vector: pgliteVectorExtension, }, }); - const migrationsDir = resolve(__dirname, "../migrations"); - const migrations = (await readdir(migrationsDir)) - .filter((filename) => filename.endsWith(".sql")) - .sort(); - for (const migrationFile of migrations) { - const migration = await readFile(resolve(migrationsDir, migrationFile), { - encoding: "utf8", - }); - await fixture.execute(migration); + const migrationsDir = resolve(__dirname, "../../junior/migrations"); + for (const filename of await readdir(migrationsDir)) { + if (!filename.endsWith(".sql")) { + continue; + } + const migration = await readFile(resolve(migrationsDir, filename), "utf8"); + if (migration.includes("Adopt the former Memory plugin tables")) { + await fixture.execute(migration); + return fixture; + } } - return fixture; + throw new Error("Memory adoption migration not found"); } async function installViewerCoreTables(fixture: MemoryFixture): Promise { diff --git a/packages/junior-memory/vitest.config.ts b/packages/junior-memory/vitest.config.ts index 25bf25596b..f330625d8a 100644 --- a/packages/junior-memory/vitest.config.ts +++ b/packages/junior-memory/vitest.config.ts @@ -4,6 +4,15 @@ import { defineConfig } from "vitest/config"; export default defineConfig({ resolve: { alias: { + "@": path.resolve(__dirname, "../junior/src"), + "@sentry/junior/src/chat/memory": path.resolve( + __dirname, + "../junior/src/chat/memory", + ), + "@sentry/junior/src/db/schema/memory": path.resolve( + __dirname, + "../junior/src/db/schema/memory.ts", + ), "@sentry/junior-plugin-api": path.resolve( __dirname, "../junior-plugin-api/src/index.ts", diff --git a/packages/junior/migrations/0043_ordinary_young_avengers.sql b/packages/junior/migrations/0043_ordinary_young_avengers.sql new file mode 100644 index 0000000000..932de0e246 --- /dev/null +++ b/packages/junior/migrations/0043_ordinary_young_avengers.sql @@ -0,0 +1,302 @@ +-- Adopt the former Memory plugin tables without copying or renaming data. +CREATE EXTENSION IF NOT EXISTS vector;--> statement-breakpoint +CREATE EXTENSION IF NOT EXISTS btree_gin;--> statement-breakpoint +CREATE TABLE IF NOT EXISTS "junior_memory_memories" ( + "id" text PRIMARY KEY NOT NULL, + "scope" text NOT NULL, + "scope_key" text NOT NULL, + "type" text NOT NULL, + "subject_type" text NOT NULL, + "subject_key" text, + "content" text NOT NULL, + "search_vector" "tsvector" GENERATED ALWAYS AS (to_tsvector('english', "content")) STORED, + "source_platform" text NOT NULL, + "source_key" text NOT NULL, + "location_id" text, + "conversation_id" text, + "idempotency_key" text, + "observed_at_ms" bigint NOT NULL, + "created_at_ms" bigint NOT NULL, + "expires_at_ms" bigint, + "superseded_at_ms" bigint, + "superseded_by_id" text, + "archived_at_ms" bigint, + "archive_reason" text +);--> statement-breakpoint +ALTER TABLE "junior_memory_memories" ADD COLUMN IF NOT EXISTS "search_vector" "tsvector" GENERATED ALWAYS AS (to_tsvector('english', "content")) STORED;--> statement-breakpoint +ALTER TABLE "junior_memory_memories" ADD COLUMN IF NOT EXISTS "location_id" text;--> statement-breakpoint +ALTER TABLE "junior_memory_memories" ADD COLUMN IF NOT EXISTS "conversation_id" text;--> statement-breakpoint +ALTER TABLE "junior_memory_memories" DROP CONSTRAINT IF EXISTS "junior_memory_memories_scope_check";--> statement-breakpoint +ALTER TABLE "junior_memory_memories" DROP CONSTRAINT IF EXISTS "junior_memory_memories_type_check";--> statement-breakpoint +ALTER TABLE "junior_memory_memories" DROP CONSTRAINT IF EXISTS "junior_memory_memories_kind_check";--> statement-breakpoint +ALTER TABLE "junior_memory_memories" DROP CONSTRAINT IF EXISTS "junior_memory_memories_subject_type_check";--> statement-breakpoint +ALTER TABLE "junior_memory_memories" DROP CONSTRAINT IF EXISTS "junior_memory_memories_subject_key_check";--> statement-breakpoint +ALTER TABLE "junior_memory_memories" DROP CONSTRAINT IF EXISTS "junior_memory_memories_source_platform_check";--> statement-breakpoint +UPDATE "junior_memory_memories" +SET "type" = CASE + WHEN "type" = 'task' THEN 'procedure' + WHEN "type" IN ('identity', 'relationship', 'context', 'event', 'observation') THEN 'knowledge' + ELSE "type" +END;--> statement-breakpoint +WITH ranked_active_rows AS ( + SELECT + id, + is_legacy_public, + row_number() OVER ( + PARTITION BY target_scope_key, idempotency_key + ORDER BY CASE WHEN is_legacy_public THEN 1 ELSE 0 END, id + ) AS duplicate_rank + FROM ( + SELECT + id, + idempotency_key, + CASE + WHEN split_part(scope_key, ':', 1) = 'slack' + AND split_part(scope_key, ':', 3) LIKE 'C%' + AND split_part(scope_key, ':', 4) <> '' + THEN 'slack:' || split_part(scope_key, ':', 2) + ELSE scope_key + END AS target_scope_key, + split_part(scope_key, ':', 1) = 'slack' + AND split_part(scope_key, ':', 3) LIKE 'C%' + AND split_part(scope_key, ':', 4) <> '' AS is_legacy_public + FROM junior_memory_memories + WHERE scope = 'conversation' + AND source_platform = 'slack' + AND idempotency_key IS NOT NULL + AND archived_at_ms IS NULL + AND superseded_at_ms IS NULL + AND superseded_by_id IS NULL + ) active_rows +) +UPDATE junior_memory_memories +SET idempotency_key = 'legacy-public-slack:' || junior_memory_memories.id +FROM ranked_active_rows +WHERE junior_memory_memories.id = ranked_active_rows.id + AND ranked_active_rows.is_legacy_public + AND ranked_active_rows.duplicate_rank > 1;--> statement-breakpoint +UPDATE junior_memory_memories +SET + scope_key = 'slack:' || split_part(scope_key, ':', 2), + subject_key = CASE + WHEN subject_type = 'conversation' + AND subject_key IS NOT NULL + AND split_part(subject_key, ':', 1) = 'slack' + AND split_part(subject_key, ':', 3) LIKE 'C%' + AND split_part(subject_key, ':', 4) <> '' + THEN 'slack:' || split_part(subject_key, ':', 2) + ELSE subject_key + END +WHERE scope = 'conversation' + AND source_platform = 'slack' + AND split_part(scope_key, ':', 1) = 'slack' + AND split_part(scope_key, ':', 3) LIKE 'C%' + AND split_part(scope_key, ':', 4) <> '';--> statement-breakpoint +CREATE TEMP TABLE junior_memory_legacy_owners ( + id text PRIMARY KEY, + user_id text NOT NULL +);--> statement-breakpoint +DO $$ +BEGIN + IF to_regclass('junior_identities') IS NOT NULL THEN + EXECUTE $migration$ + INSERT INTO junior_memory_legacy_owners (id, user_id) + SELECT memory.id, owner.user_id + FROM junior_memory_memories AS memory + INNER JOIN LATERAL ( + SELECT identity.user_id + FROM junior_identities AS identity + WHERE identity.user_id IS NOT NULL + AND ( + ( + memory.scope_key LIKE 'slack:%' + AND identity.provider = 'slack' + AND identity.provider_tenant_id = split_part(memory.scope_key, ':', 2) + AND identity.provider_subject_id = split_part(memory.scope_key, ':', 3) + ) + OR ( + memory.scope_key LIKE 'local:%' + AND identity.provider = 'local' + AND identity.provider_subject_id = substring(memory.scope_key FROM 7) + ) + OR ( + memory.scope_key LIKE 'junior:%' + AND identity.provider = 'junior' + AND identity.provider_subject_id = substring(memory.scope_key FROM 8) + ) + ) + ORDER BY identity.id + LIMIT 1 + ) AS owner ON memory.scope = 'personal' + $migration$; + END IF; +END +$$;--> statement-breakpoint +CREATE TEMP TABLE junior_memory_scope_targets AS +SELECT + memory.id, + CASE + WHEN memory.scope = 'conversation' + AND memory.source_platform = 'slack' + AND memory.scope_key = 'slack:' || split_part(memory.source_key, ':', 2) + THEN 'public' + ELSE 'private' + END AS target_scope, + CASE + WHEN memory.scope = 'conversation' + AND memory.source_platform = 'slack' + AND memory.scope_key = 'slack:' || split_part(memory.source_key, ':', 2) + THEN 'public' + WHEN memory.scope = 'personal' AND owner.user_id IS NOT NULL + THEN owner.user_id + ELSE 'legacy-unowned:' || memory.id + END AS target_scope_key, + ( + memory.scope = 'conversation' AND NOT ( + memory.source_platform = 'slack' + AND memory.scope_key = 'slack:' || split_part(memory.source_key, ':', 2) + ) + ) OR (memory.scope = 'personal' AND owner.user_id IS NULL) AS archive_unowned +FROM junior_memory_memories AS memory +LEFT JOIN junior_memory_legacy_owners AS owner ON owner.id = memory.id +WHERE memory.scope IN ('personal', 'conversation');--> statement-breakpoint +WITH duplicate_targets AS ( + SELECT + memory.id, + row_number() OVER ( + PARTITION BY target.target_scope, target.target_scope_key, memory.idempotency_key + ORDER BY memory.id + ) AS duplicate_rank + FROM junior_memory_memories AS memory + INNER JOIN junior_memory_scope_targets AS target ON target.id = memory.id + WHERE memory.idempotency_key IS NOT NULL + AND memory.archived_at_ms IS NULL + AND memory.superseded_at_ms IS NULL + AND memory.superseded_by_id IS NULL + AND NOT target.archive_unowned +) +UPDATE junior_memory_memories AS memory +SET idempotency_key = 'legacy-scope:' || memory.id +FROM duplicate_targets +WHERE memory.id = duplicate_targets.id + AND duplicate_targets.duplicate_rank > 1;--> statement-breakpoint +UPDATE junior_memory_memories AS memory +SET + scope = target.target_scope, + scope_key = target.target_scope_key, + subject_key = CASE + WHEN memory.subject_type = 'user' AND target.target_scope = 'private' + THEN target.target_scope_key + ELSE memory.subject_key + END, + archived_at_ms = CASE + WHEN target.archive_unowned + THEN coalesce(memory.archived_at_ms, floor(extract(epoch FROM clock_timestamp()) * 1000)::bigint) + ELSE memory.archived_at_ms + END, + archive_reason = CASE + WHEN target.archive_unowned + THEN coalesce(memory.archive_reason, 'legacy_unowned_scope') + ELSE memory.archive_reason + END +FROM junior_memory_scope_targets AS target +WHERE memory.id = target.id;--> statement-breakpoint +DROP TABLE junior_memory_scope_targets;--> statement-breakpoint +DROP TABLE junior_memory_legacy_owners;--> statement-breakpoint +UPDATE "junior_memory_memories" +SET "conversation_id" = "source_key" +WHERE "conversation_id" IS NULL + AND "source_platform" IN ('web', 'local');--> statement-breakpoint +UPDATE "junior_memory_memories" +SET "conversation_id" = 'slack:' || split_part("source_key", ':', 3) || ':' || split_part("source_key", ':', 4) +WHERE "conversation_id" IS NULL + AND "source_platform" = 'slack';--> statement-breakpoint +DO $$ +BEGIN + IF to_regclass('public.junior_conversation_events') IS NULL THEN + RETURN; + END IF; + + UPDATE junior_conversation_events AS event + SET payload = jsonb_set( + event.payload, + '{content,memories}', + ( + SELECT coalesce( + jsonb_agg( + CASE + WHEN jsonb_typeof(memory.value) = 'object' + AND memory.value->>'scope' = 'personal' + THEN jsonb_set(memory.value, '{scope}', '"private"'::jsonb) + WHEN jsonb_typeof(memory.value) = 'object' + AND memory.value->>'scope' = 'conversation' + THEN jsonb_set(memory.value, '{scope}', '"public"'::jsonb) + ELSE memory.value + END + ORDER BY memory.ordinality + ), + '[]'::jsonb + ) + FROM jsonb_array_elements( + CASE + WHEN jsonb_typeof(event.payload->'content'->'memories') = 'array' + THEN event.payload->'content'->'memories' + ELSE '[]'::jsonb + END + ) WITH ORDINALITY AS memory(value, ordinality) + ) + ) + WHERE event.type = 'structured_event' + AND event.payload->>'namespace' = 'memory' + AND event.payload->>'name' = 'memories_captured' + AND event.payload->>'version' = '2' + AND jsonb_typeof(event.payload->'content'->'memories') = 'array' + AND EXISTS ( + SELECT 1 + FROM jsonb_array_elements(event.payload->'content'->'memories') AS memory(value) + WHERE memory.value->>'scope' IN ('personal', 'conversation') + ); +END +$$;--> statement-breakpoint +ALTER TABLE "junior_memory_memories" ADD CONSTRAINT "junior_memory_memories_scope_check" CHECK ("scope" IN ('private', 'public'));--> statement-breakpoint +ALTER TABLE "junior_memory_memories" ADD CONSTRAINT "junior_memory_memories_kind_check" CHECK ("type" IN ('preference', 'procedure', 'knowledge'));--> statement-breakpoint +ALTER TABLE "junior_memory_memories" ADD CONSTRAINT "junior_memory_memories_subject_type_check" CHECK ("subject_type" IN ('user', 'conversation', 'general'));--> statement-breakpoint +ALTER TABLE "junior_memory_memories" ADD CONSTRAINT "junior_memory_memories_subject_key_check" CHECK (("subject_type" = 'general' AND "subject_key" IS NULL) OR ("subject_type" IN ('user', 'conversation') AND "subject_key" IS NOT NULL AND length("subject_key") > 0));--> statement-breakpoint +ALTER TABLE "junior_memory_memories" ADD CONSTRAINT "junior_memory_memories_source_platform_check" CHECK ("source_platform" IN ('slack', 'local', 'web'));--> statement-breakpoint +CREATE TABLE IF NOT EXISTS "junior_memory_embeddings" ( + "memory_id" text PRIMARY KEY NOT NULL, + "provider" text NOT NULL, + "model" text NOT NULL, + "dimensions" integer NOT NULL, + "metric" text NOT NULL, + "content_hash" text NOT NULL, + "embedding" vector(1536) NOT NULL, + "created_at_ms" bigint NOT NULL +);--> statement-breakpoint +ALTER TABLE "junior_memory_embeddings" DROP CONSTRAINT IF EXISTS "junior_memory_embeddings_metric_check";--> statement-breakpoint +ALTER TABLE "junior_memory_embeddings" DROP CONSTRAINT IF EXISTS "junior_memory_embeddings_dimensions_check";--> statement-breakpoint +ALTER TABLE "junior_memory_embeddings" ADD CONSTRAINT "junior_memory_embeddings_metric_check" CHECK ("metric" IN ('cosine'));--> statement-breakpoint +ALTER TABLE "junior_memory_embeddings" ADD CONSTRAINT "junior_memory_embeddings_dimensions_check" CHECK ("dimensions" = 1536);--> statement-breakpoint +DO $$ +BEGIN + IF NOT EXISTS ( + SELECT 1 + FROM pg_constraint + WHERE conname = 'junior_memory_embeddings_memory_id_junior_memory_memories_id_fk' + AND conrelid = 'junior_memory_embeddings'::regclass + ) THEN + ALTER TABLE "junior_memory_embeddings" + ADD CONSTRAINT "junior_memory_embeddings_memory_id_junior_memory_memories_id_fk" + FOREIGN KEY ("memory_id") REFERENCES "public"."junior_memory_memories"("id") + ON DELETE cascade ON UPDATE no action; + END IF; +END +$$;--> statement-breakpoint +CREATE INDEX IF NOT EXISTS "junior_memory_embeddings_model_idx" ON "junior_memory_embeddings" USING btree ("provider","model","dimensions","metric");--> statement-breakpoint +CREATE INDEX IF NOT EXISTS "junior_memory_embeddings_embedding_hnsw_idx" ON "junior_memory_embeddings" USING hnsw ("embedding" vector_cosine_ops) WITH (m=16,ef_construction=64);--> statement-breakpoint +CREATE INDEX IF NOT EXISTS "junior_memory_memories_visible_idx" ON "junior_memory_memories" USING btree ("scope","scope_key","created_at_ms" DESC NULLS LAST,"id") WHERE "archived_at_ms" IS NULL AND "superseded_at_ms" IS NULL AND "superseded_by_id" IS NULL;--> statement-breakpoint +CREATE INDEX IF NOT EXISTS "junior_memory_memories_expiration_idx" ON "junior_memory_memories" USING btree ("expires_at_ms") WHERE "archived_at_ms" IS NULL AND "expires_at_ms" IS NOT NULL;--> statement-breakpoint +DROP INDEX IF EXISTS "junior_memory_memories_search_idx";--> statement-breakpoint +CREATE INDEX "junior_memory_memories_search_idx" ON "junior_memory_memories" USING gin ("scope","scope_key","search_vector") WHERE "archived_at_ms" IS NULL AND "superseded_at_ms" IS NULL AND "superseded_by_id" IS NULL;--> statement-breakpoint +DROP INDEX IF EXISTS "junior_memory_memories_idempotency_idx";--> statement-breakpoint +CREATE UNIQUE INDEX "junior_memory_memories_idempotency_idx" ON "junior_memory_memories" USING btree ("scope","scope_key","idempotency_key") WHERE "idempotency_key" IS NOT NULL AND "archived_at_ms" IS NULL AND "superseded_at_ms" IS NULL AND "superseded_by_id" IS NULL; diff --git a/packages/junior/migrations/meta/0043_snapshot.json b/packages/junior/migrations/meta/0043_snapshot.json new file mode 100644 index 0000000000..983be08ed7 --- /dev/null +++ b/packages/junior/migrations/meta/0043_snapshot.json @@ -0,0 +1,4012 @@ +{ + "id": "6ab8a843-5642-4824-9158-6683a4e92537", + "prevId": "d002a83e-e566-4dcb-a397-1e3b689ad2cb", + "version": "7", + "dialect": "postgresql", + "tables": { + "public.junior_agent_bindings": { + "name": "junior_agent_bindings", + "schema": "", + "columns": { + "parent_conversation_id": { + "name": "parent_conversation_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "child_conversation_id": { + "name": "child_conversation_id", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "junior_agent_bindings_child_idx": { + "name": "junior_agent_bindings_child_idx", + "columns": [ + { + "expression": "child_conversation_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "junior_agent_bindings_parent_conversation_id_junior_conversations_conversation_id_fk": { + "name": "junior_agent_bindings_parent_conversation_id_junior_conversations_conversation_id_fk", + "tableFrom": "junior_agent_bindings", + "tableTo": "junior_conversations", + "columnsFrom": [ + "parent_conversation_id" + ], + "columnsTo": [ + "conversation_id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "junior_agent_bindings_child_conversation_id_junior_conversations_conversation_id_fk": { + "name": "junior_agent_bindings_child_conversation_id_junior_conversations_conversation_id_fk", + "tableFrom": "junior_agent_bindings", + "tableTo": "junior_conversations", + "columnsFrom": [ + "child_conversation_id" + ], + "columnsTo": [ + "conversation_id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "junior_agent_bindings_parent_conversation_id_name_pk": { + "name": "junior_agent_bindings_parent_conversation_id_name_pk", + "columns": [ + "parent_conversation_id", + "name" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.junior_agent_invocations": { + "name": "junior_agent_invocations", + "schema": "", + "columns": { + "invocation_id": { + "name": "invocation_id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "parent_conversation_id": { + "name": "parent_conversation_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "child_conversation_id": { + "name": "child_conversation_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "agent_name": { + "name": "agent_name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "input": { + "name": "input", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "actor_json": { + "name": "actor_json", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "credential_context_json": { + "name": "credential_context_json", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "source_json": { + "name": "source_json", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "destination_json": { + "name": "destination_json", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "destination_visibility": { + "name": "destination_visibility", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "reasoning_level": { + "name": "reasoning_level", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "mailbox_status": { + "name": "mailbox_status", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "result": { + "name": "result", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "error_message": { + "name": "error_message", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "terminal_at": { + "name": "terminal_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "junior_agent_invocations_child_idx": { + "name": "junior_agent_invocations_child_idx", + "columns": [ + { + "expression": "child_conversation_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "junior_agent_invocations_mailbox_idx": { + "name": "junior_agent_invocations_mailbox_idx", + "columns": [ + { + "expression": "mailbox_status", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "junior_agent_invocations_parent_conversation_id_junior_conversations_conversation_id_fk": { + "name": "junior_agent_invocations_parent_conversation_id_junior_conversations_conversation_id_fk", + "tableFrom": "junior_agent_invocations", + "tableTo": "junior_conversations", + "columnsFrom": [ + "parent_conversation_id" + ], + "columnsTo": [ + "conversation_id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "junior_agent_invocations_child_conversation_id_junior_conversations_conversation_id_fk": { + "name": "junior_agent_invocations_child_conversation_id_junior_conversations_conversation_id_fk", + "tableFrom": "junior_agent_invocations", + "tableTo": "junior_conversations", + "columnsFrom": [ + "child_conversation_id" + ], + "columnsTo": [ + "conversation_id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.junior_api_tokens": { + "name": "junior_api_tokens", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "owner_email_normalized": { + "name": "owner_email_normalized", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "token_hash": { + "name": "token_hash", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "token_suffix": { + "name": "token_suffix", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "last_used_at": { + "name": "last_used_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "revoked_at": { + "name": "revoked_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "junior_api_tokens_token_hash_uidx": { + "name": "junior_api_tokens_token_hash_uidx", + "columns": [ + { + "expression": "token_hash", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "junior_api_tokens_owner_email_idx": { + "name": "junior_api_tokens_owner_email_idx", + "columns": [ + { + "expression": "owner_email_normalized", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.junior_artifacts": { + "name": "junior_artifacts", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "conversation_id": { + "name": "conversation_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "sha256": { + "name": "sha256", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "ext": { + "name": "ext", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "storage_key": { + "name": "storage_key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "content_type": { + "name": "content_type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "bytes": { + "name": "bytes", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "public": { + "name": "public", + "type": "boolean", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "delete_requested_at": { + "name": "delete_requested_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "junior_artifacts_conversation_sha_uidx": { + "name": "junior_artifacts_conversation_sha_uidx", + "columns": [ + { + "expression": "conversation_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "sha256", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "junior_artifacts_gc_idx": { + "name": "junior_artifacts_gc_idx", + "columns": [ + { + "expression": "delete_requested_at", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "junior_artifacts_conversation_idx": { + "name": "junior_artifacts_conversation_idx", + "columns": [ + { + "expression": "conversation_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.junior_attachments": { + "name": "junior_attachments", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "conversation_id": { + "name": "conversation_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "storage_provider": { + "name": "storage_provider", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "storage_key": { + "name": "storage_key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "provider": { + "name": "provider", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "provider_id": { + "name": "provider_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "filename": { + "name": "filename", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "content_type": { + "name": "content_type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "bytes": { + "name": "bytes", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "sha256": { + "name": "sha256", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "vision_summary": { + "name": "vision_summary", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "delete_requested_at": { + "name": "delete_requested_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "junior_attachments_conversation_idx": { + "name": "junior_attachments_conversation_idx", + "columns": [ + { + "expression": "conversation_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "junior_attachments_provider_idx": { + "name": "junior_attachments_provider_idx", + "columns": [ + { + "expression": "conversation_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "provider", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "provider_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "junior_attachments_gc_idx": { + "name": "junior_attachments_gc_idx", + "columns": [ + { + "expression": "storage_provider", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "delete_requested_at", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "junior_attachments_conversation_id_junior_conversations_conversation_id_fk": { + "name": "junior_attachments_conversation_id_junior_conversations_conversation_id_fk", + "tableFrom": "junior_attachments", + "tableTo": "junior_conversations", + "columnsFrom": [ + "conversation_id" + ], + "columnsTo": [ + "conversation_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.junior_task_executions": { + "name": "junior_task_executions", + "schema": "", + "columns": { + "execution_id": { + "name": "execution_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "kind": { + "name": "kind", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "namespace": { + "name": "namespace", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "task_id": { + "name": "task_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "conversation_id": { + "name": "conversation_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "executed_at_ms": { + "name": "executed_at_ms", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "junior_task_executions_task_time_idx": { + "name": "junior_task_executions_task_time_idx", + "columns": [ + { + "expression": "kind", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "namespace", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "task_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "executed_at_ms", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "junior_task_executions_time_kind_idx": { + "name": "junior_task_executions_time_kind_idx", + "columns": [ + { + "expression": "executed_at_ms", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "kind", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "junior_task_executions_conversation_time_idx": { + "name": "junior_task_executions_conversation_time_idx", + "columns": [ + { + "expression": "conversation_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "executed_at_ms", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "junior_task_executions_conversation_id_junior_conversations_conversation_id_fk": { + "name": "junior_task_executions_conversation_id_junior_conversations_conversation_id_fk", + "tableFrom": "junior_task_executions", + "tableTo": "junior_conversations", + "columnsFrom": [ + "conversation_id" + ], + "columnsTo": [ + "conversation_id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "junior_task_executions_kind_namespace_execution_id_pk": { + "name": "junior_task_executions_kind_namespace_execution_id_pk", + "columns": [ + "kind", + "namespace", + "execution_id" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "junior_task_executions_kind_check": { + "name": "junior_task_executions_kind_check", + "value": "\"junior_task_executions\".\"kind\" in ('scheduled', 'event')" + }, + "junior_task_executions_status_check": { + "name": "junior_task_executions_status_check", + "value": "\"junior_task_executions\".\"status\" in ('blocked', 'completed', 'failed')" + } + }, + "isRLSEnabled": false + }, + "public.junior_code_changes": { + "name": "junior_code_changes", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true + }, + "closed_at": { + "name": "closed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "conversation_ids": { + "name": "conversation_ids", + "type": "text[]", + "primaryKey": false, + "notNull": true, + "default": "ARRAY[]::text[]" + }, + "merged_at": { + "name": "merged_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "number": { + "name": "number", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "opened_at": { + "name": "opened_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "provider": { + "name": "provider", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "provider_id": { + "name": "provider_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "repository_id": { + "name": "repository_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "state": { + "name": "state", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "title": { + "name": "title", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "url": { + "name": "url", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "junior_code_changes_provider_id_idx": { + "name": "junior_code_changes_provider_id_idx", + "columns": [ + { + "expression": "provider", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "provider_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "junior_code_changes_opened_at_idx": { + "name": "junior_code_changes_opened_at_idx", + "columns": [ + { + "expression": "opened_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "junior_code_changes_merged_at_idx": { + "name": "junior_code_changes_merged_at_idx", + "columns": [ + { + "expression": "merged_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "junior_code_changes_closed_at_idx": { + "name": "junior_code_changes_closed_at_idx", + "columns": [ + { + "expression": "closed_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "junior_code_changes_open_idx": { + "name": "junior_code_changes_open_idx", + "columns": [ + { + "expression": "id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"junior_code_changes\".\"state\" = 'open'", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "junior_code_changes_repository_id_junior_code_repositories_id_fk": { + "name": "junior_code_changes_repository_id_junior_code_repositories_id_fk", + "tableFrom": "junior_code_changes", + "tableTo": "junior_code_repositories", + "columnsFrom": [ + "repository_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.junior_code_repositories": { + "name": "junior_code_repositories", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "provider": { + "name": "provider", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "provider_id": { + "name": "provider_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "url": { + "name": "url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "junior_code_repositories_provider_id_idx": { + "name": "junior_code_repositories_provider_id_idx", + "columns": [ + { + "expression": "provider", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "provider_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.junior_conversation_annotations": { + "name": "junior_conversation_annotations", + "schema": "", + "columns": { + "conversation_id": { + "name": "conversation_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "plugin": { + "name": "plugin", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "kind": { + "name": "kind", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "key": { + "name": "key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "annotation_json": { + "name": "annotation_json", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "junior_conversation_annotations_conversation_id_fk": { + "name": "junior_conversation_annotations_conversation_id_fk", + "tableFrom": "junior_conversation_annotations", + "tableTo": "junior_conversations", + "columnsFrom": [ + "conversation_id" + ], + "columnsTo": [ + "conversation_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "junior_conversation_annotations_pk": { + "name": "junior_conversation_annotations_pk", + "columns": [ + "conversation_id", + "plugin", + "kind", + "key" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.junior_conversation_bindings": { + "name": "junior_conversation_bindings", + "schema": "", + "columns": { + "conversation_id": { + "name": "conversation_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "provider": { + "name": "provider", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "provider_tenant_id": { + "name": "provider_tenant_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "provider_destination_id": { + "name": "provider_destination_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "provider_conversation_id": { + "name": "provider_conversation_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "junior_conversation_bindings_conversation_idx": { + "name": "junior_conversation_bindings_conversation_idx", + "columns": [ + { + "expression": "conversation_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "junior_conversation_bindings_conversation_id_junior_conversations_conversation_id_fk": { + "name": "junior_conversation_bindings_conversation_id_junior_conversations_conversation_id_fk", + "tableFrom": "junior_conversation_bindings", + "tableTo": "junior_conversations", + "columnsFrom": [ + "conversation_id" + ], + "columnsTo": [ + "conversation_id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "junior_conversation_bindings_provider_conversation_pk": { + "name": "junior_conversation_bindings_provider_conversation_pk", + "columns": [ + "provider", + "provider_tenant_id", + "provider_destination_id", + "provider_conversation_id" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.junior_conversation_briefs": { + "name": "junior_conversation_briefs", + "schema": "", + "columns": { + "conversation_id": { + "name": "conversation_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "version": { + "name": "version", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "turn_id": { + "name": "turn_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "through_seq": { + "name": "through_seq", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "content": { + "name": "content", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "search_text": { + "name": "search_text", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "model_id": { + "name": "model_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "cost_usd": { + "name": "cost_usd", + "type": "double precision", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "junior_conversation_briefs_conversation_turn_idx": { + "name": "junior_conversation_briefs_conversation_turn_idx", + "columns": [ + { + "expression": "conversation_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "turn_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "junior_conversation_briefs_conversation_version_idx": { + "name": "junior_conversation_briefs_conversation_version_idx", + "columns": [ + { + "expression": "conversation_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "version", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "junior_conversation_briefs_search_idx": { + "name": "junior_conversation_briefs_search_idx", + "columns": [ + { + "expression": "to_tsvector('english', \"search_text\")", + "asc": true, + "isExpression": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "gin", + "with": {} + } + }, + "foreignKeys": { + "junior_conversation_briefs_conversation_id_junior_conversations_conversation_id_fk": { + "name": "junior_conversation_briefs_conversation_id_junior_conversations_conversation_id_fk", + "tableFrom": "junior_conversation_briefs", + "tableTo": "junior_conversations", + "columnsFrom": [ + "conversation_id" + ], + "columnsTo": [ + "conversation_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "junior_conversation_briefs_conversation_id_version_pk": { + "name": "junior_conversation_briefs_conversation_id_version_pk", + "columns": [ + "conversation_id", + "version" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.junior_conversation_events": { + "name": "junior_conversation_events", + "schema": "", + "columns": { + "conversation_id": { + "name": "conversation_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "seq": { + "name": "seq", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "history_version": { + "name": "history_version", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "schema_version": { + "name": "schema_version", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "idempotency_key": { + "name": "idempotency_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "type": { + "name": "type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "payload": { + "name": "payload", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "actor_identity_id": { + "name": "actor_identity_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "junior_conversation_events_history_version_idx": { + "name": "junior_conversation_events_history_version_idx", + "columns": [ + { + "expression": "conversation_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "history_version", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "seq", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "junior_conversation_events_type_idx": { + "name": "junior_conversation_events_type_idx", + "columns": [ + { + "expression": "conversation_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "type", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "seq", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "junior_conversation_events_actor_identity_idx": { + "name": "junior_conversation_events_actor_identity_idx", + "columns": [ + { + "expression": "actor_identity_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "conversation_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "seq", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "junior_conversation_events_message_search_idx": { + "name": "junior_conversation_events_message_search_idx", + "columns": [ + { + "expression": "to_tsvector('english', \"payload\"->>'text')", + "asc": true, + "isExpression": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"junior_conversation_events\".\"type\" = 'message'", + "concurrently": false, + "method": "gin", + "with": {} + }, + "junior_conversation_events_idempotency_idx": { + "name": "junior_conversation_events_idempotency_idx", + "columns": [ + { + "expression": "conversation_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "idempotency_key", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "junior_conversation_events_actor_identity_id_junior_identities_id_fk": { + "name": "junior_conversation_events_actor_identity_id_junior_identities_id_fk", + "tableFrom": "junior_conversation_events", + "tableTo": "junior_identities", + "columnsFrom": [ + "actor_identity_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "junior_conversation_events_conversation_id_junior_conversations_conversation_id_fk": { + "name": "junior_conversation_events_conversation_id_junior_conversations_conversation_id_fk", + "tableFrom": "junior_conversation_events", + "tableTo": "junior_conversations", + "columnsFrom": [ + "conversation_id" + ], + "columnsTo": [ + "conversation_id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "junior_conversation_events_conversation_id_seq_pk": { + "name": "junior_conversation_events_conversation_id_seq_pk", + "columns": [ + "conversation_id", + "seq" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.junior_conversation_metrics": { + "name": "junior_conversation_metrics", + "schema": "", + "columns": { + "conversation_id": { + "name": "conversation_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "run_id": { + "name": "run_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "metric": { + "name": "metric", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "value": { + "name": "value", + "type": "double precision", + "primaryKey": false, + "notNull": true + }, + "occurred_at": { + "name": "occurred_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "junior_conversation_metrics_occurred_at_metric_idx": { + "name": "junior_conversation_metrics_occurred_at_metric_idx", + "columns": [ + { + "expression": "occurred_at", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "metric", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "junior_conversation_metrics_conversation_id_junior_conversations_conversation_id_fk": { + "name": "junior_conversation_metrics_conversation_id_junior_conversations_conversation_id_fk", + "tableFrom": "junior_conversation_metrics", + "tableTo": "junior_conversations", + "columnsFrom": [ + "conversation_id" + ], + "columnsTo": [ + "conversation_id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "junior_conversation_metrics_conversation_id_run_id_metric_pk": { + "name": "junior_conversation_metrics_conversation_id_run_id_metric_pk", + "columns": [ + "conversation_id", + "run_id", + "metric" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.junior_conversation_participants": { + "name": "junior_conversation_participants", + "schema": "", + "columns": { + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "root_conversation_id": { + "name": "root_conversation_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "last_message_at": { + "name": "last_message_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "archived_at": { + "name": "archived_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "junior_conversation_participants_user_activity_idx": { + "name": "junior_conversation_participants_user_activity_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "last_message_at", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "junior_conversation_participants_root_idx": { + "name": "junior_conversation_participants_root_idx", + "columns": [ + { + "expression": "root_conversation_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "junior_conversation_participants_user_id_junior_users_id_fk": { + "name": "junior_conversation_participants_user_id_junior_users_id_fk", + "tableFrom": "junior_conversation_participants", + "tableTo": "junior_users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "junior_conversation_participants_root_conversation_id_junior_conversations_conversation_id_fk": { + "name": "junior_conversation_participants_root_conversation_id_junior_conversations_conversation_id_fk", + "tableFrom": "junior_conversation_participants", + "tableTo": "junior_conversations", + "columnsFrom": [ + "root_conversation_id" + ], + "columnsTo": [ + "conversation_id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "junior_conversation_participants_user_root_pk": { + "name": "junior_conversation_participants_user_root_pk", + "columns": [ + "user_id", + "root_conversation_id" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.junior_conversations": { + "name": "junior_conversations", + "schema": "", + "columns": { + "conversation_id": { + "name": "conversation_id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "schema_version": { + "name": "schema_version", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "source": { + "name": "source", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "source_json": { + "name": "source_json", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "origin_type": { + "name": "origin_type", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "origin_id": { + "name": "origin_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "origin_run_id": { + "name": "origin_run_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "location_json": { + "name": "location_json", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "destination_id": { + "name": "destination_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "destination_json": { + "name": "destination_json", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "actor_identity_id": { + "name": "actor_identity_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "creator_identity_id": { + "name": "creator_identity_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "credential_subject_identity_id": { + "name": "credential_subject_identity_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "actor_json": { + "name": "actor_json", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "channel_name": { + "name": "channel_name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "title": { + "name": "title", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "last_activity_at": { + "name": "last_activity_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "execution_updated_at": { + "name": "execution_updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "execution_status": { + "name": "execution_status", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "run_id": { + "name": "run_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "last_checkpoint_at": { + "name": "last_checkpoint_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "last_enqueued_at": { + "name": "last_enqueued_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "parent_conversation_id": { + "name": "parent_conversation_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "root_conversation_id": { + "name": "root_conversation_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "transcript_purged_at": { + "name": "transcript_purged_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "duration_ms": { + "name": "duration_ms", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "usage_json": { + "name": "usage_json", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "execution_duration_ms": { + "name": "execution_duration_ms", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "execution_usage_json": { + "name": "execution_usage_json", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "metric_run_id": { + "name": "metric_run_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "archived_at": { + "name": "archived_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "junior_conversations_last_activity_idx": { + "name": "junior_conversations_last_activity_idx", + "columns": [ + { + "expression": "last_activity_at", + "isExpression": false, + "asc": false, + "nulls": "last" + }, + { + "expression": "conversation_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "junior_conversations_active_idx": { + "name": "junior_conversations_active_idx", + "columns": [ + { + "expression": "coalesce(\"execution_updated_at\", \"updated_at\")", + "asc": true, + "isExpression": true, + "nulls": "last" + }, + { + "expression": "conversation_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"junior_conversations\".\"execution_status\" <> 'idle'", + "concurrently": false, + "method": "btree", + "with": {} + }, + "junior_conversations_destination_activity_idx": { + "name": "junior_conversations_destination_activity_idx", + "columns": [ + { + "expression": "destination_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "last_activity_at", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "junior_conversations_actor_activity_idx": { + "name": "junior_conversations_actor_activity_idx", + "columns": [ + { + "expression": "actor_identity_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "last_activity_at", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "junior_conversations_origin_idx": { + "name": "junior_conversations_origin_idx", + "columns": [ + { + "expression": "origin_type", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "origin_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "last_activity_at", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "junior_conversations_parent_idx": { + "name": "junior_conversations_parent_idx", + "columns": [ + { + "expression": "parent_conversation_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "junior_conversations_root_idx": { + "name": "junior_conversations_root_idx", + "columns": [ + { + "expression": "root_conversation_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "junior_conversations_destination_id_junior_destinations_id_fk": { + "name": "junior_conversations_destination_id_junior_destinations_id_fk", + "tableFrom": "junior_conversations", + "tableTo": "junior_destinations", + "columnsFrom": [ + "destination_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "junior_conversations_actor_identity_id_junior_identities_id_fk": { + "name": "junior_conversations_actor_identity_id_junior_identities_id_fk", + "tableFrom": "junior_conversations", + "tableTo": "junior_identities", + "columnsFrom": [ + "actor_identity_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "junior_conversations_creator_identity_id_junior_identities_id_fk": { + "name": "junior_conversations_creator_identity_id_junior_identities_id_fk", + "tableFrom": "junior_conversations", + "tableTo": "junior_identities", + "columnsFrom": [ + "creator_identity_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "junior_conversations_credential_subject_identity_id_junior_identities_id_fk": { + "name": "junior_conversations_credential_subject_identity_id_junior_identities_id_fk", + "tableFrom": "junior_conversations", + "tableTo": "junior_identities", + "columnsFrom": [ + "credential_subject_identity_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "junior_conversations_parent_conversation_id_junior_conversations_conversation_id_fk": { + "name": "junior_conversations_parent_conversation_id_junior_conversations_conversation_id_fk", + "tableFrom": "junior_conversations", + "tableTo": "junior_conversations", + "columnsFrom": [ + "parent_conversation_id" + ], + "columnsTo": [ + "conversation_id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "junior_conversations_root_conversation_id_junior_conversations_conversation_id_fk": { + "name": "junior_conversations_root_conversation_id_junior_conversations_conversation_id_fk", + "tableFrom": "junior_conversations", + "tableTo": "junior_conversations", + "columnsFrom": [ + "root_conversation_id" + ], + "columnsTo": [ + "conversation_id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.junior_destinations": { + "name": "junior_destinations", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "provider": { + "name": "provider", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "provider_tenant_id": { + "name": "provider_tenant_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "provider_destination_id": { + "name": "provider_destination_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "kind": { + "name": "kind", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "parent_destination_id": { + "name": "parent_destination_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "display_name": { + "name": "display_name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "visibility": { + "name": "visibility", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'unknown'" + }, + "metadata_json": { + "name": "metadata_json", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "junior_destinations_provider_destination_uidx": { + "name": "junior_destinations_provider_destination_uidx", + "columns": [ + { + "expression": "provider", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "provider_tenant_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "provider_destination_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "junior_destinations_provider_kind_idx": { + "name": "junior_destinations_provider_kind_idx", + "columns": [ + { + "expression": "provider", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "kind", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.junior_event_tasks": { + "name": "junior_event_tasks", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "team_id": { + "name": "team_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "namespace": { + "name": "namespace", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "identifier": { + "name": "identifier", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at_ms": { + "name": "created_at_ms", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'active'" + }, + "title": { + "name": "title", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "task_json": { + "name": "task_json", + "type": "jsonb", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "junior_event_tasks_team_idx": { + "name": "junior_event_tasks_team_idx", + "columns": [ + { + "expression": "team_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at_ms", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"junior_event_tasks\".\"status\" <> 'deleted'", + "concurrently": false, + "method": "btree", + "with": {} + }, + "junior_event_tasks_match_idx": { + "name": "junior_event_tasks_match_idx", + "columns": [ + { + "expression": "namespace", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "identifier", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at_ms", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"junior_event_tasks\".\"status\" <> 'deleted'", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.junior_identities": { + "name": "junior_identities", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "kind": { + "name": "kind", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "provider": { + "name": "provider", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "provider_tenant_id": { + "name": "provider_tenant_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "provider_subject_id": { + "name": "provider_subject_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "display_name": { + "name": "display_name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "handle": { + "name": "handle", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "email": { + "name": "email", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "avatar_url": { + "name": "avatar_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "metadata_json": { + "name": "metadata_json", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "email_normalized": { + "name": "email_normalized", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "email_verified": { + "name": "email_verified", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + } + }, + "indexes": { + "junior_identities_provider_subject_uidx": { + "name": "junior_identities_provider_subject_uidx", + "columns": [ + { + "expression": "provider", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "provider_tenant_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "provider_subject_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "junior_identities_user_idx": { + "name": "junior_identities_user_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "junior_identities_verified_email_idx": { + "name": "junior_identities_verified_email_idx", + "columns": [ + { + "expression": "email_normalized", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"junior_identities\".\"email_verified\" = true AND \"junior_identities\".\"email_normalized\" IS NOT NULL", + "concurrently": false, + "method": "btree", + "with": {} + }, + "junior_identities_kind_provider_idx": { + "name": "junior_identities_kind_provider_idx", + "columns": [ + { + "expression": "kind", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "provider", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "junior_identities_user_id_junior_users_id_fk": { + "name": "junior_identities_user_id_junior_users_id_fk", + "tableFrom": "junior_identities", + "tableTo": "junior_users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.junior_location_configurations": { + "name": "junior_location_configurations", + "schema": "", + "columns": { + "location_id": { + "name": "location_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "key": { + "name": "key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "value": { + "name": "value", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "updated_by": { + "name": "updated_by", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "source": { + "name": "source", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "expires_at": { + "name": "expires_at", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "junior_location_configurations_location_id_junior_destinations_id_fk": { + "name": "junior_location_configurations_location_id_junior_destinations_id_fk", + "tableFrom": "junior_location_configurations", + "tableTo": "junior_destinations", + "columnsFrom": [ + "location_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "junior_location_configurations_location_id_key_pk": { + "name": "junior_location_configurations_location_id_key_pk", + "columns": [ + "location_id", + "key" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.junior_memory_embeddings": { + "name": "junior_memory_embeddings", + "schema": "", + "columns": { + "memory_id": { + "name": "memory_id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "provider": { + "name": "provider", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "model": { + "name": "model", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "dimensions": { + "name": "dimensions", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "metric": { + "name": "metric", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "content_hash": { + "name": "content_hash", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "embedding": { + "name": "embedding", + "type": "vector(1536)", + "primaryKey": false, + "notNull": true + }, + "created_at_ms": { + "name": "created_at_ms", + "type": "bigint", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "junior_memory_embeddings_model_idx": { + "name": "junior_memory_embeddings_model_idx", + "columns": [ + { + "expression": "provider", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "model", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "dimensions", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "metric", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "junior_memory_embeddings_embedding_hnsw_idx": { + "name": "junior_memory_embeddings_embedding_hnsw_idx", + "columns": [ + { + "expression": "embedding", + "isExpression": false, + "asc": true, + "nulls": "last", + "opclass": "vector_cosine_ops" + } + ], + "isUnique": false, + "concurrently": false, + "method": "hnsw", + "with": { + "m": 16, + "ef_construction": 64 + } + } + }, + "foreignKeys": { + "junior_memory_embeddings_memory_id_junior_memory_memories_id_fk": { + "name": "junior_memory_embeddings_memory_id_junior_memory_memories_id_fk", + "tableFrom": "junior_memory_embeddings", + "tableTo": "junior_memory_memories", + "columnsFrom": [ + "memory_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "junior_memory_embeddings_metric_check": { + "name": "junior_memory_embeddings_metric_check", + "value": "\"junior_memory_embeddings\".\"metric\" IN ('cosine')" + }, + "junior_memory_embeddings_dimensions_check": { + "name": "junior_memory_embeddings_dimensions_check", + "value": "\"junior_memory_embeddings\".\"dimensions\" = 1536" + } + }, + "isRLSEnabled": false + }, + "public.junior_memory_memories": { + "name": "junior_memory_memories", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "scope": { + "name": "scope", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "scope_key": { + "name": "scope_key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "type": { + "name": "type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "subject_type": { + "name": "subject_type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "subject_key": { + "name": "subject_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "content": { + "name": "content", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "search_vector": { + "name": "search_vector", + "type": "tsvector", + "primaryKey": false, + "notNull": false, + "generated": { + "as": "to_tsvector('english', \"content\")", + "type": "stored" + } + }, + "source_platform": { + "name": "source_platform", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "source_key": { + "name": "source_key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "location_id": { + "name": "location_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "conversation_id": { + "name": "conversation_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "idempotency_key": { + "name": "idempotency_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "observed_at_ms": { + "name": "observed_at_ms", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "created_at_ms": { + "name": "created_at_ms", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "expires_at_ms": { + "name": "expires_at_ms", + "type": "bigint", + "primaryKey": false, + "notNull": false + }, + "superseded_at_ms": { + "name": "superseded_at_ms", + "type": "bigint", + "primaryKey": false, + "notNull": false + }, + "superseded_by_id": { + "name": "superseded_by_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "archived_at_ms": { + "name": "archived_at_ms", + "type": "bigint", + "primaryKey": false, + "notNull": false + }, + "archive_reason": { + "name": "archive_reason", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "junior_memory_memories_visible_idx": { + "name": "junior_memory_memories_visible_idx", + "columns": [ + { + "expression": "scope", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "scope_key", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at_ms", + "isExpression": false, + "asc": false, + "nulls": "last" + }, + { + "expression": "id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"junior_memory_memories\".\"archived_at_ms\" IS NULL AND \"junior_memory_memories\".\"superseded_at_ms\" IS NULL AND \"junior_memory_memories\".\"superseded_by_id\" IS NULL", + "concurrently": false, + "method": "btree", + "with": {} + }, + "junior_memory_memories_expiration_idx": { + "name": "junior_memory_memories_expiration_idx", + "columns": [ + { + "expression": "expires_at_ms", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"junior_memory_memories\".\"archived_at_ms\" IS NULL AND \"junior_memory_memories\".\"expires_at_ms\" IS NOT NULL", + "concurrently": false, + "method": "btree", + "with": {} + }, + "junior_memory_memories_search_idx": { + "name": "junior_memory_memories_search_idx", + "columns": [ + { + "expression": "scope", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "scope_key", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "search_vector", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"junior_memory_memories\".\"archived_at_ms\" IS NULL AND \"junior_memory_memories\".\"superseded_at_ms\" IS NULL AND \"junior_memory_memories\".\"superseded_by_id\" IS NULL", + "concurrently": false, + "method": "gin", + "with": {} + }, + "junior_memory_memories_idempotency_idx": { + "name": "junior_memory_memories_idempotency_idx", + "columns": [ + { + "expression": "scope", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "scope_key", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "idempotency_key", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"junior_memory_memories\".\"idempotency_key\" IS NOT NULL AND \"junior_memory_memories\".\"archived_at_ms\" IS NULL AND \"junior_memory_memories\".\"superseded_at_ms\" IS NULL AND \"junior_memory_memories\".\"superseded_by_id\" IS NULL", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "junior_memory_memories_scope_check": { + "name": "junior_memory_memories_scope_check", + "value": "\"junior_memory_memories\".\"scope\" IN ('private', 'public')" + }, + "junior_memory_memories_kind_check": { + "name": "junior_memory_memories_kind_check", + "value": "\"junior_memory_memories\".\"type\" IN (\n 'preference',\n 'procedure',\n 'knowledge'\n )" + }, + "junior_memory_memories_subject_type_check": { + "name": "junior_memory_memories_subject_type_check", + "value": "\"junior_memory_memories\".\"subject_type\" IN ('user', 'conversation', 'general')" + }, + "junior_memory_memories_subject_key_check": { + "name": "junior_memory_memories_subject_key_check", + "value": "(\"junior_memory_memories\".\"subject_type\" = 'general' AND \"junior_memory_memories\".\"subject_key\" IS NULL) OR (\"junior_memory_memories\".\"subject_type\" IN ('user', 'conversation') AND \"junior_memory_memories\".\"subject_key\" IS NOT NULL AND length(\"junior_memory_memories\".\"subject_key\") > 0)" + }, + "junior_memory_memories_source_platform_check": { + "name": "junior_memory_memories_source_platform_check", + "value": "\"junior_memory_memories\".\"source_platform\" IN ('slack', 'local', 'web')" + } + }, + "isRLSEnabled": false + }, + "public.junior_scheduler_runs": { + "name": "junior_scheduler_runs", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "task_id": { + "name": "task_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "scheduled_for_ms": { + "name": "scheduled_for_ms", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "record": { + "name": "record", + "type": "jsonb", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "junior_scheduler_runs_task_status_idx": { + "name": "junior_scheduler_runs_task_status_idx", + "columns": [ + { + "expression": "task_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "scheduled_for_ms", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "junior_scheduler_runs_status_idx": { + "name": "junior_scheduler_runs_status_idx", + "columns": [ + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "scheduled_for_ms", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.junior_scheduler_tasks": { + "name": "junior_scheduler_tasks", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "team_id": { + "name": "team_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "creator_slack_user_id": { + "name": "creator_slack_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "creator_identity_id": { + "name": "creator_identity_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "next_run_at_ms": { + "name": "next_run_at_ms", + "type": "bigint", + "primaryKey": false, + "notNull": false + }, + "run_now_at_ms": { + "name": "run_now_at_ms", + "type": "bigint", + "primaryKey": false, + "notNull": false + }, + "created_at_ms": { + "name": "created_at_ms", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "title": { + "name": "title", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "record": { + "name": "record", + "type": "jsonb", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "junior_scheduler_tasks_creator_idx": { + "name": "junior_scheduler_tasks_creator_idx", + "columns": [ + { + "expression": "team_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "creator_slack_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at_ms", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"junior_scheduler_tasks\".\"status\" <> 'deleted'", + "concurrently": false, + "method": "btree", + "with": {} + }, + "junior_scheduler_tasks_creator_identity_idx": { + "name": "junior_scheduler_tasks_creator_identity_idx", + "columns": [ + { + "expression": "creator_identity_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at_ms", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"junior_scheduler_tasks\".\"status\" <> 'deleted' AND \"junior_scheduler_tasks\".\"creator_identity_id\" IS NOT NULL", + "concurrently": false, + "method": "btree", + "with": {} + }, + "junior_scheduler_tasks_team_status_idx": { + "name": "junior_scheduler_tasks_team_status_idx", + "columns": [ + { + "expression": "team_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at_ms", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"junior_scheduler_tasks\".\"status\" <> 'deleted'", + "concurrently": false, + "method": "btree", + "with": {} + }, + "junior_scheduler_tasks_run_now_due_idx": { + "name": "junior_scheduler_tasks_run_now_due_idx", + "columns": [ + { + "expression": "run_now_at_ms", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at_ms", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"junior_scheduler_tasks\".\"status\" = 'active' AND \"junior_scheduler_tasks\".\"run_now_at_ms\" IS NOT NULL", + "concurrently": false, + "method": "btree", + "with": {} + }, + "junior_scheduler_tasks_next_run_due_idx": { + "name": "junior_scheduler_tasks_next_run_due_idx", + "columns": [ + { + "expression": "next_run_at_ms", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at_ms", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"junior_scheduler_tasks\".\"status\" = 'active' AND \"junior_scheduler_tasks\".\"next_run_at_ms\" IS NOT NULL", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.junior_snapshots": { + "name": "junior_snapshots", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "workspace_id": { + "name": "workspace_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "profile_hash": { + "name": "profile_hash", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "snapshot_id": { + "name": "snapshot_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "build_duration_ms": { + "name": "build_duration_ms", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "size_bytes": { + "name": "size_bytes", + "type": "bigint", + "primaryKey": false, + "notNull": false + }, + "generated_at": { + "name": "generated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "build_started_at": { + "name": "build_started_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "build_phase": { + "name": "build_phase", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "build_sandbox_name": { + "name": "build_sandbox_name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "build_command_id": { + "name": "build_command_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "build_error": { + "name": "build_error", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "junior_snapshots_snapshot_id_uidx": { + "name": "junior_snapshots_snapshot_id_uidx", + "columns": [ + { + "expression": "snapshot_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "junior_snapshots_workspace_idx": { + "name": "junior_snapshots_workspace_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "junior_snapshots_workspace_profile_status_idx": { + "name": "junior_snapshots_workspace_profile_status_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "profile_hash", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "junior_snapshots_active_build_uidx": { + "name": "junior_snapshots_active_build_uidx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "profile_hash", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"junior_snapshots\".\"status\" = 'building'", + "concurrently": false, + "method": "btree", + "with": {} + }, + "junior_snapshots_workspace_status_idx": { + "name": "junior_snapshots_workspace_status_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "junior_snapshots_workspace_id_junior_workspaces_id_fk": { + "name": "junior_snapshots_workspace_id_junior_workspaces_id_fk", + "tableFrom": "junior_snapshots", + "tableTo": "junior_workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "junior_snapshots_status_check": { + "name": "junior_snapshots_status_check", + "value": "\"junior_snapshots\".\"status\" in ('building', 'failed', 'ready')" + }, + "junior_snapshots_build_phase_check": { + "name": "junior_snapshots_build_phase_check", + "value": "\"junior_snapshots\".\"build_phase\" is null or \"junior_snapshots\".\"build_phase\" in ('created', 'dependencies_installed', 'repositories_prepared')" + }, + "junior_snapshots_ready_fields_check": { + "name": "junior_snapshots_ready_fields_check", + "value": "\"junior_snapshots\".\"status\" <> 'ready' or (\"junior_snapshots\".\"snapshot_id\" is not null and \"junior_snapshots\".\"build_duration_ms\" is not null and \"junior_snapshots\".\"generated_at\" is not null)" + }, + "junior_snapshots_build_fields_check": { + "name": "junior_snapshots_build_fields_check", + "value": "\"junior_snapshots\".\"status\" = 'ready' or (\"junior_snapshots\".\"build_started_at\" is not null and \"junior_snapshots\".\"build_phase\" is not null)" + }, + "junior_snapshots_build_duration_check": { + "name": "junior_snapshots_build_duration_check", + "value": "\"junior_snapshots\".\"build_duration_ms\" is null or \"junior_snapshots\".\"build_duration_ms\" >= 0" + }, + "junior_snapshots_size_bytes_check": { + "name": "junior_snapshots_size_bytes_check", + "value": "\"junior_snapshots\".\"size_bytes\" is null or \"junior_snapshots\".\"size_bytes\" >= 0" + } + }, + "isRLSEnabled": false + }, + "public.junior_stats": { + "name": "junior_stats", + "schema": "", + "columns": { + "date": { + "name": "date", + "type": "date", + "primaryKey": false, + "notNull": true + }, + "namespace": { + "name": "namespace", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "metric": { + "name": "metric", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "count": { + "name": "count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": { + "junior_stats_date_namespace_metric_name_pk": { + "name": "junior_stats_date_namespace_metric_name_pk", + "columns": [ + "date", + "namespace", + "metric", + "name" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.junior_users": { + "name": "junior_users", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "primary_email": { + "name": "primary_email", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "primary_email_normalized": { + "name": "primary_email_normalized", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "display_name": { + "name": "display_name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "junior_users_primary_email_normalized_uidx": { + "name": "junior_users_primary_email_normalized_uidx", + "columns": [ + { + "expression": "primary_email_normalized", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.junior_workspace_repos": { + "name": "junior_workspace_repos", + "schema": "", + "columns": { + "workspace_id": { + "name": "workspace_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "provider": { + "name": "provider", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "repo": { + "name": "repo", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "junior_workspace_repos_workspace_id_junior_workspaces_id_fk": { + "name": "junior_workspace_repos_workspace_id_junior_workspaces_id_fk", + "tableFrom": "junior_workspace_repos", + "tableTo": "junior_workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "junior_workspace_repos_workspace_id_provider_repo_pk": { + "name": "junior_workspace_repos_workspace_id_provider_repo_pk", + "columns": [ + "workspace_id", + "provider", + "repo" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.junior_workspaces": { + "name": "junior_workspaces", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "setup_script": { + "name": "setup_script", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "junior_workspaces_name_idx": { + "name": "junior_workspaces_name_idx", + "columns": [ + { + "expression": "name", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + } + }, + "enums": {}, + "schemas": {}, + "sequences": {}, + "roles": {}, + "policies": {}, + "views": {}, + "_meta": { + "columns": {}, + "schemas": {}, + "tables": {} + } +} \ No newline at end of file diff --git a/packages/junior/migrations/meta/_journal.json b/packages/junior/migrations/meta/_journal.json index 88691c2eed..43aa5e17aa 100644 --- a/packages/junior/migrations/meta/_journal.json +++ b/packages/junior/migrations/meta/_journal.json @@ -302,6 +302,13 @@ "when": 1789152226086, "tag": "0042_conversation_metrics", "breakpoints": true + }, + { + "idx": 43, + "version": "7", + "when": 1789586275271, + "tag": "0043_ordinary_young_avengers", + "breakpoints": true } ] } \ No newline at end of file diff --git a/packages/junior/package.json b/packages/junior/package.json index 71c62c98ee..6e2aac19ee 100644 --- a/packages/junior/package.json +++ b/packages/junior/package.json @@ -24,6 +24,10 @@ "types": "./dist/instrumentation.d.ts", "default": "./dist/instrumentation.js" }, + "./memory": { + "types": "./dist/memory/index.d.ts", + "default": "./dist/memory/index.js" + }, "./nitro": { "types": "./dist/nitro.d.ts", "default": "./dist/nitro.js" @@ -54,11 +58,11 @@ "scripts": { "prepare": "pnpm run build", "prepack": "pnpm run build", - "build": "tsdown", + "build": "tsdown && tsdown --config tsdown.memory.config.ts", "acp:smoke": "pnpm exec tsx scripts/acp-smoke.ts", "db:generate": "pnpm exec drizzle-kit generate --config drizzle.config.ts", - "lint": "oxlint --config .oxlintrc.json --deny-warnings src tests scripts bin tsdown.config.ts && depcruise --config .dependency-cruiser.mjs src/chat", - "lint:fix": "oxlint --config .oxlintrc.json --deny-warnings --fix src tests scripts bin tsdown.config.ts", + "lint": "oxlint --config .oxlintrc.json --deny-warnings src tests scripts bin drizzle.config.ts tsdown.config.ts tsdown.memory.config.ts && depcruise --config .dependency-cruiser.mjs src/chat", + "lint:fix": "oxlint --config .oxlintrc.json --deny-warnings --fix src tests scripts bin drizzle.config.ts tsdown.config.ts tsdown.memory.config.ts", "test": "vitest run --maxWorkers=4", "test:watch": "vitest", "typecheck": "tsc --noEmit", @@ -109,7 +113,6 @@ "@hono/node-server": "1.19.14", "@oxlint/plugins": "1.79.0", "@sentry/junior-github": "workspace:*", - "@sentry/junior-memory": "workspace:*", "@sentry/junior-testing": "workspace:*", "@types/node": "^25.9.1", "@types/pg": "^8.15.6", diff --git a/packages/junior/src/app.ts b/packages/junior/src/app.ts index 10c6546c88..3524c21396 100644 --- a/packages/junior/src/app.ts +++ b/packages/junior/src/app.ts @@ -94,6 +94,11 @@ import { } from "@/chat/app/production"; import type { ConversationWorkCallbackOptions } from "@/chat/app/conversation-work"; import { createAgentRunner } from "@/chat/runtime/agent-runner"; +import { + installedRuntimeRegistrations, + legacyMemoryOptions, + memoryRuntimeRegistrations, +} from "@/chat/memory/runtime"; import { createVercelAttachmentStorage } from "@/chat/attachments/vercel"; import { publicArtifactGET } from "@/handlers/artifacts"; import type { WaitUntilFn } from "@/handlers/types"; @@ -116,6 +121,7 @@ export type { JuniorPluginSetOptions, } from "./plugins"; export type { ModelProfileInput } from "@/chat/model-profile"; +export type { MemoryOptions } from "@/chat/memory/registration"; export interface JuniorAppOptions extends BotModelConfig { /** * Generate a durable Brief after each completed Turn. This costs one @@ -124,6 +130,8 @@ export interface JuniorAppOptions extends BotModelConfig { briefs?: { enabled?: boolean }; /** Authenticated dashboard mounted by core when configured. */ dashboard?: JuniorDashboardOptions; + /** Long-term Memory behavior. Memory is always available in core. */ + memory?: import("@/chat/memory/registration").MemoryOptions; /** * Opt into unstable product features. Experimental keys may change or be * removed without a stable migration path; leave unset in production unless @@ -685,14 +693,24 @@ export async function createApp(options?: JuniorAppOptions): Promise { } const dashboard = options?.dashboard ?? virtualConfig?.dashboard; const configuredPlugins = options?.plugins ?? virtualConfig?.pluginSet; - const plugins = pluginRuntimeRegistrationsFromPluginSet(configuredPlugins); + const configuredRuntimePlugins = + pluginRuntimeRegistrationsFromPluginSet(configuredPlugins); + const plugins = memoryRuntimeRegistrations( + configuredRuntimePlugins, + options?.memory ?? + legacyMemoryOptions(configuredPlugins?.registrations ?? []) ?? + {}, + ); const pluginConfig = configuredPlugins ? pluginCatalogConfigFromPluginSet(configuredPlugins) : (virtualConfig?.plugins ?? pluginCatalogConfigFromEnv()); if (configuredPlugins) { validateBuildIncludesPluginPackages(pluginConfig, virtualConfig); } - validateBuildIncludesPluginRuntimeRegistrations(plugins, virtualConfig); + validateBuildIncludesPluginRuntimeRegistrations( + configuredRuntimePlugins, + virtualConfig, + ); validatePlugins(plugins); getDb(); const shouldValidatePluginCatalog = @@ -747,9 +765,11 @@ export async function createApp(options?: JuniorAppOptions): Promise { } if (shouldValidatePluginCatalog) { pluginCatalogRuntime.getSignature(); - validatePluginRegistrations(configuredPlugins?.registrations ?? []); + validatePluginRegistrations( + installedRuntimeRegistrations(configuredPlugins?.registrations ?? []), + ); validatePluginEgressCredentialHooks( - configuredPlugins?.registrations ?? [], + installedRuntimeRegistrations(configuredPlugins?.registrations ?? []), ); } pluginRoutes = getPluginRoutes({ events }); diff --git a/packages/junior/src/chat/memory/README.md b/packages/junior/src/chat/memory/README.md new file mode 100644 index 0000000000..db43e4d340 --- /dev/null +++ b/packages/junior/src/chat/memory/README.md @@ -0,0 +1,104 @@ +# Memory + +Memory is a core Junior feature. It stores durable facts, recalls relevant facts +into prompts, and learns candidates from completed sessions. SQL schemas, +exported types, tools, and tests are authoritative. + +## Surfaces + +- `createMemory`, `archiveMemory`, `listMemories`, and `searchMemories` are + model-visible tools registered by `registration.ts`. `archiveMemory` can forget + public memory or private memory owned by the current User. +- `userPrompt` recall contributes bounded memory context before a run. +- `processSession` reviews completed sessions asynchronously for passive + learning. +- The `memory` CLI namespace provides explicit administrative search and + inspection. +- The dashboard exposes a searchable, paginated **Memories** user page. It + includes public memory and private memory owned by the authenticated user. + The overview charts global passive-extraction cost from the durable + `memory/memories_captured` events. The System plugin report uses the same + event-cost feed. +- Authenticated REST clients can list and search authorized memories through + `GET /api/plugins/memory/memories`, read one through + `GET /api/plugins/memory/memories/:id`, and forget an authorized private + memory through `DELETE /api/plugins/memory/memories/:id`. Public memory is + read-only in the dashboard and REST API. + +## Scope And Visibility + +- The Source sets memory visibility. Model output cannot set it. +- Public memory is visible everywhere. +- Private memory belongs to one User. Every Identity linked to that User can + access it. +- Junior records the optional Location where it learned a memory. Location is + a record of where Junior learned it. It does not grant access. +- The subject says what a memory is about. It does not set access. A user + preference can be public or private based on its Source. +- Recall filters candidates by visibility, status, and relevance before content + reaches the model. +- Administrative reads require explicit selectors and safe output defaults. +- Memory content, embeddings, source excerpts, and review prompts must not be + logged or traced. + +## Storage + +- The Drizzle schema in `../../db/schema/memory.ts` and the core migrations in + `../../../migrations` define the database contract. +- Records retain provenance, the optional origin `conversation_id`, lifecycle + status, supersession relationships, and timestamps needed for review and deletion. +- Embeddings are derived indexes, not independent memory authority. +- Embedding distance never decides that two memories are duplicates. Exact + content and preference review own duplicate and supersession decisions. +- Writes are idempotent where a completed session or tool retry can repeat. +- Removal and supersession preserve enough lifecycle information to prevent + deleted facts from being recalled or silently recreated. + +## Learning And Recall + +- Explicit user requests to remember or forget take priority over passive + learning. +- Passive extraction creates only durable, reusable facts—not transient tasks, + conversation summaries, secrets, or speculative interpretation. +- Every completed passive extraction emits the namespaced + `memory/memories_captured` conversation event with its best-effort model cost. + Empty extraction outcomes remain durable for reporting but do not produce a + transcript row. +- Candidate review resolves duplicates and supersession before activation. +- Search combines independently ranked vector and PostgreSQL full-text matches + with reciprocal rank fusion; provider-specific raw scores are never added + together. +- Both retrieval legs always run in parallel as bounded top-k probes. Each leg + fetches at least the caller's requested limit (and never more than the store + limit ceiling). Recall keeps a smaller overfetch window than explicit search + and slightly prefers lexical ranks so exact tokens survive soft semantic + neighbors. Vector recall also applies the cosine distance cutoff in SQL, and + embeddings use an HNSW cosine index (`vector_cosine_ops`). +- Automatic recall also searches private memory by itself. This keeps newer + public memory with common words from hiding older private memory. On equal + RRF scores, private memory ranks first. +- Automatic recall retrieves a bounded candidate window, then uses the + memory relevance model and prompt limit to select useful memories. An empty + result adds no prompt text. +- Every completed automatic recall attempt emits an invisible, namespaced + `memory/memories_recalled` conversation event with the admitted memory IDs + and best-effort embedding and relevance-model cost, including retrievals that + find no candidates and decisions that admit no memories. +- Automatic recall degrades to no prompt contribution when relevance selection + fails. Review, extraction, and write failures still fail their owning + hook/task without corrupting existing memory state. + +## Configuration + +- `AI_MEMORY_MODEL` or `createApp({ memory: { modelId } })` selects the structured + review model. +- `createApp({ memory: { disableRecall: true } })` disables automatic prompt recall. +- `createApp({ memory: { disableExtraction: true } })` disables passive session + extraction. The two flags are independent and do not disable explicit memory + tools. +- Automatic recall uses a fixed cosine distance cutoff of `0.45` (for + `text-embedding-3-small`). Explicit search does not apply that cutoff. +- Generate Memory schema changes with + `pnpm --filter @sentry/junior db:generate --name `. + +Follow `../../../../../policies/data-redaction.md` and `../../../../../policies/security.md`. diff --git a/packages/junior-memory/src/agent.ts b/packages/junior/src/chat/memory/agent.ts similarity index 100% rename from packages/junior-memory/src/agent.ts rename to packages/junior/src/chat/memory/agent.ts diff --git a/packages/junior-memory/src/api.ts b/packages/junior/src/chat/memory/api.ts similarity index 100% rename from packages/junior-memory/src/api.ts rename to packages/junior/src/chat/memory/api.ts diff --git a/packages/junior-memory/src/cli/format.ts b/packages/junior/src/chat/memory/cli/format.ts similarity index 92% rename from packages/junior-memory/src/cli/format.ts rename to packages/junior/src/chat/memory/cli/format.ts index c828c69930..66145afcbe 100644 --- a/packages/junior-memory/src/cli/format.ts +++ b/packages/junior/src/chat/memory/cli/format.ts @@ -1,4 +1,4 @@ -import type { juniorMemoryMemories } from "../db/schema"; +import type { juniorMemoryMemories } from "@/db/schema/memory"; function formatDate(ms: number | null): string { return ms === null ? "-" : new Date(ms).toISOString(); diff --git a/packages/junior-memory/src/cli/index.ts b/packages/junior/src/chat/memory/cli/index.ts similarity index 100% rename from packages/junior-memory/src/cli/index.ts rename to packages/junior/src/chat/memory/cli/index.ts diff --git a/packages/junior-memory/src/cli/search.ts b/packages/junior/src/chat/memory/cli/search.ts similarity index 98% rename from packages/junior-memory/src/cli/search.ts rename to packages/junior/src/chat/memory/cli/search.ts index 41bba8cfa7..901f76f828 100644 --- a/packages/junior-memory/src/cli/search.ts +++ b/packages/junior/src/chat/memory/cli/search.ts @@ -4,7 +4,7 @@ import type { PluginCliActionContext, PluginCliHost, } from "@sentry/junior-plugin-api"; -import { juniorMemoryMemories } from "../db/schema"; +import { juniorMemoryMemories } from "@/db/schema/memory"; import type { MemoryDb } from "../store"; import { MEMORY_SCOPES, type MemoryScope } from "../types"; import { formatMemory } from "./format"; diff --git a/packages/junior-memory/src/cli/show.ts b/packages/junior/src/chat/memory/cli/show.ts similarity index 94% rename from packages/junior-memory/src/cli/show.ts rename to packages/junior/src/chat/memory/cli/show.ts index 7d2ec6a9d9..6c8ce3efd3 100644 --- a/packages/junior-memory/src/cli/show.ts +++ b/packages/junior/src/chat/memory/cli/show.ts @@ -4,7 +4,7 @@ import type { PluginCliHost, } from "@sentry/junior-plugin-api"; import { eq } from "drizzle-orm"; -import { juniorMemoryMemories } from "../db/schema"; +import { juniorMemoryMemories } from "@/db/schema/memory"; import type { MemoryDb } from "../store"; import { formatMemory } from "./format"; diff --git a/packages/junior-memory/src/events.ts b/packages/junior/src/chat/memory/events.ts similarity index 100% rename from packages/junior-memory/src/events.ts rename to packages/junior/src/chat/memory/events.ts diff --git a/packages/junior/src/chat/memory/index.ts b/packages/junior/src/chat/memory/index.ts new file mode 100644 index 0000000000..432dfe7250 --- /dev/null +++ b/packages/junior/src/chat/memory/index.ts @@ -0,0 +1,28 @@ +export { + memoryApiSchema, + memoryDashboardResponseSchema, + memoryListResponseSchema, + type MemoryApi, + type MemoryDashboardResponse, + type MemoryListResponse, +} from "./api"; +export { createMemoryStore } from "./store"; +export type { + ArchiveMemoryInput, + CreateMemoryInput, + CreateMemoryResult, + ListMemoriesInput, + MemoryDb, + MemoryEmbeddingProvider, + MemoryRecord, + MemoryStore, + MemoryStoreOptions, + SearchMemoriesInput, +} from "./store"; +export { + juniorMemoryEmbeddings, + juniorMemoryMemories, +} from "@/db/schema/memory"; +export { MEMORY_KINDS } from "./types"; +export type { MemoryKind, MemoryRuntimeContext } from "./types"; +export type { MemoryOptions } from "./registration"; diff --git a/packages/junior-memory/src/operational-report.ts b/packages/junior/src/chat/memory/operational-report.ts similarity index 98% rename from packages/junior-memory/src/operational-report.ts rename to packages/junior/src/chat/memory/operational-report.ts index 51a791c643..d5d434b160 100644 --- a/packages/junior-memory/src/operational-report.ts +++ b/packages/junior/src/chat/memory/operational-report.ts @@ -4,7 +4,10 @@ import type { } from "@sentry/junior-plugin-api"; import { and, eq, gt, isNull, or, sql } from "drizzle-orm"; import { z } from "zod"; -import { juniorMemoryEmbeddings, juniorMemoryMemories } from "./db/schema"; +import { + juniorMemoryEmbeddings, + juniorMemoryMemories, +} from "@/db/schema/memory"; import type { MemoryDb } from "./store"; const DAY_MS = 24 * 60 * 60 * 1_000; diff --git a/packages/junior-memory/src/process-session.ts b/packages/junior/src/chat/memory/process-session.ts similarity index 100% rename from packages/junior-memory/src/process-session.ts rename to packages/junior/src/chat/memory/process-session.ts diff --git a/packages/junior-memory/src/ranking.ts b/packages/junior/src/chat/memory/ranking.ts similarity index 96% rename from packages/junior-memory/src/ranking.ts rename to packages/junior/src/chat/memory/ranking.ts index 67649cd33a..f068d077d0 100644 --- a/packages/junior-memory/src/ranking.ts +++ b/packages/junior/src/chat/memory/ranking.ts @@ -81,7 +81,9 @@ export function rankMemoryMatches( ...(!existing.lexical && match.lexical ? { lexical: match.lexical } : undefined), - ...(!existing.vector && match.vector ? { vector: match.vector } : undefined), + ...(!existing.vector && match.vector + ? { vector: match.vector } + : undefined), }); } return [...byId.values()].sort((left, right) => { diff --git a/packages/junior-memory/src/recall.ts b/packages/junior/src/chat/memory/recall.ts similarity index 98% rename from packages/junior-memory/src/recall.ts rename to packages/junior/src/chat/memory/recall.ts index 438d6c9c3b..da7efce9ca 100644 --- a/packages/junior-memory/src/recall.ts +++ b/packages/junior/src/chat/memory/recall.ts @@ -174,7 +174,9 @@ export async function createMemoryPromptContributions( }); if (candidates.length === 0) { await emitRecallOutcome({ - ...(embeddingCostUsd !== undefined ? { costUsd: embeddingCostUsd } : undefined), + ...(embeddingCostUsd !== undefined + ? { costUsd: embeddingCostUsd } + : undefined), events: context.events, memories: [], }); diff --git a/packages/junior-memory/src/plugin.ts b/packages/junior/src/chat/memory/registration.ts similarity index 87% rename from packages/junior-memory/src/plugin.ts rename to packages/junior/src/chat/memory/registration.ts index d08e8aaf93..fb00c62dd5 100644 --- a/packages/junior-memory/src/plugin.ts +++ b/packages/junior/src/chat/memory/registration.ts @@ -2,6 +2,15 @@ import { defineJuniorPlugin } from "@sentry/junior-plugin-api"; import { createMemoryAgent } from "./agent"; import { createMemoryApi } from "./api"; import { createMemoryCliCommand } from "./cli"; +import { + memoriesCapturedEvent, + memoriesCapturedEventV1, + memoriesRecalledEvent, +} from "./events"; +import { buildMemoryOperationalReport } from "./operational-report"; +import { processMemorySession } from "./process-session"; +import { createMemoryPromptContributions } from "./recall"; +import type { MemoryDb } from "./store"; import { createMemoryArchiveTool, createMemoryCreateTool, @@ -11,34 +20,25 @@ import { type MemoryReviewer, type MemoryToolContext, } from "./tools"; -import { processMemorySession } from "./process-session"; -import { createMemoryPromptContributions } from "./recall"; -import { buildMemoryOperationalReport } from "./operational-report"; -import { - memoriesCapturedEvent, - memoriesCapturedEventV1, - memoriesRecalledEvent, -} from "./events"; -import type { MemoryDb } from "./store"; import { createMemoryUserPage } from "./user-pages"; const MEMORY_MODEL_ENV = "AI_MEMORY_MODEL"; -export interface MemoryPluginOptions { +export interface MemoryOptions { /** Disable automatic prompt recall while keeping explicit memory tools available. */ disableRecall?: boolean; /** Disable passive memory extraction from completed sessions. */ disableExtraction?: boolean; + /** Structured model used by Memory. Defaults to AI_MEMORY_MODEL, then the default model. */ modelId?: string; } -function memoryModelId(options: MemoryPluginOptions): string | undefined { - const explicitModelId = options.modelId?.trim(); - if (explicitModelId) { - return explicitModelId; - } - const envModelId = process.env[MEMORY_MODEL_ENV]?.trim(); - return envModelId || undefined; +function memoryModelId(options: MemoryOptions): string | undefined { + return ( + options.modelId?.trim() || + process.env[MEMORY_MODEL_ENV]?.trim() || + undefined + ); } function memoryToolContext(ctx: { @@ -85,8 +85,8 @@ function memoryCreateToolContext(ctx: { }; } -/** Register Junior's long-term memory plugin. */ -export function memoryPlugin(options: MemoryPluginOptions = {}) { +/** Create the core Memory registration. */ +export function createMemoryRegistration(options: MemoryOptions = {}) { const modelId = memoryModelId(options); return defineJuniorPlugin({ manifest: { @@ -97,15 +97,12 @@ export function memoryPlugin(options: MemoryPluginOptions = {}) { model: modelId ? { structuredModelId: modelId } : { structuredModel: "default" }, - packageName: "@sentry/junior-memory", conversationEvents: [ memoriesCapturedEventV1, memoriesCapturedEvent, memoriesRecalledEvent, ], - cli: { - commands: [createMemoryCliCommand()], - }, + cli: { commands: [createMemoryCliCommand()] }, tasks: options.disableExtraction ? {} : { @@ -118,13 +115,12 @@ export function memoryPlugin(options: MemoryPluginOptions = {}) { userPages: [createMemoryUserPage()], hooks: { async operationalReport(ctx) { - const extractionDays = await ctx.eventStats.costsByDay({ - days: 90, - eventName: "memories_captured", - }); return await buildMemoryOperationalReport({ db: ctx.db as MemoryDb, - extractionDays, + extractionDays: await ctx.eventStats.costsByDay({ + days: 90, + eventName: "memories_captured", + }), nowMs: ctx.nowMs, }); }, diff --git a/packages/junior/src/chat/memory/runtime.ts b/packages/junior/src/chat/memory/runtime.ts new file mode 100644 index 0000000000..059000226d --- /dev/null +++ b/packages/junior/src/chat/memory/runtime.ts @@ -0,0 +1,51 @@ +import type { PluginRegistration } from "@sentry/junior-plugin-api"; +import { createMemoryRegistration, type MemoryOptions } from "./registration"; + +const LEGACY_MEMORY_PACKAGE = "@sentry/junior-memory"; +type LegacyMemoryRegistration = PluginRegistration & { + coreMemoryOptions?: MemoryOptions; +}; + +/** Return options carried by the deprecated Memory registration. */ +export function legacyMemoryOptions( + plugins: readonly PluginRegistration[], +): MemoryOptions | undefined { + const legacy = plugins.find( + (plugin): plugin is LegacyMemoryRegistration => + plugin.manifest.name === "memory" && + plugin.packageName === LEGACY_MEMORY_PACKAGE, + ); + return legacy?.coreMemoryOptions; +} + +/** Return whether a registration is the deprecated Memory marker. */ +export function isLegacyMemoryRegistration( + plugin: PluginRegistration, +): boolean { + return ( + plugin.manifest.name === "memory" && + plugin.packageName === LEGACY_MEMORY_PACKAGE + ); +} + +/** Remove the deprecated marker and reject another Memory registration. */ +export function installedRuntimeRegistrations( + plugins: PluginRegistration[], +): PluginRegistration[] { + return plugins.filter((plugin) => { + if (plugin.manifest.name !== "memory") return true; + if (isLegacyMemoryRegistration(plugin)) return false; + throw new Error('Plugin registration name "memory" is reserved by core'); + }); +} + +/** Add core Memory to installed runtime registrations. */ +export function memoryRuntimeRegistrations( + plugins: PluginRegistration[], + options: MemoryOptions = {}, +): PluginRegistration[] { + return [ + createMemoryRegistration(options), + ...installedRuntimeRegistrations(plugins), + ]; +} diff --git a/packages/junior-memory/src/scope.ts b/packages/junior/src/chat/memory/scope.ts similarity index 100% rename from packages/junior-memory/src/scope.ts rename to packages/junior/src/chat/memory/scope.ts diff --git a/packages/junior-memory/src/store.ts b/packages/junior/src/chat/memory/store.ts similarity index 99% rename from packages/junior-memory/src/store.ts rename to packages/junior/src/chat/memory/store.ts index 9b4850db57..45a27d5f26 100644 --- a/packages/junior-memory/src/store.ts +++ b/packages/junior/src/chat/memory/store.ts @@ -26,8 +26,11 @@ import type { PgDatabase } from "drizzle-orm/pg-core"; import type { PgQueryResultHKT } from "drizzle-orm/pg-core/session"; import { z } from "zod"; import { getSourceKey } from "@sentry/junior-plugin-api"; -import * as memorySqlSchema from "./db/schema"; -import { juniorMemoryEmbeddings, juniorMemoryMemories } from "./db/schema"; +import * as memorySqlSchema from "@/db/schema/memory"; +import { + juniorMemoryEmbeddings, + juniorMemoryMemories, +} from "@/db/schema/memory"; import { rankMemoryMatches, type MemoryMatch } from "./ranking"; import { MEMORY_EMBEDDING_DIMENSIONS, diff --git a/packages/junior-memory/src/tools.ts b/packages/junior/src/chat/memory/tools.ts similarity index 99% rename from packages/junior-memory/src/tools.ts rename to packages/junior/src/chat/memory/tools.ts index 97da63068a..a1a1a2591d 100644 --- a/packages/junior-memory/src/tools.ts +++ b/packages/junior/src/chat/memory/tools.ts @@ -507,10 +507,7 @@ export function createMemoryArchiveTool(context: MemoryToolContext) { inputSchema: archiveMemoryInputSchema, outputSchema: memorySingleOutputSchema, execute: async (input) => { - const parsedInput = parseMemoryToolInput( - archiveMemoryInputSchema, - input, - ); + const parsedInput = parseMemoryToolInput(archiveMemoryInputSchema, input); const runtimeContext = await memoryRuntimeContext(context); const memory = await (async () => { try { diff --git a/packages/junior-memory/src/types.ts b/packages/junior/src/chat/memory/types.ts similarity index 100% rename from packages/junior-memory/src/types.ts rename to packages/junior/src/chat/memory/types.ts diff --git a/packages/junior-memory/src/user-pages.ts b/packages/junior/src/chat/memory/user-pages.ts similarity index 100% rename from packages/junior-memory/src/user-pages.ts rename to packages/junior/src/chat/memory/user-pages.ts diff --git a/packages/junior-memory/src/viewer.ts b/packages/junior/src/chat/memory/viewer.ts similarity index 99% rename from packages/junior-memory/src/viewer.ts rename to packages/junior/src/chat/memory/viewer.ts index 95b0093354..31167d1090 100644 --- a/packages/junior-memory/src/viewer.ts +++ b/packages/junior/src/chat/memory/viewer.ts @@ -17,7 +17,10 @@ import { sql, } from "drizzle-orm"; import { z } from "zod"; -import { juniorMemoryEmbeddings, juniorMemoryMemories } from "./db/schema"; +import { + juniorMemoryEmbeddings, + juniorMemoryMemories, +} from "@/db/schema/memory"; import { publicMemoryScope } from "./scope"; import { parseMemoryRow, type MemoryDb, type MemoryRecord } from "./store"; import { MEMORY_KINDS, type MemorySourcePlatform } from "./types"; @@ -438,4 +441,3 @@ export async function getMemoryTimelineHours( }; }); } - diff --git a/packages/junior/src/chat/plugins/auth/oauth-bearer-broker.ts b/packages/junior/src/chat/plugins/auth/oauth-bearer-broker.ts index cc481bd7e9..6f0a703f03 100644 --- a/packages/junior/src/chat/plugins/auth/oauth-bearer-broker.ts +++ b/packages/junior/src/chat/plugins/auth/oauth-bearer-broker.ts @@ -265,7 +265,9 @@ export function createOAuthBearerBroker( ? { refreshTokenExpiresAt: latest.refreshTokenExpiresAt } : undefined), ...refreshed, - ...(latest.account ? { account: latest.account } : undefined), + ...(latest.account + ? { account: latest.account } + : undefined), }; await deps.userTokenStore.set( userSubjectId, diff --git a/packages/junior/src/chat/plugins/conversation-sidebar.ts b/packages/junior/src/chat/plugins/conversation-sidebar.ts index b36f4830b9..43827b4d9b 100644 --- a/packages/junior/src/chat/plugins/conversation-sidebar.ts +++ b/packages/junior/src/chat/plugins/conversation-sidebar.ts @@ -20,9 +20,9 @@ export async function listConversationSidebarAnnotations( if (!hook) continue; const annotationsByConversationId = Object.fromEntries( conversationIds.flatMap((conversationId) => { - const annotations = (annotationsByConversation.get(conversationId) ?? []).filter( - (annotation) => annotation.plugin === plugin.manifest.name, - ); + const annotations = ( + annotationsByConversation.get(conversationId) ?? [] + ).filter((annotation) => annotation.plugin === plugin.manifest.name); return annotations.length > 0 ? [[conversationId, annotations]] : []; }), ); @@ -38,7 +38,9 @@ export async function listConversationSidebarAnnotations( result.annotationsByConversationId, )) { if (!candidates.has(conversationId)) continue; - const parsed = conversationSidebarAnnotationSchema.array().safeParse(annotations); + const parsed = conversationSidebarAnnotationSchema + .array() + .safeParse(annotations); if (!parsed.success || parsed.data.length === 0) continue; selected[conversationId] = [ ...(selected[conversationId] ?? []), @@ -48,7 +50,8 @@ export async function listConversationSidebarAnnotations( } catch (error) { logWarn("plugin.conversation_sidebar.hook.failed", { "app.plugin.name": plugin.manifest.name, - "exception.message": error instanceof Error ? error.message : String(error), + "exception.message": + error instanceof Error ? error.message : String(error), }); } } diff --git a/packages/junior/src/chat/plugins/credential-hooks.ts b/packages/junior/src/chat/plugins/credential-hooks.ts index 390646e192..740b80e080 100644 --- a/packages/junior/src/chat/plugins/credential-hooks.ts +++ b/packages/junior/src/chat/plugins/credential-hooks.ts @@ -121,7 +121,9 @@ export async function selectPluginGrant( const result = await hook({ ...basePluginContext(plugin), request: { - ...(input.bodyText !== undefined ? { bodyText: input.bodyText } : undefined), + ...(input.bodyText !== undefined + ? { bodyText: input.bodyText } + : undefined), method: input.method, ...(input.operation ? { operation: input.operation } : undefined), url: input.upstreamUrl.toString(), diff --git a/packages/junior/src/chat/plugins/model.ts b/packages/junior/src/chat/plugins/model.ts index e69cad12b0..8bbf0e4292 100644 --- a/packages/junior/src/chat/plugins/model.ts +++ b/packages/junior/src/chat/plugins/model.ts @@ -37,7 +37,9 @@ export function createPluginModel( }); return { object: result.object, - ...(result.costUsd !== undefined ? { costUsd: result.costUsd } : undefined), + ...(result.costUsd !== undefined + ? { costUsd: result.costUsd } + : undefined), }; }, }; diff --git a/packages/junior/src/chat/plugins/registry.ts b/packages/junior/src/chat/plugins/registry.ts index 8b030dc90d..a961052431 100644 --- a/packages/junior/src/chat/plugins/registry.ts +++ b/packages/junior/src/chat/plugins/registry.ts @@ -511,7 +511,9 @@ export function createPluginCatalogRuntime(): PluginCatalogRuntime { commands.push({ cmd: command.cmd, ...(command.args ? { args: [...command.args] } : undefined), - ...(command.sudo !== undefined ? { sudo: command.sudo } : undefined), + ...(command.sudo !== undefined + ? { sudo: command.sudo } + : undefined), }); } } diff --git a/packages/junior/src/chat/plugins/viewer.ts b/packages/junior/src/chat/plugins/viewer.ts index ae4aedcd42..b608ffd7d0 100644 --- a/packages/junior/src/chat/plugins/viewer.ts +++ b/packages/junior/src/chat/plugins/viewer.ts @@ -20,7 +20,9 @@ function identityFromRow(row: IdentityRow): Identity { id: row.id, provider: row.provider, providerSubjectId: row.providerSubjectId, - ...(row.providerTenantId ? { providerTenantId: row.providerTenantId } : undefined), + ...(row.providerTenantId + ? { providerTenantId: row.providerTenantId } + : undefined), ...(row.displayName ? { displayName: row.displayName } : undefined), ...(row.handle ? { handle: row.handle } : undefined), }); diff --git a/packages/junior/src/cli/chat.ts b/packages/junior/src/cli/chat.ts index 83ded0fbc2..791a1a6f70 100644 --- a/packages/junior/src/cli/chat.ts +++ b/packages/junior/src/cli/chat.ts @@ -146,19 +146,31 @@ async function configureLocalChatPlugins( catalogRuntimeModule, validationModule, databaseModule, + memoryRuntimeModule, ] = await Promise.all([ import("@/plugins"), import("@/chat/plugins/agent-hooks"), import("@/chat/plugins/catalog-runtime"), import("@/chat/plugins/validation"), import("@/chat/db"), + import("@/chat/memory/runtime"), ]); const resolvedPluginSet = pluginSet === undefined ? await loadLocalPluginSet() : (pluginSet ?? undefined); - const plugins = + const configuredPlugins = pluginsModule.pluginRuntimeRegistrationsFromPluginSet(resolvedPluginSet); + const configuredRegistrations = + memoryRuntimeModule.installedRuntimeRegistrations( + resolvedPluginSet?.registrations ?? [], + ); + const plugins = memoryRuntimeModule.memoryRuntimeRegistrations( + configuredPlugins, + memoryRuntimeModule.legacyMemoryOptions( + resolvedPluginSet?.registrations ?? [], + ), + ); const pluginConfig = resolvedPluginSet ? pluginsModule.pluginCatalogConfigFromPluginSet(resolvedPluginSet) : pluginsModule.pluginCatalogConfigFromEnv(); @@ -170,11 +182,9 @@ async function configureLocalChatPlugins( try { if (shouldValidatePluginCatalog) { catalogRuntimeModule.pluginCatalogRuntime.getSignature(); - validationModule.validatePluginRegistrations( - resolvedPluginSet?.registrations ?? [], - ); + validationModule.validatePluginRegistrations(configuredRegistrations); validationModule.validatePluginEgressCredentialHooks( - resolvedPluginSet?.registrations ?? [], + configuredRegistrations, ); } databaseModule.getDb(); diff --git a/packages/junior/src/cli/init.ts b/packages/junior/src/cli/init.ts index da6ada8174..0c972012e4 100644 --- a/packages/junior/src/cli/init.ts +++ b/packages/junior/src/cli/init.ts @@ -41,10 +41,8 @@ function writePluginsFile(targetDir: string): void { fs.writeFileSync( path.join(targetDir, "plugins.ts"), `import { defineJuniorPlugins } from "@sentry/junior"; -import { memoryPlugin } from "@sentry/junior-memory"; export const plugins = defineJuniorPlugins([ - memoryPlugin(), "@sentry/junior-maintenance", ]); `, @@ -182,7 +180,6 @@ export async function runInit( "@opentelemetry/api": "1.9.1", "@opentelemetry/core": "2.9.0", "@sentry/junior": "latest", - "@sentry/junior-memory": "latest", "@sentry/junior-maintenance": "latest", "@sentry/nitro": "10.65.0", hono: "^4.12.27", diff --git a/packages/junior/src/cli/plugins.ts b/packages/junior/src/cli/plugins.ts index 206dbd6360..32e48a15e8 100644 --- a/packages/junior/src/cli/plugins.ts +++ b/packages/junior/src/cli/plugins.ts @@ -21,6 +21,12 @@ import { validatePluginRegistrations, } from "@/chat/plugins/validation"; import { loadAppPluginSet } from "@/plugin-module"; +import { createMemoryRegistration } from "@/chat/memory/registration"; +import { + installedRuntimeRegistrations, + legacyMemoryOptions, + memoryRuntimeRegistrations, +} from "@/chat/memory/runtime"; import { pluginCliRegistrationsFromPluginSet, pluginCatalogConfigFromPluginSet, @@ -221,27 +227,44 @@ function validateConfiguredPluginCommands(plugins: PluginRegistration[]): void { async function loadPluginRegistrations(args: { pluginSet?: JuniorPluginSet; validateConfiguredCommands?: (plugins: PluginRegistration[]) => void; -}): Promise<{ - cliPlugins: PluginRegistration[]; - runtimePlugins: PluginRegistration[]; -}> { +}): Promise { const pluginSet = args.pluginSet; + const memory = createMemoryRegistration(); if (!pluginSet) { - return { cliPlugins: [], runtimePlugins: [] }; + const cliPlugins = [memory]; + args.validateConfiguredCommands?.(cliPlugins); + setPlugins([memory]); + return cliPlugins; } - const cliPlugins = pluginCliRegistrationsFromPluginSet(pluginSet); - const runtimePlugins = pluginRuntimeRegistrationsFromPluginSet(pluginSet); + const cliPlugins = [ + memory, + ...pluginCliRegistrationsFromPluginSet(pluginSet), + ]; + const configuredRuntimePlugins = + pluginRuntimeRegistrationsFromPluginSet(pluginSet); + const runtimePlugins = installedRuntimeRegistrations( + configuredRuntimePlugins, + ); const pluginConfig = pluginCatalogConfigFromPluginSet(pluginSet); validatePlugins(runtimePlugins); const previousPluginCatalogConfig = pluginCatalogRuntime.setConfig(pluginConfig); try { - validatePluginRegistrations(pluginSet.registrations); - validatePluginEgressCredentialHooks(pluginSet.registrations); + validatePluginRegistrations( + installedRuntimeRegistrations(pluginSet.registrations), + ); + validatePluginEgressCredentialHooks( + installedRuntimeRegistrations(pluginSet.registrations), + ); args.validateConfiguredCommands?.(cliPlugins); - setPlugins(runtimePlugins); - return { cliPlugins, runtimePlugins }; + setPlugins( + memoryRuntimeRegistrations( + runtimePlugins, + legacyMemoryOptions(pluginSet.registrations), + ), + ); + return cliPlugins; } catch (error) { pluginCatalogRuntime.setConfig(previousPluginCatalogConfig); throw error; @@ -256,7 +279,7 @@ export async function loadCliPluginCommands( pluginSet === undefined ? await loadCliPluginSet() : (pluginSet ?? undefined); - const { cliPlugins } = await loadPluginRegistrations({ + const cliPlugins = await loadPluginRegistrations({ pluginSet: resolvedPluginSet, validateConfiguredCommands: validateConfiguredPluginCommands, }); diff --git a/packages/junior/src/db/schema.ts b/packages/junior/src/db/schema.ts index 23d176bcf9..ac561ba639 100644 --- a/packages/junior/src/db/schema.ts +++ b/packages/junior/src/db/schema.ts @@ -14,6 +14,7 @@ import { juniorAgentInvocations, } from "./schema/agent-invocations"; import { juniorLocationConfigurations } from "./schema/location-configurations"; +import { juniorMemoryEmbeddings, juniorMemoryMemories } from "./schema/memory"; import { juniorDestinations } from "./schema/destinations"; import { juniorEventAutomations } from "./schema/event-automations"; import { juniorIdentities } from "./schema/identities"; @@ -43,6 +44,8 @@ export { juniorConversationParticipants, juniorConversations, juniorLocationConfigurations, + juniorMemoryEmbeddings, + juniorMemoryMemories, juniorDestinations, juniorEventAutomations, juniorIdentities, @@ -72,6 +75,8 @@ export const juniorSqlSchema = { juniorConversationParticipants, juniorConversations, juniorLocationConfigurations, + juniorMemoryEmbeddings, + juniorMemoryMemories, juniorDestinations, juniorEventAutomations, juniorIdentities, diff --git a/packages/junior-memory/src/db/schema.ts b/packages/junior/src/db/schema/memory.ts similarity index 97% rename from packages/junior-memory/src/db/schema.ts rename to packages/junior/src/db/schema/memory.ts index 048d0dc9eb..f6b97a463d 100644 --- a/packages/junior-memory/src/db/schema.ts +++ b/packages/junior/src/db/schema/memory.ts @@ -1,8 +1,8 @@ /** - * Drizzle source of truth for memory plugin SQL migrations. + * Drizzle source of truth for core Memory SQL migrations. * * Update this schema first, then regenerate packaged migrations with - * `pnpm --filter @sentry/junior-memory db:generate`. + * `pnpm --filter @sentry/junior db:generate`. */ import { sql } from "drizzle-orm"; import { @@ -23,7 +23,7 @@ import { MEMORY_SOURCE_PLATFORMS, MEMORY_SUBJECT_TYPES, MEMORY_KINDS, -} from "../types"; +} from "@/chat/memory/types"; const tsvector = customType<{ data: string }>({ dataType() { diff --git a/packages/junior/src/plugins.ts b/packages/junior/src/plugins.ts index 3f55d4144c..47b5fccb99 100644 --- a/packages/junior/src/plugins.ts +++ b/packages/junior/src/plugins.ts @@ -52,7 +52,9 @@ function cloneInlineManifests( } : undefined), }, - ...(plugin.packageName ? { packageName: plugin.packageName } : undefined), + ...(plugin.packageName + ? { packageName: plugin.packageName } + : undefined), }, ] : [], @@ -128,9 +130,15 @@ export function pluginCatalogConfigFromPluginSet( plugin.packageName ? [plugin.packageName] : [], ), ]), - ]; + ].filter((packageName) => packageName !== "@sentry/junior-memory"); const manifests = cloneManifests(pluginSet.manifests); - const inlineManifests = cloneInlineManifests(pluginSet.registrations); + const inlineManifests = cloneInlineManifests( + pluginSet.registrations.filter( + (plugin) => + plugin.manifest.name !== "memory" || + plugin.packageName !== "@sentry/junior-memory", + ), + ); if (packages.length === 0 && !manifests && !inlineManifests) { return undefined; diff --git a/packages/junior/tests/component/memory-plugin-storage.test.ts b/packages/junior/tests/component/memory-plugin-storage.test.ts index 1dbd00541a..154fe68cd7 100644 --- a/packages/junior/tests/component/memory-plugin-storage.test.ts +++ b/packages/junior/tests/component/memory-plugin-storage.test.ts @@ -1,21 +1,24 @@ import path from "node:path"; -import { readdirSync } from "node:fs"; -import { afterAll, afterEach, describe, expect, it, vi } from "vitest"; import { - memoryPlugin, - createMemoryStore, - type MemoryDb, -} from "@sentry/junior-memory"; + copyFileSync, + mkdirSync, + mkdtempSync, + readFileSync, + writeFileSync, +} from "node:fs"; +import { tmpdir } from "node:os"; +import { afterAll, afterEach, describe, expect, it, vi } from "vitest"; +import { createMemoryStore, type MemoryDb } from "@/chat/memory/store"; +import { createMemoryRegistration as memoryPlugin } from "@/chat/memory/registration"; +import { memoryRuntimeRegistrations } from "@/chat/memory/runtime"; import { defineJuniorPlugins } from "@/plugins"; import { getPluginTools, setPlugins } from "@/chat/plugins/agent-hooks"; -import { migratePluginSchemas } from "@/chat/plugins/migrations"; import { readMigrationFiles } from "drizzle-orm/migrator"; import { closeDb } from "@/chat/db"; import { migrateSchema } from "@/chat/conversations/sql/migrations"; import { createSqlStore } from "@/chat/conversations/sql/store"; import { readActorIdentity, resolveViewerUser } from "@/chat/plugins/viewer"; import { readPluginUserPage } from "@/chat/plugins/user-pages"; -import { migratePluginsToSql } from "@/cli/upgrade/migrations/plugin-sql"; import { runUpgrade } from "@/cli/upgrade"; import { createLocalJuniorSqlFixture } from "../fixtures/sql"; import { @@ -86,25 +89,64 @@ afterAll(() => { } }); -function memoryMigrationsDir(): string { - return path.resolve(process.cwd(), "../junior-memory/migrations"); +function coreMigrationsDir(): string { + return path.resolve(process.cwd(), "migrations"); } -function memoryMigrationFiles(): string[] { - return readdirSync(memoryMigrationsDir()) - .filter((filename) => filename.endsWith(".sql")) - .sort(); +function copyPreMemoryCoreMigrations(): string { + const source = coreMigrationsDir(); + const destination = mkdtempSync( + path.join(tmpdir(), "junior-pre-memory-core-"), + ); + mkdirSync(path.join(destination, "meta")); + const journal = JSON.parse( + readFileSync(path.join(source, "meta", "_journal.json"), "utf8"), + ) as { entries: Array<{ idx: number; tag: string }> }; + const adoption = journal.entries.find((entry) => { + const sql = readFileSync(path.join(source, `${entry.tag}.sql`), "utf8"); + return sql.includes("Adopt the former Memory plugin tables"); + }); + if (!adoption) { + throw new Error("Memory adoption migration not found"); + } + const entries = journal.entries.filter((entry) => entry.idx < adoption.idx); + writeFileSync( + path.join(destination, "meta", "_journal.json"), + JSON.stringify({ ...journal, entries }), + ); + for (const entry of entries) { + copyFileSync( + path.join(source, `${entry.tag}.sql`), + path.join(destination, `${entry.tag}.sql`), + ); + } + return destination; } -async function migrateMemorySchema( +async function createLegacyMemoryTable( fixture: Awaited>, -) { - await migratePluginSchemas(fixture.sql, [ - { - dir: memoryMigrationsDir(), - pluginName: "memory", - }, - ]); +): Promise { + await fixture.sql.execute(` +CREATE TABLE junior_memory_memories ( + id TEXT PRIMARY KEY NOT NULL, + scope TEXT NOT NULL, + scope_key TEXT NOT NULL, + type TEXT NOT NULL, + subject_type TEXT NOT NULL, + subject_key TEXT, + content TEXT NOT NULL, + source_platform TEXT NOT NULL, + source_key TEXT NOT NULL, + idempotency_key TEXT, + observed_at_ms BIGINT NOT NULL, + created_at_ms BIGINT NOT NULL, + expires_at_ms BIGINT, + superseded_at_ms BIGINT, + superseded_by_id TEXT, + archived_at_ms BIGINT, + archive_reason TEXT +) +`); } async function recordPrivateConversation( @@ -183,166 +225,76 @@ function memoryToolsFor(args: { } describe("memory plugin host wiring", () => { - it("adopts exact legacy migration hashes without replaying them", async () => { + it("adopts deployed Memory rows into the core schema", async () => { const fixture = await createLocalJuniorSqlFixture(); - const migrations = readMigrationFiles({ - migrationsFolder: memoryMigrationsDir(), - }); - const migrationFiles = memoryMigrationFiles(); - expect(migrationFiles).toHaveLength(migrations.length); + const oldCoreMigrations = copyPreMemoryCoreMigrations(); try { - await migrateMemorySchema(fixture); - const [migrationTable] = await fixture.sql.query<{ tablename: string }>(` -SELECT tablename -FROM pg_tables -WHERE schemaname = 'drizzle' - AND tablename LIKE '__drizzle_memory_%' -`); - expect(migrationTable).toBeDefined(); - await fixture.sql.execute( - `DROP TABLE drizzle.${migrationTable!.tablename}`, - ); - await fixture.sql.execute(` -CREATE TABLE junior_schema_migrations ( - id TEXT PRIMARY KEY, - checksum TEXT NOT NULL, - applied_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP -) -`); - for (const [index, migration] of migrations.entries()) { - await fixture.sql.execute( - `INSERT INTO junior_schema_migrations (id, checksum) VALUES ($1, $2)`, - [`plugin:memory/${migrationFiles[index]}`, migration.hash], - ); - } - - await expect( - migratePluginSchemas(fixture.sql, [ - { - dir: memoryMigrationsDir(), - pluginName: "memory", - }, - ]), - ).resolves.toEqual({ - existing: migrations.length, - migrated: 0, - scanned: migrations.length, + await fixture.sql.migrate({ + migrationsFolder: oldCoreMigrations, + migrationsTable: "__drizzle_junior_core", }); - } finally { - await fixture.close(); - } - }); - - it("does not adopt an unknown memory legacy checksum", async () => { - const fixture = await createLocalJuniorSqlFixture(); - const migrationCount = readMigrationFiles({ - migrationsFolder: memoryMigrationsDir(), - }).length; - const [baselineFile] = memoryMigrationFiles(); - expect(baselineFile).toBeDefined(); - - try { - await fixture.sql.execute(` -CREATE TABLE junior_schema_migrations ( - id TEXT PRIMARY KEY, - checksum TEXT NOT NULL, - applied_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP -) -`); + await createLegacyMemoryTable(fixture); await fixture.sql.execute( - `INSERT INTO junior_schema_migrations (id, checksum) VALUES ($1, $2)`, - [`plugin:memory/${baselineFile}`, "unknown-memory-checksum"], + `INSERT INTO junior_memory_memories ( + id, scope, scope_key, type, subject_type, subject_key, content, + source_platform, source_key, idempotency_key, observed_at_ms, created_at_ms + ) VALUES ($1, 'conversation', 'slack:T123:C123:1718800000.000000', + 'task', 'conversation', 'slack:T123:C123:1718800000.000000', $2, + 'slack', 'slack:T123:C123:1718800000.000000', $3, $4, $4)`, + [ + "legacy-memory", + "Use the deploy runbook.", + "legacy-memory-key", + Date.parse("2026-08-21T12:00:00.000Z"), + ], ); - await expect( - migratePluginSchemas(fixture.sql, [ - { - dir: memoryMigrationsDir(), - pluginName: "memory", - }, - ]), - ).resolves.toEqual({ - existing: 0, - migrated: migrationCount, - scanned: migrationCount, - }); - } finally { - await fixture.close(); - } - }); - - it("applies packaged migrations through plugin discovery", async () => { - const fixture = await createLocalJuniorSqlFixture(); - NEON.sql = fixture.sql; - - try { - const migrationCount = readMigrationFiles({ - migrationsFolder: memoryMigrationsDir(), - }).length; - await expect( - migratePluginsToSql({ - pluginSet: defineJuniorPlugins([memoryPlugin()]), - sqlExecutor: fixture.sql, - }), - ).resolves.toEqual({ - existing: 0, - migrated: migrationCount, - scanned: migrationCount, - }); - - await expect( - fixture.sql.query<{ table_name: string }>( - ` -SELECT table_name -FROM information_schema.tables -WHERE table_name = 'junior_memory_memories' -`, - ), - ).resolves.toEqual([{ table_name: "junior_memory_memories" }]); + await migrateSchema(fixture.sql); await expect( - fixture.sql.query<{ extname: string }>( - "SELECT extname FROM pg_extension WHERE extname = 'btree_gin'", + fixture.sql.query<{ + conversationId: string | null; + id: string; + kind: string; + scope: string; + scopeKey: string; + }>( + `SELECT id, type AS kind, scope, scope_key AS "scopeKey", + conversation_id AS "conversationId" + FROM junior_memory_memories WHERE id = $1`, + ["legacy-memory"], ), - ).resolves.toEqual([{ extname: "btree_gin" }]); - + ).resolves.toEqual([ + { + conversationId: "slack:C123:1718800000.000000", + id: "legacy-memory", + kind: "procedure", + scope: "public", + scopeKey: "public", + }, + ]); await expect( - fixture.sql.query<{ is_generated: string }>( - ` -SELECT is_generated -FROM information_schema.columns -WHERE table_name = 'junior_memory_memories' - AND column_name = 'search_vector' -`, + fixture.sql.query<{ isGenerated: string }>( + `SELECT is_generated AS "isGenerated" + FROM information_schema.columns + WHERE table_name = 'junior_memory_memories' + AND column_name = 'search_vector'`, ), - ).resolves.toEqual([{ is_generated: "ALWAYS" }]); - - const [searchIndex] = await fixture.sql.query<{ indexdef: string }>(` -SELECT indexdef -FROM pg_indexes -WHERE indexname = 'junior_memory_memories_search_idx' -`); - expect(searchIndex?.indexdef).toContain( - "USING gin (scope, scope_key, search_vector)", - ); + ).resolves.toEqual([{ isGenerated: "ALWAYS" }]); } finally { await fixture.close(); } }, 15_000); - it("reports core and nonempty plugin migration journals", async () => { + it("reports Memory in the core migration journal", async () => { const fixture = await createLocalJuniorSqlFixture(); NEON.sql = fixture.sql; try { const coreMigrationCount = readMigrationFiles({ - migrationsFolder: path.resolve(process.cwd(), "migrations"), + migrationsFolder: coreMigrationsDir(), }).length; - const memoryMigrationCount = readMigrationFiles({ - migrationsFolder: memoryMigrationsDir(), - }).length; - const totalMigrationCount = coreMigrationCount + memoryMigrationCount; const lines: string[] = []; const pluginSet = defineJuniorPlugins([ memoryPlugin(), @@ -359,8 +311,7 @@ WHERE indexname = 'junior_memory_memories_search_idx' expect(lines).toEqual([ "Checking database migrations...", ` junior: applied ${coreMigrationCount} migrations (${coreMigrationCount} total)`, - ` junior-memory: applied ${memoryMigrationCount} migrations (${memoryMigrationCount} total)`, - `Applied ${totalMigrationCount} migrations (${totalMigrationCount} total).`, + `Applied ${coreMigrationCount} migrations (${coreMigrationCount} total).`, ]); lines.length = 0; @@ -368,8 +319,7 @@ WHERE indexname = 'junior_memory_memories_search_idx' expect(lines).toEqual([ "Checking database migrations...", ` junior: up to date (${coreMigrationCount} migrations)`, - ` junior-memory: up to date (${memoryMigrationCount} migrations)`, - `Database is up to date (${totalMigrationCount} migrations).`, + `Database is up to date (${coreMigrationCount} migrations).`, ]); } finally { await fixture.close(); @@ -378,14 +328,11 @@ WHERE indexname = 'junior_memory_memories_search_idx' it("reads public memory everywhere and private memory only for its User", async () => { const fixture = await createLocalJuniorSqlFixture(); - const plugin = memoryPlugin(); - setPlugins([plugin]); + setPlugins(memoryRuntimeRegistrations([])); NEON.sql = fixture.sql; try { await migrateSchema(fixture.sql); - await migrateMemorySchema(fixture); - // @ts-expect-error non-overlapping boundary cast; rule forbids as-unknown-as chains const db = fixture.sql.db() as MemoryDb; const viewerConversationId = "slack:D123:1718800001.000000"; const viewer = await recordPrivateConversation(fixture, { @@ -485,12 +432,11 @@ WHERE indexname = 'junior_memory_memories_search_idx' it("registers memory tools with runtime-provided plugin DB access", async () => { const fixture = await createLocalJuniorSqlFixture(); - setPlugins([memoryPlugin()]); + setPlugins(memoryRuntimeRegistrations([])); NEON.sql = fixture.sql; try { await migrateSchema(fixture.sql); - await migrateMemorySchema(fixture); const conversationId = "slack:C123:1718800000.000000"; const actor = { platform: "slack" as const, @@ -512,17 +458,13 @@ WHERE indexname = 'junior_memory_memories_search_idx' nowMs: Date.parse("2026-08-21T12:00:00.000Z"), userId: actor.userId, }); - const store = createMemoryStore( - // @ts-expect-error non-overlapping boundary cast; rule forbids as-unknown-as chains - fixture.sql.db() as MemoryDb, - { - conversationId, - locationId: userContext.locationId, - actor, - source, - userId: userContext.user.id, - }, - ); + const store = createMemoryStore(fixture.sql.db() as MemoryDb, { + conversationId, + locationId: userContext.locationId, + actor, + source, + userId: userContext.user.id, + }); await store.createMemory({ content: "I prefer host-wired personal recall.", idempotencyKey: "component-memory-personal", diff --git a/packages/junior/tests/integration/conversation-sql.test.ts b/packages/junior/tests/integration/conversation-sql.test.ts index 3bf58c857e..5360736416 100644 --- a/packages/junior/tests/integration/conversation-sql.test.ts +++ b/packages/junior/tests/integration/conversation-sql.test.ts @@ -458,7 +458,7 @@ ORDER BY conversation_id } }); - it("creates migrated tables matching the Drizzle schema", async () => { + it("creates core migrated tables matching the core Drizzle schema", async () => { const fixture = await createLocalJuniorSqlFixture(); try { diff --git a/packages/junior/tests/unit/app-config.test.ts b/packages/junior/tests/unit/app-config.test.ts index 2b2c3a3442..4e23f3934d 100644 --- a/packages/junior/tests/unit/app-config.test.ts +++ b/packages/junior/tests/unit/app-config.test.ts @@ -21,6 +21,10 @@ const originalCwd = process.cwd(); const originalPluginPackages = process.env.JUNIOR_PLUGIN_PACKAGES; const tempDirs: string[] = []; +function registeredPluginNames(): string[] { + return getPlugins().map((plugin) => plugin.manifest.name); +} + async function makeTempDir(): Promise { const tempDir = await fs.mkdtemp( path.join(os.tmpdir(), "junior-app-config-"), @@ -150,7 +154,7 @@ describe("createApp plugin config", () => { }); expect(pluginCatalogRuntime.getProviders()).toEqual([]); - expect(getPlugins().map((plugin) => plugin.manifest.name)).toEqual([]); + expect(registeredPluginNames()).toEqual(["memory"]); }); it("validates sandbox egress trace propagation domains from app options", async () => { @@ -189,9 +193,7 @@ describe("createApp plugin config", () => { expect( pluginCatalogRuntime.getProviders().map((plugin) => plugin.manifest.name), ).toEqual(["base"]); - expect(getPlugins().map((plugin) => plugin.manifest.name)).toEqual([ - "base", - ]); + expect(registeredPluginNames()).toEqual(["base", "memory"]); }); it("loads package plugins with runtime hook plugins", async () => { @@ -228,9 +230,7 @@ describe("createApp plugin config", () => { expect( pluginCatalogRuntime.getProviders().map((plugin) => plugin.manifest.name), ).toEqual(["dashboard", "env"]); - expect(getPlugins().map((plugin) => plugin.manifest.name)).toEqual([ - "dashboard", - ]); + expect(registeredPluginNames()).toEqual(["dashboard", "memory"]); }); it("fails loudly when configured plugin package names are invalid", async () => { @@ -322,9 +322,7 @@ describe("createApp plugin config", () => { expect( pluginCatalogRuntime.getProviders().map((plugin) => plugin.manifest.name), ).toEqual(["hooked"]); - expect(getPlugins().map((plugin) => plugin.manifest.name)).toEqual([ - "hooked", - ]); + expect(registeredPluginNames()).toEqual(["hooked", "memory"]); }); it("rejects incomplete plugin egress credential hooks", async () => { @@ -354,7 +352,7 @@ describe("createApp plugin config", () => { 'Plugin "example" egress credential hooks must include both grantForEgress and issueCredential.', ); - expect(getPlugins().map((plugin) => plugin.manifest.name)).toEqual([]); + expect(registeredPluginNames()).toEqual(["memory"]); expect(pluginCatalogRuntime.getProviders()).toEqual([]); }); @@ -390,7 +388,7 @@ describe("createApp plugin config", () => { 'Plugin "example" egress credential hooks require manifest.domains to list sandbox egress hosts.', ); - expect(getPlugins().map((plugin) => plugin.manifest.name)).toEqual([]); + expect(registeredPluginNames()).toEqual(["memory"]); expect(pluginCatalogRuntime.getProviders()).toEqual([]); }); @@ -422,7 +420,7 @@ describe("createApp plugin config", () => { 'Plugin "example" manifest.oauth without oauth-bearer credentials requires egress credential hooks.', ); - expect(getPlugins().map((plugin) => plugin.manifest.name)).toEqual([]); + expect(registeredPluginNames()).toEqual(["memory"]); expect(pluginCatalogRuntime.getProviders()).toEqual([]); }); @@ -454,9 +452,7 @@ describe("createApp plugin config", () => { expect( pluginCatalogRuntime.getProviders().map((plugin) => plugin.manifest.name), ).toEqual(["example"]); - expect(getPlugins().map((plugin) => plugin.manifest.name)).toEqual([ - "example", - ]); + expect(registeredPluginNames()).toEqual(["example", "memory"]); }); it("does not assign app skills to runtime hook inline plugins", async () => { @@ -612,7 +608,7 @@ describe("createApp plugin config", () => { 'Plugin "invalid" manifest.domains requires egress credential hooks when no generic credentials or apiHeaders are configured.', ); - expect(getPlugins().map((plugin) => plugin.manifest.name)).toEqual([]); + expect(registeredPluginNames()).toEqual(["memory"]); expect(pluginCatalogRuntime.getProviders()).toEqual([]); }); @@ -654,9 +650,7 @@ describe("createApp plugin config", () => { expect( pluginCatalogRuntime.getProviders().map((plugin) => plugin.manifest.name), ).toEqual(["hooked"]); - expect(getPlugins().map((plugin) => plugin.manifest.name)).toEqual([ - "hooked", - ]); + expect(registeredPluginNames()).toEqual(["hooked", "memory"]); }); it("loads manifest-only package plugins by package name", async () => { @@ -679,7 +673,7 @@ describe("createApp plugin config", () => { plugins: defineJuniorPlugins(["@acme/full-plugin"]), }); - expect(getPlugins().map((plugin) => plugin.manifest.name)).toEqual([]); + expect(registeredPluginNames()).toEqual(["memory"]); expect( pluginCatalogRuntime.getProviders().map((plugin) => plugin.manifest.name), ).toEqual(["full"]); @@ -709,7 +703,7 @@ describe("createApp plugin config", () => { ]), ).toThrow('Duplicate plugin registration name "dupe"'); - expect(getPlugins().map((plugin) => plugin.manifest.name)).toEqual([]); + expect(registeredPluginNames()).toEqual(["memory"]); expect(pluginCatalogRuntime.getProviders()).toEqual([]); }); @@ -731,7 +725,7 @@ describe("createApp plugin config", () => { 'Junior plugin registration name "GitHub" must be a lowercase plugin identifier', ); - expect(getPlugins().map((plugin) => plugin.manifest.name)).toEqual([]); + expect(registeredPluginNames()).toEqual(["memory"]); expect(pluginCatalogRuntime.getProviders()).toEqual([]); }); @@ -812,9 +806,9 @@ describe("createApp plugin config", () => { pluginSet: defineJuniorPlugins([ defineJuniorPlugin({ manifest: { - name: "memory", - displayName: "Memory", - description: "Memory plugin", + name: "demo-api", + displayName: "Demo API", + description: "Demo API plugin", }, hooks: { apiRoutes() { @@ -824,13 +818,13 @@ describe("createApp plugin config", () => { }), ]), plugins: undefined, - pluginRuntimeRegistrations: ["memory"], + pluginRuntimeRegistrations: ["demo-api"], })); const app = await createApp(); const response = await app.fetch( - new Request("http://localhost/api/plugins/memory"), + new Request("http://localhost/api/plugins/demo-api"), ); expect(response.status).toBe(200); diff --git a/packages/junior/tests/unit/cli/init-cli.test.ts b/packages/junior/tests/unit/cli/init-cli.test.ts index 89d263ce25..bfc6497a93 100644 --- a/packages/junior/tests/unit/cli/init-cli.test.ts +++ b/packages/junior/tests/unit/cli/init-cli.test.ts @@ -151,11 +151,7 @@ describe("init cli", () => { expect(pluginsFile).toContain( 'import { defineJuniorPlugins } from "@sentry/junior";', ); - expect(pluginsFile).toContain( - 'import { memoryPlugin } from "@sentry/junior-memory";', - ); expect(pluginsFile).toContain("defineJuniorPlugins("); - expect(pluginsFile).toContain("memoryPlugin()"); expect(pluginsFile).toContain('"@sentry/junior-maintenance"'); const pkg = readJsonFile<{ @@ -164,7 +160,7 @@ describe("init cli", () => { scripts: Record; }>(path.join(target, "package.json")); expect(pkg.dependencies["@sentry/junior"]).toBe("latest"); - expect(pkg.dependencies["@sentry/junior-memory"]).toBe("latest"); + expect(pkg.dependencies["@sentry/junior-memory"]).toBeUndefined(); expect(pkg.dependencies["@sentry/junior-maintenance"]).toBe("latest"); expect(pkg.dependencies["@sentry/nitro"]).toBe("10.65.0"); expect(pkg.devDependencies.nitro).toBeDefined(); diff --git a/packages/junior/tests/unit/cli/plugin-commands.test.ts b/packages/junior/tests/unit/cli/plugin-commands.test.ts index 7ee8c2cbb3..b33532e4a5 100644 --- a/packages/junior/tests/unit/cli/plugin-commands.test.ts +++ b/packages/junior/tests/unit/cli/plugin-commands.test.ts @@ -110,15 +110,15 @@ describe("plugin CLI commands", () => { pluginSetRef.current = defineJuniorPlugins([ defineJuniorPlugin({ manifest: { - name: "memory", - displayName: "Memory", - description: "Memory plugin", + name: "notes", + displayName: "Notes", + description: "Notes plugin", }, cli: { commands: [ { - name: "memory", - summary: "Memory command", + name: "notes", + summary: "Notes command", configure(command) { command.name("renamed"); command.command("search"); @@ -130,7 +130,7 @@ describe("plugin CLI commands", () => { ]); await expect(loadCliPluginCommands()).rejects.toThrow( - 'Plugin CLI command "memory" from plugin "memory" must not rename its top-level command', + 'Plugin CLI command "notes" from plugin "notes" must not rename its top-level command', ); }); @@ -138,15 +138,15 @@ describe("plugin CLI commands", () => { pluginSetRef.current = defineJuniorPlugins([ defineJuniorPlugin({ manifest: { - name: "memory", - displayName: "Memory", - description: "Memory plugin", + name: "notes", + displayName: "Notes", + description: "Notes plugin", }, cli: { commands: [ { - name: "memory", - summary: "Memory command", + name: "notes", + summary: "Notes command", configure(command) { command.alias("mem"); command.command("search"); @@ -158,7 +158,7 @@ describe("plugin CLI commands", () => { ]); await expect(loadCliPluginCommands()).rejects.toThrow( - 'Plugin CLI command "memory" from plugin "memory" must not define top-level aliases', + 'Plugin CLI command "notes" from plugin "notes" must not define top-level aliases', ); }); @@ -252,8 +252,8 @@ describe("plugin CLI commands", () => { cli: { commands: [ { - name: "memory", - summary: "First memory", + name: "shared", + summary: "First shared command", configure(command) { command.command("search"); }, @@ -270,8 +270,8 @@ describe("plugin CLI commands", () => { cli: { commands: [ { - name: "memory", - summary: "Second memory", + name: "shared", + summary: "Second shared command", configure(command) { command.command("show"); }, @@ -282,7 +282,7 @@ describe("plugin CLI commands", () => { ]); await expect(loadCliPluginCommands()).rejects.toThrow( - 'Plugin CLI command "memory" from plugin "second" conflicts with plugin "first"', + 'Plugin CLI command "shared" from plugin "second" conflicts with plugin "first"', ); }); diff --git a/packages/junior/tsdown.memory.config.ts b/packages/junior/tsdown.memory.config.ts new file mode 100644 index 0000000000..e37ecc3cc9 --- /dev/null +++ b/packages/junior/tsdown.memory.config.ts @@ -0,0 +1,14 @@ +import { defineConfig } from "tsdown"; + +export default defineConfig({ + entry: { index: "src/chat/memory/index.ts" }, + format: "esm", + tsconfig: "tsconfig.build.json", + dts: true, + outDir: "dist/memory", + outExtensions: () => ({ + js: ".js", + dts: ".d.ts", + }), + clean: false, +}); diff --git a/packages/junior/vitest.config.ts b/packages/junior/vitest.config.ts index e73b041641..06328a0f04 100644 --- a/packages/junior/vitest.config.ts +++ b/packages/junior/vitest.config.ts @@ -20,10 +20,6 @@ export default defineConfig({ __dirname, "../junior-plugin-api/src/index.ts", ), - "@sentry/junior-memory": path.resolve( - __dirname, - "../junior-memory/src/index.ts", - ), }, }, test: { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index bd7115ba00..70356d3d35 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -121,9 +121,6 @@ importers: '@sentry/junior-linear': specifier: workspace:* version: link:../../packages/junior-linear - '@sentry/junior-memory': - specifier: workspace:* - version: file:packages/junior-memory(@opentelemetry/api@1.9.1) '@sentry/junior-notion': specifier: workspace:* version: link:../../packages/junior-notion @@ -294,9 +291,6 @@ importers: '@sentry/junior-github': specifier: workspace:* version: file:packages/junior-github(@neondatabase/serverless@1.1.0)(@opentelemetry/api@1.9.1)(@types/pg@8.15.6)(pg@8.21.0) - '@sentry/junior-memory': - specifier: workspace:* - version: file:packages/junior-memory(@neondatabase/serverless@1.1.0)(@opentelemetry/api@1.9.1)(@types/pg@8.15.6)(pg@8.21.0) '@sentry/junior-testing': specifier: workspace:* version: file:packages/junior-testing(@neondatabase/serverless@1.1.0)(@opentelemetry/api@1.9.1)(@types/pg@8.15.6) @@ -444,9 +438,6 @@ importers: '@sentry/junior-github': specifier: workspace:* version: file:packages/junior-github - '@sentry/junior-memory': - specifier: workspace:* - version: file:packages/junior-memory '@sentry/junior-plugin-api': specifier: workspace:* version: link:../junior-plugin-api @@ -583,21 +574,12 @@ importers: packages/junior-memory: dependencies: + '@sentry/junior': + specifier: workspace:* + version: file:packages/junior '@sentry/junior-plugin-api': specifier: workspace:* version: link:../junior-plugin-api - '@sinclair/typebox': - specifier: ^0.34.49 - version: 0.34.49 - commander: - specifier: ^14.0.3 - version: 14.0.3 - drizzle-orm: - specifier: 'catalog:' - version: 0.45.2 - zod: - specifier: 'catalog:' - version: 4.5.4 devDependencies: '@oxlint/plugins': specifier: 1.79.0 @@ -605,12 +587,18 @@ importers: '@sentry/junior-testing': specifier: workspace:* version: file:packages/junior-testing + '@sinclair/typebox': + specifier: ^0.34.49 + version: 0.34.49 '@types/node': specifier: ^25.9.1 version: 25.9.1 - drizzle-kit: + commander: + specifier: ^14.0.3 + version: 14.0.3 + drizzle-orm: specifier: 'catalog:' - version: 0.31.10 + version: 0.45.2 oxlint: specifier: ^1.79.0 version: 1.79.0 @@ -623,6 +611,9 @@ importers: vitest: specifier: ^4.1.7 version: 4.1.7(@types/node@25.9.1)(tsx@4.22.3) + zod: + specifier: 'catalog:' + version: 4.5.4 packages/junior-notion: {} @@ -3828,9 +3819,6 @@ packages: '@sentry/junior-github@file:packages/junior-github': resolution: {directory: packages/junior-github, type: directory} - '@sentry/junior-memory@file:packages/junior-memory': - resolution: {directory: packages/junior-memory, type: directory} - '@sentry/junior-plugin-api@file:packages/junior-plugin-api': resolution: {directory: packages/junior-plugin-api, type: directory} @@ -3839,6 +3827,7 @@ packages: '@sentry/junior@file:packages/junior': resolution: {directory: packages/junior, type: directory} + hasBin: true '@sentry/nitro@10.65.0': resolution: {integrity: sha512-whySjTbpvV2/iWTl/smFO9BAbJ9kaUL2UK3PT4tTZYeXBdTGXE1JBNir5kmYO/sFzswS/RCElcs0IhpcqKQKEQ==} @@ -11964,120 +11953,6 @@ snapshots: - sql.js - sqlite3 - '@sentry/junior-memory@file:packages/junior-memory': - dependencies: - '@sentry/junior-plugin-api': file:packages/junior-plugin-api - '@sinclair/typebox': 0.34.52 - commander: 14.0.3 - drizzle-orm: 0.45.2 - zod: 4.5.4 - transitivePeerDependencies: - - '@aws-sdk/client-rds-data' - - '@cloudflare/workers-types' - - '@electric-sql/pglite' - - '@libsql/client' - - '@libsql/client-wasm' - - '@neondatabase/serverless' - - '@op-engineering/op-sqlite' - - '@opentelemetry/api' - - '@planetscale/database' - - '@prisma/client' - - '@tidbcloud/serverless' - - '@types/better-sqlite3' - - '@types/pg' - - '@types/sql.js' - - '@upstash/redis' - - '@vercel/postgres' - - '@xata.io/client' - - better-sqlite3 - - bun-types - - expo-sqlite - - gel - - knex - - kysely - - mysql2 - - pg - - postgres - - prisma - - sql.js - - sqlite3 - - '@sentry/junior-memory@file:packages/junior-memory(@neondatabase/serverless@1.1.0)(@opentelemetry/api@1.9.1)(@types/pg@8.15.6)(pg@8.21.0)': - dependencies: - '@sentry/junior-plugin-api': file:packages/junior-plugin-api - '@sinclair/typebox': 0.34.52 - commander: 14.0.3 - drizzle-orm: 0.45.2(@neondatabase/serverless@1.1.0)(@opentelemetry/api@1.9.1)(@types/pg@8.15.6)(pg@8.21.0) - zod: 4.5.4 - transitivePeerDependencies: - - '@aws-sdk/client-rds-data' - - '@cloudflare/workers-types' - - '@electric-sql/pglite' - - '@libsql/client' - - '@libsql/client-wasm' - - '@neondatabase/serverless' - - '@op-engineering/op-sqlite' - - '@opentelemetry/api' - - '@planetscale/database' - - '@prisma/client' - - '@tidbcloud/serverless' - - '@types/better-sqlite3' - - '@types/pg' - - '@types/sql.js' - - '@upstash/redis' - - '@vercel/postgres' - - '@xata.io/client' - - better-sqlite3 - - bun-types - - expo-sqlite - - gel - - knex - - kysely - - mysql2 - - pg - - postgres - - prisma - - sql.js - - sqlite3 - - '@sentry/junior-memory@file:packages/junior-memory(@opentelemetry/api@1.9.1)': - dependencies: - '@sentry/junior-plugin-api': file:packages/junior-plugin-api - '@sinclair/typebox': 0.34.52 - commander: 14.0.3 - drizzle-orm: 0.45.2(@opentelemetry/api@1.9.1) - zod: 4.5.4 - transitivePeerDependencies: - - '@aws-sdk/client-rds-data' - - '@cloudflare/workers-types' - - '@electric-sql/pglite' - - '@libsql/client' - - '@libsql/client-wasm' - - '@neondatabase/serverless' - - '@op-engineering/op-sqlite' - - '@opentelemetry/api' - - '@planetscale/database' - - '@prisma/client' - - '@tidbcloud/serverless' - - '@types/better-sqlite3' - - '@types/pg' - - '@types/sql.js' - - '@upstash/redis' - - '@vercel/postgres' - - '@xata.io/client' - - better-sqlite3 - - bun-types - - expo-sqlite - - gel - - knex - - kysely - - mysql2 - - pg - - postgres - - prisma - - sql.js - - sqlite3 - '@sentry/junior-plugin-api@file:packages/junior-plugin-api': dependencies: commander: 14.0.3 diff --git a/scripts/file-length-exceptions.mjs b/scripts/file-length-exceptions.mjs index b1219cb97e..7ca1e49879 100644 --- a/scripts/file-length-exceptions.mjs +++ b/scripts/file-length-exceptions.mjs @@ -16,7 +16,7 @@ export const fileLengthExceptions = { "Existing broad plugin suite; split with plugin modules.", "packages/junior-github/tests/webhook-outcomes.test.ts": "Existing broad webhook outcome suite; split by outcome.", - "packages/junior-memory/src/store.ts": + "packages/junior/src/chat/memory/store.ts": "Existing memory store; split by storage concern.", "packages/junior-memory/tests/storage.test.ts": "Existing broad memory storage suite; split by storage concern.",