@jambonz/llm 0.2.6 → 0.3.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/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() {
@@ -1619,6 +1631,7 @@ var VertexOpenAIAdapter = class {
1619
1631
  vendor = vertexOpenAIManifest.vendor;
1620
1632
  acceptedAuth = ["vertexServiceAccount"];
1621
1633
  client;
1634
+ googleAuth;
1622
1635
  init(auth, client) {
1623
1636
  if (auth.kind !== "vertexServiceAccount") {
1624
1637
  throw new Error(
@@ -1635,12 +1648,12 @@ var VertexOpenAIAdapter = class {
1635
1648
  throw new Error("VertexOpenAIAdapter: location is required");
1636
1649
  }
1637
1650
  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({
1651
+ this.googleAuth = new import_google_auth_library.GoogleAuth({
1639
1652
  credentials: auth.credentials,
1640
1653
  scopes: ["https://www.googleapis.com/auth/cloud-platform"]
1641
1654
  });
1642
1655
  const authedFetch = async (input, init) => {
1643
- const googleClient = await googleAuth.getClient();
1656
+ const googleClient = await this.googleAuth.getClient();
1644
1657
  const token = await googleClient.getAccessToken();
1645
1658
  const headers = new Headers(init?.headers);
1646
1659
  headers.set("Authorization", `Bearer ${token.token ?? ""}`);
@@ -1669,6 +1682,16 @@ var VertexOpenAIAdapter = class {
1669
1682
  async listAvailableModels() {
1670
1683
  return [...vertexOpenAIManifest.knownModels];
1671
1684
  }
1685
+ async testCredential() {
1686
+ if (!this.googleAuth) {
1687
+ throw new Error("VertexOpenAIAdapter: init() must be called before testCredential()");
1688
+ }
1689
+ const googleClient = await this.googleAuth.getClient();
1690
+ const token = await googleClient.getAccessToken();
1691
+ if (!token.token) {
1692
+ throw new Error("VertexOpenAIAdapter: service account did not mint an access token");
1693
+ }
1694
+ }
1672
1695
  async warmup() {
1673
1696
  }
1674
1697
  ensureClient() {
@@ -1690,6 +1713,7 @@ var vertexOpenAIFactory = {
1690
1713
 
1691
1714
  // src/adapters/bedrock/adapter.ts
1692
1715
  var import_client_bedrock_runtime = require("@aws-sdk/client-bedrock-runtime");
1716
+ var import_client_bedrock = require("@aws-sdk/client-bedrock");
1693
1717
 
1694
1718
  // src/adapters/bedrock/manifest.ts
1695
1719
  var BEDROCK_KNOWN_MODELS = [
@@ -1904,6 +1928,7 @@ var BedrockAdapter = class {
1904
1928
  vendor = bedrockManifest.vendor;
1905
1929
  acceptedAuth = ["bedrockApiKey", "bedrockIam"];
1906
1930
  client;
1931
+ controlClientConfig;
1907
1932
  init(auth, client) {
1908
1933
  if (!auth.region) {
1909
1934
  throw new Error("BedrockAdapter: region is required");
@@ -1934,6 +1959,7 @@ var BedrockAdapter = class {
1934
1959
  );
1935
1960
  }
1936
1961
  this.client = new import_client_bedrock_runtime.BedrockRuntimeClient(config);
1962
+ this.controlClientConfig = config;
1937
1963
  }
1938
1964
  async *stream(req) {
1939
1965
  assertValidRequest(req);
@@ -2112,6 +2138,17 @@ var BedrockAdapter = class {
2112
2138
  async listAvailableModels() {
2113
2139
  return [...bedrockManifest.knownModels];
2114
2140
  }
2141
+ async testCredential() {
2142
+ if (!this.controlClientConfig) {
2143
+ throw new Error("BedrockAdapter: init() must be called before testCredential()");
2144
+ }
2145
+ const control = new import_client_bedrock.BedrockClient(this.controlClientConfig);
2146
+ try {
2147
+ await control.send(new import_client_bedrock.ListFoundationModelsCommand({}));
2148
+ } finally {
2149
+ control.destroy();
2150
+ }
2151
+ }
2115
2152
  async warmup() {
2116
2153
  }
2117
2154
  ensureClient() {