{"_id":"@accordkit/provider-openai","name":"@accordkit/provider-openai","dist-tags":{"latest":"0.2.0"},"versions":{"0.2.0":{"name":"@accordkit/provider-openai","version":"0.2.0","description":"OpenAI SDK adapter that emits AccordKit normalized trace events.","repository":{"type":"git","url":"git+https://github.com/accordkit/provider-openai.git","directory":"packages/provider-openai"},"bugs":{"url":"https://github.com/accordkit/provider-openai/issues"},"homepage":"https://github.com/accordkit/provider-openai/tree/main?tab=readme-ov-file","license":"MIT","type":"module","main":"dist/index.cjs","module":"dist/index.js","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"publishConfig":{"access":"public"},"sideEffects":false,"scripts":{"build":"tsup src/index.ts --format esm,cjs --dts","dev":"tsup --watch --clean=false","clean":"rimraf dist","typecheck":"tsc -p tsconfig.json --noEmit","test":"vitest run --reporter=dot","test:watch":"vitest","docs":"typedoc --options typedoc.json","lint":"eslint . --ext .ts","lint:fix":"eslint . --ext .ts --fix","format":"prettier --write ."},"peerDependencies":{"openai":"^4 || ^5"},"dependencies":{"@accordkit/tracer":"^0.2.0"},"devDependencies":{"@types/node":"^24.8.0","@typescript-eslint/eslint-plugin":"^8.46.0","@typescript-eslint/parser":"^8.46.0","@vitest/eslint-plugin":"^1.3.23","eslint":"^9.38.0","eslint-config-prettier":"^10.1.8","eslint-plugin-import":"^2.32.0","eslint-plugin-unused-imports":"^4.2.0","globals":"^16.4.0","openai":"^4.0.0","prettier":"^3.6.2","rimraf":"^6.0.0","tsup":"^8.1.0","typedoc":"^0.28.14","typedoc-plugin-markdown":"^4.9.0","typescript":"^5.9.3","vitest":"^3.2.0"},"_id":"@accordkit/provider-openai@0.2.0","gitHead":"92db7c613dafd9a98d4000ded452bc63f7bbb6b0","_nodeVersion":"24.9.0","_npmVersion":"11.6.0","dist":{"integrity":"sha512-3Yy0irZr9ryQujZeTFfuF0NGeybVSBEJ2BtTC+8tgEZMYBHbgt6ZN3Up6i9q2syxpYkw37q4y7HaniwEz4elxw==","shasum":"3fecdaa2e094b2cdc8e9a46fccee56e5ade0b171","tarball":"https://registry.npmjs.org/@accordkit/provider-openai/-/provider-openai-0.2.0.tgz","fileCount":9,"unpackedSize":184620,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQDeDYmIuP3YYD/8ETrvMyIJShmXhmpVU+qaOlRSsEhlIQIgcP0tG05qSze6xgyvoZSgAn/sahoHVf2s3LqpEng9DUc="}]},"_npmUser":{"name":"faranjit","email":"trkmen.blent@gmail.com"},"directories":{},"maintainers":[{"name":"faranjit","email":"trkmen.blent@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/provider-openai_0.2.0_1762116716708_0.14551377196239956"},"_hasShrinkwrap":false}},"time":{"created":"2025-11-02T20:51:56.587Z","0.2.0":"2025-11-02T20:51:56.901Z","modified":"2025-11-02T20:51:57.172Z"},"maintainers":[{"name":"faranjit","email":"trkmen.blent@gmail.com"}],"description":"OpenAI SDK adapter that emits AccordKit normalized trace events.","homepage":"https://github.com/accordkit/provider-openai/tree/main?tab=readme-ov-file","repository":{"type":"git","url":"git+https://github.com/accordkit/provider-openai.git","directory":"packages/provider-openai"},"bugs":{"url":"https://github.com/accordkit/provider-openai/issues"},"license":"MIT","readme":"<p align=\"center\">\n  <img src=\"https://docs.accordkit.dev/img/logo.png\" height=\"80\">\n</p>\n\n<h1 align=\"center\">AccordKit - Provider OpenAI</h1>\n\n<p align=\"center\">\n  AccordKit OpenAI Provider, a lightweight adapter that adds tracing to your OpenAI SDK calls.\n  <br />\n  <a href=\"https://docs.accordkit.dev\"><strong>📘 Read the docs</strong></a>\n</p>\n\n---\n\n[![Part of AccordKit](https://img.shields.io/badge/AccordKit-ecosystem-00cc88?style=flat-square)](https://github.com/accordkit)\n\n> **Part of the [AccordKit](https://github.com/accordkit) ecosystem**  \n> an open, AI-agnostic tracing SDK for LLM-powered and ChatGPT-interoperable applications.  \n> AccordKit gives developers local-first observability: **no vendor lock-in, no opaque dashboards**, just clean event streams and tools that work anywhere.\n\n> AccordKit adapter that instruments the official OpenAI SDK and emits normalized\n> tracing events (`message`, `tool_call`, `usage`, `tool_result`, `span`) through\n> an AccordKit [`Tracer`](https://github.com/accordkit/tracer).\n\n## Overview\n\n- **Drop-in wrapper** — call `withOpenAI(new OpenAI(), tracer)` and continue using the SDK.\n- **Complete event coverage** — prompts, assistant responses, tool invocations, token usage, and latency are captured.\n- **Streaming aware** — streaming completions flush events when `finalChatCompletion()` resolves.\n- **Trace-friendly** — every event reuses a shared `ctx` so downstream tooling can correlate activity.\n\n## Installation\n\n```bash\npnpm add @accordkit/tracer @accordkit/provider-openai openai\n```\n\n## Quickstart\n\n```ts\nimport OpenAI from 'openai';\nimport { FileSink, Tracer } from '@accordkit/tracer';\nimport { withOpenAI } from '@accordkit/provider-openai';\n\nconst tracer = new Tracer({ sink: new FileSink() });\nconst client = withOpenAI(new OpenAI({ apiKey: process.env.OPENAI_API_KEY! }), tracer);\n\nawait client.chat.completions.create({\n  model: 'gpt-4o',\n  messages: [\n    { role: 'system', content: 'You are AccordKit.' },\n    { role: 'user', content: 'Say hi!' },\n  ],\n});\n```\n\nEvents are written to the `FileSink` in normalized AccordKit format. Swap in any other sink (browser, HTTP, etc.) depending on your deployment needs.\n\n## API\n\n### `withOpenAI(client, tracer, options?)`\n\n| Parameter | Type                               | Description                                      |\n| --------- | ---------------------------------- | ------------------------------------------------ |\n| `client`  | `OpenAI`                           | The OpenAI SDK instance to instrument.           |\n| `tracer`  | `Tracer`                           | AccordKit tracer responsible for writing events. |\n| `options` | [`OpenAIAdapterOptions`](#options) | Optional tuning knobs described below.           |\n\nReturns a proxy that mirrors the OpenAI SDK. Re-wrapping the same client always returns the existing proxy so instrumentation is only applied once.\n\n### Options\n\n| Option | Default | Description |\n|--------|---------|-------------|\n| `enableResponsesApi` | `false` | Wrap the beta `responses` namespace so `responses.create` emits events that mirror chat completions. |\n| `enableImagesApi` | `false` | Instrument `images.generate` calls to capture latency and success/failure without emitting large binary payloads. |\n| `enableAudioApi` | `false` | Instrument `audio.speech/transcriptions/translations` namespaces. |\n| `provider` | `'openai'` | Provider identifier attached to every event. Override if you proxy the API through a custom service. |\n| `operationName` | `'openai.chat.completions.create'` | Logical operation name that shows up on `tool_result` and `span` events. |\n| `emitPrompts` | `true` | Emit `message` events for system/user prompts before submitting the request. |\n| `emitResponses` | `true` | Emit `message` events for assistant completions in the response. |\n| `emitToolCalls` | `true` | Emit `tool_call` events for function/tool invocations requested by the assistant (including legacy `function_call`). |\n| `emitUsage` | `true` | Emit `usage` events when OpenAI reports token accounting. |\n| `emitToolResults` | `true` | Emit `tool_result` events summarizing latency and success/error details. |\n| `emitSpan` | `true` | Emit `span` events around each request with duration and status metadata. |\n\n```ts\nwithOpenAI(client, tracer, {\n  provider: 'openai',\n  emitResponses: false, // example override: skip assistant message emission\n});\n```\n\nAll boolean flags default to `true`; omit overrides unless you intentionally want less output.\n\n## Emitted Events\n\n| Event         | When it fires                                                  | Notable fields                                     |\n| ------------- | -------------------------------------------------------------- | -------------------------------------------------- |\n| `message`     | Before the API call (prompts) and after completion (assistant) | `role`, `content`, `format`, `requestId`           |\n| `tool_call`   | When the assistant requests a tool/function                    | `tool`, parsed JSON `input`, `$ext.id`             |\n| `usage`       | When OpenAI reports token accounting                           | `inputTokens`, `outputTokens`, `$ext.totalTokens`  |\n| `tool_result` | After the API call completes or throws                         | `ok`, `latencyMs`, `output` (summary or error)     |\n| `span`        | Surrounding each API call (if `emitSpan`)                      | `operation`, `durationMs`, `status`, `attrs.model` |\n\nEvery event reuses the same `ctx` so grouping by `traceId`/`spanId` is straightforward.\n\n## Streaming Support\n\nStreaming responses are detected automatically. Events are buffered until\n`finalChatCompletion()` resolves, at which point the adapter:\n\n1. Emits accumulated assistant/tool events.\n2. Emits `usage`, `tool_result`, and `span` events with `attrs.stream = true`.\n\nEnsure your OpenAI SDK version exposes `finalChatCompletion()` (v4+). When `enableResponsesApi`\nis set, the adapter coerces `responses.create` output into a chat-like completion so the same\nstreaming hooks and event emitters apply.\n\n## Error Handling\n\nExceptions thrown by `chat.completions.create` are re-thrown after emitting:\n\n- A failed `tool_result` event containing the serialized error.\n- A `span` event with `status: 'error'` and the error message in `attrs.error`.\n\nThis keeps tracing consistent while preserving native SDK error semantics.\n\n### Optional APIs\n\nEnable extra endpoints while keeping default minimal surface:\n\n```ts\nwithOpenAI(openai, tracer, {\n  enableResponsesApi: true,\n  enableImagesApi: true,\n  enableAudioApi: true,\n});\n```\n\n## Emitted events by OpenAI method (per flag)\n\n| OpenAI method                                 | Flag                    | prompts | responses | usage | tool_result | span |\n|-----------------------------------------------|-------------------------|:-------:|:---------:|:----:|:-----------:|:----:|\n| `chat.completions.create`                     | _none_ (always on)      |   ✓     |     ✓     |  ✓   |      ✓      |  ✓   |\n| `chat.completions.create (stream)`            | _none_ (always on)      |   ✓     |  ✓ (final)|  ✓   |      ✓      |  ✓   |\n| `responses.create`                            | `enableResponsesApi`    |   —     |     ✓     |  ✓   |      ✓      |  ✓   |\n| `images.generate`                             | `enableImagesApi`       |   —     |     —     |  —   |      ✓      |  ✓   |\n| `audio.speech.create`                         | `enableAudioApi`        |   —     |     —     |  —   |      ✓      |  ✓   |\n| `audio.transcriptions.create`                 | `enableAudioApi`        |   —     |     —     |  —   |      ✓      |  ✓   |\n| `audio.translations.create`                   | `enableAudioApi`        |   —     |     —     |  —   |      ✓      |  ✓   |\n\n**Notes**  \n- For chat streaming we emit **final** artifacts after the stream resolves. Partial chunk emission is currently **off** by default.\n- `images`/`audio` endpoints intentionally avoid attaching large binary payloads; only summary info is sent via `tool_result` plus `span` timings.\n\n## TypeScript\n\nThe adapter ships with full TypeScript typings. Helper modules use discriminated\nunions to keep event emission strongly typed, and lint rules enforce no `any`.\n\n## Contributing\n\n- Run `pnpm --filter @accordkit/provider-openai lint` and `pnpm --filter @accordkit/provider-openai test` before submitting changes.\n- Tests rely on Vitest with in-memory sinks and mocked OpenAI clients—no API key required.\n- Please document new options or behaviors directly in this README.\n\n## License\n\nMIT © AccordKit contributors.\n","readmeFilename":"README.md","_rev":"1-f24db2cef15d827bd631939f331ee76f"}