# Changelog

All notable changes to `@audin.ai/operator-sdk` are documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

Because the SDK talks to the Audin operator service over a versioned wire
protocol (currently **v1**), an **incompatible change to that protocol is a
breaking change** and triggers a MAJOR version bump.

## [Unreleased]

### Changed

- License changed from `UNLICENSED` to **MIT** ahead of the first public npm
  release. The SDK is now distributable under the MIT terms (see `LICENSE`).

## [0.3.0] - 2026-06-10

### Added

- **`setAudioConstraints(constraints)`** on `AudinOperator` — switch the
  microphone input device (or any `MediaTrackConstraints`) at runtime, e.g.
  `op.setAudioConstraints({ deviceId: { exact: id }, echoCancellation: true })`.
  The new constraints are read when the next call's audio leg opens, so the
  change takes effect from the NEXT `dial()`/accepted inbound call; a call
  already in progress keeps the device its bridge opened with (the microphone is
  not re-opened mid-call).

## [0.2.1] - 2026-06-10

### Fixed

- Capture/playback frozen after first audio block — resample read-head
  overshoot caused a `RangeError` in the worklet. The capture resampler's
  fractional read head could advance past the end of the accumulated buffer,
  so on the next `process()` the buffer-grow step computed a negative offset
  and threw, stopping the processor after the very first block and muting both
  directions. The read head is now clamped to the buffer length so it never
  produces a negative offset. Also added an `onprocessorerror` handler so any
  future worklet error is logged instead of failing silently.

## [0.2.0] - 2026-06-10

### Added

- **`listPhoneNumbers()`** on `AudinOperator` — fetch the phone numbers the
  account owns (`{ id, phoneNumber, displayName }[]`) directly via the SDK using
  the same short-lived session token as the WebSockets. The Account API Key
  never enters the browser. On a `401` the cached token is dropped and the
  request is retried once with a fresh token; a persistent `401` throws an
  `OperatorRequestError` with code `UNAUTHORIZED`. New exports:
  `OperatorPhoneNumber` (type) and `OperatorRequestError` (class).
- **Token manager (internal)** — session tokens are now obtained through a
  central cache shared by the REST helper, the presence WebSocket and the audio
  WebSocket. A valid cached token is reused (using its `expiresAt` when present,
  with a safety skew, or a conservative TTL otherwise) so a `listPhoneNumbers()`
  → `goOnline()` → `dial()` sequence mints a single token. Concurrent callers
  share one in-flight `getToken()`. The cache is invalidated on auth failures
  (REST `401` / auth-related WebSocket close) so the next use re-mints.

## [0.1.0] - 2026-06-09

Initial public release.

### Added

- **Presence client** — connect/disconnect an operator presence channel, go
  online on a set of phone numbers and receive availability confirmations,
  with automatic reconnection (configurable backoff) and heartbeats.
- **Audio client** — microphone capture and full-duplex audio over the call's
  audio channel, with mute/unmute.
- **AudioWorklet μ-law pipeline** — capture-side downsampling to 8 kHz +
  G.711 μ-law encoding, playback-side μ-law decoding + upsampling, run off the
  main thread. Codec and resampling helpers (`encodeMuLaw`, `decodeMuLaw`,
  `resampleLinear`, …) are also exported for advanced integrators.
- **Outbound calls** — `dial(to, { callerId })` placing an outbound call.
- **Inbound calls** — `incomingCall` events with `accept()` / `reject()`.
- **Active-call controls** — `mute(on)` and `hangup()`.
- **Single-active-call concurrency (MVP)** — while a call is live, new inbound
  offers are auto-declined and `dial()` rejects.
- **Typed event API** — `on` / `off` / `once` for `presenceStateChanged`,
  `availabilityChanged`, `incomingCall`, `callStarted`, `callEnded`, `error`.
- Ships as **ESM** (`dist/audin-operator-sdk.js`) and **UMD**
  (`dist/audin-operator-sdk.umd.cjs`) with full **TypeScript declarations**
  (`dist/index.d.ts`). Zero runtime dependencies.

### Known limitations

- **`sendDtmf` is not yet supported end-to-end.** The digit is validated and
  emitted as a control message, but the server does not yet forward the tones
  onto the telephone network, so the far end will not hear them. The method and
  its wire message are kept so that enabling it server-side in a future release
  needs no SDK change.

[Unreleased]: https://bitbucket.org/thecovesrl/audin-ai/branches/compare/main%0Av0.3.0
[0.3.0]: https://bitbucket.org/thecovesrl/audin-ai/branches/compare/v0.3.0%0Av0.2.1
[0.2.1]: https://bitbucket.org/thecovesrl/audin-ai/branches/compare/v0.2.1%0Av0.2.0
[0.2.0]: https://bitbucket.org/thecovesrl/audin-ai/branches/compare/v0.2.0%0Av0.1.0
[0.1.0]: https://bitbucket.org/thecovesrl/audin-ai/src/v0.1.0/audin-operator-sdk
