feat(sdkx): checkpoint backends (sqlite/postgres) + image-LLM OTel parity#78
Merged
Conversation
## 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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Phase 1 of the sdkx track that closes the v0.2 roadmap. Two themes,
one PR (体量小、共享 `sdkx/v0.2.7` tag):
`engine.Resumer` / `engine.LoadAndResume` APIs shipped in
`sdk/v0.2.9`.
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
```
for `Wrap` callers) and a `WithTable` option for multi-vessel
namespacing.
`CheckpointDeleter` interfaces.
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
16-way concurrent Save; postgres skips when `FC_PG_DSN` is unset.
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