# ElizaOS Developer Update - July 27, 2025

## Core Framework

This week marked a significant milestone for the ElizaOS architecture with the completion of the migration from JSON-based prompts to an XML format across the codebase. This refactoring greatly enhances the reliability of LLM responses and affects core entities and the bootstrap plugin ([#5623](https://github.com/elizaos/eliza/pull/5623)). 

The runtime architecture saw two major improvements:

1. **EventTarget Migration**: We've replaced Node.js's `EventEmitter` with Bun's native `EventTarget` API ([#5609](https://github.com/elizaos/eliza/pull/5609)), improving performance and runtime compatibility. Full backward compatibility is maintained with comprehensive tests verifying EventEmitter-compatible behavior.

2. **Service Types System**: A new standardized interface for services has been implemented ([#5565](https://github.com/elizaos/eliza/pull/5565)), allowing for multiple services per type and the new `getServicesByType()` method. This creates a more modular architecture where agents can dynamically discover and leverage available services by capability.

The plugin system benefited from a new backend-only `plugin-quick-starter` template ([#5589](https://github.com/elizaos/eliza/pull/5589)) that enables more streamlined development of plugins without frontend overhead.

## New Features

### Action Chaining

Action chaining ([#5436](https://github.com/elizaos/eliza/pull/5436)) is now available, enabling agents to plan and execute multiple actions in sequence:

```javascript
// Define a chain of actions
const actionChain = [
  { 
    name: "fetchData", 
    params: { source: "api", endpoint: "/users" }
  },
  { 
    name: "processData", 
    // Will use result from previous action
  },
  { 
    name: "respondToUser"
  }
];

// Action state is stored and passed through the chain
async function fetchDataAction(state) {
  // Previous actions' results available in state.actionState
  const data = await fetchFromAPI(state.params.endpoint);
  
  // Store result for next action
  return {
    result: data,
    // Optional message to user during processing
    callback: "Fetching your data..."
  };
}
```

State is preserved between actions, allowing each step to build upon the results of previous actions. This enables complex workflows like data retrieval, processing, and response generation to be executed in sequence.

### Image Generation

A new `generateImageAction` has been added to the agent pipeline ([#5446](https://github.com/elizaos/eliza/pull/5446)), enabling agents to generate images based on conversational context using `ModelType.IMAGE`.

### Auto-Resizing Chat Input

The ChatInput component now features auto-resizing functionality that dynamically adjusts based on content length ([#5546](https://github.com/elizaos/eliza/pull/5546)):

```jsx
function resizeTextarea(textarea) {
  if (!textarea) return;
  
  textarea.style.height = "auto";
  textarea.style.height = `${Math.min(textarea.scrollHeight, MAX_HEIGHT)}px`;
}

// Used in ChatInput component
const textareaRef = useRef(null);

useEffect(() => {
  if (textareaRef.current) {
    resizeTextarea(textareaRef.current);
  }
}, [value]);
```

## Bug Fixes

We've resolved several critical bugs this week:

1. **EventTarget Migration Stability**: Fixed method chaining and enhanced type safety in the EventTarget migration to ensure a smooth transition from EventEmitter ([#5612](https://github.com/elizaos/eliza/pull/5612), [#5611](https://github.com/elizaos/eliza/pull/5611)).

2. **Plugin Actions Loading**: Fixed a critical issue where plugin actions were not being received by the runtime when using the NPM deployed version of the ElizaOS CLI ([#5624](https://github.com/elizaos/eliza/pull/5624)). This issue only affected the published NPM package and was resolved by importing `*/dist/index.js` to ensure the compiled files were correctly loaded.

3. **JSON String Handling in SQL Base**: Fixed a bug in the SQL plugin where raw objects were incorrectly passed to PostgreSQL's JSONB type, causing insert failures ([#5628](https://github.com/elizaos/eliza/pull/5628)). The fix ensures proper stringification of content and metadata before database operations.

4. **Nested Project Database Isolation**: Fixed an issue where creating a new ElizaOS project within an existing project directory caused the child to incorrectly inherit the parent's `PGLITE_DATA_DIR` environment variable ([#5618](https://github.com/elizaos/eliza/pull/5618)).

## API Changes

The primary API change this week is the introduction of service types and the `getServicesByType()` method ([#5565](https://github.com/elizaos/eliza/pull/5565)). This method allows plugins to discover and use services based on their capabilities rather than specific implementations:

```javascript
// Before: Had to know exact service name
const webSearchService = runtime.services.googleSearch;

// After: Get any available web search service
const webSearchServices = runtime.getServicesByType('webSearch');
const webSearchService = webSearchServices[0]; // Use first available
```

New standardized service interfaces include:
- WebSearchService
- BrowserService
- EmailService
- PDFService
- TranscriptionService
- VideoService
- MessageService
- PostService

Plugins should adopt these interfaces for better interoperability across the ecosystem.

## Social Media Integrations

The Twitter plugin has received significant attention this week:

1. **Default Character Enhancement**: The default Eliza character now includes Twitter posting examples ([#5652](https://github.com/elizaos/eliza/pull/5652)), enabling Twitter functionality out of the box:

```javascript
// Example Twitter posting functionality now included in default character
const twitterAction = {
  name: 'postToTwitter',
  description: 'Post a message to Twitter/X',
  parameters: {
    message: {
      type: 'string',
      description: 'The message to post'
    }
  }
};
```

2. **X Platform Ban Resolution**: During Discord discussions this week, the team revealed they are working toward resolving the suspension of ElizaOS-related accounts from X/Twitter. Kenk mentioned they have "a resolution with X in sight" and that communication between ElizaOS and X teams has reportedly become quicker.

## Model Provider Updates

A significant architecture change has been proposed to consolidate AI model providers into a single `plugin-inference` that would support multiple API-compatible services like OpenAI, Anthropic, Google, and Groq. Discord discussions showed a preference for dynamic plugin loading/unloading as the most scalable approach for switching between providers, leveraging the existing ai-sdk for standardization.

Other model provider updates:

1. **Plugin Prompts Migration**: All JSON-based prompts in the bootstrap plugin have been migrated to XML format ([#5623](https://github.com/elizaos/eliza/pull/5623)) for improved LLM reliability.

2. **Ollama Integration**: The Ollama plugin is now conditionally included based on the `OLLAMA_API_ENDPOINT` environment variable ([#5594](https://github.com/elizaos/eliza/pull/5594)) rather than being a universal fallback.

3. **Improved Provider Selection**: The LLM provider selection prompt has been refined to reduce unnecessary provider use and improve reply speed ([#5526](https://github.com/elizaos/eliza/pull/5526)).

## Breaking Changes

### V1 to V2 Migration

To support backward compatibility, we've added automatic V1 to V2 character conversion during JSON import ([#5536](https://github.com/elizaos/eliza/pull/5536)). This ensures older character files work seamlessly with the new version:

```javascript
// Example of the conversion process
function convertV1ToV2(character) {
  if (!isV1Character(character)) return character;
  
  return {
    name: character.name,
    description: character.description || '',
    systemPrompt: character.systemPrompt,
    plugins: mapLegacyProvidersToPlugins(character.providers),
    settings: {
      avatar: character.avatar || '',
      model: mapLegacyModelToV2Model(character.model),
      temperature: character.temperature || 0.7
    }
  };
}
```

Notable changes in the conversion include:
- `providers` array is mapped to the new `plugins` array with modern plugin names
- Provider-specific settings are properly restructured under the `settings` object
- Legacy models are mapped to their V2 equivalents

This automatic conversion ensures a smooth transition for users migrating from V1 to V2 of the platform.