# Fireworks Client

Interact with Fireworks AI's fast inference platform for LLM chat completions and embeddings.

## Methods

| Method                                   | Description                                           |
| ---------------------------------------- | ----------------------------------------------------- |
| `apiRequest(options, schema, metadata?)` | Make any Fireworks API request with schema validation |

## Usage

### Step 1: List Available Models

Model availability varies by account. Before making requests, validate which models are deployed on your account:

```typescript
import { api, z, fireworks } from "@superblocksteam/sdk-api";

// Integration ID from the integrations panel
const PROD_FIREWORKS = "a1b2c3d4-5678-90ab-cdef-fireworks001";

const ModelsResponseSchema = z.object({
  data: z.array(
    z.object({
      id: z.string(),
      object: z.string(),
    }),
  ),
});

const models = await ctx.integrations.fireworks.apiRequest(
  {
    method: "GET",
    path: "/v1/models",
  },
  { response: ModelsResponseSchema },
);

// Use a model ID from the response in subsequent requests
const availableModelId = models.data[0]?.id;
```

### Chat Completion

```typescript
const ChatCompletionResponseSchema = z.object({
  id: z.string(),
  object: z.string(),
  created: z.number(),
  model: z.string(),
  choices: z.array(
    z.object({
      index: z.number(),
      message: z.object({
        role: z.string(),
        content: z.string(),
      }),
      finish_reason: z.string(),
    }),
  ),
  usage: z.object({
    prompt_tokens: z.number(),
    completion_tokens: z.number(),
    total_tokens: z.number(),
  }),
});

export default api({
  integrations: {
    fireworks: fireworks(PROD_FIREWORKS),
  },
  name: "FireworksExample",
  input: z.object({
    prompt: z.string(),
  }),
  output: z.object({
    response: z.string(),
  }),
  async run(ctx, { prompt }) {
    const result = await ctx.integrations.fireworks.apiRequest(
      {
        method: "POST",
        path: "/v1/chat/completions",
        body: {
          model: "accounts/fireworks/models/llama-v3p1-70b-instruct",
          messages: [{ role: "user", content: prompt }],
        },
      },
      { response: ChatCompletionResponseSchema },
    );

    return { response: result.choices[0]?.message.content ?? "" };
  },
});
```

### Using Different Models

```typescript
// Llama 3.1 70B - High quality
const llama70b = await ctx.integrations.fireworks.apiRequest(
  {
    method: "POST",
    path: "/v1/chat/completions",
    body: {
      model: "accounts/fireworks/models/llama-v3p1-70b-instruct",
      messages: [{ role: "user", content: "Complex task..." }],
    },
  },
  { response: ChatCompletionResponseSchema },
);

// Llama 3.1 8B - Fast and efficient
const llama8b = await ctx.integrations.fireworks.apiRequest(
  {
    method: "POST",
    path: "/v1/chat/completions",
    body: {
      model: "accounts/fireworks/models/llama-v3p1-8b-instruct",
      messages: [{ role: "user", content: "Simple task..." }],
    },
  },
  { response: ChatCompletionResponseSchema },
);

// Mixtral MoE - Good for diverse tasks
const mixtral = await ctx.integrations.fireworks.apiRequest(
  {
    method: "POST",
    path: "/v1/chat/completions",
    body: {
      model: "accounts/fireworks/models/mixtral-8x7b-instruct",
      messages: [{ role: "user", content: "..." }],
    },
  },
  { response: ChatCompletionResponseSchema },
);

// Qwen for code
const qwen = await ctx.integrations.fireworks.apiRequest(
  {
    method: "POST",
    path: "/v1/chat/completions",
    body: {
      model: "accounts/fireworks/models/qwen2p5-coder-32b-instruct",
      messages: [{ role: "user", content: "Write code..." }],
    },
  },
  { response: ChatCompletionResponseSchema },
);
```

### Generate Embeddings

```typescript
const EmbeddingsResponseSchema = z.object({
  object: z.string(),
  data: z.array(
    z.object({
      object: z.string(),
      embedding: z.array(z.number()),
      index: z.number(),
    }),
  ),
  model: z.string(),
  usage: z.object({
    prompt_tokens: z.number(),
    total_tokens: z.number(),
  }),
});

const result = await ctx.integrations.fireworks.apiRequest(
  {
    method: "POST",
    path: "/v1/embeddings",
    body: {
      model: "accounts/fireworks/models/nomic-embed-text-v1.5",
      input: ["Hello world", "How are you?"],
    },
  },
  { response: EmbeddingsResponseSchema },
);
```

### Function Calling

```typescript
const FunctionCallResponseSchema = z.object({
  id: z.string(),
  choices: z.array(
    z.object({
      message: z.object({
        role: z.string(),
        content: z.string().nullable(),
        tool_calls: z
          .array(
            z.object({
              id: z.string(),
              type: z.literal("function"),
              function: z.object({
                name: z.string(),
                arguments: z.string(),
              }),
            }),
          )
          .optional(),
      }),
      finish_reason: z.string(),
    }),
  ),
});

const result = await ctx.integrations.fireworks.apiRequest(
  {
    method: "POST",
    path: "/v1/chat/completions",
    body: {
      model: "accounts/fireworks/models/firefunction-v2",
      messages: [{ role: "user", content: "What's the weather in Paris?" }],
      tools: [
        {
          type: "function",
          function: {
            name: "get_weather",
            description: "Get weather for a location",
            parameters: {
              type: "object",
              properties: {
                location: { type: "string" },
              },
              required: ["location"],
            },
          },
        },
      ],
    },
  },
  { response: FunctionCallResponseSchema },
);
```

### JSON Mode

```typescript
const result = await ctx.integrations.fireworks.apiRequest(
  {
    method: "POST",
    path: "/v1/chat/completions",
    body: {
      model: "accounts/fireworks/models/llama-v3p1-70b-instruct",
      messages: [{ role: "user", content: "List 3 colors in JSON format" }],
      response_format: { type: "json_object" },
    },
  },
  { response: ChatCompletionResponseSchema },
);

const data = JSON.parse(result.choices[0]?.message.content ?? "{}");
```

### Grammar-Constrained Output

```typescript
const result = await ctx.integrations.fireworks.apiRequest(
  {
    method: "POST",
    path: "/v1/chat/completions",
    body: {
      model: "accounts/fireworks/models/llama-v3p1-70b-instruct",
      messages: [{ role: "user", content: "Generate user data" }],
      response_format: {
        type: "json_object",
        schema: {
          type: "object",
          properties: {
            name: { type: "string" },
            age: { type: "integer" },
            email: { type: "string" },
          },
          required: ["name", "age"],
        },
      },
    },
  },
  { response: ChatCompletionResponseSchema },
);
```

## Trace Metadata

All methods accept an optional `metadata` parameter as the last argument for diagnostics labeling. See the [root SDK README](../../../README.md#trace-metadata) for details.

## Common Pitfalls

### Streaming Is Not Supported

`apiRequest()` does not support streaming or Server-Sent Events. Do not set
`stream: true` — streaming responses fail schema validation. Every call
returns the complete response; if a UI needs real-time token streaming,
handle it at the frontend layer, not through the SDK.

### No Specialized Methods

```typescript
// WRONG - These methods do not exist
await fireworks.chat({ ... });
await fireworks.complete({ ... });

// CORRECT - Use apiRequest
await ctx.integrations.fireworks.apiRequest(
  { method: "POST", path: "/v1/chat/completions", body: { ... } },
  { response: ChatCompletionResponseSchema }
);
```

### Model Path Format

Fireworks uses a specific model path format:

```typescript
// WRONG - Short model name
const body = {
  model: "llama-3.1-70b",
  messages: [...],
};

// CORRECT - Full model path
const body = {
  model: "accounts/fireworks/models/llama-v3p1-70b-instruct",
  messages: [...],
};
```

### API Path

The integration's base URL already includes `https://api.fireworks.ai/inference`, so paths should start with `/v1/`:

```typescript
// WRONG - Duplicates the /inference prefix (base URL already includes it)
await ctx.integrations.fireworks.apiRequest(
  { method: "POST", path: "/inference/v1/chat/completions", body: { ... } },
  { response: schema }
);

// CORRECT - Start with /v1/ (the integration prepends /inference automatically)
await ctx.integrations.fireworks.apiRequest(
  { method: "POST", path: "/v1/chat/completions", body: { ... } },
  { response: schema }
);
```

### Function Calling Model

For best function calling results, use the dedicated model:

```typescript
// Use firefunction model for tool use
const body = {
  model: "accounts/fireworks/models/firefunction-v2",
  tools: [...],
  messages: [...],
};
```

### Rate Limits

Fireworks has rate limits. Check response headers:

```typescript
// Monitor usage for rate limiting
const result = await ctx.integrations.fireworks.apiRequest(...);
console.log("Tokens used:", result.usage.total_tokens);
```

## Error Handling

```typescript
import { RestApiValidationError } from "@superblocksteam/sdk-api";

try {
  const result = await ctx.integrations.fireworks.apiRequest(
    { method: "POST", path: "/v1/chat/completions", body: { ... } },
    { response: ChatCompletionResponseSchema }
  );
} catch (error) {
  if (error instanceof RestApiValidationError) {
    console.error("Validation failed:", error.details.zodError);
  }
}
```

## API Reference

- [Fireworks Documentation](https://docs.fireworks.ai/)
- [Chat Completions](https://docs.fireworks.ai/api-reference/post-chatcompletions)
- [Embeddings](https://docs.fireworks.ai/api-reference/post-embeddings)
- [Models](https://fireworks.ai/models)
