Skip to content

feat(sdkx): checkpoint backends (sqlite/postgres) + image-LLM OTel parity#78

Merged
lIang70 merged 1 commit into
mainfrom
feat/sdkx-phase1-checkpoint-otel
May 8, 2026
Merged

feat(sdkx): checkpoint backends (sqlite/postgres) + image-LLM OTel parity#78
lIang70 merged 1 commit into
mainfrom
feat/sdkx-phase1-checkpoint-otel

Conversation

@lIang70

@lIang70 lIang70 commented May 8, 2026

Copy link
Copy Markdown
Collaborator

Summary

Phase 1 of the sdkx track that closes the v0.2 roadmap. Two themes,
one PR (体量小、共享 `sdkx/v0.2.7` tag):

  1. Concrete `engine.CheckpointStore` backends for the new
    `engine.Resumer` / `engine.LoadAndResume` APIs shipped in
    `sdk/v0.2.9`.
  2. Image-LLM OTel parity — the 3 image adapters added in
    PR feat(sdkx/llm): add image-generation adapters + align chat caps #72 were missing the instrumentation every chat provider
    already ships. Closes the gap.

sdkx/engine/checkpoint/

```
├── conformance/ ← shared contract suite (Save/Load/List/Delete + concurrency)
├── sqlite/ ← modernc.org/sqlite, single-writer pool + busy_timeout
└── postgres/ ← jackc/pgx/v5 via pgxpool, JSONB + UPSERT
```

  • Both backends ship `Migrate(ctx)` (auto-run by `Open`, exposed
    for `Wrap` callers) and a `WithTable` option for multi-vessel
    namespacing.
  • Both implement the optional `CheckpointLister` and
    `CheckpointDeleter` interfaces.
  • Postgres tests gate on `FC_PG_DSN` env var, matching the pattern
    used by `sdkx/retrieval/postgres`.

`redis` checkpoint backend was deliberately scoped out — it is a
cache tier, not a source-of-truth, and its semantics differ enough
to warrant its own minor.

Image-LLM OTel parity (`sdkx/llm/{bytedance,minimax,qwen}/image`)

Each image adapter now follows the exact pattern the chat providers
use:

```go
ctx, span := telemetry.Tracer().Start(ctx,
fmt.Sprintf("llm.qwen-image.generate.%s", l.model),
trace.WithAttributes(
attribute.String(telemetry.AttrLLMProvider, providerKey),
attribute.String(telemetry.AttrLLMModel, l.model),
))
defer span.End()
// ... call, time, RecordLLMMetrics(success/error) ...
```

Provider keys `bytedance-image` / `minimax-image` / `qwen-image`
keep image traffic distinct from chat in dashboards.
`TokenUsage.OutputTokens` carries `image_count` (the only quantity
these endpoints report).

After this PR, every `llm.LLM` in sdkx — chat or image, direct or
delegating — emits OTel spans and records metrics through the same
`sdk/telemetry` helpers.

Test plan

  • `make fmt` clean
  • `go vet ./...` (sdkx)
  • `go test ./engine/checkpoint/...` — sqlite suite passes incl.
    16-way concurrent Save; postgres skips when `FC_PG_DSN` is unset.
  • `go test ./llm/{bytedance,minimax,qwen}/image` — green.
  • Postgres backend has not been exercised against a live PG
    instance in CI; suite design mirrors sdkx/retrieval/postgres which
    has the same gating.

Release notes

Cumulative bump for `sdkx/v0.2.7`. No `[skip-tag:sdkx]` marker —
this is a single-PR release.

Made with Cursor

## Checkpoint backends — sdkx/engine/checkpoint/{sqlite,postgres,conformance}

Concrete engine.CheckpointStore implementations so users of the
new engine.Resumer / engine.LoadAndResume APIs (sdk/v0.2.9) have
a production-grade place to land their state.

- sqlite — modernc.org/sqlite (pure Go, no cgo). Single-writer
  pool + busy_timeout=5s for SQLITE_BUSY safety. Good for
  single-process daemons (vesseld), embedded examples, tests.
- postgres — jackc/pgx/v5 via pgxpool. JSONB columns + UPSERT.
  Multi-writer safe; fits horizontally scaled vesseld fleets.
- conformance — table-driven contract suite shared by both
  backends (and any third-party impl). Subtests covering Save/
  Load/Roundtrip, missing-load, overwrite-latest, payload &
  attribute fidelity, concurrent saves, plus auto-skipping
  List/Delete subtests for backends that opt into the optional
  CheckpointLister/CheckpointDeleter interfaces.

Both backends ship Migrate() (run automatically by Open, exposed
for callers using Wrap on an existing pool/db) and a WithTable
option for multi-vessel namespacing.

Postgres tests gate on FC_PG_DSN env var, matching the pattern
already used by sdkx/retrieval/postgres.

## Image-LLM OTel parity — sdkx/llm/{bytedance,minimax,qwen}/image

The three image-generation adapters added in PR #72 were missing
the OTel instrumentation that every chat-LLM provider already
ships, leaving a coverage gap in the v0.2 OTel story.

Add the same telemetry.Tracer().Start + RecordLLMMetrics pattern
the chat providers use, with provider keys "bytedance-image" /
"minimax-image" / "qwen-image" so dashboards distinguish image
calls from chat. TokenUsage.OutputTokens carries image_count
(the only quantity the endpoints report) for spans that produce
images.

After this commit every llm.LLM in sdkx — chat or image, direct
or delegating — emits OTel spans and records metrics through the
same sdk/telemetry helpers.

## Tests

- go vet ./... — sdkx green
- go test ./engine/checkpoint/... — sqlite suite passes (incl.
  16-way concurrent Save); postgres suite passes when FC_PG_DSN
  is set, otherwise auto-skips.
- go test ./llm/{bytedance,minimax,qwen}/image — green.

Co-authored-by: Cursor <cursoragent@cursor.com>
@lIang70
lIang70 merged commit 52dd3b2 into main May 8, 2026
13 checks passed
@lIang70
lIang70 deleted the feat/sdkx-phase1-checkpoint-otel branch May 8, 2026 08:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant