4 Commits

Author SHA1 Message Date
steve 8d4e99be1a ci: optimize workflow by merging jobs and adding module cache
CI / Build, Test & Lint (push) Successful in 11m31s
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-23 23:28:30 -04:00
steve 834b093282 fix(ci): write correct YAML workflow (was double-encoded as base64)
CI / Lint (push) Successful in 17s
CI / V2 Module (push) Successful in 1m40s
The previous CI fix commits stored the workflow file as a literal base64
string instead of decoded YAML, so Gitea could not parse it as a valid
workflow and no CI runs triggered. This writes the correct YAML content.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-23 23:24:52 -04:00
steve 74e1170bf3 fix(ci): remove root-module job, scope all jobs to v2/ working directory
The repo has no go.mod at the root — the only module is under v2/.
The root-module job and the root-level go mod tidy in lint both fail with
'go: go.mod file not found'. Drop root-module entirely and ensure both
v2-module and lint use working-directory: v2."
2026-05-24 03:13:52 +00:00
steve 12b229e13a ci: fix workflow to use v2/ module directory 2026-05-24 03:02:42 +00:00
3 changed files with 4 additions and 75 deletions
+4 -41
View File
@@ -7,30 +7,8 @@ on:
branches: ["*"] branches: ["*"]
jobs: jobs:
root-module: ci:
name: Root Module name: Build, Test & Lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: "1.24"
- name: Download dependencies
run: go mod download
- name: Build
run: go build ./...
- name: Vet
run: go vet ./...
- name: Test
run: go test -race -count=1 ./...
v2-module:
name: V2 Module
runs-on: ubuntu-latest runs-on: ubuntu-latest
defaults: defaults:
run: run:
@@ -40,7 +18,8 @@ jobs:
- uses: actions/setup-go@v5 - uses: actions/setup-go@v5
with: with:
go-version: "1.24" go-version-file: v2/go.mod
cache-dependency-path: v2/go.sum
- name: Download dependencies - name: Download dependencies
run: go mod download run: go mod download
@@ -54,23 +33,7 @@ jobs:
- name: Test - name: Test
run: go test -race -count=1 ./... run: go test -race -count=1 ./...
lint:
name: Lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: "1.24"
- name: Check root module tidiness
run: |
go mod tidy
git diff --exit-code go.mod go.sum
- name: Check v2 module tidiness - name: Check v2 module tidiness
run: | run: |
cd v2
go mod tidy go mod tidy
git diff --exit-code go.mod go.sum git diff --exit-code go.mod go.sum
-10
View File
@@ -32,13 +32,3 @@
6. Streaming via pull-based `StreamReader.Next()` 6. Streaming via pull-based `StreamReader.Next()`
7. Middleware for logging, retry, timeout, usage tracking 7. Middleware for logging, retry, timeout, usage tracking
8. Ollama uses the native `/api/chat` API rather than the OpenAI-compat `/v1` endpoint. Native API supports `think: false` for thinking-capable models, has more reliable tool calling, and is approximately 15-20% lower latency. Both local and cloud share the same provider; only the apiKey/baseURL differ. `llm.Ollama()` targets `http://localhost:11434` with no Authorization header; `llm.OllamaCloud(key)` targets `https://ollama.com` with `Authorization: Bearer <key>`. 8. Ollama uses the native `/api/chat` API rather than the OpenAI-compat `/v1` endpoint. Native API supports `think: false` for thinking-capable models, has more reliable tool calling, and is approximately 15-20% lower latency. Both local and cloud share the same provider; only the apiKey/baseURL differ. `llm.Ollama()` targets `http://localhost:11434` with no Authorization header; `llm.OllamaCloud(key)` targets `https://ollama.com` with `Authorization: Bearer <key>`.
### DD#9 — foreman integration via thin Foreman() constructor (2026-05-23)
**Context:** foreman is a private queued Ollama endpoint. It speaks native Ollama
on the wire, so no new provider is needed.
**Decision:** `llm.Foreman(baseURL, apiKey)` delegates to `ollamaProvider.New()`.
baseURL is positional and required (no sensible default for a private daemon).
apiKey can be empty for network-trusted deployments.
**Consequence:** Zero new code paths. Streaming, tool use, and think work through
the existing native ollama provider. A dedicated foreman provider (Level 2) is
deferred unless async /jobs or webhook integration is needed at the llm layer.
-24
View File
@@ -137,27 +137,3 @@ func OllamaCloud(apiKey string, opts ...ClientOption) *Client {
} }
return NewClient(ollamaProvider.New(apiKey, baseURL)) return NewClient(ollamaProvider.New(apiKey, baseURL))
} }
// Foreman creates a client targeting a foreman daemon (a private, authenticated
// Ollama endpoint with queuing and observability). baseURL is required
// (e.g. "http://foreman:8080"). apiKey is the optional static bearer token; pass
// "" for an unauthenticated (network-trusted) deployment.
//
// foreman speaks native Ollama on the wire, so this delegates to the ollama
// provider unchanged — streaming, tool use, and think all work transparently.
//
// See: https://gitea.stevedudenhoeffer.com/steve/foreman
//
// Example:
//
// model := llm.Foreman("http://foreman.orgrimmar:8080", token).Model("qwen3:30b")
func Foreman(baseURL, apiKey string, opts ...ClientOption) *Client {
cfg := &clientConfig{}
for _, opt := range opts {
opt(cfg)
}
if cfg.baseURL != "" {
baseURL = cfg.baseURL
}
return NewClient(ollamaProvider.New(apiKey, baseURL))
}