{
  "interval": {
    "intervalStart": "2025-11-16T00:00:00.000Z",
    "intervalEnd": "2025-11-23T00:00:00.000Z",
    "intervalType": "week"
  },
  "repository": "elizaos/eliza",
  "overview": "From 2025-11-16 to 2025-11-23, elizaos/eliza had 6 new PRs (6 merged), 6 new issues, and 15 active contributors.",
  "topIssues": [
    {
      "id": "I_kwDOMT5cIs7YjZ7G",
      "title": "can i use deepseek api?",
      "author": "870171594",
      "number": 6156,
      "repository": "elizaos/eliza",
      "body": "**Is your feature request related to a problem? Please describe.**\n\n<!-- A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] -->\n\n**Describe the solution you'd like**\n\n<!-- A clear and concise description of what you want to happen. -->\n\n**Describe alternatives you've considered**\n\n<!-- A clear and concise description of any alternative solutions or features you've considered. -->\n\n**Additional context**\n\n<!-- Add any other context or screenshots about the feature request here. -->\n",
      "createdAt": "2025-11-17T12:36:09Z",
      "closedAt": null,
      "state": "OPEN",
      "commentCount": 1
    },
    {
      "id": "I_kwDOMT5cIs7NzHXv",
      "title": "Migrate All Dependencies and Plugins to Zod v4",
      "author": "borisudovicic",
      "number": 5999,
      "repository": "elizaos/eliza",
      "body": "We need to migrate the Eliza monorepo and all plugins from Zod v3 to Zod v4.\n\n* Stan has already initiated \\~20–25 PRs across referenced plugins to bump dependencies (core, bootstrap, langchain/ai/vercel, etc.) to the latest compatible Zod v4 versions.\n* Some plugins currently have mismatched peer dependencies; migration only works if all packages are upgraded consistently.\n* Newer versions of the AI SDK also rely on Zod v4, so all LLM plugins must be updated to the latest ai-sdk.\n\nThis migration is a blocking dependency upgrade: partial migration causes runtime and type errors. We need a coordinated effort to upgrade and test the full set of \\~40 plugins.\n\nAcceptance Criteria:\n\n* Update package.json in all monorepo packages to depend on zod@^4.\n* Update all plugins (bootstrap, sql, LLM plugins, etc.) to use Zod v4 schemas.\n* Resolve peer dependency mismatches across packages.\n* Upgrade all AI SDK–based packages to versions that use Zod v4.",
      "createdAt": "2025-09-25T09:15:09Z",
      "closedAt": "2025-11-20T17:14:17Z",
      "state": "CLOSED",
      "commentCount": 0
    },
    {
      "id": "I_kwDOMT5cIs7V2FT1",
      "title": "Container Billing Logic",
      "author": "borisudovicic",
      "number": 6124,
      "repository": "elizaos/eliza",
      "body": "* Add **monthly cron** to deduct container costs (\\~$25–35 per user).\n* If cron fails → **pause container**, retain for one week, send email → delete after grace period.",
      "createdAt": "2025-11-04T18:13:32Z",
      "closedAt": "2025-11-20T17:14:21Z",
      "state": "CLOSED",
      "commentCount": 0
    },
    {
      "id": "I_kwDOMT5cIs7XzOLe",
      "title": "Deprecation of Langchain v0.3 - migrate to langchian-classic or bump version to v1",
      "author": "skurzyp",
      "number": 6145,
      "repository": "elizaos/eliza",
      "body": "**Is your feature request related to a problem? Please describe.**\nElizaOS currently uses LangChain v0.3, which is now outdated. The latest release is LangChain v1, and the previous functionality with the same API has been moved to a separate package called langchain-classic. Since LangChain v0.3 and v1 are incompatible, we cannot easily upgrade the LangChain version in our SDK, as ElizaOS depends on the older v0.3 release.\n\n**Describe the solution you'd like**\nbumping `langchain` version to v1\n\n**Describe alternatives you've considered**\nmigtration to `langchain-classic`\n\n**Additional context**\n",
      "createdAt": "2025-11-13T10:16:57Z",
      "closedAt": "2025-11-17T18:18:24Z",
      "state": "CLOSED",
      "commentCount": 0
    },
    {
      "id": "I_kwDOMT5cIs7YJ3C6",
      "title": "Figma UI implementation on cloud",
      "author": "samarth30",
      "number": 6153,
      "repository": "elizaos/eliza",
      "body": "",
      "createdAt": "2025-11-14T17:13:07Z",
      "closedAt": "2025-11-20T17:14:31Z",
      "state": "CLOSED",
      "commentCount": 0
    }
  ],
  "topPRs": [
    {
      "id": "PR_kwDOMT5cIs607dMZ",
      "title": "feat: Entity-level RLS & Security Improvements",
      "author": "standujar",
      "number": 6167,
      "body": "## Summary\r\n\r\nThis PR implements four major improvements to ElizaOS's security, data architecture, and observability:\r\n\r\n1. **Entity-Level Row Level Security (RLS)** - PostgreSQL RLS policies for entity-based data isolation\r\n2. **Semantic Clarity Refactoring** - Renames `serverId` to `messageServerId` for clarity\r\n3. **Performance Optimization** - Efficient participant checking methods (`isRoomParticipant`, `isChannelParticipant`)\r\n4. **Timeline Action Spans Fix** - Correct inclusion of `action_event` logs in run timelines\r\n\r\nAll changes maintain full backward compatibility with existing deployments and plugins.\r\n\r\n---\r\n\r\n## Table of Contents\r\n\r\n1. [Architecture Overview](#architecture-overview)\r\n   - [Entity-Level RLS](#1-entity-level-row-level-security-rls)\r\n   - [Semantic Clarity](#2-semantic-clarity-serverid-vs-messageserverid)\r\n   - [Performance Optimization](#3-performance-optimization-participant-checking)\r\n   - [Timeline Action Spans Fix](#4-timeline-action-spans-fix)\r\n2. [Test Coverage](#test-coverage)\r\n3. [Database Migration](#database-migration)\r\n4. [Configuration](#configuration)\r\n\r\n---\r\n\r\n## Architecture Overview\r\n\r\n### 1. Entity-Level Row Level Security (RLS)\r\n\r\n**Problem**: ElizaOS needed fine-grained access control to isolate data by entity (users, agents, bots, etc.) within the same database.\r\n\r\n**Solution**: Implemented PostgreSQL RLS policies that automatically filter data based on the current entity context.\r\n\r\n**Benefits:**\r\n- ✅ **Data Isolation**: Each entity only sees its own data\r\n- ✅ **Automatic Enforcement**: RLS is enforced at the database level, preventing accidental data leaks\r\n- ✅ **Performance**: Database-level filtering is more efficient than application-level checks\r\n- ✅ **Security**: Even if application code has bugs, RLS prevents unauthorized access\r\n\r\n**Implementation:**\r\n- Added `current_entity_id()` PostgreSQL function to track current entity context via `app.entity_id` session variable\r\n- Created `add_entity_isolation()` function to apply RLS policies to tables\r\n- Two isolation strategies:\r\n  - **Direct ownership**: Tables with `entityId` or `authorId` columns\r\n  - **Shared access**: Tables with `roomId` that join to `participants` table\r\n- Integrated with entity context management in ElizaOS core\r\n\r\n**RLS Isolation Strategies:**\r\n\r\nThe system automatically detects which strategy to use based on table schema:\r\n\r\n**Strategy 1: Direct Entity Ownership**\r\n- Tables: `memories`, `tasks`, `components`\r\n- Policy: `entityId = current_entity_id()`\r\n- Effect: Users see only their own records\r\n\r\n**Strategy 2: Room-Based Shared Access**\r\n- Tables: `logs`, `messages` (via `roomId`)\r\n- Policy: `roomId IN (SELECT roomId FROM participants WHERE entityId = current_entity_id())`\r\n- Effect: Users see all records in rooms they're a participant in\r\n- **Key Benefit**: In a room with 3 participants, all 3 can see the same logs/messages\r\n\r\n---\r\n\r\n### 2. Server-Level Row Level Security (RLS)\r\n\r\n**Problem**: ElizaOS needed multi-tenant isolation to prevent data leakage between different server instances (deployments, environments).\r\n\r\n**Solution**: Implemented PostgreSQL RLS policies that automatically isolate data by ElizaOS server instance.\r\n\r\nAlready implemented: #6101\r\n\r\n---\r\n\r\n### 3. Semantic Clarity: `serverId` vs `messageServerId`\r\n\r\n#### Problem Statement\r\n\r\n##### Why `serverId` was problematic\r\n\r\nThe term `serverId` was ambiguous and created confusion in the codebase for multiple reasons:\r\n\r\n**1. Semantic Ambiguity**\r\n\r\nThe name `serverId` doesn't clearly indicate what type of server it refers to. In a distributed system like ElizaOS, \"server\" could mean:\r\n- Message servers (Discord, Telegram, Slack)\r\n- Application servers (ElizaOS instances)\r\n- Database servers\r\n- Authentication servers\r\n\r\nThis ambiguity made code harder to read and maintain.\r\n\r\n**2. Conflict with Row Level Security (RLS)**\r\n\r\nElizaOS uses PostgreSQL Row Level Security for multi-tenant isolation. In this context:\r\n- `server_id` in RLS refers to the **ElizaOS server instance** (for tenant isolation)\r\n- `serverId` in messaging refers to **external message platforms** (Discord guild, Telegram bot, etc.)\r\n\r\n**Key distinction:**\r\n- ONE ElizaOS server instance (`server_id = \"abc-123\"`) can connect to MULTIPLE message servers\r\n  - Discord guilds (`messageServerId = \"discord-1\"`, `messageServerId = \"discord-2\"`)\r\n  - Telegram bots (`messageServerId = \"telegram-1\"`)\r\n\r\nThis dual meaning created confusion:\r\n\r\n```typescript\r\n// Which serverId is this? ElizaOS instance or Discord guild?\r\nconst room = await adapter.getRoom({ serverId, roomId });\r\n\r\n// Is this filtering by tenant or by Discord server?\r\nawait adapter.getRoomsByServerId(serverId);\r\n```\r\n\r\n**3. Developer Confusion**\r\n\r\nWhen working on features involving both RLS and messaging:\r\n- Setting RLS policies with `server_id` (tenant isolation)\r\n- Querying rooms by `serverId` (message platform)\r\n\r\nSame name, completely different concepts → bugs and confusion\r\n\r\n**4. API Inconsistency**\r\n\r\nAPI routes like `/api/agents/:agentId/servers/:serverId/channels` didn't clearly communicate that `serverId` refers to a messaging platform, not an ElizaOS server.\r\n\r\n#### Solution\r\n\r\nRename message-related `serverId` to `messageServerId` to:\r\n- **Clearly indicate purpose**: It's the ID of an external messaging platform\r\n- **Avoid RLS conflicts**: RLS continues using `server_id` for tenant isolation\r\n- **Improve maintainability**: Code is self-documenting and semantically clear\r\n- **Better API design**: Routes like `/api/agents/:agentId/message-servers/:messageServerId/channels` are crystal clear\r\n\r\n---\r\n\r\n### 4. Performance Optimization: Participant Checking\r\n\r\n**Problem**: Checking if an entity is a participant required loading ALL participants into memory and using `.some()` - O(n) complexity.\r\n\r\n**Solution**: Added direct database existence checks - O(1) complexity.\r\n\r\n**New Methods:**\r\n- `isRoomParticipant(entityId, roomId)` - Direct DB query\r\n- `isChannelParticipant(entityId, channelId)` - Direct DB query\r\n\r\n**Benefits:**\r\n- **Constant time complexity** - O(1) instead of O(n)\r\n- **Lower memory usage** - No loading all participants\r\n- **Better scalability** - Handles rooms with 1000+ participants\r\n- **Database indexes** - Optimized queries\r\n\r\n**Implementation:**\r\n\r\n```typescript\r\n// OLD: O(n) - Load all participants into memory\r\nasync isParticipant(entityId: UUID, roomId: UUID): Promise<boolean> {\r\n  const participants = await this.getParticipantsForRoom(roomId);\r\n  return participants.some(p => p === entityId);\r\n}\r\n\r\n// NEW: O(1) - Direct database existence check\r\nasync isRoomParticipant(entityId: UUID, roomId: UUID): Promise<boolean> {\r\n  return this.withEntityContext(null, async (tx) => {\r\n    const result = await tx\r\n      .select({ exists: sql<number>`1` })\r\n      .from(participantTable)\r\n      .where(\r\n        and(\r\n          eq(participantTable.roomId, roomId),\r\n          eq(participantTable.entityId, entityId)\r\n        )\r\n      )\r\n      .limit(1);\r\n    return result.length > 0;\r\n  });\r\n}\r\n```\r\n\r\n**Impact on Authorization Checks:**\r\n\r\nBefore:\r\n```typescript\r\n// Load 1000 participants into memory\r\nconst participants = await runtime.getParticipantsForRoom(roomId);\r\nif (!participants.includes(entityId)) {\r\n  return sendError(res, 403, 'FORBIDDEN', 'Not a participant');\r\n}\r\n```\r\n\r\nAfter:\r\n```typescript\r\n// Single indexed DB query\r\nif (!(await runtime.isRoomParticipant(entityId, roomId))) {\r\n  return sendError(res, 403, 'FORBIDDEN', 'Not a participant');\r\n}\r\n```\r\n\r\n---\r\n\r\n### 5. Timeline Action Spans Fix\r\n\r\n**Problem**: The Timeline tab showed run summaries with action counts (e.g., \"11 spans\") but didn't display individual action details (REPLY, GET_TOKEN_CRYPTOSCORE, etc.). Only model calls (TEXT_LARGE, TEXT_EMBEDDING) were visible.\r\n\r\n**Root Cause**:\r\n\r\nElizaOS creates two types of logs for actions:\r\n- `action_event`: Logged when action STARTS (contains `runId` of the action, NO `parentRunId`)\r\n- `action`: Logged when action COMPLETES (contains `runId` of the action AND `parentRunId` pointing to main run)\r\n\r\n**Example from database:**\r\n\r\n```sql\r\n-- Main run\r\nrunId: c29cc856-4ee0-435b-a5ca-b81f76f7ef43\r\n\r\n-- Action completion log (type: 'action')\r\nrunId: 03286e8f-6eff-4c48-b0b9-e92cf2c52d0a  -- action's run\r\nparentRunId: c29cc856-4ee0-435b-a5ca-b81f76f7ef43  -- main run ✅\r\n\r\n-- Action start log (type: 'action_event')\r\nrunId: 03286e8f-6eff-4c48-b0b9-e92cf2c52d0a  -- action's run\r\nparentRunId: NULL  -- ❌ no link to main run\r\n```\r\n\r\n**The Filter Problem:**\r\n\r\nThe original filter in `runs.ts` only matched logs where:\r\n```typescript\r\nbody.runId === runId || body.parentRunId === runId\r\n```\r\n\r\nFor main run `c29cc856...`:\r\n- ✅ `action` logs matched (via `parentRunId`)\r\n- ❌ `action_event` logs didn't match (neither `runId` nor `parentRunId` matched)\r\n\r\n**Frontend Behavior:**\r\n\r\nThe frontend (`eliza-span-adapter.ts`) requires BOTH events:\r\n- `ACTION_STARTED` (from `action_event` logs) → **creates** the action span\r\n- `ACTION_COMPLETED` (from `action` logs) → **updates** the existing span\r\n\r\nWithout `ACTION_STARTED` events:\r\n- Action spans never created\r\n- `ACTION_COMPLETED` events try to update non-existent spans\r\n- Actions invisible in timeline UI\r\n\r\n**Solution:**\r\n\r\nModified the filter logic in [`runs.ts:439-466`](/Users/stanislasandujar/Projects/elizaos/eliza/packages/server/src/api/agents/runs.ts#L439-L466):\r\n\r\n```typescript\r\n// Step 1: Find directly related logs (run_event, action, etc.)\r\nconst directlyRelated = logs.filter((l) => {\r\n  const body = l.body as { runId?: UUID; parentRunId?: UUID };\r\n  return body.runId === runId || body.parentRunId === runId;\r\n});\r\n\r\n// Step 2: Extract action runIds from matched action completion logs\r\nconst actionRunIds = new Set(\r\n  directlyRelated\r\n    .filter((l) => l.type === 'action')\r\n    .map((l) => (l.body as { runId?: UUID }).runId)\r\n    .filter((id): id is UUID => !!id)\r\n);\r\n\r\n// Step 3: Include action_event logs that share runId with matched actions\r\nconst related = logs.filter((l) => {\r\n  const body = l.body as { runId?: UUID; parentRunId?: UUID };\r\n\r\n  // Include if directly related to main run\r\n  if (body.runId === runId || body.parentRunId === runId) {\r\n    return true;\r\n  }\r\n\r\n  // Also include action_event logs matching action runIds\r\n  if (l.type === 'action_event' && body.runId && actionRunIds.has(body.runId)) {\r\n    return true;\r\n  }\r\n\r\n  return false;\r\n});\r\n```\r\n\r\n**How it Works:**\r\n\r\n1. **First pass**: Find all logs directly related to the main run\r\n   - Includes `action` completion logs (via `parentRunId`)\r\n   - Includes `run_event`, model calls, etc.\r\n\r\n2. **Extract action IDs**: Collect all `runId` values from the matched `action` logs\r\n   - These are the action-specific run IDs\r\n\r\n3. **Second pass**: Also include `action_event` logs that share those action run IDs\r\n   - Even though they don't link to the main run via `parentRunId`\r\n   - They're identified by matching the action's `runId`\r\n\r\n**Result:**\r\n\r\nNow the API returns complete action data:\r\n- `ACTION_STARTED` events (from `action_event` logs)\r\n- `ACTION_COMPLETED` events (from `action` logs)\r\n\r\nFrontend can now:\r\n- Create action spans on `ACTION_STARTED`\r\n- Update them on `ACTION_COMPLETED`\r\n- Display actions in timeline alongside model calls\r\n\r\n**Files Modified:**\r\n- [`packages/server/src/api/agents/runs.ts`](/Users/stanislasandujar/Projects/elizaos/eliza/packages/server/src/api/agents/runs.ts#L439-L466)\r\n\r\n**Impact:**\r\n- ✅ Timeline now shows ALL spans (actions + model calls)\r\n- ✅ Action details visible (REPLY, GET_TOKEN_CRYPTOSCORE, etc.)\r\n- ✅ Accurate span counts match displayed spans\r\n- ✅ Complete observability for debugging agent behavior\r\n\r\n---\r\n\r\n### 6. RLS Security for Junction Table\r\n\r\n**Problem Identified**: Without RLS on `message_server_agents`, Server A could see the existence of Discord/Telegram servers linked to Server B's agents.\r\n\r\n**Solution**: The RLS system automatically adds isolation to the junction table:\r\n\r\n- Adds `server_id UUID DEFAULT current_server_id()` column\r\n- Creates `server_isolation_policy` for complete isolation\r\n- Server A cannot see or modify Server B's message server associations\r\n\r\n---\r\n\r\n## Test Coverage\r\n\r\n### All Tests Passing ✅\r\n\r\n**RLS Tests**: 77 tests pass, 0 fail, 173 expect() calls\r\n\r\n**Participant Tests**: 11 tests pass, 0 fail, 27 expect() calls\r\n- 5 tests in `participant.test.ts` (3 new for `isRoomParticipant`)\r\n- 6 tests in `messaging.test.ts` (2 new for `isChannelParticipant`)\r\n\r\n**Timeline Tests**: Integration tests verify action spans display correctly\r\n- Run detail API returns both `ACTION_STARTED` and `ACTION_COMPLETED` events\r\n- Frontend renders action spans with correct names and status\r\n- Span counts match displayed spans\r\n\r\n### Test Files\r\n\r\n**Unit Tests - Entity RLS** (`entity-rls.test.ts`)\r\n- Column detection priority (`roomId` > `entityId` > `authorId`)\r\n- Policy generation (STRICT vs PERMISSIVE modes)\r\n- Isolation behavior logic\r\n\r\n**Integration Tests - Entity RLS** (`rls-entity.test.ts`)\r\n- Entity isolation (Alice, Bob, Charlie)\r\n- Participant-based access control (room membership)\r\n- Combined Server RLS + Entity RLS (double isolation)\r\n\r\n**Integration Tests - message_server_agents** (`rls-message-server-agents.test.ts`)\r\n- Isolation: Server A sees only its 2 associations, Server B sees only its 1\r\n- Auto-population: `server_id` automatically set via `DEFAULT current_server_id()`\r\n- Query blocking: Server A queries Server B's message server → 0 results\r\n- Modification blocking: Server B tries to delete Server A's association → blocked\r\n- JOIN protection: Cross-server JOINs filtered correctly\r\n- Schema validation: Policy and DEFAULT constraint verified\r\n\r\n**Room Integration Tests** (5/5 passing)\r\n- Added test: `should map messageServerId to serverId for backward compatibility`\r\n- Verifies both fields are populated correctly\r\n\r\n**Timeline Integration Tests**\r\n- Verifies `action_event` logs included in run details\r\n- Confirms `ACTION_STARTED` events generated\r\n- Validates action spans display in frontend\r\n\r\n---\r\n\r\n## Breaking Changes\r\n\r\n**None**. All changes are fully backward compatible.\r\n\r\n---\r\n\r\n## Benefits\r\n\r\n### Code Clarity\r\n- **Developers immediately understand what `messageServerId` refers to**\r\n- **Self-documenting code**: No additional comments needed\r\n- **Clear method names**: `isChannelParticipant()` vs generic checks\r\n\r\n### Security\r\n- **Three-layer security**: Server RLS + Entity RLS + Application Authorization\r\n- **Complete RLS isolation** for both Server-level and Entity-level data\r\n- **Fail-closed** security model (deny access on errors)\r\n- **Database-enforced** isolation (can't be bypassed by application bugs)\r\n- **Zero Configuration**: RLS policies apply automatically to all tables\r\n\r\n### Developer Experience\r\n- **Reduced Bugs**: No more confusion between RLS `server_id` and messaging `serverId`\r\n- **Better Onboarding**: New developers don't need to guess which \"server\" is referenced\r\n- **Future-Proof**: Clear naming prevents similar ambiguities in future development\r\n- **Backward Compatible**: Existing code continues to work\r\n- **Type Safety**: TypeScript guides migration with deprecation warnings\r\n\r\n### Performance\r\n- **O(1) participant checks**: Constant time instead of linear\r\n- **Lower memory usage**: No loading all participants\r\n- **Database optimization**: Indexed queries for fast lookups\r\n- **Scalable**: Handles rooms with thousands of participants\r\n\r\n### Observability\r\n- **Complete timeline visibility**: All actions and model calls displayed\r\n- **Accurate span counts**: Numbers match displayed spans\r\n- **Better debugging**: See exactly what actions executed and when\r\n- **Production monitoring**: Full observability for agent behavior analysis\r\n\r\n### Testing\r\n- **Comprehensive Testing**: 88+ total tests ensure complete coverage\r\n- **All tests passing**: 0 failures, 200+ assertions\r\n- **Integration tests**: Real database scenarios\r\n- **Performance tests**: Verify optimization improvements\r\n- **Security tests**: RLS isolation, unauthorized access prevention\r\n\r\n---\r\n\r\n## Database Migration\r\n\r\n### Automatic Migration System\r\n\r\nThe migration system automatically handles:\r\n\r\n1. **Table rename**: `server_agents` → `message_server_agents`\r\n2. **Column rename**: `server_id` → `message_server_id` in junction table\r\n3. **RLS automatic application**:\r\n   - Adds `server_id` column with `DEFAULT current_server_id()` to all tables\r\n   - Creates indexes for performance\r\n   - Applies isolation policies (both server-level and entity-level)\r\n   - Handles backfill for existing data\r\n\r\n**Developer experience:**\r\n- **Zero configuration required** - just update and restart\r\n- **No manual SQL scripts** - everything is automated\r\n- **Idempotent and safe** - can be run multiple times without issues\r\n\r\n---\r\n\r\n## RLS Architecture Details\r\n\r\n### Three-Layer Security Model\r\n\r\n**Layer 1: Server RLS (Multi-Tenant Isolation)**\r\n- Isolates data between different ElizaOS server instances\r\n- Uses `server_id` for isolation\r\n- Context set via `application_name` connection parameter\r\n\r\n**Layer 2: Entity RLS (User Privacy Isolation)**\r\n- Isolates data between different entities within a server\r\n- Uses `entityId`, `authorId`, or joins via `participants` table\r\n- Context set via `app.entity_id` transaction-local variable\r\n- Provides DM privacy and multi-user isolation\r\n\r\n**Layer 3: Application Layer**\r\n- Authorization checks (participant validation)\r\n- Business logic enforcement\r\n\r\n**All three layers stack** - a user can only see data from their server AND their accessible entities AND that they have permission to access.\r\n\r\n### Excluded Tables (with rationale)\r\n\r\n**Entity RLS Exclusions:**\r\n- `users` - Authentication table (no entity isolation needed)\r\n- `entity_mappings` - Cross-platform entity mapping\r\n- `drizzle_migrations`, `__drizzle_migrations` - Migration tracking\r\n- `agents` - Shared across entities\r\n- `owners` - RLS management table\r\n\r\nAll other tables receive RLS automatically based on their column structure.\r\n\r\n---\r\n\r\n## Configuration\r\n\r\n### Environment Variables\r\n\r\n```bash\r\n# Layer 1: Server RLS (Multi-tenant isolation)\r\nENABLE_RLS_ISOLATION=true                  # Enable Row Level Security\r\nRLS_OWNER_ID=my-server-uuid               # Server instance ID for multi-tenant isolation\r\n\r\n# Layer 2: Entity RLS (User privacy isolation)\r\nENABLE_DATA_ISOLATION=true                # Enable entity-level data isolation\r\n\r\n# Database\r\nPOSTGRES_URL=postgresql://user:password@localhost:5432/eliza\r\n```\r\n\r\n---\r\n\r\n## API Changes\r\n\r\n### Backward Compatibility\r\n\r\nAll API changes maintain backward compatibility:\r\n\r\n**Database Adapter Methods:**\r\n- ✅ New methods added: `isRoomParticipant()`, `isChannelParticipant()`\r\n- ✅ Existing methods unchanged\r\n- ✅ `serverId` field still populated (maps to `messageServerId`)\r\n\r\n**API Endpoints:**\r\n- ✅ All existing endpoints continue to work\r\n- ✅ Run detail endpoint now includes `action_event` logs\r\n- ✅ No breaking changes to request/response formats\r\n\r\n**TypeScript:**\r\n- ✅ `serverId` marked as deprecated (still works)\r\n- ✅ Migration path via TypeScript warnings\r\n- ✅ Type safety preserved\r\n\r\n---\r\n\r\n## Summary\r\n\r\nThis PR delivers a complete security, performance, and observability overhaul:\r\n\r\n- **Entity-Level RLS**: Automatic data isolation at the database level\r\n- **Semantic Clarity**: Clear naming eliminates confusion\r\n- **Performance Optimization**: O(1) participant checking\r\n- **Timeline Fix**: Complete action visibility in observability UI\r\n- **100% Backward Compatible**: Zero breaking changes\r\n- **Fully Tested**: 88+ tests, 0 failures\r\n- **Production Ready**: Auto-migration, fail-closed security\r\n\r\n**Impact:**\r\n- 🔒 **Stronger security** with three-layer isolation (Server RLS + Entity RLS + Authorization)\r\n- 📖 **Clearer code** with semantic naming\r\n- 🚀 **Better performance** with optimized queries\r\n- 👁️ **Complete observability** with action spans in timelines\r\n- 🛡️ **Database-enforced** security that can't be bypassed\r\n- 🔧 **Developer-friendly** zero-config automatic migrations\r\n\r\n**Testing:**\r\n- ✅ 77 RLS tests passing\r\n- ✅ 11 participant optimization tests passing\r\n- ✅ Timeline integration tests passing\r\n- ✅ All existing tests passing\r\n- ✅ 0 failures\r\n",
      "repository": "elizaos/eliza",
      "createdAt": "2025-11-22T01:44:49Z",
      "mergedAt": null,
      "additions": 6115,
      "deletions": 2143
    },
    {
      "id": "PR_kwDOMT5cIs6xzKBP",
      "title": "fix: align server tests with ElizaOS API changes",
      "author": "odilitime",
      "number": 6135,
      "body": "<!-- CURSOR_SUMMARY -->\n> [!NOTE]\n> Aligns server tests and routers with new ElizaOS interfaces, clarifies plugin auto-injection behavior, and deflakes/modernizes middleware, loader, socket, and utility tests.\n> \n> - **Server/API alignment**:\n>   - Update `agentExistsMiddleware`, Socket.IO router, Jobs and Agent Runs routers to use `ElizaOS` getters instead of agent maps.\n>   - Adjust message flow and log streaming tests to new event/filter semantics.\n> - **Plugin loading behavior**:\n>   - Clarify that server auto-injects `sql` plugin; bootstrap injection handled at character level; ensure deduping and order expectations.\n> - **Test refactors/deflakes**:\n>   - Replace heavy `mock.module` with spies and lightweight mocks; remove brittle fs mocks.\n>   - Skip flaky/integration suites causing interference (version, DB ops, message bus, agent runs, some jobs tests).\n> - **Utilities and middleware**:\n>   - Update tests for `authMiddleware`, validation, security headers, rate limits.\n>   - Adjust `sanitizeFilename` expectations and `resolvePgliteDir` behavior; strengthen path handling assertions.\n> - **Misc**:\n>   - Minor type/interface tweaks (e.g., runtime methods) and improved express server boot/teardown in tests.\n> \n> <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit a988400e95a3efe7e9366332d18e83a99429c2f2. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup>\n<!-- /CURSOR_SUMMARY -->\n\n<!-- This is an auto-generated comment: release notes by coderabbit.ai -->\n\n## Summary by CodeRabbit\n\n* **Bug Fixes**\n  * Improved plugin loading flexibility: server now recognizes both short and full bootstrap plugin identifiers during initialization.\n  * Enhanced SQL plugin auto-injection and plugin deduplication logic.\n\n* **Refactor**\n  * Removed internal loader APIs: `tryLoadFile` and `loadCharacterTryPath` functions are no longer available.\n  * Updated core routing infrastructure for improved agent management.\n  * Simplified test infrastructure by reducing mock dependencies and improving test reliability across environments.\n\n<!-- end of auto-generated comment: release notes by coderabbit.ai -->",
      "repository": "elizaos/eliza",
      "createdAt": "2025-11-06T04:07:48Z",
      "mergedAt": "2025-11-20T23:02:50Z",
      "additions": 4294,
      "deletions": 4383
    },
    {
      "id": "PR_kwDOMT5cIs60tivJ",
      "title": "feat: improve accepted formats for plugin names in plugin dependencies",
      "author": "odilitime",
      "number": 6164,
      "body": "<!-- CURSOR_SUMMARY -->\n> [!NOTE]\n> Adds name normalization and enhanced dependency resolution to handle both scoped package names and short names, with deduped queuing and comprehensive tests.\n> \n> - **Core (`packages/core/src/plugin.ts`)**\n>   - Add `normalizePluginName` to extract short names from scoped packages.\n>   - Enhance `resolvePluginDependencies` with a lookup map supporting both scoped (`@scope/plugin-x`) and short (`x`) names; use canonical names for cycle tracking and final ordering.\n>   - Add `queueDependency` and update `resolvePluginsImpl` to queue normalized dependencies and avoid duplicates.\n>   - Minor log message tweak in browser warning.\n> - **Tests (`packages/core/src/__tests__/plugin.test.ts`)**\n>   - Add tests for `normalizePluginName` and resolving dependencies using scoped, short, and mixed names, including testDependencies and complex chains.\n> \n> <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 5ea3546d4aa38128a1d5825ec8138012a7c72796. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup>\n<!-- /CURSOR_SUMMARY -->\n\n<!-- This is an auto-generated comment: release notes by coderabbit.ai -->\n\n## Summary by CodeRabbit\n\n* **New Features**\n  * Added `normalizePluginName()` utility to standardize plugin identifiers across scoped and non-scoped naming conventions.\n  * Added `resolvePluginDependencies()` function to resolve plugin dependencies with improved ordering and support for mixed naming conventions.\n\n* **Tests**\n  * Expanded test coverage for new plugin utilities, including scoped/non-scoped packages, complex dependency chains, and missing dependency handling.\n\n<sub>✏️ Tip: You can customize this high-level summary in your review settings.</sub>\n\n<!-- end of auto-generated comment: release notes by coderabbit.ai -->",
      "repository": "elizaos/eliza",
      "createdAt": "2025-11-20T23:01:34Z",
      "mergedAt": "2025-11-21T03:35:46Z",
      "additions": 614,
      "deletions": 73
    },
    {
      "id": "PR_kwDOMT5cIs60u0ti",
      "title": "fix(server): update MessageBusService integration tests",
      "author": "standujar",
      "number": 6165,
      "body": "# Relates to\r\n\r\nUpdates to MessageBusService integration tests following architecture changes\r\n\r\n# Risks\r\n\r\nLow - Test-only changes, no production code modified\r\n\r\n# Background\r\n\r\n## What does this PR do?\r\n\r\nUpdates MessageBusService integration tests to align with the current architecture:\r\n- Removes checks for `MESSAGE_RECEIVED` event (no longer emitted)\r\n- Updates tests to verify message validation flow passes before downstream processing\r\n- Removes redundant Metadata Propagation tests (covered by Message Handling tests)\r\n\r\n## What kind of change is this?\r\n\r\nBug fixes (non-breaking change which fixes an issue)\r\n\r\n# Documentation changes needed?\r\n\r\nMy changes do not require a change to the project documentation.\r\n\r\n# Testing\r\n\r\n## Where should a reviewer start?\r\n\r\n`packages/server/src/__tests__/integration/message-bus-service.test.ts`\r\n\r\n## Detailed testing steps\r\n\r\n```bash\r\ncd packages/server\r\nbun test src/__tests__/integration/message-bus-service.test.ts\r\n```\r\n\r\nExpected: 12 pass, 0 fail\r\n",
      "repository": "elizaos/eliza",
      "createdAt": "2025-11-21T01:53:34Z",
      "mergedAt": "2025-11-21T12:12:30Z",
      "additions": 303,
      "deletions": 529
    },
    {
      "id": "PR_kwDOMT5cIs6zfDfx",
      "title": "fix: migrate from LangChain v0.3 to @langchain/textsplitters v1.0",
      "author": "0xbbjoker",
      "number": 6152,
      "body": "- Replace langchain dependency with @langchain/textsplitters in @elizaos/core\r\n- Update import from 'langchain/text_splitter' to '@langchain/textsplitters'\r\n- Remove outdated langchain resolutions from plugin starter packages\r\n- Add comprehensive test coverage for splitChunks functionality\r\n- All 89 tests passing with new LangChain v1 integration\r\n\r\nThis addresses the deprecation of LangChain v0.3 by migrating to the\r\nmodular @langchain/textsplitters package which is part of the LangChain v1\r\necosystem. The migration maintains full backward compatibility while\r\nreducing bundle size and future-proofing the codebase.\r\n\r\nFixes #6145\r\n\r\nhttps://github.com/elizaOS/eliza/issues/6145#event-20943795877\n\n<!-- CURSOR_SUMMARY -->\n---\n\n> [!NOTE]\n> Migrates core from langchain/text_splitter to @langchain/textsplitters v1, updates deps, removes plugin langchain resolutions, and expands splitChunks tests.\n> \n> - **Core (@elizaos/core)**\n>   - **Dependencies**: Add `@langchain/textsplitters@^1.0.0`; remove `langchain`.\n>   - **Code**: Switch import in `src/utils.ts` to `@langchain/textsplitters` and use `RecursiveCharacterTextSplitter` in `splitChunks`.\n>   - **Tests**: Expand `splitChunks` coverage in `src/__tests__/utils.test.ts` (empty input, overlap behavior, large chunk sizes, v1 splitter validation).\n> - **Plugins**\n>   - **Starter templates**: Remove `langchain`-related `resolutions/overrides`; retain `zod` resolution only in `packages/plugin-quick-starter` and `packages/plugin-starter`.\n> \n> <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit fa89f69859ea02c64bbab119021ab889174a52d5. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup>\n<!-- /CURSOR_SUMMARY -->",
      "repository": "elizaos/eliza",
      "createdAt": "2025-11-14T15:47:47Z",
      "mergedAt": "2025-11-17T18:18:23Z",
      "additions": 160,
      "deletions": 94
    }
  ],
  "codeChanges": {
    "additions": 4569,
    "deletions": 5140,
    "files": 73,
    "commitCount": 112
  },
  "completedItems": [
    {
      "title": "docs: fix old links to actual",
      "prNumber": 6050,
      "type": "bugfix",
      "body": "<!-- Use this template by filling in information and copying and pasting relevant items out of the HTML comments. -->\r\n\r\n<!-- This risks section must be filled out before the final review and merge. -->\r\n\r\n# Risks\r\n\r\nLow\r\n\r\n## What does thi",
      "files": [
        "packages/cli/README.md"
      ]
    },
    {
      "title": "fix: align server tests with ElizaOS API changes",
      "prNumber": 6135,
      "type": "bugfix",
      "body": "<!-- CURSOR_SUMMARY -->\n> [!NOTE]\n> Aligns server tests and routers with new ElizaOS interfaces, clarifies plugin auto-injection behavior, and deflakes/modernizes middleware, loader, socket, and utility tests.\n> \n> - **Server/API alignment*",
      "files": [
        "bun.lock",
        "packages/server/src/__tests__/agent-plugin-reload.test.ts",
        "packages/server/src/__tests__/agent-server-database.test.ts",
        "packages/server/src/__tests__/agent-server-errors.test.ts",
        "packages/server/src/__tests__/agent-server-initialization.test.ts",
        "packages/server/src/__tests__/agent-server-management.test.ts",
        "packages/server/src/__tests__/agent-server-middleware.test.ts",
        "packages/server/src/__tests__/agents-runs.test.ts",
        "packages/server/src/__tests__/api.test.ts",
        "packages/server/src/__tests__/authMiddleware.test.ts",
        "packages/server/src/__tests__/basic-functionality.test.ts",
        "packages/server/src/__tests__/bootstrap-autoload.test.ts",
        "packages/server/src/__tests__/file-utils.test.ts",
        "packages/server/src/__tests__/integration/database-operations.test.ts",
        "packages/server/src/__tests__/integration/jobs-message-flow.test.ts",
        "packages/server/src/__tests__/loader.test.ts",
        "packages/server/src/__tests__/message-bus.test.ts",
        "packages/server/src/__tests__/middleware.test.ts",
        "packages/server/src/__tests__/simple-validation.test.ts",
        "packages/server/src/__tests__/socketio-router.test.ts",
        "packages/server/src/__tests__/ui-disable-feature.test.ts",
        "packages/server/src/__tests__/utils.test.ts",
        "packages/server/src/__tests__/validation.test.ts",
        "packages/server/src/api/system/__tests__/version.test.ts",
        ".github/workflows/core-package-tests.yaml",
        "package.json",
        "packages/core/src/__tests__/secrets.test.ts",
        "packages/core/src/__tests__/settings.test.ts",
        "packages/core/src/elizaos.ts",
        "packages/core/src/secrets.ts",
        "packages/server/README.md",
        "packages/server/package.json",
        "packages/server/scripts/run-integration-tests.sh",
        "packages/server/src/__tests__/EventEmitter-Compatibility-README.md",
        "packages/server/src/__tests__/README.md",
        "packages/server/src/__tests__/agent-server-lifecycle.test.ts",
        "packages/server/src/__tests__/builders/channel.builder.ts",
        "packages/server/src/__tests__/builders/character.builder.ts",
        "packages/server/src/__tests__/builders/message.builder.ts",
        "packages/server/src/__tests__/compatibility/cli-compatibility.test.ts",
        "packages/server/src/__tests__/compatibility/cli-patterns.test.ts",
        "packages/server/src/__tests__/features/bootstrap-autoload.test.ts",
        "packages/server/src/__tests__/features/character-file-size-regression.test.ts",
        "packages/server/src/__tests__/features/server-core.test.ts",
        "packages/server/src/__tests__/features/socketio-router.test.ts",
        "packages/server/src/__tests__/features/ui-toggle.test.ts",
        "packages/server/src/__tests__/fixtures/agent.fixture.ts",
        "packages/server/src/__tests__/fixtures/database.fixture.ts",
        "packages/server/src/__tests__/fixtures/server.fixture.ts",
        "packages/server/src/__tests__/helpers/networking.ts",
        "packages/server/src/__tests__/helpers/retry.ts",
        "packages/server/src/__tests__/helpers/wait.ts",
        "packages/server/src/__tests__/index.ts",
        "packages/server/src/__tests__/integration/agent-server-interaction.test.ts",
        "packages/server/src/__tests__/integration/message-bus-service.test.ts",
        "packages/server/src/__tests__/integration/socketio-message-flow.test.ts",
        "packages/server/src/__tests__/run-working-tests.sh",
        "packages/server/src/__tests__/security/rls-server.test.ts",
        "packages/server/src/__tests__/spa-routing-fix.test.ts"
      ]
    },
    {
      "title": "fix: Add openrouter embedding option in CLI",
      "prNumber": 6142,
      "type": "bugfix",
      "body": "# Relates to\r\n\r\nImproves OpenRouter integration in ElizaOS CLI by adding native embedding support, eliminating the need for users to configure a separate embedding provider when using OpenRouter.\r\n\r\n# Risks\r\n\r\n**Low Risk** - Well-contained ",
      "files": [
        "packages/cli/src/commands/create/actions/setup.ts",
        "packages/cli/src/commands/create/utils/selection.ts",
        "packages/cli/src/utils/get-config.ts",
        "packages/cli/tests/unit/utils/selection.test.ts"
      ]
    },
    {
      "title": "fix: migrate from LangChain v0.3 to @langchain/textsplitters v1.0",
      "prNumber": 6152,
      "type": "bugfix",
      "body": "- Replace langchain dependency with @langchain/textsplitters in @elizaos/core\r\n- Update import from 'langchain/text_splitter' to '@langchain/textsplitters'\r\n- Remove outdated langchain resolutions from plugin starter packages\r\n- Add compreh",
      "files": [
        "bun.lock",
        "packages/core/package.json",
        "packages/core/src/__tests__/utils.test.ts",
        "packages/core/src/utils.ts",
        "packages/plugin-quick-starter/package.json",
        "packages/plugin-starter/package.json"
      ]
    },
    {
      "title": "feat: improve accepted formats for plugin names in plugin dependencies",
      "prNumber": 6164,
      "type": "feature",
      "body": "<!-- CURSOR_SUMMARY -->\n> [!NOTE]\n> Adds name normalization and enhanced dependency resolution to handle both scoped package names and short names, with deduped queuing and comprehensive tests.\n> \n> - **Core (`packages/core/src/plugin.ts`)*",
      "files": [
        "packages/core/src/__tests__/plugin.test.ts",
        "packages/core/src/plugin.ts",
        "packages/cli/tests/commands/plugins.test.ts",
        "packages/core/src/runtime.ts"
      ]
    },
    {
      "title": "fix(server): update MessageBusService integration tests",
      "prNumber": 6165,
      "type": "bugfix",
      "body": "# Relates to\r\n\r\nUpdates to MessageBusService integration tests following architecture changes\r\n\r\n# Risks\r\n\r\nLow - Test-only changes, no production code modified\r\n\r\n# Background\r\n\r\n## What does this PR do?\r\n\r\nUpdates MessageBusService integr",
      "files": [
        "bun.lock",
        "packages/server/package.json",
        "packages/server/scripts/run-integration-tests.sh",
        "packages/server/src/__tests__/integration/database-operations.test.ts",
        "packages/server/src/__tests__/integration/message-bus-service.test.ts"
      ]
    }
  ],
  "topContributors": [
    {
      "username": "standujar",
      "avatarUrl": "https://avatars.githubusercontent.com/u/16385918?u=718bdcd1585be8447bdfffb8c11ce249baa7532d&v=4",
      "totalScore": 99.15835800199321,
      "prScore": 83.38035800199322,
      "issueScore": 0,
      "reviewScore": 15,
      "commentScore": 0.7779999999999999,
      "summary": null
    },
    {
      "username": "0xbbjoker",
      "avatarUrl": "https://avatars.githubusercontent.com/u/54844437?u=90fe1762420de6ad493a1c1582f1f70c0d87d8e2&v=4",
      "totalScore": 87.5518788239393,
      "prScore": 67.8518788239393,
      "issueScore": 0,
      "reviewScore": 19.5,
      "commentScore": 0.2,
      "summary": null
    },
    {
      "username": "odilitime",
      "avatarUrl": "https://avatars.githubusercontent.com/u/16395496?u=c9bac48e632aae594a0d85aaf9e9c9c69b674d8b&v=4",
      "totalScore": 50.71550658181175,
      "prScore": 40.815506581811746,
      "issueScore": 0,
      "reviewScore": 9.5,
      "commentScore": 0.4,
      "summary": null
    },
    {
      "username": "LinuxIsCool",
      "avatarUrl": "https://avatars.githubusercontent.com/u/31582215?u=b8eb5d3849bf877a3a0b686cf1632aca92e744ae&v=4",
      "totalScore": 23.88213122712422,
      "prScore": 23.68213122712422,
      "issueScore": 0,
      "reviewScore": 0,
      "commentScore": 0.2,
      "summary": null
    },
    {
      "username": "borisudovicic",
      "avatarUrl": "https://avatars.githubusercontent.com/u/31806472?u=8935f4d43fd7e4eb9bf5ff92d54d4d2f8ac8a786&v=4",
      "totalScore": 8,
      "prScore": 0,
      "issueScore": 8,
      "reviewScore": 0,
      "commentScore": 0,
      "summary": null
    },
    {
      "username": "skurzyp",
      "avatarUrl": "https://avatars.githubusercontent.com/u/98319381?v=4",
      "totalScore": 5,
      "prScore": 0,
      "issueScore": 0,
      "reviewScore": 5,
      "commentScore": 0,
      "summary": null
    },
    {
      "username": "devbrett90-prog",
      "avatarUrl": "https://avatars.githubusercontent.com/u/241853504?v=4",
      "totalScore": 4.5,
      "prScore": 0,
      "issueScore": 0,
      "reviewScore": 4.5,
      "commentScore": 0,
      "summary": null
    },
    {
      "username": "TommyVeit",
      "avatarUrl": "https://avatars.githubusercontent.com/u/244845549?v=4",
      "totalScore": 2,
      "prScore": 0,
      "issueScore": 2,
      "reviewScore": 0,
      "commentScore": 0,
      "summary": null
    },
    {
      "username": "870171594",
      "avatarUrl": "https://avatars.githubusercontent.com/u/216127669?u=d4669261a63be8c0bcb69c4e497ed51ecc07776e&v=4",
      "totalScore": 2,
      "prScore": 0,
      "issueScore": 2,
      "reviewScore": 0,
      "commentScore": 0,
      "summary": null
    },
    {
      "username": "nguyennk92",
      "avatarUrl": "https://avatars.githubusercontent.com/u/30664183?u=d6e579cd25d50bc8e9ec4928d95909d759b841db&v=4",
      "totalScore": 0.4,
      "prScore": 0,
      "issueScore": 0,
      "reviewScore": 0,
      "commentScore": 0.4,
      "summary": null
    },
    {
      "username": "otaku-x402",
      "avatarUrl": "https://avatars.githubusercontent.com/u/242004857?u=1325b26d380eec4a0b8d84e8e249c523eebd28dc&v=4",
      "totalScore": 0.2,
      "prScore": 0,
      "issueScore": 0,
      "reviewScore": 0,
      "commentScore": 0.2,
      "summary": null
    },
    {
      "username": "letmehateu",
      "avatarUrl": "https://avatars.githubusercontent.com/u/133153661?u=2217cec1ebd7bf22a8e4e3ace28b3183720dd444&v=4",
      "totalScore": 0.2,
      "prScore": 0,
      "issueScore": 0,
      "reviewScore": 0,
      "commentScore": 0.2,
      "summary": null
    }
  ],
  "newPRs": 6,
  "mergedPRs": 6,
  "newIssues": 6,
  "closedIssues": 5,
  "activeContributors": 15
}