# ElizaOS Developer Update
## Week of November 24, 2025

### 1. Core Framework

#### Entity-Level Row-Level Security
We've implemented comprehensive PostgreSQL Row-Level Security (RLS) to provide robust data isolation at the entity level. This system automatically filters data based on the current entity context, creating a three-layer security model:

- **Server RLS**: Isolates data between different ElizaOS server instances
- **Entity RLS**: Isolates data between different entities within a server
- **Application Authorization**: Business logic enforcement and permissions

The system automatically detects which isolation strategy to use based on table schema:

```sql
-- Direct Entity Ownership
CREATE POLICY entity_isolation_policy ON memories
  USING (entityId = current_entity_id());

-- Room-Based Shared Access
CREATE POLICY participant_isolation_policy ON messages
  USING (roomId IN (
    SELECT roomId FROM participants 
    WHERE entityId = current_entity_id()
  ));
```

#### Runtime Enhancements
We've added an ElizaOS reference directly to the runtime, streamlining framework interactions and enabling the upcoming unified messaging API:

```typescript
// Now available in runtime:
if (runtime.hasElizaOS()) {
  const elizaOS = runtime.getElizaOS();
  // Access unified API methods
}
```

#### Improved Plugin Loading
Plugin dependency resolution now handles both scoped package names and short names, with deduped queuing:

```typescript
// Both forms now work:
dependencies: [
  "@elizaos/plugin-sql",  // Full scoped name
  "sql"                   // Short name
]
```

### 2. New Features

#### Skip Migrations Option
Added a new option to `runtime.initialize()` to conditionally skip plugin migrations, useful for serverless environments where migrations are handled separately:

```typescript
// Skip migrations for faster startup
await runtime.initialize({
  skipMigrations: true
});
```

#### Performance Optimization: Participant Checking
Improved participant checking with direct database existence checks, reducing complexity from O(n) to O(1):

```typescript
// OLD: O(n) - Load all participants into memory
async isParticipant(entityId: UUID, roomId: UUID): Promise<boolean> {
  const participants = await this.getParticipantsForRoom(roomId);
  return participants.some(p => p === entityId);
}

// NEW: O(1) - Direct database existence check
async isRoomParticipant(entityId: UUID, roomId: UUID): Promise<boolean> {
  return this.withEntityContext(null, async (tx) => {
    const result = await tx
      .select({ exists: sql<number>`1` })
      .from(participantTable)
      .where(
        and(
          eq(participantTable.roomId, roomId),
          eq(participantTable.entityId, entityId)
        )
      )
      .limit(1);
    return result.length > 0;
  });
}
```

#### x402 Payment Protection
Implemented comprehensive payment middleware for plugin routes supporting both EVM and Solana chains:

```typescript
// Define a payment-protected route
export const getWeatherRoute: PaymentEnabledRoute = {
  method: 'get',
  path: '/weather/:city',
  handler: async (req, res) => {
    // Protected endpoint logic
  },
  x402: {
    chainId: 'eip155:8453',  // Base chain
    tokenAddress: '0xd9aAEc86B65D86f6A7B5B1b0c42FFA531710b6CA', // Base USDC
    amount: '0.01',  // $0.01 per request
  }
};
```

### 3. Bug Fixes

#### Timeline Action Spans Fix
Fixed an issue where the Timeline tab wasn't showing individual action details. The root cause was that `action_event` logs (which contain action start events) weren't properly linked to the main run:

```typescript
// Modified filter logic in runs.ts:
// Step 1: Find directly related logs
const directlyRelated = logs.filter((l) => {
  const body = l.body as { runId?: UUID; parentRunId?: UUID };
  return body.runId === runId || body.parentRunId === runId;
});

// Step 2: Extract action runIds from matched action completion logs
const actionRunIds = new Set(
  directlyRelated
    .filter((l) => l.type === 'action')
    .map((l) => (l.body as { runId?: UUID }).runId)
    .filter((id): id is UUID => !!id)
);

// Step 3: Include action_event logs that share runId with matched actions
const related = logs.filter((l) => {
  const body = l.body as { runId?: UUID; parentRunId?: UUID };
  // Include action_event logs matching action runIds
  if (l.type === 'action_event' && body.runId && actionRunIds.has(body.runId)) {
    return true;
  }
  return body.runId === runId || body.parentRunId === runId;
});
```

#### Agent Settings Persistence
Fixed a critical bug where agent settings weren't persisting across restarts, causing runtime-generated configurations to be lost. This change enhances the core runtime initialization logic for agent settings merge.

#### Environment Variable Loading
Fixed an issue where `runtime.getSetting("ANY_VARIABLE")` returned `undefined` when environment variables were exported on the host instead of being defined in a `.env` file. The system now correctly loads variables from `process.env`.

#### RLS Validation
Fixed a bug where RLS server_id validation checks were incorrectly blocking all users when RLS isolation was disabled. The fix implements proper conditional checks to ensure the system works correctly regardless of RLS settings.

#### Entity Array Serialization
Fixed entity creation failures by normalizing the names field to ensure it's always a proper array before database operations. This handles Set objects by converting them with Array.from().

### 4. API Changes

#### Semantic Clarity: `serverId` vs `messageServerId`
Renamed message-related `serverId` to `messageServerId` for clarity:

```typescript
// OLD: Ambiguous - which server type?
const room = await adapter.getRoom({ serverId, roomId });

// NEW: Crystal clear - external messaging platform
const room = await adapter.getRoom({ messageServerId, roomId });
```

Backward compatibility is maintained:
- `serverId` field is still populated (maps to `messageServerId`)
- TypeScript marks `serverId` as deprecated with warnings
- All existing endpoints continue to work

#### New Database Adapter Methods
Added efficient participant checking methods:
- `isRoomParticipant(entityId, roomId)`
- `isChannelParticipant(entityId, channelId)`

### 5. Social Media Integrations

#### Discord Plugin Updates
The Discord plugin is being updated to support EVM chains for verification purposes, as mentioned by Odilitime in the partners channel. The changes include:

- Support for the `/verify` command across EVM chains
- Integration with the new unified messaging API
- Prevention of empty Discord messages to avoid API errors

#### Farcaster Integration
Work is underway to add Farcaster and Base app support, as noted in issue #6161. This will expand ElizaOS's reach to the Farcaster ecosystem.

### 6. Model Provider Updates

#### Anthropic Updates
Fixed an issue with Anthropic's Sonnet 4.0 model not properly closing XML tags, possibly related to max token settings. A fix was submitted in PR #6166 to add topP support for Anthropic models.

#### OpenRouter Integration
Improved OpenRouter integration in ElizaOS CLI by adding native embedding support, eliminating the need for users to configure a separate embedding provider when using OpenRouter.

### 7. Breaking Changes

#### LangChain Migration
Completed the migration from LangChain v0.3 to @langchain/textsplitters v1.0:
- Replaced langchain dependency with @langchain/textsplitters in @elizaos/core
- Updated import from 'langchain/text_splitter' to '@langchain/textsplitters'
- Removed outdated langchain resolutions from plugin starter packages

This change resolves issue #6145, which identified the deprecated LangChain version as a technical debt concern.

#### Token Migration
Users have reported issues with AI16Z → ElizaOS token migration, particularly with the "max amount reached" error. Important points to note:
- Tokens purchased after November 11, 11:40 UTC cannot be migrated
- Users on exchanges should wait for their exchange to make an announcement
- The migration period runs for 90 days (until February)
- The team will assist with manual migrations if exchanges fail to implement automatic migration

---

For more details, please refer to the relevant PR links provided throughout this update. If you're building on ElizaOS and have any questions, please reach out in the #core-devs channel on Discord.