zcode-workbuddy-connect 0.0.0-stage → 1.0.0
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/.zcode-plugin/plugin.json +40 -0
- package/LICENSE +22 -0
- package/NOTICE.md +49 -0
- package/README.md +264 -2
- package/bin/cli.mjs +8 -0
- package/docs/adr/0001-loopback-provider-for-zcode.md +66 -0
- package/docs/adr/0002-widest-window-and-output-ceiling.md +98 -0
- package/docs/adr/0003-region-by-url-path.md +97 -0
- package/docs/adr/0004-workbuddy-56-at-rest-credentials.md +111 -0
- package/docs/validate-provider-config.mjs +203 -0
- package/docs/verify-endpoint.mjs +162 -0
- package/hooks/service-ensure.mjs +133 -0
- package/package.json +59 -4
- package/skills/workbuddy-models/SKILL.md +107 -0
- package/src/app-version.js +119 -0
- package/src/auth.js +441 -0
- package/src/catalog.js +100 -0
- package/src/cli.js +1010 -0
- package/src/client-identity.js +213 -0
- package/src/config.js +91 -0
- package/src/desktop-credential-protection.js +890 -0
- package/src/loopback.js +40 -0
- package/src/server.js +873 -0
- package/src/upstream.js +762 -0
package/src/catalog.js
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WorkBuddy model catalog: a static fallback list captured from the live CN
|
|
3
|
+
* endpoint, replaced by the upstream's dynamic answer once it loads.
|
|
4
|
+
*
|
|
5
|
+
* The fallback exists so the provider registers a usable roster even while the
|
|
6
|
+
* first fetch is in flight or offline. It is deliberately *not* a promise about
|
|
7
|
+
* the upstream's current state.
|
|
8
|
+
*
|
|
9
|
+
* @module zcode-workbuddy-connect/catalog
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { modelWithCurrentPromotion } from './upstream.js'
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Static CLI models observed on the CN endpoint. Reasoning metadata is taken
|
|
16
|
+
* verbatim from the live endpoint — each model's supported effort set and
|
|
17
|
+
* whether thinking can be disabled — and the `free` flag follows the upstream
|
|
18
|
+
* `x0.00` credits marker.
|
|
19
|
+
*
|
|
20
|
+
* Rows without `supportedEfforts` carry only a default effort.
|
|
21
|
+
*/
|
|
22
|
+
export const FALLBACK_WORKBUDDY_MODELS = [
|
|
23
|
+
{ id: 'auto', name: 'Auto', contextWindow: 256_000, maxTokens: 32_000, supportsImages: true, reasoning: { supports: false, onlyReasoning: false, defaultEffort: 'high', canDisableThinking: true }, billing: { free: false } },
|
|
24
|
+
{ id: 'hy4-preview', name: 'Hy4 preview', contextWindow: 1_000_000, maxTokens: 64_000, supportsImages: true, reasoning: { supports: true, onlyReasoning: true, supportedEfforts: ['high'], defaultEffort: 'high', canDisableThinking: false }, billing: { free: false, rateUnknown: true } },
|
|
25
|
+
{ id: 'hy3', name: 'Hy3', contextWindow: 192_000, maxTokens: 64_000, supportsImages: true, reasoning: { supports: false, onlyReasoning: false, defaultEffort: 'high', canDisableThinking: true }, billing: { credits: 'x0.00', free: true } },
|
|
26
|
+
{ id: 'hy3-x', name: 'Hy3-X', contextWindow: 192_000, maxTokens: 64_000, supportsImages: true, reasoning: { supports: true, onlyReasoning: true, supportedEfforts: ['low', 'high'], defaultEffort: 'high', canDisableThinking: false }, billing: { credits: 'x0.05', free: false } },
|
|
27
|
+
{ id: 'deepseek-v4.1-flash', name: 'Deepseek-V4.1-Flash', contextWindow: 1_000_000, maxTokens: 128_000, supportsImages: true, reasoning: { supports: false, onlyReasoning: false, defaultEffort: 'high', canDisableThinking: true }, billing: { credits: 'x0.03', free: false } },
|
|
28
|
+
{ id: 'glm-5.3', name: 'GLM-5.3', contextWindow: 1_000_000, maxTokens: 64_000, supportsImages: true, reasoning: { supports: true, onlyReasoning: true, supportedEfforts: ['low', 'high', 'max'], defaultEffort: 'high', canDisableThinking: true }, billing: { credits: 'x0.79', free: false } },
|
|
29
|
+
{ id: 'glm-5.3-flash', name: 'GLM-5.3-Flash', contextWindow: 1_000_000, maxTokens: 32_000, supportsImages: true, reasoning: { supports: true, onlyReasoning: true, supportedEfforts: ['low', 'high', 'max'], defaultEffort: 'high', canDisableThinking: true }, billing: { credits: 'x0.06', free: false } },
|
|
30
|
+
{ id: 'glm-5.2', name: 'GLM-5.2', contextWindow: 1_000_000, maxTokens: 64_000, supportsImages: true, reasoning: { supports: false, onlyReasoning: false, defaultEffort: 'medium', canDisableThinking: true }, billing: { credits: 'x0.79', free: false } },
|
|
31
|
+
{ id: 'glm-5.1', name: 'GLM-5.1', contextWindow: 200_000, maxTokens: 48_000, supportsImages: false, reasoning: { supports: false, onlyReasoning: false, defaultEffort: 'medium', canDisableThinking: true }, billing: { credits: 'x0.79', free: false } },
|
|
32
|
+
{ id: 'glm-5v-turbo', name: 'GLM-5v-Turbo', contextWindow: 200_000, maxTokens: 64_000, supportsImages: true, reasoning: { supports: false, onlyReasoning: false, defaultEffort: 'medium', canDisableThinking: true }, billing: { credits: 'x0.71', free: false } },
|
|
33
|
+
{ id: 'kimi-k3-1', name: 'Kimi-K3', contextWindow: 1_000_000, maxTokens: 32_000, supportsImages: true, reasoning: { supports: false, onlyReasoning: false, defaultEffort: 'medium', canDisableThinking: true }, billing: { credits: 'x1.62', free: false } },
|
|
34
|
+
{ id: 'kimi-k2.8-preview', name: 'Kimi-K2.8-Preview', contextWindow: 1_000_000, maxTokens: 64_000, supportsImages: true, reasoning: { supports: true, onlyReasoning: true, supportedEfforts: ['low', 'high', 'max'], defaultEffort: 'high', canDisableThinking: true }, billing: { credits: 'x0.77', free: false } },
|
|
35
|
+
{ id: 'kimi-k2.7', name: 'Kimi-K2.7-Code', contextWindow: 256_000, maxTokens: 32_000, supportsImages: true, reasoning: { supports: false, onlyReasoning: false, defaultEffort: 'medium', canDisableThinking: true }, billing: { credits: 'x0.57', free: false } },
|
|
36
|
+
{ id: 'kimi-k2.6', name: 'Kimi-K2.6', contextWindow: 256_000, maxTokens: 32_000, supportsImages: true, reasoning: { supports: false, onlyReasoning: false, defaultEffort: 'medium', canDisableThinking: true }, billing: { credits: 'x0.52', free: false } },
|
|
37
|
+
{ id: 'minimax-m3', name: 'MiniMax-M3', contextWindow: 512_000, maxTokens: 64_000, supportsImages: true, reasoning: { supports: false, onlyReasoning: false, defaultEffort: 'medium', canDisableThinking: true }, billing: { credits: 'x0.25', free: false } },
|
|
38
|
+
{ id: 'deepseek-v4-pro', name: 'Deepseek-v4-Pro', contextWindow: 1_000_000, maxTokens: 128_000, supportsImages: true, reasoning: { supports: false, onlyReasoning: false, defaultEffort: 'high', canDisableThinking: true }, billing: { credits: 'x0.51', free: false } },
|
|
39
|
+
]
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Mutable catalog shared by the endpoint's `/v1/models` and the status CLI.
|
|
43
|
+
*
|
|
44
|
+
* Visibility is separate from content. A signed-out account must expose *no*
|
|
45
|
+
* models rather than a fallback roster: serving the fallback would advertise
|
|
46
|
+
* models that can only fail, which is worse than showing nothing.
|
|
47
|
+
*/
|
|
48
|
+
export class WorkBuddyCatalog {
|
|
49
|
+
constructor(initial = FALLBACK_WORKBUDDY_MODELS) {
|
|
50
|
+
this.models = initial
|
|
51
|
+
this.visible = true
|
|
52
|
+
/** Provenance of the roster currently held. */
|
|
53
|
+
this.source = 'fallback'
|
|
54
|
+
this.fetchedAtMs = undefined
|
|
55
|
+
this.useMaximumContextWindow = false
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/** Current entries; empty while the catalog has no usable credential. */
|
|
59
|
+
current() {
|
|
60
|
+
if (!this.visible) return []
|
|
61
|
+
return this.models.map(model => {
|
|
62
|
+
const current = modelWithCurrentPromotion(model)
|
|
63
|
+
const maximum = current.supportedContextWindows === undefined
|
|
64
|
+
? undefined : Math.max(...current.supportedContextWindows)
|
|
65
|
+
return this.useMaximumContextWindow && maximum !== undefined && maximum > current.contextWindow
|
|
66
|
+
? { ...current, defaultContextWindow: current.defaultContextWindow ?? current.contextWindow, contextWindow: maximum }
|
|
67
|
+
: current
|
|
68
|
+
})
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/** Replace the list with a freshly fetched roster. */
|
|
72
|
+
set(models, { source, fetchedAtMs } = {}) {
|
|
73
|
+
this.models = [...models]
|
|
74
|
+
if (source !== undefined) this.source = source
|
|
75
|
+
this.fetchedAtMs = fetchedAtMs ?? Date.now()
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
isVisible() {
|
|
79
|
+
return this.visible
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/** Show or hide the whole catalog. Returns whether the value changed. */
|
|
83
|
+
setVisible(visible) {
|
|
84
|
+
if (this.visible === visible) return false
|
|
85
|
+
this.visible = visible
|
|
86
|
+
return true
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/** Select the largest declared window where the upstream offers a choice. */
|
|
90
|
+
setUseMaximumContextWindow(useMaximum) {
|
|
91
|
+
if (this.useMaximumContextWindow === useMaximum) return false
|
|
92
|
+
this.useMaximumContextWindow = useMaximum
|
|
93
|
+
return true
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/** Models to fall back to when the upstream fetch fails; ignores visibility. */
|
|
97
|
+
fallback() {
|
|
98
|
+
return this.models
|
|
99
|
+
}
|
|
100
|
+
}
|