@jambonz/llm 0.2.7 → 0.3.1

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
@@ -11,6 +11,10 @@ A voice-oriented LLM adapter library for Node.js.
11
11
  3. **Lossless history round-trip.** Vendor-native message shapes (Anthropic content blocks, OpenAI `tool_calls` arrays, Google `parts`, Bedrock `content[]`) are preserved via an opaque `vendorRaw` escape hatch.
12
12
  4. **Community-friendly contribution.** A new vendor is a single directory under `src/adapters/`, plus a line in `src/adapters/index.ts`.
13
13
 
14
+ ## Contributing
15
+
16
+ New vendor adapters are the primary contribution path. See [docs/adding-a-vendor.md](docs/adding-a-vendor.md) for the step-by-step guide — copy the template, fill in the adapter, run the contract test-kit. A PR is merge-ready when all contract-kit checks pass against the new adapter and the build is green.
17
+
14
18
  ## Status
15
19
 
16
20
  Under active development. API may change before `1.0.0`.
package/dist/index.cjs CHANGED
@@ -477,6 +477,9 @@ var OpenAIAdapter = class {
477
477
  async listAvailableModels() {
478
478
  return listOpenAICompatibleModels(this.ensureClient(), openAIManifest.knownModels);
479
479
  }
480
+ async testCredential() {
481
+ await this.ensureClient().models.list();
482
+ }
480
483
  async warmup() {
481
484
  const client = this.ensureClient();
482
485
  await client.models.list().catch(() => void 0);
@@ -903,6 +906,9 @@ var AnthropicAdapter = class {
903
906
  }
904
907
  return models;
905
908
  }
909
+ async testCredential() {
910
+ await this.ensureClient().models.list();
911
+ }
906
912
  async warmup() {
907
913
  const client = this.ensureClient();
908
914
  await client.models.list().catch(() => void 0);
@@ -1329,6 +1335,9 @@ var GoogleAdapter = class {
1329
1335
  async listAvailableModels() {
1330
1336
  return listGeminiModels(this.ensureClient(), googleManifest.knownModels);
1331
1337
  }
1338
+ async testCredential() {
1339
+ await listGeminiModels(this.ensureClient(), googleManifest.knownModels);
1340
+ }
1332
1341
  async warmup() {
1333
1342
  }
1334
1343
  ensureClient() {
@@ -1499,6 +1508,9 @@ var VertexGeminiAdapter = class {
1499
1508
  async listAvailableModels() {
1500
1509
  return listGeminiModels(this.ensureClient(), vertexGeminiManifest.knownModels);
1501
1510
  }
1511
+ async testCredential() {
1512
+ await listGeminiModels(this.ensureClient(), vertexGeminiManifest.knownModels);
1513
+ }
1502
1514
  async warmup() {
1503
1515
  }
1504
1516
  ensureClient() {
@@ -1597,11 +1609,22 @@ var vertexOpenAIManifest = {
1597
1609
  type: "select",
1598
1610
  required: true,
1599
1611
  default: "us-central1",
1612
+ // Same region set as vertex-gemini plus us-east5 (where Google
1613
+ // hosts Llama partner models). Partner-model availability varies
1614
+ // per region; Google's docs for each model are the source of truth.
1600
1615
  options: [
1601
1616
  { value: "us-central1", label: "us-central1" },
1617
+ { value: "us-east1", label: "us-east1" },
1602
1618
  { value: "us-east4", label: "us-east4" },
1619
+ { value: "us-east5", label: "us-east5" },
1620
+ { value: "us-west1", label: "us-west1" },
1621
+ { value: "us-west4", label: "us-west4" },
1603
1622
  { value: "europe-west1", label: "europe-west1" },
1623
+ { value: "europe-west2", label: "europe-west2" },
1624
+ { value: "europe-west3", label: "europe-west3" },
1604
1625
  { value: "europe-west4", label: "europe-west4" },
1626
+ { value: "asia-east1", label: "asia-east1" },
1627
+ { value: "asia-northeast1", label: "asia-northeast1" },
1605
1628
  { value: "asia-southeast1", label: "asia-southeast1" }
1606
1629
  ]
1607
1630
  }
@@ -1619,6 +1642,7 @@ var VertexOpenAIAdapter = class {
1619
1642
  vendor = vertexOpenAIManifest.vendor;
1620
1643
  acceptedAuth = ["vertexServiceAccount"];
1621
1644
  client;
1645
+ googleAuth;
1622
1646
  init(auth, client) {
1623
1647
  if (auth.kind !== "vertexServiceAccount") {
1624
1648
  throw new Error(
@@ -1635,12 +1659,12 @@ var VertexOpenAIAdapter = class {
1635
1659
  throw new Error("VertexOpenAIAdapter: location is required");
1636
1660
  }
1637
1661
  const baseURL = `https://${auth.location}-aiplatform.googleapis.com/v1beta1/projects/${auth.projectId}/locations/${auth.location}/endpoints/openapi`;
1638
- const googleAuth = new import_google_auth_library.GoogleAuth({
1662
+ this.googleAuth = new import_google_auth_library.GoogleAuth({
1639
1663
  credentials: auth.credentials,
1640
1664
  scopes: ["https://www.googleapis.com/auth/cloud-platform"]
1641
1665
  });
1642
1666
  const authedFetch = async (input, init) => {
1643
- const googleClient = await googleAuth.getClient();
1667
+ const googleClient = await this.googleAuth.getClient();
1644
1668
  const token = await googleClient.getAccessToken();
1645
1669
  const headers = new Headers(init?.headers);
1646
1670
  headers.set("Authorization", `Bearer ${token.token ?? ""}`);
@@ -1669,6 +1693,16 @@ var VertexOpenAIAdapter = class {
1669
1693
  async listAvailableModels() {
1670
1694
  return [...vertexOpenAIManifest.knownModels];
1671
1695
  }
1696
+ async testCredential() {
1697
+ if (!this.googleAuth) {
1698
+ throw new Error("VertexOpenAIAdapter: init() must be called before testCredential()");
1699
+ }
1700
+ const googleClient = await this.googleAuth.getClient();
1701
+ const token = await googleClient.getAccessToken();
1702
+ if (!token.token) {
1703
+ throw new Error("VertexOpenAIAdapter: service account did not mint an access token");
1704
+ }
1705
+ }
1672
1706
  async warmup() {
1673
1707
  }
1674
1708
  ensureClient() {
@@ -1690,6 +1724,7 @@ var vertexOpenAIFactory = {
1690
1724
 
1691
1725
  // src/adapters/bedrock/adapter.ts
1692
1726
  var import_client_bedrock_runtime = require("@aws-sdk/client-bedrock-runtime");
1727
+ var import_client_bedrock = require("@aws-sdk/client-bedrock");
1693
1728
 
1694
1729
  // src/adapters/bedrock/manifest.ts
1695
1730
  var BEDROCK_KNOWN_MODELS = [
@@ -1904,6 +1939,7 @@ var BedrockAdapter = class {
1904
1939
  vendor = bedrockManifest.vendor;
1905
1940
  acceptedAuth = ["bedrockApiKey", "bedrockIam"];
1906
1941
  client;
1942
+ controlClientConfig;
1907
1943
  init(auth, client) {
1908
1944
  if (!auth.region) {
1909
1945
  throw new Error("BedrockAdapter: region is required");
@@ -1934,6 +1970,7 @@ var BedrockAdapter = class {
1934
1970
  );
1935
1971
  }
1936
1972
  this.client = new import_client_bedrock_runtime.BedrockRuntimeClient(config);
1973
+ this.controlClientConfig = config;
1937
1974
  }
1938
1975
  async *stream(req) {
1939
1976
  assertValidRequest(req);
@@ -2112,6 +2149,17 @@ var BedrockAdapter = class {
2112
2149
  async listAvailableModels() {
2113
2150
  return [...bedrockManifest.knownModels];
2114
2151
  }
2152
+ async testCredential() {
2153
+ if (!this.controlClientConfig) {
2154
+ throw new Error("BedrockAdapter: init() must be called before testCredential()");
2155
+ }
2156
+ const control = new import_client_bedrock.BedrockClient(this.controlClientConfig);
2157
+ try {
2158
+ await control.send(new import_client_bedrock.ListFoundationModelsCommand({}));
2159
+ } finally {
2160
+ control.destroy();
2161
+ }
2162
+ }
2115
2163
  async warmup() {
2116
2164
  }
2117
2165
  ensureClient() {