Actions

Get Customer Info

import { createAction } from "spinai";
import { ZendeskAPI } from "@zendesk/api";

export const getCustomerInfo = createAction({
  id: "getCustomerInfo",
  description: "Get customer information from Zendesk",
  async run(context) {
    const zendesk = new ZendeskAPI({
      subdomain: process.env.ZENDESK_SUBDOMAIN,
      token: process.env.ZENDESK_API_TOKEN,
    });

    const email = extractEmail(context.input);
    const user = await zendesk.users.search({ email });

    context.state.customer = user;
    return context;
  },
});

Create Ticket

import { createAction } from "spinai";

export const createTicket = createAction({
  id: "createTicket",
  description: "Create a new support ticket",
  dependsOn: ["getCustomerInfo"],
  async run(context) {
    const { customer } = context.state;

    const ticket = await zendesk.tickets.create({
      subject: "Support Request",
      comment: { body: context.input },
      requester_id: customer.id,
      priority: "normal",
    });

    context.state.ticket = ticket;
    return context;
  },
});

Agent Setup

import { createAgent, createOpenAILLM } from "spinai";
import { getCustomerInfo } from "./actions/getCustomerInfo";
import { createTicket } from "./actions/createTicket";
import { getTicketStatus } from "./actions/getTicketStatus";

const supportAgent = createAgent({
  instructions: `You are a helpful support agent that can:
    - Look up customer information
    - Create support tickets
    - Check ticket status
    Always verify customer information before creating tickets.`,
  actions: [getCustomerInfo, createTicket, getTicketStatus],
  llm: createOpenAILLM({
    apiKey: process.env.OPENAI_API_KEY,
  }),
});

// Use the agent
const { response } = await supportAgent({
  input: "I need help with my account",
  state: {},
});

Error Handling

const createTicket = createAction({
  id: "createTicket",
  description: "Create a new support ticket",
  retries: 3, // Retry on API failures
  async run(context) {
    try {
      // ... ticket creation logic
    } catch (error) {
      if (error.status === 429) {
        // Rate limit hit, retry
        throw new Error("Rate limit exceeded");
      }
      throw error;
    }
  },
});

Next Steps