@jskit-ai/connectors-catalog 0.1.47 → 0.1.50

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/docs/ai.md CHANGED
@@ -34,15 +34,20 @@ The raw-source hashes and source URLs are in the bundled `ai-models.json`;
34
34
  [upstream MIT notices](ai-upstream-notices.md) accompany it. Updates require
35
35
  deliberate review and a new package release.
36
36
 
37
- The 2 October review adds the exact `deepseek/deepseek-flash` identity for
38
- DeepSeek V4.1 Flash and removes its two retired direct-provider Flash entries
39
- from the bundled data. They are absent even when requesting deprecated models.
40
- Existing configuration using a removed name must explicitly select a current
41
- model; JSKIT does not translate it. The source hashes identify the original
42
- extraction, before this reviewed update. The new entry declares paid access without a fixed price because the
43
- provider has peak and off-peak rates. See the
37
+ The reviewed catalogue adds the exact `deepseek/deepseek-flash` identity for
38
+ DeepSeek V4.1 Flash. It retains `deepseek/deepseek-v4-flash` and
39
+ `deepseek/deepseek-v4-flash-vision-exp` for saved selections: DeepSeek still
40
+ accepts these names and serves their requests with V4.1 Flash. JSKIT sends the
41
+ selected ID unchanged and does not rewrite configuration. All three Flash
42
+ entries accept text and images. They and `deepseek/deepseek-v4-pro` declare
43
+ the provider's exact 1,048,576-token context and 393,216-token output limits;
44
+ Pro accepts text only. The bundled catalogue now has 7,615 model records.
45
+ The source hashes identify the original 7,614-record extraction, before this
46
+ reviewed update. Flash entries declare paid access without a fixed price because
47
+ the provider has peak and off-peak rates. See the
44
48
  [provider update](https://api-docs.deepseek.com/updates/) and
45
- [model details](https://api-docs.deepseek.com/quick_start/pricing/).
49
+ [model details](https://api-docs.deepseek.com/quick_start/pricing/), including
50
+ [exact model metadata](https://api-docs.deepseek.com/api/list-models/).
46
51
 
47
52
  `listAiModels()` hides deprecated entries and sorts free choices first, with
48
53
  `opencode/big-pickle` first. `includeDeprecated: true` exposes retained upstream
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jskit-ai/connectors-catalog",
3
- "version": "0.1.47",
3
+ "version": "0.1.50",
4
4
  "description": "Provider definitions and focused API operations for JSKIT connectors.",
5
5
  "type": "module",
6
6
  "exports": {
@@ -123,14 +123,14 @@
123
123
  "@aws-sdk/client-redshift-data": "3.1128.0",
124
124
  "@aws-sdk/client-s3": "3.1128.0",
125
125
  "@aws-sdk/s3-request-presigner": "3.1128.0",
126
- "@jskit-ai/connectors-core": "0.1.47",
126
+ "@jskit-ai/connectors-core": "0.1.50",
127
127
  "@modelcontextprotocol/sdk": "1.32.1",
128
128
  "@smithy/fetch-http-handler": "5.8.0",
129
129
  "jose": "^6.1.3",
130
130
  "json-rest-schema": "^1.0.17"
131
131
  },
132
132
  "peerDependencies": {
133
- "@jskit-ai/kernel": "0.1.230"
133
+ "@jskit-ai/kernel": "0.1.233"
134
134
  },
135
135
  "jskit": {
136
136
  "kind": "runtime",
@@ -1535,8 +1535,10 @@
1535
1535
  {"id":"zai-org/GLM-5.3-Flash","name":"GLM-5.3-Flash","cost":{"input":0.15,"output":0.5,"cache_read":0.03},"limit":{"context":1048576,"output":131072},"modalities":{"input":["text","image","video","pdf"],"output":["text"]},"sdkPackage":"@ai-sdk/deepinfra","access":"paid"}
1536
1536
  ]},
1537
1537
  {"id": "deepseek", "name": "DeepSeek", "documentationUrl": "https://api-docs.deepseek.com/quick_start/pricing", "baseURL": "https://api.deepseek.com", "environment": ["DEEPSEEK_API_KEY"], "sdkPackage": "@ai-sdk/openai-compatible", "models": [
1538
- {"id":"deepseek-flash","name":"DeepSeek V4.1 Flash","limit":{"context":1048576,"output":384000},"modalities":{"input":["text","image"],"output":["text"]},"sdkPackage":"@ai-sdk/openai-compatible","access":"paid"},
1539
- {"id":"deepseek-v4-pro","name":"DeepSeek V4 Pro","cost":{"input":0.435,"output":0.87,"reasoning":0.87,"cache_read":0.003625},"limit":{"context":1000000,"output":384000},"modalities":{"input":["text"],"output":["text"]},"sdkPackage":"@ai-sdk/openai-compatible","access":"paid"}
1538
+ {"id":"deepseek-flash","name":"DeepSeek V4.1 Flash","limit":{"context":1048576,"output":393216},"modalities":{"input":["text","image"],"output":["text"]},"sdkPackage":"@ai-sdk/openai-compatible","access":"paid"},
1539
+ {"id":"deepseek-v4-flash","name":"DeepSeek V4 Flash (legacy alias)","limit":{"context":1048576,"output":393216},"modalities":{"input":["text","image"],"output":["text"]},"sdkPackage":"@ai-sdk/openai-compatible","access":"paid"},
1540
+ {"id":"deepseek-v4-flash-vision-exp","name":"DeepSeek V4 Flash Vision Exp (legacy alias)","limit":{"context":1048576,"output":393216},"modalities":{"input":["text","image"],"output":["text"]},"sdkPackage":"@ai-sdk/openai-compatible","access":"paid"},
1541
+ {"id":"deepseek-v4-pro","name":"DeepSeek V4 Pro","cost":{"input":0.435,"output":0.87,"reasoning":0.87,"cache_read":0.003625},"limit":{"context":1048576,"output":393216},"modalities":{"input":["text"],"output":["text"]},"sdkPackage":"@ai-sdk/openai-compatible","access":"paid"}
1540
1542
  ]},
1541
1543
  {"id": "digitalocean", "name": "DigitalOcean", "documentationUrl": "https://docs.digitalocean.com/products/gradient-ai-platform/details/models/", "baseURL": "https://inference.do-ai.run/v1", "environment": ["DIGITALOCEAN_ACCESS_TOKEN"], "sdkPackage": "@ai-sdk/openai-compatible", "models": [
1542
1544
  {"id":"alibaba-qwen3-32b","name":"Qwen3 32B","cost":{"input":0.25,"output":0.55},"limit":{"context":32768,"output":32768},"modalities":{"input":["text"],"output":["text"]},"sdkPackage":"@ai-sdk/openai-compatible","access":"paid"},
package/test/ai.test.js CHANGED
@@ -17,25 +17,36 @@ const validate = (config) => validateIntegrationConfiguration(config, { provider
17
17
  test("AI retains the attributed snapshot with reviewed current identities and explicit deprecations", () => {
18
18
  assert.equal(aiCatalogue.extractedAt, "2026-09-10");
19
19
  assert.equal(aiCatalogue.providers.length, 213);
20
- assert.equal(listAiModels({ includeDeprecated: true }).length, 7613);
20
+ assert.equal(listAiModels({ includeDeprecated: true }).length, 7615);
21
21
  assert.match(aiCatalogue.sourceSha256, /^[a-f0-9]{64}$/u);
22
22
  assert.equal(getAiModel("opencode/grok-code").status, "deprecated");
23
23
  assert.equal(listAiModels().some((model) => model.key === "opencode/grok-code"), false);
24
24
  assert.equal(aiCatalogue.providers.find((provider) => provider.id === "amazon-bedrock").connection, "framework");
25
25
  });
26
26
 
27
- test("DeepSeek uses its current exact Flash identity and rejects retired provider aliases", async () => {
27
+ test("DeepSeek retains provider-supported saved aliases and exact current model limits", async () => {
28
28
  const current = "deepseek/deepseek-flash";
29
29
  assert.equal(getAiModel(current).name, "DeepSeek V4.1 Flash");
30
30
  assert.deepEqual(getAiModel(current).modalities.input, ["text", "image"]);
31
31
  const config = configuration({ settings: { model: current }, authentication: { method: "api-key", secretRef: "env:KEY" } });
32
32
  const resolver = createAiConnectionResolver({ configuration: config, authorize, resolveReference: () => "test-key" });
33
33
  assert.equal((await resolver.resolve(request)).model, "deepseek-flash");
34
+ assert.deepEqual((await resolver.resolve(request)).modelLimits, { context: 1048576, output: 393216 });
34
35
  for (const model of ["deepseek/deepseek-v4-flash", "deepseek/deepseek-v4-flash-vision-exp"]) {
35
- assert.equal(getAiModel(model), undefined);
36
- assert.equal(listAiModels({ providerId: "deepseek", includeDeprecated: true }).some(entry => entry.key === model), false);
37
- assert.throws(() => validate(configuration({ ...config.integrations.suggestions, settings: { model } })), { code: "integration_configuration_invalid" });
36
+ assert.equal(getAiModel(model).id, model.slice("deepseek/".length));
37
+ assert.deepEqual(getAiModel(model).modalities.input, ["text", "image"]);
38
+ assert.equal(listAiModels({ providerId: "deepseek" }).some(entry => entry.key === model), true);
39
+ const saved = validate(configuration({ ...config.integrations.suggestions, settings: { model } }));
40
+ assert.equal(saved.integrations.suggestions.settings.model, model);
41
+ const aliasResolver = createAiConnectionResolver({ configuration: saved, authorize, resolveReference: () => "test-key" });
42
+ const connection = await aliasResolver.resolve(request);
43
+ assert.equal(connection.providerId, "deepseek");
44
+ assert.equal(connection.model, model.slice("deepseek/".length));
45
+ assert.deepEqual(connection.modelLimits, { context: 1048576, output: 393216 });
38
46
  }
47
+ const pro = getAiModel("deepseek/deepseek-v4-pro");
48
+ assert.deepEqual(pro.limit, { context: 1048576, output: 393216 });
49
+ assert.deepEqual(pro.modalities.input, ["text"]);
39
50
  });
40
51
 
41
52
  test("AI lists every active Zen public model first and uses Big Pickle as the explicit default", () => {
@@ -47,6 +47,7 @@ async function fixture(t, domainPrefix = "fixture-store", selectedScopes = scope
47
47
  assert.equal(new Headers(init.headers).get("authorization"), `Bearer fixture-access-${state.count}`);
48
48
  assert.equal(url.searchParams.has("access_token"), false);
49
49
  if (state.hang) return new Promise((_, reject) => {
50
+ state.requestStarted?.();
50
51
  const timer = setTimeout(() => reject(new Error("Missing abort")), 1000);
51
52
  const abort = () => { clearTimeout(timer); reject(init.signal.reason); };
52
53
  if (init.signal.aborted) abort(); else init.signal.addEventListener("abort", abort, { once: true });
@@ -199,8 +200,9 @@ test("Lightspeed invalid refresh tokens require reconnect without returning prov
199
200
 
200
201
  test("Lightspeed delivers cancellation and timeout without retry", async (t) => {
201
202
  const f = await fixture(t); await f.connect(); f.state.hang = true;
203
+ const started = Promise.withResolvers(); f.state.requestStarted = started.resolve;
202
204
  const abort = new AbortController(); const result = f.service.invoke({ ...args, operation: "customers.list", signal: abort.signal });
203
- setTimeout(() => abort.abort(), 10); await assert.rejects(result, { code: "connector_cancelled" });
205
+ await Promise.race([started.promise, result]); abort.abort(); await assert.rejects(result, { code: "connector_cancelled" });
204
206
  await assert.rejects(f.service.invoke({ ...args, operation: "customers.list" }), { code: "connector_provider_timeout" });
205
207
  assert.equal(f.requests.length, 4);
206
208
  });