Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions sdks/elixir/sdk/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,35 @@
# Changelog

## [Unreleased]

### Added

- **MOS-14 device-id contract (SDK layer)** — `Moss.DeviceId` sources a stable,
persisted, per-device id (UUIDv4, no OS vendor id on this platform) and
memoizes it once per client so every telemetry surface (IndexManager,
ManageClient, Session) reports the same id — "one device, one id". Persisted
to `.moss-device-id` under `$XDG_CACHE_HOME/moss` (when set) else
`<home>/.moss` — the same scheme as the JS/Python/Go SDKs so one physical
device resolves to a single id across languages; non-synced/non-migrating;
falls back to an ephemeral id on any persistence error so a real operation
never fails over device-id work. Honors `MOSS_DISABLE_TELEMETRY` (truthy set,
trimmed/lowercased), checked at runtime before the memo fast-path. Threaded
through `Moss.Client.new/3` into all three surfaces (IndexManager, Session,
ManageClient). Contains zero telemetry HTTP/buffer/flush/event code — the
closed core owns transport.

### Blocked (native binding / CI)

- Handing the id to the core (setter mechanism, spec R5.2) is **not yet wired**:
the mono-repo Elixir NIF exposes no `set_device_id` entry point. The apply
path degrades gracefully (terminal success) until a `manager_set_device_id` /
`session_set_device_id` / `manage_set_device_id` NIF is added in
`bindings/native/moss_core/src/*` delegating to the core
`set_device_id(Option<String>)`. See the `MOS-14` TODOs in
`Moss.IndexManager`, `Moss.Session`, and `Moss.ManageClient`.

---

## [1.0.1] - 2026-04-05

### Changed
Expand Down
27 changes: 23 additions & 4 deletions sdks/elixir/sdk/lib/moss/client.ex
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,14 @@ defmodule Moss.Client do

@default_model_id "moss-minilm"

defstruct [:project_id, :project_key, :base_url, :client_id, :manage_ref, :manager_pid]
defstruct [:project_id, :project_key, :base_url, :client_id, :device_id, :manage_ref, :manager_pid]

@type t :: %__MODULE__{
project_id: String.t(),
project_key: String.t(),
base_url: String.t() | nil,
client_id: String.t(),
device_id: String.t() | nil,
manage_ref: reference(),
manager_pid: pid()
}
Expand All @@ -52,20 +53,35 @@ defmodule Moss.Client do
base_url = Keyword.get(opts, :base_url, nil)
client_id = Uniq.UUID.uuid4()

# MOS-14: source a stable, persisted, per-device id ONCE at client
# construction and thread it through every telemetry surface (the
# IndexManager, ManageClient, and any sessions) so a device counts once —
# "one device, one id" (spec R2.3, R3, R5.5). Sourcing/persistence/opt-out
# all happen here; nil means telemetry is disabled via
# MOSS_DISABLE_TELEMETRY, in which case no id is sourced and nothing is
# handed to the core (R4).
#
# The Elixir SDK has no client cache dir at this layer, so the per-user
# fallback dir (Moss.DeviceId.default_dir/0) is the persistence location.
{device_id, _state} = Moss.DeviceId.resolve_client(Moss.DeviceId.new_state(), nil)

with {:ok, ref} <- Moss.ManageClient.new(project_id, project_key,
base_url: base_url, client_id: client_id),
base_url: base_url, client_id: client_id,
device_id: device_id),
{:ok, pid} <- Moss.IndexManager.start_link(
project_id: project_id,
project_key: project_key,
base_url: base_url,
client_id: client_id
client_id: client_id,
device_id: device_id
) do
{:ok,
%__MODULE__{
project_id: project_id,
project_key: project_key,
base_url: base_url,
client_id: client_id,
device_id: device_id,
manage_ref: ref,
manager_pid: pid
}}
Expand Down Expand Up @@ -235,7 +251,10 @@ defmodule Moss.Client do
model_id: model_id,
project_id: client.project_id,
project_key: client.project_key,
client_id: client.client_id
client_id: client.client_id,
# MOS-14: sessions share the client's already-resolved device id
# so every surface of one client reports the same id (R5.5).
device_id: client.device_id
)
) do
# Silently attempt to load from cloud — ignore errors (index may not exist yet).
Expand Down
Loading
Loading