OpenAI function calling

Operations

JSON schema function definitions you can drop straight into the OpenAI Chat Completions or Responses API.

import OpenAI from "openai";

const openai = new OpenAI();
const KEY   = process.env.MYAGENTMAIL_KEY!;
const API   = "https://myagentmail.com/v1";

async function mam(method: string, path: string, body?: unknown) {
  const r = await fetch(`${API}${path}`, {
    method,
    headers: { "X-API-Key": KEY, "Content-Type": "application/json" },
    body: body ? JSON.stringify(body) : undefined,
  });
  if (!r.ok) throw new Error(`${method} ${path} → ${r.status}`);
  return r.json();
}

const tools = [
  {
    type: "function" as const,
    function: {
      name: "send_email",
      description: "Send an email from a myagentmail inbox.",
      parameters: {
        type: "object",
        required: ["inboxId", "to", "subject", "plainBody"],
        properties: {
          inboxId:   { type: "string" },
          to:        { type: "string", format: "email" },
          subject:   { type: "string" },
          plainBody: { type: "string" },
        },
      },
    },
  },
  {
    type: "function" as const,
    function: {
      name: "list_inbox_messages",
      description: "List inbound messages in a myagentmail inbox.",
      parameters: {
        type: "object",
        required: ["inboxId"],
        properties: {
          inboxId: { type: "string" },
          limit:   { type: "number", default: 10 },
        },
      },
    },
  },
];

async function dispatch(name: string, args: any) {
  if (name === "send_email") {
    return mam("POST", `/inboxes/${args.inboxId}/send`, {
      to: args.to, subject: args.subject, plainBody: args.plainBody, verified: true,
    });
  }
  if (name === "list_inbox_messages") {
    return mam("GET", `/inboxes/${args.inboxId}/messages?direction=inbound&limit=${args.limit ?? 10}`);
  }
  throw new Error(`unknown tool: ${name}`);
}

// Standard tool-call loop
const messages: any[] = [
  { role: "user", content: "Check my inbox abc-123 for new mail and reply to anything urgent." },
];
while (true) {
  const res = await openai.chat.completions.create({
    model: "gpt-5",
    messages,
    tools,
  });
  const msg = res.choices[0].message;
  messages.push(msg);
  if (!msg.tool_calls?.length) break;
  for (const call of msg.tool_calls) {
    const result = await dispatch(call.function.name, JSON.parse(call.function.arguments));
    messages.push({
      role: "tool",
      tool_call_id: call.id,
      content: JSON.stringify(result),
    });
  }
}