feat: add Go client package with sync facade over async /jobs
Adds client/ -- a public Go package providing a synchronous facade over
foreman's async POST /jobs API (Level 1 integration per ADR-0011).
Two delivery modes:
- Webhook receiver (preferred): ephemeral HTTP server on random port,
pushes results immediately, verifies HMAC when configured
- Polling fallback: polls GET /jobs/{id} at configurable interval
Also includes Tags() and Embed() helpers, bearer auth support, and
comprehensive integration tests against the real foreman HTTP handlers.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
+38
@@ -165,3 +165,41 @@ with the real SQLite-backed job queue and single worker loop.
|
||||
no HMAC when no secret, signature format validation.
|
||||
- Artifacts: small inline, large by URL, empty returns nil.
|
||||
- TTL pruner: deletes old terminal jobs.
|
||||
|
||||
## Phase 5: Go client package + go-llm Foreman() constructor — 2026-05-23
|
||||
|
||||
**Level 0 + Level 1 integration complete** (ADR-0011).
|
||||
|
||||
- `client/` — public Go client package (sync facade over async `/jobs` API):
|
||||
- `client.New(baseURL, opts...)`: configurable client with bearer auth,
|
||||
webhook secret, custom HTTP client, poll interval.
|
||||
- `client.Submit(ctx, SubmitRequest) (*Result, error)`: synchronous
|
||||
submission — blocks until the job reaches a terminal state (`done`/`failed`).
|
||||
- **Two delivery modes:**
|
||||
- **Webhook receiver (preferred):** starts an ephemeral HTTP server on a
|
||||
random port, sets `state_webhook_url`, waits for the `done`/`failed`
|
||||
webhook event. Verifies HMAC signature when `WithWebhookSecret` is set.
|
||||
Falls back to polling automatically if the listener fails to bind.
|
||||
- **Polling fallback:** polls `GET /jobs/{id}` at `pollInterval` (default
|
||||
2s) until terminal state. Forced via `WithPollingMode()`.
|
||||
- `client.Tags(ctx)`: fetches installed models via `GET /api/tags`.
|
||||
- `client.Embed(ctx, EmbedRequest)`: sends embedding requests via
|
||||
`POST /api/embed` (bypasses queue, ADR-0013).
|
||||
- Both modes respect context cancellation/deadline and clean up resources.
|
||||
|
||||
- Tests (all passing with `-race`):
|
||||
- Happy path (polling): submit, poll, verify completed result + artifacts.
|
||||
- Happy path (webhook): submit with webhook receiver, verify push delivery.
|
||||
- Failed job: returns Result with state=failed and error message.
|
||||
- Context timeout: returns error on deadline exceeded.
|
||||
- Auth: bearer token sent when configured; 401 without it.
|
||||
- HMAC webhook verification: signed webhooks verified correctly.
|
||||
- Tags and Embed endpoints: round-trip through the client.
|
||||
- Missing model validation: returns error before network call.
|
||||
|
||||
- go-llm integration (Level 0):
|
||||
- `llm.Foreman(baseURL, apiKey, opts...)` constructor added to
|
||||
`v2/constructors.go` on branch `feat/foreman-constructor`.
|
||||
- Delegates to existing `ollamaProvider.New()` — zero new code paths.
|
||||
- DD#9 added to `v2/CLAUDE.md`.
|
||||
- PR: https://gitea.stevedudenhoeffer.com/steve/go-llm/pulls/4
|
||||
|
||||
Reference in New Issue
Block a user