catence 0.2.0-beta.1 → 0.2.0-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -153,7 +153,7 @@ export OPENAI_API_KEY='…'
153
153
  uvx catence-console@0.2.0 serve
154
154
  ```
155
155
 
156
- On the first authenticated visit, the Console wizard asks for an Azure, OpenAI, or Anthropic model and writes only the non-secret model configuration to `~/.catence/config.json`. Model-provider keys remain process environment variables. The Console settings include an athlete selector; the server overwrites model-supplied athlete scope with that selected value on every personal-data call.
156
+ On the first authenticated visit, the Console wizard asks for an OpenAI-compatible, OpenAI, or Anthropic model and writes only the non-secret model configuration to `~/.catence/config.json`. The `openai-compatible` option covers Azure and Opencode; see [`docs/llm-providers.md`](docs/llm-providers.md). Model-provider keys remain process environment variables. The Console settings include an athlete selector; the server overwrites model-supplied athlete scope with that selected value on every personal-data call.
157
157
 
158
158
  To preflight the Console and a running runtime:
159
159
 
@@ -23,36 +23,23 @@
23
23
  }
24
24
  },
25
25
  "console": {
26
- "defaultProfile": "azure-foundry",
26
+ "defaultProfile": "openai",
27
27
  "limits": {
28
28
  "toolRounds": 8,
29
29
  "toolResultCharacters": 24000
30
30
  },
31
31
  "profiles": {
32
- "azure-foundry": {
33
- "label": "Azure Foundry",
34
- "defaultModel": "terra",
35
- "defaultReasoningEffort": "medium",
36
- "models": {
37
- "terra": { "label": "GPT-5.6 Terra", "model": "azure_ai/gpt-5.6-terra" },
38
- "luna": { "label": "GPT-5.6 Luna", "model": "azure_ai/gpt-5.6-luna" },
39
- "sol": { "label": "GPT-5.6 Sol", "model": "azure_ai/gpt-5.6-sol" }
40
- },
41
- "apiKeyEnv": "AZURE_API_KEY",
42
- "apiBaseEnv": "AZURE_API_BASE",
43
- "apiVersionEnv": "AZURE_API_VERSION"
44
- },
45
- "opencode": {
46
- "label": "OpenCode-compatible",
47
- "model": "openai/your-model-name",
48
- "apiKeyEnv": "OPENCODE_API_KEY",
49
- "apiBaseEnv": "OPENCODE_API_BASE"
50
- },
51
32
  "openai": {
52
33
  "label": "OpenAI",
53
34
  "model": "openai/gpt-5-mini",
54
35
  "apiKeyEnv": "OPENAI_API_KEY"
55
36
  },
37
+ "openai-compatible": {
38
+ "label": "OpenAI-compatible",
39
+ "model": "openai/your-model-name",
40
+ "apiKeyEnv": "OPENAI_API_KEY",
41
+ "apiBaseEnv": "OPENAI_API_BASE"
42
+ },
56
43
  "anthropic": {
57
44
  "label": "Anthropic",
58
45
  "model": "anthropic/claude-sonnet-4-5",
@@ -3,7 +3,7 @@
3
3
  * Keep these values synchronized with release/manifest.json; release checks
4
4
  * deliberately reject drift before a package can be published.
5
5
  */
6
- export declare const CATENCE_RUNTIME_VERSION = "0.2.0-beta.1";
6
+ export declare const CATENCE_RUNTIME_VERSION = "0.2.0-beta.2";
7
7
  export declare const CATENCE_PROTOCOL_VERSION = 1;
8
8
  export type CatenceRuntimeCapabilities = {
9
9
  mcp: true;
@@ -3,7 +3,7 @@
3
3
  * Keep these values synchronized with release/manifest.json; release checks
4
4
  * deliberately reject drift before a package can be published.
5
5
  */
6
- export const CATENCE_RUNTIME_VERSION = '0.2.0-beta.1';
6
+ export const CATENCE_RUNTIME_VERSION = '0.2.0-beta.2';
7
7
  export const CATENCE_PROTOCOL_VERSION = 1;
8
8
  export function catenceRuntimeHealth() {
9
9
  return {
@@ -0,0 +1,237 @@
1
+ # Console LLM providers
2
+
3
+ Catence Console talks to a model through [LiteLLM](https://docs.litellm.ai/).
4
+ There are exactly three provider shapes: **OpenAI**, **Anthropic**, and a
5
+ generic **OpenAI-compatible** profile. Azure and Opencode are not special cases
6
+ in the code: both are reached through the OpenAI-compatible profile, and the
7
+ steps for each are documented below.
8
+
9
+ ## How configuration is split
10
+
11
+ Catence never stores a credential value in `config.json`. A Console profile
12
+ records only a LiteLLM model name and the *names* of the environment variables
13
+ that hold the key, base URL, and (optionally) API version. The values
14
+ themselves stay in the Console process environment.
15
+
16
+ ```jsonc
17
+ // ~/.catence/config.json (or /data/config.json inside the Docker image)
18
+ {
19
+ "console": {
20
+ "defaultProfile": "openai",
21
+ "profiles": {
22
+ "openai": {
23
+ "label": "OpenAI",
24
+ "model": "openai/gpt-5-mini",
25
+ "apiKeyEnv": "OPENAI_API_KEY"
26
+ },
27
+ "anthropic": {
28
+ "label": "Anthropic",
29
+ "model": "anthropic/claude-sonnet-4-5",
30
+ "apiKeyEnv": "ANTHROPIC_API_KEY"
31
+ },
32
+ "openai-compatible": {
33
+ "label": "OpenAI-compatible",
34
+ "model": "openai/your-model-name",
35
+ "apiKeyEnv": "OPENAI_API_KEY",
36
+ "apiBaseEnv": "OPENAI_API_BASE"
37
+ }
38
+ }
39
+ }
40
+ }
41
+ ```
42
+
43
+ The supported profile fields are `label`, `model` (or `models` + `defaultModel`
44
+ for multiple deployments), `defaultReasoningEffort`, `apiKeyEnv`, `apiBaseEnv`,
45
+ and `apiVersionEnv`. Every `*Env` value must be an uppercase environment
46
+ variable name; a raw secret there is rejected.
47
+
48
+ | Profile field | Environment variable it reads |
49
+ | --- | --- |
50
+ | `apiKeyEnv` | API key |
51
+ | `apiBaseEnv` | Base URL (OpenAI-compatible endpoints) |
52
+ | `apiVersionEnv` | Optional API version, only for endpoints that require one |
53
+
54
+ ## OpenAI
55
+
56
+ Point the profile at the public OpenAI API. Only a key is required.
57
+
58
+ ```sh
59
+ export OPENAI_API_KEY='sk-…'
60
+ ```
61
+
62
+ ```jsonc
63
+ {
64
+ "console": {
65
+ "defaultProfile": "openai",
66
+ "profiles": {
67
+ "openai": {
68
+ "label": "OpenAI",
69
+ "model": "openai/gpt-5-mini",
70
+ "apiKeyEnv": "OPENAI_API_KEY"
71
+ }
72
+ }
73
+ }
74
+ }
75
+ ```
76
+
77
+ ## Anthropic
78
+
79
+ Only a key is required.
80
+
81
+ ```sh
82
+ export ANTHROPIC_API_KEY='sk-ant-…'
83
+ ```
84
+
85
+ ```jsonc
86
+ {
87
+ "console": {
88
+ "defaultProfile": "anthropic",
89
+ "profiles": {
90
+ "anthropic": {
91
+ "label": "Anthropic",
92
+ "model": "anthropic/claude-sonnet-4-5",
93
+ "apiKeyEnv": "ANTHROPIC_API_KEY"
94
+ }
95
+ }
96
+ }
97
+ }
98
+ ```
99
+
100
+ ## OpenAI-compatible
101
+
102
+ Use this one profile for any endpoint that speaks the OpenAI Chat Completions
103
+ API: Azure, Opencode, Ollama, LM Studio, a LiteLLM proxy, and so on. Set the
104
+ key and the base URL; the model name is whatever the endpoint expects.
105
+
106
+ ```sh
107
+ export OPENAI_API_KEY='…'
108
+ export OPENAI_API_BASE='https://host.example/v1'
109
+ ```
110
+
111
+ ```jsonc
112
+ {
113
+ "console": {
114
+ "defaultProfile": "openai-compatible",
115
+ "profiles": {
116
+ "openai-compatible": {
117
+ "label": "OpenAI-compatible",
118
+ "model": "openai/your-model-name",
119
+ "apiKeyEnv": "OPENAI_API_KEY",
120
+ "apiBaseEnv": "OPENAI_API_BASE"
121
+ }
122
+ }
123
+ }
124
+ }
125
+ ```
126
+
127
+ LiteLLM appends `/chat/completions` to `OPENAI_API_BASE`, so point it at the
128
+ `…/v1` root of the endpoint, not the full completions path.
129
+
130
+ ### Azure
131
+
132
+ Azure OpenAI's unified v1 API is OpenAI-compatible, so it uses the same
133
+ `openai-compatible` profile. Use the **Azure deployment name** as the model.
134
+
135
+ ```sh
136
+ export OPENAI_API_KEY='your-azure-openai-api-key'
137
+ export OPENAI_API_BASE='https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/'
138
+ ```
139
+
140
+ ```jsonc
141
+ {
142
+ "console": {
143
+ "defaultProfile": "openai-compatible",
144
+ "profiles": {
145
+ "openai-compatible": {
146
+ "label": "Azure OpenAI",
147
+ "model": "openai/gpt-4.1-nano", // your deployment name
148
+ "apiKeyEnv": "OPENAI_API_KEY",
149
+ "apiBaseEnv": "OPENAI_API_BASE"
150
+ }
151
+ }
152
+ }
153
+ }
154
+ ```
155
+
156
+ Notes:
157
+
158
+ - `OPENAI_API_BASE` also accepts the Foundry models form
159
+ `https://YOUR-RESOURCE-NAME.services.ai.azure.com/openai/v1/`.
160
+ - With the v1 API the `api-version` query parameter is no longer required, so
161
+ `apiVersionEnv` stays unset. If an older endpoint still needs one, add
162
+ `"apiVersionEnv": "OPENAI_API_VERSION"` and export
163
+ `OPENAI_API_VERSION='2024-06-01'` (or your API version).
164
+ - `OPENAI_API_KEY` holds the Azure OpenAI API key. If you use Microsoft Entra
165
+ ID instead, a keyless token provider can be passed in the same variable.
166
+
167
+ ### Opencode
168
+
169
+ Opencode itself does not expose an OpenAI-compatible server; its `serve` command
170
+ publishes Opencode's own API. To reuse the providers you already configured in
171
+ Opencode, run an OpenAI-compatible gateway such as the
172
+ [`opencode-llm-proxy`](https://github.com/KochC/opencode-llm-proxy) plugin, which
173
+ serves Chat Completions at `http://127.0.0.1:4010/v1` and lists every configured
174
+ model as `provider/model`.
175
+
176
+ ```sh
177
+ export OPENAI_API_KEY='unused' # or your OPENCODE_LLM_PROXY_TOKEN
178
+ export OPENAI_API_BASE='http://127.0.0.1:4010/v1'
179
+ ```
180
+
181
+ ```jsonc
182
+ {
183
+ "console": {
184
+ "defaultProfile": "openai-compatible",
185
+ "profiles": {
186
+ "openai-compatible": {
187
+ "label": "Opencode",
188
+ "model": "openai/github-copilot/claude-sonnet-4.6", // provider/model
189
+ "apiKeyEnv": "OPENAI_API_KEY",
190
+ "apiBaseEnv": "OPENAI_API_BASE"
191
+ }
192
+ }
193
+ }
194
+ }
195
+ ```
196
+
197
+ Notes:
198
+
199
+ - Use the fully qualified `provider/model` id from the gateway's
200
+ `GET /v1/models` listing.
201
+ - If the gateway requires a bearer token, set `OPENAI_API_KEY` to the
202
+ `OPENCODE_LLM_PROXY_TOKEN`; otherwise any non-empty value satisfies the
203
+ profile's required-environment check.
204
+
205
+ ## Multiple deployments per provider
206
+
207
+ A profile can list several models under one set of credentials; the Console
208
+ settings then offer a per-deployment choice.
209
+
210
+ ```jsonc
211
+ {
212
+ "console": {
213
+ "profiles": {
214
+ "openai-compatible": {
215
+ "label": "Azure OpenAI",
216
+ "defaultModel": "nano",
217
+ "models": {
218
+ "nano": { "label": "GPT-4.1 nano", "model": "openai/gpt-4.1-nano" },
219
+ "mini": { "label": "GPT-5 mini", "model": "openai/gpt-5-mini" }
220
+ },
221
+ "apiKeyEnv": "OPENAI_API_KEY",
222
+ "apiBaseEnv": "OPENAI_API_BASE"
223
+ }
224
+ }
225
+ }
226
+ }
227
+ ```
228
+
229
+ ## Verifying a profile
230
+
231
+ `catence-console doctor` reports, for each profile, which environment variables
232
+ are still missing and whether the local Catence runtime is reachable. It never
233
+ prints credential values.
234
+
235
+ ```sh
236
+ catence-console doctor --home "$HOME/.catence" --mcp-url http://127.0.0.1:8787/mcp
237
+ ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "catence",
3
- "version": "0.2.0-beta.1",
3
+ "version": "0.2.0-beta.2",
4
4
  "description": "Local MCP access to normalized Garmin, Intervals.icu, and targeted Strava fitness data.",
5
5
  "license": "AGPL-3.0-or-later",
6
6
  "repository": {