> ## Documentation Index
> Fetch the complete documentation index at: https://docs.agnost.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Spectrum-TS

> Capture traces from Photon Spectrum-TS with native OpenTelemetry telemetry

Spectrum-TS has built-in OpenTelemetry instrumentation. Enable it with `telemetry: true`, then route its OTLP exporter to Agnost with standard `OTEL_EXPORTER_OTLP_*` environment variables.

Note: Spectrum telemetry is exported by the `spectrum-ts` package itself, so the app must have `spectrum-ts` installed. The umbrella package includes the official provider packages; install a scoped `@spectrum-ts/*` package only if the app imports that provider directly.

## 1. Install

**Already have `spectrum-ts` installed?** Skip.

```bash theme={null}
npm install spectrum-ts
```

Official provider imports:

| Provider          | Umbrella import                           | Direct package                   |
| ----------------- | ----------------------------------------- | -------------------------------- |
| Telegram          | `spectrum-ts/providers/telegram`          | `@spectrum-ts/telegram`          |
| Slack             | `spectrum-ts/providers/slack`             | `@spectrum-ts/slack`             |
| WhatsApp Business | `spectrum-ts/providers/whatsapp-business` | `@spectrum-ts/whatsapp-business` |
| iMessage          | `spectrum-ts/providers/imessage`          | `@spectrum-ts/imessage`          |
| Terminal          | `spectrum-ts/providers/terminal`          | `@spectrum-ts/terminal`          |

## 2. Point Spectrum telemetry at Agnost

Set these before starting the Spectrum app:

```bash theme={null}
export AGNOST_ORG_ID=<your-org-id>
export OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=https://otel.agnost.ai/v1/traces
export OTEL_EXPORTER_OTLP_HEADERS="X-Agnost-Org-ID=$AGNOST_ORG_ID"
export OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf
```

## 3. Enable Spectrum telemetry

```typescript theme={null}
import { randomBytes } from "node:crypto";
import { Spectrum } from "spectrum-ts";
import { telegram } from "spectrum-ts/providers/telegram";

const hex = (bytes: number) => randomBytes(bytes).toString("hex");
const nsNow = () => String(BigInt(Date.now()) * 1_000_000n);
const otelValue = (value: string) => ({ stringValue: value });

async function emitAgnostTurn(input: string, output: string, spaceId: string, userId?: string) {
  await fetch(process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT!, {
    method: "POST",
    headers: {
      "content-type": "application/json",
      "X-Agnost-Org-ID": process.env.AGNOST_ORG_ID!,
    },
    body: JSON.stringify({
      resourceSpans: [{
        resource: { attributes: [{ key: "service.name", value: otelValue("spectrum-ts") }] },
        scopeSpans: [{
          scope: { name: "agnost-spectrum-text" },
          spans: [{
            traceId: hex(16),
            spanId: hex(8),
            name: "tool.spectrum.turn",
            kind: 1,
            startTimeUnixNano: nsNow(),
            endTimeUnixNano: nsNow(),
            status: { code: 1 },
            attributes: [
              { key: "agnost.session_id", value: otelValue(spaceId) },
              ...(userId ? [{ key: "agnost.user_id", value: otelValue(userId) }] : []),
              { key: "input", value: otelValue(input) },
              { key: "output", value: otelValue(output) },
            ],
          }],
        }],
      }],
    }),
  });
}

const app = await Spectrum({
  projectId: process.env.PROJECT_ID!,
  projectSecret: process.env.PROJECT_SECRET!,
  providers: [
    // Telegram is only an example. Any official Spectrum provider works with
    // the same telemetry config.
    telegram.config({ botToken: process.env.TELEGRAM_BOT_TOKEN! }),
  ],
  telemetry: true,
});

for await (const [space, message] of app.messages) {
  if (message.content.type !== "text") continue;

  const input = message.content.text;
  const output = `Echo: ${input}`;
  await space.send(output);
  await emitAgnostTurn(input, output, space.id, message.sender?.id);
}
```

`telemetry: true` sends Spectrum's native spans for provider/session/message metadata. The `tool.spectrum.turn` span sends the transcript text that Agnost Chat View renders.

## Local Sample

```bash theme={null}
npm create spectrum-project@latest clank -- --providers telegram
cd clank

export PROJECT_ID=<spectrum-project-id>
export PROJECT_SECRET=<spectrum-project-secret>
export TELEGRAM_BOT_TOKEN=<telegram-bot-token>
export AGNOST_ORG_ID=<your-org-id>
export OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=https://otel.agnost.ai/v1/traces
export OTEL_EXPORTER_OTLP_HEADERS="X-Agnost-Org-ID=$AGNOST_ORG_ID"
export OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf
```

Use the provider you need, for example `telegram`, `slack`, `whatsapp-business`, `imessage`, or `terminal`. Then set `telemetry: true` in the generated `Spectrum(...)` config. For transcript text, add the small `tool.spectrum.turn` OTLP JSON helper from the sample app.

## References

* [Spectrum-TS telemetry](https://photon.codes/docs/spectrum-ts/getting-started#telemetry)
* [Spectrum-TS repository](https://github.com/photon-hq/spectrum-ts)
