AI Chat App Tutorial

Build a complete, AI-powered chat assistant on the Fiberwise platform. Go from zero to a deployed app in under 15 minutes.

โฑ๏ธ 15 minutes ๐Ÿ“š Beginner ๐Ÿค– AI App

๐Ÿค– What You'll Build

A production-ready, intelligent chat application that uses Fiberwise agent activations for storing conversations. Think of it as your own personal ChatGPT, powered by the Fiberwise platform.

  • Interactive Chat UI: A clean, modern interface for real-time conversations.
  • Intelligent AI Agent: Powered by a flexible assistant agent you can customize.
  • Conversation History: Automatically saves and retrieves chat sessions.
  • One-Click Deploy: Ready to be deployed live on the Fiberwise platform.

๐Ÿ“‹ Prerequisites: Your Setup Checklist

Before you begin, you need a fully configured Fiberwise environment. This is the foundation for building any app on the platform.

๐Ÿ”ง Required Setup

โœ… All Set?

Once all boxes are checked, you are ready to start building the chat app. If not, please complete the linked guides first.

Step 1: Get the Code

The Fiberwise platform includes example apps in the local fiber-apps/ directory. Navigate to the activation chat example project to explore its structure.

1
Navigate to Example Apps
# Navigate to the fiber-apps directory (included with Fiberwise)
cd fiber-apps/activation-chat
2
Explore the Project Structure
# List the files to see the app structure
ls -la
3
Open in Your Code Editor

Open the current directory (`activation-chat`) in an editor like VS Code to explore the files.

code .

Step 2: Understanding the App's Blueprint

Before installing, let's look at the key concepts that define the application. This will help you understand what happens in the next step.

The Manifest: `app_manifest.yaml`

This is the most important file. It's the blueprint that tells Fiberwise what resources your app needs. It defines the app itself, the data models it uses, and the AI agent that powers the chat.

๐Ÿ’ก Key Concept: The Manifest

The manifest is a declarative file that defines all the backend resources for your app. When you run `fiber app install`, the CLI reads this file and automatically provisions everything your app needs on the platform.

Project Structure

The app is built from several modern web components that handle different parts of the UI. This separation makes the code clean and easy to maintain.

activation-chat/
โ”œโ”€โ”€ ๐Ÿ“„ app_manifest.yaml           # โ† The app's blueprint
โ”œโ”€โ”€ ๐ŸŽฏ index.js                    # Main entry point, initializes the app
โ”œโ”€โ”€ ๐Ÿ’ฌ chat-app.js                 # The main component that orchestrates everything
โ”œโ”€โ”€ ๐Ÿ’ญ chat-messages.js            # Displays the list of messages for a session
โ””โ”€โ”€ ... (other UI components & styles)

๐Ÿ—๏ธ App Architecture Flow

Here's the high-level architecture of how Fiberwise applications initialize and prepare for user interaction:

graph TD A[๐Ÿ‘ค User Opens App] --> B[๐Ÿ”ง Initialize FIBER SDK] B --> C[๐ŸŒ Connect to API] C --> D[๐Ÿ“Š Load App Metadata] D --> E[๐Ÿ”Œ Initialize Providers] E --> F[๐Ÿ’พ Setup Component State] F --> G[๐ŸŽจ Render Chat Interface] G --> H[โœ… Ready for User Input] classDef user fill:#e3f2fd classDef system fill:#e8f5e8 classDef ready fill:#e8f5e8 class A user class B,C,D,E,F,G system class H ready

Step 3: Install and Run the App

Now it's time to bring the application to life. This two-step process installs the frontend dependencies and then installs the app onto the Fiberwise platform.

1
Install Frontend Dependencies

This command reads `package.json` and installs the necessary Node.js packages for the frontend UI.

npm install
2
Install the App to Fiberwise

This command uses the Fiberwise CLI to read your `app_manifest.yaml` and create all the necessary resources (the app, the agent, the data model) on your instance.

fiber app install ./

โœ… Expected Output

Installing app: Activation Chat
App installed successfully!
App ID: activation-chat
Status: Active โœ“

๏ฟฝ Technical App Loading Flow

Now let's see the detailed technical flow when you open your app in the browser:

graph TD A[๐ŸŒ Browser: GET /activation-chat] --> B[๐Ÿ–ฅ๏ธ Fiberwise Server] B --> C[๐Ÿ“„ Serves HTML/JS Files] C --> D[๐Ÿ”ง index.js Loads] D --> E[โšก FIBER SDK Initialize] E --> F[๐Ÿ’ฌ chat-app.js Renders] F --> G[๐ŸŒ FIBER.listAgents API Call] G --> H[๐Ÿ“‹ Agents Response: chatAgent] H --> I[๐Ÿ”Œ Load Available Providers] I --> J[๐Ÿ“ฑ Empty Chat UI Ready] classDef browser fill:#e3f2fd classDef server fill:#f3e5f5 classDef system fill:#e8f5e8 classDef ui fill:#fff3e0 class A browser class B,C server class D,E,F,G,H,I system class J ui

๐Ÿ” Key Files in Action

  • index.js - Entry point that initializes FIBER SDK and renders the main component
  • chat-app.js - Main component that calls FIBER.listAgents() and sets up UI state
  • app_manifest.yaml - Defines the "chatAgent" that gets loaded from the API

๏ฟฝ๐Ÿ”Œ Provider Selection Flow

Before sending messages, users select their LLM provider. Here's how provider metadata works:

graph TD A[๐Ÿ‘ค User Selects Provider] --> B[๐Ÿ’ฌ chat-app.js] B --> C[๐Ÿ”ง FIBER.listProviders] C --> D[๐ŸŒ GET /llm-providers] D --> E[๐Ÿ“‹ Provider List Response] E --> F[๐Ÿ’พ Store provider_id] F --> G[โœ… Ready to Send Messages] classDef user fill:#e3f2fd classDef component fill:#f3e5f5 classDef system fill:#e8f5e8 classDef ready fill:#e8f5e8 class A user class B,F component class C,D,E system class G ready

Step 4: Send Your First Message

Your chat app is now live on your Fiberwise instance. Let's send a message to see it in action and understand exactly what happens behind the scenes.

1. Open Your App

Navigate to your app in a browser. By default, the URL will be:

http://localhost:8000/activation-chat

You'll see the clean chat interface with an empty message area and an input box at the bottom.

2. Start a Conversation

Type a message like "Hello, who are you?" into the input box and press Enter.

๏ฟฝ Message Sending Flow

When you type and send a message, here's the complete flow with provider metadata:

graph TD A[๐Ÿ‘ค Types & Sends] --> B[๏ฟฝ chat-app.js] B --> C[๐Ÿ”ง FIBER.agents.activate] C --> D[๐ŸŒ POST /activations] D --> E[๐Ÿค– chatAgent] E --> F[๐Ÿง  LLM Provider] F --> G[๐Ÿค– AI Response] G --> H[๏ฟฝ Save to Database] H --> I[๐Ÿ”„ Refresh Chat UI] classDef user fill:#e3f2fd classDef component fill:#f3e5f5 classDef system fill:#e8f5e8 classDef storage fill:#fff3e0 class A user class B,I component class C,D,E,F,G system class H storage

Code Reference - chat-input.js:

// When user presses Enter or clicks send
handleSubmit() {
  const message = this.input.value.trim();
  if (message) {
    // Fire custom event that chat-app.js listens for
    this.dispatchEvent(new CustomEvent('message-sent', {
      detail: { content: message }
    }));
    this.input.value = ''; // Clear input
  }
}

3. See the Magic!

You will see your message appear instantly, followed shortly by a response from the AI. You've just completed a full loop: from UI to AI and back!

๐Ÿค– Complete Message Processing Flow

Here's the complete journey of your message through the Fiberwise platform:

graph TD Input[๐Ÿ“ User Message] -->|"Event dispatch"| ChatApp[๐Ÿ’ฌ chat-app.js] ChatApp -->|"FIBER.agents.activate(chatAgent)"| SDK[๐Ÿ”ง Fiberwise SDK] SDK -->|"POST /activations"| API[๐ŸŒ Fiberwise API] API -->|"Creates activation record"| DB[(๐Ÿ’พ Database)] API -->|"Triggers agent execution"| Agent[๐Ÿค– Chat Agent] Agent -->|"Reads system_prompt from context"| Config[โš™๏ธ Agent Config] Config -->|"Calls LLM with combined prompt"| LLM[๐Ÿง  LLM Provider] LLM -->|"AI Response"| Agent2[๐Ÿค– Agent Processes] Agent2 -->|"Saves response to activation.output"| DB2[(๐Ÿ’พ Update Database)] DB2 -->|"Updates status: completed"| API2[๐ŸŒ API Updated] API2 -->|"WebSocket: activation_completed"| Realtime[โšก Real-time Event] Realtime -->|"Event received"| ChatApp2[๐Ÿ’ฌ Chat App Listener] ChatApp2 -->|"Update UI with AI response"| UI[๐Ÿ“ฑ Chat Interface] classDef user fill:#e3f2fd classDef component fill:#f3e5f5 classDef system fill:#e8f5e8 classDef storage fill:#fff3e0 classDef ai fill:#f0f9ff class Input user class ChatApp,ChatApp2,UI component class SDK,API,API2,Agent,Agent2,Config,Realtime system class DB,DB2 storage class LLM ai

Code Reference - chat-app.js sendMessage():

async sendMessage(content) {
  // Create the activation with your message
  const activation = await FIBER.agents.activate(
    this.selectedAgentId,           // 'chatAgent' from manifest
    { prompt: content },            // Your message: "Hello, who are you?"
    { 
      chat_id: this.currentChatId,  // Links messages to this conversation
      system_prompt: this.modelSettings.systemPrompt,
      role: 'user'
    },
    {
      provider_id: this.selectedProviderId,  // Which LLM to use
      temperature: this.modelSettings.temperature
    }
  );
  
  // Add pending message to UI immediately
  this.addMessageToUI({
    content: content,
    role: 'user',
    activationId: activation.id,
    status: 'completed'
  });
  
  // Add pending AI response placeholder
  this.addMessageToUI({
    content: '',
    role: 'assistant', 
    activationId: activation.id,
    status: 'pending'
  });
}

Manifest Reference - app_manifest.yaml:

# The agent that processes your messages
agents:
  - name: chatAgent
    agent_slug: chat-agent
    description: AI chat assistant agent
    system_prompt: |
      You are a helpful AI assistant. Be friendly and provide 
      clear, concise responses to user questions.
    
    # This agent will automatically use the connected LLM provider
    # with the context and metadata you send via FIBER.agents.activate()
๐Ÿ’ซ What You Just Witnessed
Your Message: "Hello, who are you?" โ†’ Instantly appears in UI
Behind the Scenes: Activation created โ†’ Agent triggered โ†’ LLM called โ†’ Response saved
AI Response: "Hello! I'm your AI assistant..." โ†’ Updates UI via WebSocket
Result: Complete conversation stored as linked activations with shared chat_id

๐Ÿ” Real-time Updates Explained

One of the most impressive parts is how the UI updates automatically when the AI responds:

graph TD Activation[๐Ÿค– Agent Completes] -->|"Status: completed"| API[๐ŸŒ Fiberwise API] API -->|"WebSocket Event"| Client[๐Ÿ“ฑ Browser Client] Client -->|"FIBER.realtime.on('message')"| Handler[โšก Event Handler] Handler -->|"Find pending message in UI"| Update[๐Ÿ”„ Update Component] Update -->|"Replace 'thinking...' with response"| UI[โœจ Live UI Update] classDef system fill:#e8f5e8 classDef component fill:#f3e5f5 classDef realtime fill:#f0f9ff class Activation,API system class Client,Update,UI component class Handler realtime

Code Reference - Real-time listener in chat-app.js:

// Set up real-time listener for activation updates
connectedCallback() {
  // ... other initialization ...
  
  // Listen for activation completion events
  FIBER.realtime.on('message', (message) => {
    if (message.type === 'activation_completed') {
      this.handleActivationCompleted(message);
    }
  });
}

handleActivationCompleted(message) {
  // Find the pending message in the UI
  const pendingMessage = this.messages.find(m => 
    m.activationId === message.activation_id && m.status === 'pending'
  );
  
  if (pendingMessage) {
    // Update with the AI's response
    pendingMessage.content = message.output;
    pendingMessage.status = 'completed';
    this.updateMessagesDisplay();
  }
}

Step 5: Deep Dive - How Did That Work?

What just happened when you sent that message? Let's trace the data flow from your browser to the Fiberwise platform and back.

1. The UI Captures Your Input (`chat-input.js`)

The `` component captures your text and fires a custom `message-sent` event that the main app component can listen to.

๐Ÿ› ๏ธ Router System & App Launch Flow

Behind the scenes, here's how the Fiberwise router system manages app loading and navigation:

graph TD A[๐ŸŒ URL Change] --> B[๐Ÿ“ Router.handleRouteChange] B --> C[๐Ÿ” Route Matching Algorithm] C --> D{App Route?} D -->|Yes| E[๐Ÿš€ Check if App Launched] D -->|No| F[๐Ÿ“„ Render Static Component] E --> G{Already Launched?} G -->|No| H[๐Ÿ“‹ Fetch App Manifest] G -->|Yes| I[๐Ÿ“ฑ Render App Component] H --> J[๐Ÿ”ง Register App Routes] J --> K[๐Ÿ’พ Load App Module] K --> L[๐ŸŽฏ Create App Container] L --> I I --> M[โœ… App Ready] classDef router fill:#fff3e0 classDef app fill:#e8f5e8 classDef system fill:#f3e5f5 classDef ready fill:#c8e6c9 class A,B,C,D router class E,G,H,J,K,L app class F,I system class M ready

Key Router Components:

  • Router.getInstance() - Singleton pattern for single router across app
  • _matchRoute() - Advanced pattern matching with parameters and priorities
  • launchApp() - Dynamic app loading and manifest processing
  • registerAppRoutes() - Add app routes to router registry

2. The App Component Makes the SDK Call (`chat-app.js`)

The main `` component listens for the event and calls the core function of the application: `FIBER.agents.activate()`. This is where the magic begins.

๐Ÿ’ก Key Concept: Agent Activation

An **activation** is a record of a single run of an agent. It stores the agent's inputs, outputs, status (e.g., pending, completed), and context. This app uses activations as its message store.

// In chat-app.js -> sendMessage()
const activation = await FIBER.agents.activate(
  this.selectedAgentId, // The ID of our chat agent
  { prompt: content },   // The user's message as input
  { 
    chat_id: this.currentChatId, // Context to group messages
    system_prompt: this.modelSettings.systemPrompt
  },
  metadata // Additional settings like temperature
);

3. The Fiberwise Platform Takes Over

When the platform receives the `activate` call:

  1. It immediately creates a new **activation** with a `pending` status.
  2. It triggers the "Chat Agent" (defined in your manifest) and passes it the `prompt`.
  3. The agent calls the connected LLM Provider (e.g., OpenAI).
  4. When the LLM responds, the agent saves the text as the activation's `output`.
  5. Finally, the activation's status is updated to `completed`.

4. Real-time Update to the UI

How does the UI know when the response is ready? The app listens for real-time events from the platform using a WebSocket connection.

โšก WebSocket Real-time Flow
graph TD A[๐Ÿš€ Agent Activation Starts] --> B[๐Ÿ’พ Save to Database] B --> C[๐Ÿ”„ Background Processing] C --> D[๐Ÿง  LLM Provider Response] D --> E[โœ… Mark Activation Complete] E --> F[๐Ÿ“ก WebSocket Event Emit] F --> G[๐Ÿ“ฑ Browser Receives Event] G --> H[๐ŸŽฏ FIBER.realtime.on Handler] H --> I[๐Ÿ” Find Pending Message] I --> J[๐ŸŽจ Update UI with Response] classDef system fill:#e8f5e8 classDef realtime fill:#fff3e0 classDef ui fill:#f3e5f5 class A,B,C,D,E system class F,G,H realtime class I,J ui

WebSocket Event Types:

  • activation_completed - Agent finished processing
  • activation_failed - Agent encountered an error
  • activation_progress - Real-time progress updates
// In chat-app.js -> init()
FIBER.realtime.on('message', (message) => {
  // We listen for the specific event that tells us an activation is done
  if (message.type === 'activation_completed') {
    // We find the 'pending' message in the UI and update it
    // with the final output from the activation.
    this.handleActivationCompleted(message);
  }
});

5. Chat Session & History Management

When you select an existing chat or start a new conversation, here's how message history loads:

๐Ÿ“œ Load Message History Flow
graph TD A[๐Ÿ‘ค Selects Chat] --> B[๐Ÿ’ฌ chat-app.js] B --> C[๐Ÿ”ง FIBER.agents.listActivations] C --> D[๐ŸŒ GET /activations] D --> E[๐Ÿ“‹ Filter by chat_id] E --> F[๐Ÿ’ญ Previous Messages] F --> G[๐Ÿ“ฑ Render Chat History] classDef user fill:#e3f2fd classDef component fill:#f3e5f5 classDef system fill:#e8f5e8 class A user class B,G component class C,D,E,F system

Code Reference - How chat history works:

// Loading previous messages for a chat session
async loadChatHistory(chatId) {
  const activations = await FIBER.agents.listActivations({
    context: { chat_id: chatId },  // Filter by chat session
    sort: 'created_at',            // Order by time
    limit: 50                      // Recent messages
  });
  
  // Convert activations to chat messages
  const messages = activations.map(activation => ({
    content: activation.output,
    role: activation.context.role || 'assistant',
    timestamp: activation.created_at
  }));
  
  this.renderMessages(messages);
}

6. Component Lifecycle & State Management

Understanding how web components initialize and manage state in Fiberwise applications:

๐Ÿ—๏ธ Component Lifecycle Flow
graph TD A[๐Ÿ“„ Component Created] --> B[๐Ÿ”ง connectedCallback] B --> C[โšก FIBER SDK Initialize] C --> D[๐Ÿ“‹ Load Agents & Providers] D --> E[๐Ÿ’พ Setup Initial State] E --> F[๐ŸŽจ Render Initial UI] F --> G[๐Ÿ“ก Setup Event Listeners] G --> H[โšก Setup Realtime Listeners] H --> I[โœ… Component Ready] I --> J{User Interaction?} J -->|Message Send| K[๐Ÿš€ State Update] J -->|Route Change| L[๐Ÿงน Cleanup & Navigate] K --> M[๐ŸŽจ Re-render UI] M --> J L --> N[๐Ÿ—‘๏ธ disconnectedCallback] classDef lifecycle fill:#e3f2fd classDef state fill:#f3e5f5 classDef interaction fill:#fff3e0 classDef cleanup fill:#ffebee class A,B,C,D,E,F,G,H,I lifecycle class K,M state class J interaction class L,N cleanup

Key Lifecycle Methods:

  • connectedCallback() - Component mounted to DOM
  • disconnectedCallback() - Component removed from DOM
  • attributeChangedCallback() - Attributes changed
  • render() - Custom method to update UI

7. Complete Data Flow Diagram

Here's the complete data flow diagram that shows how all components interact from user input to AI response:

Complete Data Flow

graph TD User[๐Ÿ‘ค Types & Sends Message] -->|"message-sent event"| ChatInput[๐Ÿ“ chat-input.js] ChatInput -->|"Calls sendMessage()"| ChatApp[๐Ÿ’ฌ chat-app.js] ChatApp -->|"FIBER.agents.activate()"| SDK[๐Ÿ”ง Fiberwise SDK] SDK -->|"POST /activations"| API[๐ŸŒ Fiberwise API] API -->|"Creates pending activation"| Agent[๐Ÿค– Chat Agent] Agent -->|"Calls LLM"| LLM[๐Ÿง  LLM Provider] LLM -->|"Returns response"| Agent2[๐Ÿค– Agent Saves] Agent2 -->|"Saves output, marks completed"| API2[๐ŸŒ API Updates] API2 -->|"Sends activation_completed event"| WebSocket[โšก WebSocket] WebSocket -->|"Notifies UI via FIBER.realtime.on()"| ChatApp2[๐Ÿ’ฌ Chat App Updates] ChatApp2 -->|"Updates the UI"| UIRefresh[๐Ÿ“ฑ UI Refreshed] classDef user fill:#e3f2fd classDef component fill:#f3e5f5 classDef system fill:#e8f5e8 class User,ChatInput,ChatApp,ChatApp2,UIRefresh component class SDK,API,API2,Agent,Agent2,LLM,WebSocket system

Step 6: Understanding the Technical Implementation

Now that you've built and tested your chat app, let's dive into the technical details of how it works. This section explains the key implementation patterns you can use in your own apps.

๐Ÿ“‹ Application Manifest Structure

The app_manifest.yaml file defines your complete application. Here's the activation-chat manifest structure:

app:
  name: Activation Chat
  app_slug: activation-chat
  version: 0.0.21
  description: A chat application that uses agent activations and dynamic data as the message store
  entryPoint: index.js
  icon: fas fa-comments
  category: simple
  
  # Minimal model for session tracking only
  models:
  - name: Chat
    model_slug: chats
    description: Simple chat session container
    fields:
    - name: Chat ID
      field_column: chat_id
      type: uuid
      required: true
      is_primary_key: true
      description: Primary key used as chat_id in agent activation context
    - name: Title
      field_column: title
      type: string
      required: true
      default: New Chat

  routes:
  - path: /
    component: chat-app
    title: Chat
    icon: fas fa-comments

agents:
- name: chatAgent
  agent_type_id: llm
  version: 0.0.2

๐Ÿ—๏ธ App Entry Point Implementation

Every Fiberwise app follows a standard pattern for platform integration. Here's the complete index.js structure:

// index.js - Standard platform integration pattern
import fiber from 'fiberwise';

// Create FIBER SDK instance using modern constructor pattern
export const FIBER = new FiberWise();

/**
 * Standard initialize function for app platform integration
 * @param {Object} appBridge - AppBridge instance from platform
 * @param {Object} manifest - The application manifest
 * @returns {Promise<boolean>} Success status
 */
export async function initialize(appBridge, manifest) {
  console.log('[ActivationChat] Initializing app...');
  FIBER.initialize(appBridge, manifest);
  return true;
}

/**
 * Standard render function for app platform integration
 * @param {HTMLElement} mountPoint - Where to mount the app
 */
export function render(mountPoint) {
  console.log('[ActivationChat] Rendering app...');
  const el = document.createElement('chat-app');
  mountPoint.appendChild(el);
}

// Register the main Web Component
import './chat-app.js';

๐Ÿ’พ Activation Context Structure

The chat app stores messages as agent activations with special context metadata. Here's how the data structure works:

// User message activation
{
  "agent_id": "chatAgent",
  "input_data": {
    "message": "Hello, how are you?"
  },
  "context": {
    "chat_id": "unique-session-identifier",
    "session_title": "Morning Chat",
    "role": "user",
    "system_prompt": "You are a helpful assistant"
  },
  "status": "completed"
}

// Assistant response activation
{
  "agent_id": "chatAgent",
  "input_data": {
    "message": "Hello, how are you?"
  },
  "output_data": {
    "text": "Hello! I'm doing well, thank you for asking."
  },
  "context": {
    "chat_id": "unique-session-identifier", 
    "session_title": "Morning Chat",
    "role": "assistant",
    "system_prompt": "You are a helpful assistant"
  },
  "status": "completed"
}

๐Ÿ“ก Data Flow Implementation

Here are the key methods that power the chat functionality:

Message Retrieval

// Query activations by context for chat history
async loadChatHistory(chatId) {
  const activations = await FIBER.agents.getActivations(agentId, {
    context: { chat_id: chatId },
    sort: 'started_at'
  });
  
  return activations
    .filter(a => a.context?.role)
    .map(activation => ({
      role: activation.context.role,
      content: activation.context.role === 'user' 
        ? activation.input_data?.message
        : activation.output_data?.text,
      timestamp: activation.started_at,
      activationId: activation.activation_id
    }));
}

Session Management

// Discover unique chat sessions from activations
async loadSessions() {
  const activations = await FIBER.agents.getActivations(agentId);
  const sessions = new Map();
  
  activations.forEach(activation => {
    if (activation.context?.chat_id && activation.context?.session_title) {
      sessions.set(activation.context.chat_id, {
        id: activation.context.chat_id,
        title: activation.context.session_title,
        lastActivity: activation.started_at
      });
    }
  });
  
  return Array.from(sessions.values())
    .sort((a, b) => new Date(b.lastActivity) - new Date(a.lastActivity));
}

Message Sending Flow

// Complete message sending implementation
async sendMessage(message, chatId) {
  // 1. Create user message activation
  const userActivation = await FIBER.agents.activate(agentId, {
    message: message
  }, {
    chat_id: chatId,
    session_title: this.currentSession.title,
    role: 'user'
  });
  
  // 2. Create assistant activation for AI response  
  const assistantActivation = await FIBER.agents.activate(agentId, {
    message: message,
    system_prompt: this.systemPrompt
  }, {
    chat_id: chatId,
    session_title: this.currentSession.title,
    role: 'assistant'
  });
  
  // 3. Refresh chat history to show both messages
  await this.loadChatHistory(chatId);
}

๐Ÿ“Š Conceptual Database Query

While you interact with activations through the SDK, here's the conceptual SQL that shows how message retrieval works:

-- Conceptual query for message retrieval
SELECT * FROM agent_activations 
WHERE context->>'chat_id' = 'session-identifier'
ORDER BY started_at ASC;

๐Ÿ’ก Key Patterns for Your Apps

  • Activation-Based Storage: Use activations instead of traditional database tables
  • Context Metadata: Store application data in activation context
  • Role-Based Organization: Use context.role to categorize data
  • Virtual Entities: Derive app entities from activation context patterns
  • Standard App Structure: Follow initialize/render pattern for platform integration

๐Ÿ† Congratulations!

You've successfully installed, run, and understood a production-grade AI application on Fiberwise. You now know the core pattern for building apps on the platform.

๐Ÿš€ Next Steps

๐Ÿ—๏ธ Build Your Own App

Use what you've learned to start building your own custom AI application from scratch.

Start Building

๐Ÿค– Explore Agent Development

Dive deeper into creating custom, powerful agents for any use case.

Agent Development Guide

๐Ÿ“š Browse More Examples

Check out other example applications in the `fiber-apps` repository for more patterns.

More Examples