@namzu/sdk 18.0.0 → 18.1.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/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,49 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 18.1.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- d3bd080: A wrong API key is no longer reported as working
|
|
8
|
+
|
|
9
|
+
Typing a key into the picker ran a check that could not fail for two providers.
|
|
10
|
+
Measured against deliberately invalid keys, both said the key was good.
|
|
11
|
+
|
|
12
|
+
**With an OpenRouter key, any string at all passed.** A typo, the wrong
|
|
13
|
+
clipboard entry, a revoked key — all were accepted and reported as verified. The
|
|
14
|
+
check listed the model catalogue and treated a successful list as a passed
|
|
15
|
+
check, and OpenRouter's catalogue endpoint does not authenticate, so it answered
|
|
16
|
+
the same way whatever was sent. Nothing was wrong with that driver's listing; a
|
|
17
|
+
catalogue was simply never evidence about a key.
|
|
18
|
+
|
|
19
|
+
**With an Anthropic key, a real rejection was discarded.** The listing caught
|
|
20
|
+
the `401` and returned a hardcoded three-model list, which the check read as
|
|
21
|
+
success — so the truth existed, was thrown away, and was replaced by something
|
|
22
|
+
that looked like an answer.
|
|
23
|
+
|
|
24
|
+
A credential check is now a separate, declared capability. A driver that
|
|
25
|
+
declares no probe is reported as **not checked**, never as verified, so a driver
|
|
26
|
+
added in future cannot silently inherit a check it does not perform. Anthropic,
|
|
27
|
+
OpenRouter, OpenAI and Ollama declare one; OpenRouter's asks about the key
|
|
28
|
+
rather than the catalogue.
|
|
29
|
+
|
|
30
|
+
Refusal and doubt stay distinct. A `401` means the key is genuinely refused; a
|
|
31
|
+
timeout or a DNS failure means nothing was learned, and is reported that way —
|
|
32
|
+
telling someone on a broken connection to rotate a working key is a different
|
|
33
|
+
error, not a smaller one.
|
|
34
|
+
|
|
35
|
+
**Anthropic's model listing also never once ran.** The SDK method was pulled out
|
|
36
|
+
of its namespace and called bare, so it lost `this`, threw a `TypeError` on
|
|
37
|
+
every call, and was swallowed by the same catch — the hardcoded models were not
|
|
38
|
+
a fallback but the only answer the method could give. It now calls the live
|
|
39
|
+
endpoint, and falls back only when that genuinely fails.
|
|
40
|
+
|
|
41
|
+
The four driver packages are `minor` rather than `patch`: each gains a method
|
|
42
|
+
it did not have, and added functionality is a minor whatever the size of the
|
|
43
|
+
diff. Anthropic's earns it twice over, because its listing now returns the live
|
|
44
|
+
catalogue where it previously returned the same three hardcoded entries to every
|
|
45
|
+
caller - so the value every existing caller receives changes.
|
|
46
|
+
|
|
3
47
|
## 18.0.0
|
|
4
48
|
|
|
5
49
|
### Major Changes
|
|
@@ -32,6 +32,40 @@ export interface LLMProvider {
|
|
|
32
32
|
*/
|
|
33
33
|
chatStream(params: ChatCompletionParams): AsyncIterable<StreamChunk>;
|
|
34
34
|
listModels?(): Promise<ModelInfo[]>;
|
|
35
|
+
/**
|
|
36
|
+
* Establish whether this credential actually works. Resolves if it does,
|
|
37
|
+
* throws if it does not.
|
|
38
|
+
*
|
|
39
|
+
* Separate from `listModels` because the two answer different questions, and
|
|
40
|
+
* conflating them is a defect measured rather than imagined. `listModels`
|
|
41
|
+
* builds a MENU: "what can I offer this operator to choose from?" — a stale
|
|
42
|
+
* hardcoded list is a degraded but legitimate answer, since someone offline
|
|
43
|
+
* still has to pick a model. This builds a PROBE: "did this key work?" — and
|
|
44
|
+
* for that a list is not a degraded answer, it is no answer, because it
|
|
45
|
+
* arrives whether the key is right, wrong, expired or never sent.
|
|
46
|
+
*
|
|
47
|
+
* Two drivers proved a menu cannot stand in for a probe, and they failed
|
|
48
|
+
* differently. One caught a real `401` and returned its hardcoded catalogue,
|
|
49
|
+
* so the truth existed and was thrown away. The other has no fallback at all
|
|
50
|
+
* and is entirely honest about its menu — its listing endpoint simply does
|
|
51
|
+
* not authenticate, so ANY string returned the real catalogue. That second
|
|
52
|
+
* case is why this is a separate method rather than a rule about writing
|
|
53
|
+
* `listModels` more carefully: no amount of care in a menu makes it a probe.
|
|
54
|
+
*
|
|
55
|
+
* The probe is per-driver by nature — one has an authenticated call whose
|
|
56
|
+
* failure is real, another needs a different endpoint than its menu — so it
|
|
57
|
+
* is DECLARED, never inferred. A driver that does not implement this is
|
|
58
|
+
* reported as unverifiable, never as verified, and that has to hold for the
|
|
59
|
+
* driver nobody has written yet: inheriting a generic path silently is how
|
|
60
|
+
* this defect returns.
|
|
61
|
+
*
|
|
62
|
+
* Throw so the caller can tell the two failures apart. A rejection from the
|
|
63
|
+
* server (`401`/`403`) means the credential is genuinely bad; anything else
|
|
64
|
+
* — a timeout, DNS, a proxy — means nothing was learned, and reporting that
|
|
65
|
+
* as a bad key would tell an operator on broken wifi to go and rotate a
|
|
66
|
+
* credential that is fine.
|
|
67
|
+
*/
|
|
68
|
+
probeCredential?(): Promise<void>;
|
|
35
69
|
healthCheck?(): Promise<boolean>;
|
|
36
70
|
/**
|
|
37
71
|
* Optional structured health probe used by `runDoctor()`.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"interface.d.ts","sourceRoot":"","sources":["../../../src/types/provider/interface.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAA;AAE3D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAA;AACrD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAA;AACvD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AAC3C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAE9C,MAAM,WAAW,WAAW;IAC3B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IAErB;;;;;;;OAOG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,oBAAoB,CAAA;IAE5C;;;;;;;;;;;;;;OAcG;IACH,UAAU,CAAC,MAAM,EAAE,oBAAoB,GAAG,aAAa,CAAC,WAAW,CAAC,CAAA;IAEpE,UAAU,CAAC,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC,CAAA;IAEnC,WAAW,CAAC,IAAI,OAAO,CAAC,OAAO,CAAC,CAAA;IAEhC;;;;;;;OAOG;IACH,WAAW,CAAC,IAAI,OAAO,CAAC,iBAAiB,CAAC,CAAA;IAE1C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAiCG;IACH,eAAe,CAAC,CACf,KAAK,EAAE,MAAM,EACb,QAAQ,CAAC,EAAE,OAAO,WAAW,EAAE,cAAc,GAC3C,SAAS,OAAO,WAAW,EAAE,eAAe,EAAE,CAAA;CACjD"}
|
|
1
|
+
{"version":3,"file":"interface.d.ts","sourceRoot":"","sources":["../../../src/types/provider/interface.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAA;AAE3D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAA;AACrD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAA;AACvD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AAC3C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAE9C,MAAM,WAAW,WAAW;IAC3B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IAErB;;;;;;;OAOG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,oBAAoB,CAAA;IAE5C;;;;;;;;;;;;;;OAcG;IACH,UAAU,CAAC,MAAM,EAAE,oBAAoB,GAAG,aAAa,CAAC,WAAW,CAAC,CAAA;IAEpE,UAAU,CAAC,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC,CAAA;IAEnC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAgCG;IACH,eAAe,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;IAEjC,WAAW,CAAC,IAAI,OAAO,CAAC,OAAO,CAAC,CAAA;IAEhC;;;;;;;OAOG;IACH,WAAW,CAAC,IAAI,OAAO,CAAC,iBAAiB,CAAC,CAAA;IAE1C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAiCG;IACH,eAAe,CAAC,CACf,KAAK,EAAE,MAAM,EACb,QAAQ,CAAC,EAAE,OAAO,WAAW,EAAE,cAAc,GAC3C,SAAS,OAAO,WAAW,EAAE,eAAe,EAAE,CAAA;CACjD"}
|
package/package.json
CHANGED
|
@@ -38,6 +38,41 @@ export interface LLMProvider {
|
|
|
38
38
|
|
|
39
39
|
listModels?(): Promise<ModelInfo[]>
|
|
40
40
|
|
|
41
|
+
/**
|
|
42
|
+
* Establish whether this credential actually works. Resolves if it does,
|
|
43
|
+
* throws if it does not.
|
|
44
|
+
*
|
|
45
|
+
* Separate from `listModels` because the two answer different questions, and
|
|
46
|
+
* conflating them is a defect measured rather than imagined. `listModels`
|
|
47
|
+
* builds a MENU: "what can I offer this operator to choose from?" — a stale
|
|
48
|
+
* hardcoded list is a degraded but legitimate answer, since someone offline
|
|
49
|
+
* still has to pick a model. This builds a PROBE: "did this key work?" — and
|
|
50
|
+
* for that a list is not a degraded answer, it is no answer, because it
|
|
51
|
+
* arrives whether the key is right, wrong, expired or never sent.
|
|
52
|
+
*
|
|
53
|
+
* Two drivers proved a menu cannot stand in for a probe, and they failed
|
|
54
|
+
* differently. One caught a real `401` and returned its hardcoded catalogue,
|
|
55
|
+
* so the truth existed and was thrown away. The other has no fallback at all
|
|
56
|
+
* and is entirely honest about its menu — its listing endpoint simply does
|
|
57
|
+
* not authenticate, so ANY string returned the real catalogue. That second
|
|
58
|
+
* case is why this is a separate method rather than a rule about writing
|
|
59
|
+
* `listModels` more carefully: no amount of care in a menu makes it a probe.
|
|
60
|
+
*
|
|
61
|
+
* The probe is per-driver by nature — one has an authenticated call whose
|
|
62
|
+
* failure is real, another needs a different endpoint than its menu — so it
|
|
63
|
+
* is DECLARED, never inferred. A driver that does not implement this is
|
|
64
|
+
* reported as unverifiable, never as verified, and that has to hold for the
|
|
65
|
+
* driver nobody has written yet: inheriting a generic path silently is how
|
|
66
|
+
* this defect returns.
|
|
67
|
+
*
|
|
68
|
+
* Throw so the caller can tell the two failures apart. A rejection from the
|
|
69
|
+
* server (`401`/`403`) means the credential is genuinely bad; anything else
|
|
70
|
+
* — a timeout, DNS, a proxy — means nothing was learned, and reporting that
|
|
71
|
+
* as a bad key would tell an operator on broken wifi to go and rotate a
|
|
72
|
+
* credential that is fine.
|
|
73
|
+
*/
|
|
74
|
+
probeCredential?(): Promise<void>
|
|
75
|
+
|
|
41
76
|
healthCheck?(): Promise<boolean>
|
|
42
77
|
|
|
43
78
|
/**
|