Skip to content

Latest commit

 

History

History
299 lines (237 loc) · 6.42 KB

File metadata and controls

299 lines (237 loc) · 6.42 KB

Quick Start

This guide will help you get started with the Aikit library.

Installation

npm install aikit
# or
yarn add aikit
# or
pnpm add aikit

Basic Usage

1. Simple Chat Out of the Box

The fastest way to get started is to use the ready-made ChatContainer component:

import React, { useState } from 'react';
import { ChatContainer } from 'aikit';
import type { ChatType, MessageType } from 'aikit';

function App() {
    const [messages, setMessages] = useState<MessageType[]>([]);
    const [chats, setChats] = useState<ChatType[]>([]);
    const [activeChat, setActiveChat] = useState<ChatType | null>(null);

    const handleSendMessage = async (content: string) => {
        // Your message sending logic
        const response = await fetch('/api/chat', {
            method: 'POST',
            body: JSON.stringify({ message: content })
        });
        const data = await response.json();

        // Update state
        setMessages(prev => [...prev, data]);
    };

    return (
        <ChatContainer
            chats={chats}
            activeChat={activeChat}
            messages={messages}
            onSendMessage={handleSendMessage}
            onSelectChat={setActiveChat}
            onCreateChat={() => {/* Create chat */}}
            onDeleteChat={(chat) => {/* Delete chat */}}
        />
    );
}

2. Using Individual Components

For more flexible customization, use components separately:

import {
    Header,
    MessageList,
    PromptBox,
} from 'aikit';

function CustomChat() {
    return (
        <div className="custom-chat">
            <Header
                title="AI Assistant"
                onNewChat={() => {/* ... */}}
            />

            <MessageList
                messages={messages}
                showTimestamp
            />

            <PromptBox
                onSend={handleSend}
                placeholder="Enter message..."
            />
        </div>
    );
}

3. Using Hooks for Full Customization

import { usePromptBox } from 'aikit';

function MyCustomPromptBox() {
    const {
        value,
        setValue,
        handleSubmit,
        canSubmit
    } = usePromptBox({
        onSend: async (data) => {
            // Your logic
        }
    });

    return (
        <div className="my-prompt">
            <textarea
                value={value}
                onChange={(e) => setValue(e.target.value)}
            />
            <button
                onClick={handleSubmit}
                disabled={!canSubmit}
            >
                Send
            </button>
        </div>
    );
}

Working with Message Types

Built-in Types

The library supports three built-in message types:

  1. Simple — regular text message
  2. Thinking — AI thinking process
  3. Tool — tool execution
import type {SimpleMessageType} from 'aikit';

const message: SimpleMessageType = {
  type: 'simple',
  id: 'msg-1',
  author: 'assistant',
  timestamp: new Date().toISOString(),
  state: 'success',
  data: {
    formattedText: 'Hello! How can I help?',
  },
};

Custom Message Types

You can create your own message types:

import type { BaseMessage, MessageTypeRegistry } from 'aikit';

// 1. Define data
interface ImageMessageData {
    imageUrl: string;
    caption?: string;
}

// 2. Create message type
type ImageMessage = BaseMessage<ImageMessageData> & {
    type: 'image';
};

// 3. Create display component
const ImageMessageView = ({ message }: { message: ImageMessage }) => {
    return (
        <div>
            <img src={message.data.imageUrl} />
            {message.data.caption && <p>{message.data.caption}</p>}
        </div>
    );
};

// 4. Register type
const customTypes: MessageTypeRegistry = {
    image: {
        component: ImageMessageView,
        validator: (msg) => msg.type === 'image'
    }
};

// 5. Use in ChatContainer
<ChatContainer
    messages={messages}
    messageTypeRegistry={customTypes}
/>

Theming

Using Built-in Themes

<ChatContainer
    theme="dark"  // 'light' | 'dark' | 'auto'
    // ...
/>

Customization via CSS Variables

.g-root {
  --g-aikit-color-bg-primary: #ffffff;
  /* ... */
}

[data-theme='dark'] {
  --g-aikit-bg-primary: #1a1a1a;
  /* ... */
}

Streaming

The library supports streaming responses:

const handleSendMessage = async (content: string) => {
  // Create temporary message in streaming state
  const tempMessage: SimpleMessageType = {
    type: 'simple',
    id: 'temp-' + Date.now(),
    author: 'assistant',
    timestamp: new Date().toISOString(),
    state: 'streaming',
    data: {formattedText: ''},
  };

  setMessages((prev) => [...prev, tempMessage]);

  // Streaming from server
  const response = await fetch('/api/chat/stream', {
    method: 'POST',
    body: JSON.stringify({message: content}),
  });

  const reader = response.body.getReader();
  let accumulated = '';

  while (true) {
    const {done, value} = await reader.read();
    if (done) break;

    accumulated += new TextDecoder().decode(value);

    // Update message as data arrives
    setMessages((prev) =>
      prev.map((msg) =>
        msg.id === tempMessage.id ? {...msg, data: {formattedText: accumulated}} : msg,
      ),
    );
  }

  // Change state to success
  setMessages((prev) =>
    prev.map((msg) => (msg.id === tempMessage.id ? {...msg, state: 'success' as const} : msg)),
  );
};

Server

Streaming

const service = new OpenAIService({...})

const stream = await service.createResponseStream({
    input: 'Hello world',
});

stream.start() // start stream to get chunks
stream.onEventChunk(console.log) // a typed chunk object
stream.onBufferChunk(console.log) // if we need pass chunks to another service (for example via http)
stream.abort() // abort stream

Summarizing the header of a dialog.

const summarizing = await service.summarizeConversationTitle({
  conversation: '<convId>',
  byLastItems: 5, // summarizes based on the last 5 messages
  // byFirstItems: 5, summarizes based on the first 5 messages
});

console.log('summarizing :>> ', summarizing); // header of conversation

If neither the byLastItems nor the byFirstItems parameter is provided, summarization will, by default, be performed on the first 5 items.

Next Steps