xsAI v0.1 is now available! Read Announcement
xsAI0.2.0-beta.2
Tools

Composio

Composio adapter for xsAI.

This code is untested, feel free to test it yourself and provide feedback.

npm i composio-core zod @xsai/shared-chat @xsai/tool
import type { Tool } from '@xsai/shared-chat'
import type { RawActionData } from 'composio-core'
 
import { ComposioToolSet } from 'composio-core'
import { z } from 'zod'
 
type Optional<T> = null | T
 
const ZExecuteToolCallParams = z.object({
  actions: z.array(z.string()).optional(),
  apps: z.array(z.string()).optional(),
  connectedAccountId: z.string().optional(),
  entityId: z.string().optional(),
  filterByAvailableApps: z.boolean().optional().default(false),
  params: z.record(z.any()).optional(),
  tags: z.array(z.string()).optional(),
  useCase: z.string().optional(),
  useCaseLimit: z.number().optional(),
})
 
export class XSAIToolSet extends ComposioToolSet {
  fileName: string = 'js/src/frameworks/xsai.ts'
 
  constructor(
    config: {
      allowTracing?: boolean
      apiKey?: Optional<string>
      baseUrl?: Optional<string>
      connectedAccountIds?: Record<string, string>
      entityId?: string
    } = {},
  ) {
    super({
      allowTracing: config.allowTracing || false,
      apiKey: config.apiKey ?? null,
      baseUrl: config.baseUrl ?? null,
      connectedAccountIds: config.connectedAccountIds,
      entityId: config.entityId ?? 'default',
      runtime: null,
    })
  }
 
  async executeToolCall(
    tool: { arguments: unknown, name: string },
    entityId: Optional<string> = null,
  ): Promise<string> {
    const toolSchema = await this.getToolsSchema({ actions: [tool.name] })
    const appName = toolSchema[0]?.appName?.toLowerCase()
    const connectedAccountId = appName && this.connectedAccountIds?.[appName]
 
    return JSON.stringify(
      await this.executeAction({
        action: tool.name,
        connectedAccountId,
        entityId: entityId ?? this.entityId,
        params:
          typeof tool.arguments === 'string'
            ? JSON.parse(tool.arguments) as Record<string, unknown>
            : tool.arguments as Record<string, unknown>,
      }),
    )
  }
 
  async getTools(
    filters: {
      actions?: Array<string>
      apps?: Array<string>
      filterByAvailableApps?: Optional<boolean>
      integrationId?: Optional<string>
      tags?: Optional<Array<string>>
      useCase?: Optional<string>
      useCaseLimit?: Optional<number>
    },
    entityId: Optional<string> = null,
  ): Promise<Tool[]> {
    const {
      actions,
      apps,
      filterByAvailableApps,
      tags,
      useCase,
      useCaseLimit,
    } = ZExecuteToolCallParams.parse(filters)
 
    const actionsList = await this.getToolsSchema(
      {
        actions,
        apps,
        filterByAvailableApps,
        tags,
        useCase,
        useCaseLimit,
      },
      entityId,
      filters.integrationId,
    )
 
    return actionsList.map(actionSchema => this.generateTool(
      actionSchema,
      entityId,
    ))
  }
 
  private generateTool(
    schema: RawActionData,
    entityId: Optional<string> = null,
  ) {
    return {
      execute: async params => this.executeToolCall(
        {
          arguments: JSON.stringify(params),
          name: schema.name,
        },
        entityId ?? this.entityId,
      ),
      function: {
        description: schema.description,
        name: schema.name,
        parameters: schema.parameters,
        strict: true,
      },
      type: 'function',
    } satisfies Tool
  }
}

Examples

import { generateText } from '@xsai/generate-text'
import { env } from 'node:process'
 
import { XSAIToolSet } from './utils/xsai-tool-set'
 
const toolset = new XSAIToolSet()
 
const tools = await toolset.getTools({ apps: ['github'] })
 
const result = await generateText({
  apiKey: env.OPENAI_API_KEY!,
  baseURL: 'https://api.openai.com/v1/',
  maxSteps: 5,
  model: 'gpt-4o-mini',
  messages: [{
    role: 'user',
    content: 'Star the repository "moeru-ai/xsai"',
  }],
  tools,
  toolChoice: 'required',
  temperature: 0,
})
 
console.log(result.steps)
console.log(result.text)
Edit on GitHub

Last updated on

On this page