# Cohere Client

Interact with Cohere's APIs for text generation, embeddings, classification, and semantic search.

## Methods

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

## Usage

### Chat Completion

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

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

const ChatResponseSchema = z.object({
  text: z.string(),
  generation_id: z.string(),
  chat_history: z.array(
    z.object({
      role: z.enum(["USER", "CHATBOT", "SYSTEM"]),
      message: z.string(),
    }),
  ),
  finish_reason: z.string(),
  meta: z.object({
    api_version: z.object({ version: z.string() }),
    billed_units: z.object({
      input_tokens: z.number(),
      output_tokens: z.number(),
    }),
  }),
});

export default api({
  name: "CohereExample",
  integrations: {
    cohere: cohere(PROD_COHERE),
  },
  input: z.object({
    message: z.string(),
  }),
  output: z.object({
    response: z.string(),
  }),
  async run(ctx, { message }) {
    const result = await ctx.integrations.cohere.apiRequest(
      {
        method: "POST",
        path: "/chat",
        body: {
          model: "command-r-plus",
          message: message,
        },
      },
      { response: ChatResponseSchema },
    );

    return { response: result.text };
  },
});
```

### Generate Embeddings

```typescript
const EmbedResponseSchema = z.object({
  id: z.string(),
  embeddings: z.array(z.array(z.number())),
  texts: z.array(z.string()),
  meta: z.object({
    api_version: z.object({ version: z.string() }),
  }),
});

const result = await ctx.integrations.cohere.apiRequest(
  {
    method: "POST",
    path: "/embed",
    body: {
      model: "embed-english-v3.0",
      texts: ["Hello world", "How are you?"],
      input_type: "search_document",
    },
  },
  { response: EmbedResponseSchema },
);

result.embeddings.forEach((embedding, i) => {
  console.log(`Text ${i}: ${embedding.length} dimensions`);
});
```

### Text Classification

```typescript
const ClassifyResponseSchema = z.object({
  id: z.string(),
  classifications: z.array(
    z.object({
      id: z.string(),
      input: z.string(),
      prediction: z.string(),
      confidence: z.number(),
      labels: z.record(z.object({ confidence: z.number() })),
    }),
  ),
});

const result = await ctx.integrations.cohere.apiRequest(
  {
    method: "POST",
    path: "/classify",
    body: {
      model: "embed-english-v3.0",
      inputs: ["This product is amazing!", "Terrible experience, never again"],
      examples: [
        { text: "I love this!", label: "positive" },
        { text: "Great product", label: "positive" },
        { text: "This is awful", label: "negative" },
        { text: "Worst purchase ever", label: "negative" },
      ],
    },
  },
  { response: ClassifyResponseSchema },
);

result.classifications.forEach((c) => {
  console.log(`"${c.input}" -> ${c.prediction} (${c.confidence})`);
});
```

### Rerank Documents

```typescript
const RerankResponseSchema = z.object({
  id: z.string(),
  results: z.array(
    z.object({
      index: z.number(),
      relevance_score: z.number(),
      document: z.object({ text: z.string() }).optional(),
    }),
  ),
});

const documents = [
  "Carson City is the capital of Nevada.",
  "The Commonwealth of the Northern Mariana Islands is a US territory.",
  "Washington, D.C. is the capital of the United States.",
  "Capital punishment has existed since ancient times.",
];

const result = await ctx.integrations.cohere.apiRequest(
  {
    method: "POST",
    path: "/rerank",
    body: {
      model: "rerank-english-v3.0",
      query: "What is the capital of the United States?",
      documents: documents,
      top_n: 3,
      return_documents: true,
    },
  },
  { response: RerankResponseSchema },
);

result.results.forEach((r) => {
  console.log(`Score: ${r.relevance_score}, Doc: ${r.document?.text}`);
});
```

### Generate Text (Legacy)

```typescript
const GenerateResponseSchema = z.object({
  id: z.string(),
  generations: z.array(
    z.object({
      id: z.string(),
      text: z.string(),
      finish_reason: z.string(),
    }),
  ),
});

const result = await ctx.integrations.cohere.apiRequest(
  {
    method: "POST",
    path: "/generate",
    body: {
      model: "command",
      prompt: "Write a creative story about",
      max_tokens: 200,
      temperature: 0.7,
    },
  },
  { response: GenerateResponseSchema },
);
```

## 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 cohere.chat({ ... });
await cohere.embed({ ... });

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

### Embedding Input Types

When creating embeddings, specify the correct `input_type`:

```typescript
// For documents to be searched
const docEmbeddings = await ctx.integrations.cohere.apiRequest(
  {
    method: "POST",
    path: "/embed",
    body: {
      texts: documents,
      input_type: "search_document", // For documents
    },
  },
  { response: EmbedResponseSchema },
);

// For search queries
const queryEmbedding = await ctx.integrations.cohere.apiRequest(
  {
    method: "POST",
    path: "/embed",
    body: {
      texts: [query],
      input_type: "search_query", // For queries
    },
  },
  { response: EmbedResponseSchema },
);
```

### Classification Requires Examples

The classify endpoint requires labeled examples:

```typescript
// WRONG - No examples
const result = await ctx.integrations.cohere.apiRequest(
  {
    method: "POST",
    path: "/classify",
    body: {
      inputs: ["Great product!"],
      // Missing examples!
    },
  },
  { response: ClassifyResponseSchema },
);

// CORRECT - Include examples
const result = await ctx.integrations.cohere.apiRequest(
  {
    method: "POST",
    path: "/classify",
    body: {
      inputs: ["Great product!"],
      examples: [
        { text: "I love this!", label: "positive" },
        { text: "Terrible", label: "negative" },
      ],
    },
  },
  { response: ClassifyResponseSchema },
);
```

## Error Handling

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

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

## API Reference

- [Cohere API Reference](https://docs.cohere.com/reference/about)
- [Chat](https://docs.cohere.com/reference/chat)
- [Embed](https://docs.cohere.com/reference/embed)
- [Classify](https://docs.cohere.com/reference/classify)
- [Rerank](https://docs.cohere.com/reference/rerank)
