@dbx-tools/model 0.9.118 → 0.9.120
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 +10 -8
- package/index.ts +2 -2
- package/lib/index.d.ts +2 -2
- package/lib/index.js +2 -2
- package/lib/src/_cache.d.ts +4 -0
- package/lib/src/_cache.js +12 -0
- package/lib/src/metadata-cache.d.ts +10 -52
- package/lib/src/metadata-cache.js +34 -187
- package/lib/src/metadata.d.ts +3 -5
- package/lib/src/metadata.js +7 -10
- package/lib/src/model-catalog.d.ts +9 -19
- package/lib/src/model-catalog.js +25 -27
- package/lib/src/model-client.js +3 -2
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/package.json +7 -9
- package/src/_cache.ts +13 -0
- package/src/metadata-cache.ts +52 -245
- package/src/metadata.ts +6 -10
- package/src/model-catalog.ts +30 -32
- package/src/model-client.ts +2 -1
- package/lib/package.json +0 -137
package/src/model-catalog.ts
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Lists the workspace's `/serving-endpoints` and, when the caller supplies a
|
|
5
5
|
* trusted credential identity, caches the result per host and identity with a
|
|
6
|
-
* TTL via
|
|
6
|
+
* TTL via `@dbx-tools/cache`. Concurrent callers in the same scope share
|
|
7
7
|
* one in-flight promise. Surfaces each endpoint as a stable
|
|
8
8
|
* {@link ServingEndpointSummary} - including the Foundation Model API
|
|
9
9
|
* `quality` / `speed` / `cost` profile when present, the classified
|
|
@@ -22,8 +22,8 @@
|
|
|
22
22
|
*/
|
|
23
23
|
|
|
24
24
|
import { createHash } from "node:crypto";
|
|
25
|
-
import { CacheManager } from "@databricks/appkit";
|
|
26
25
|
import { appkit } from "@dbx-tools/appkit";
|
|
26
|
+
import { deleteCachedValue, getOrSet } from "@dbx-tools/cache/cache";
|
|
27
27
|
import { errorUtils, log } from "@dbx-tools/shared-core";
|
|
28
28
|
import {
|
|
29
29
|
model,
|
|
@@ -33,6 +33,7 @@ import {
|
|
|
33
33
|
type ServingEndpointSummary,
|
|
34
34
|
} from "@dbx-tools/shared-model";
|
|
35
35
|
|
|
36
|
+
import { modelCatalogueCache } from "./_cache.ts";
|
|
36
37
|
import { classifyEndpointClasses, normalizeEndpoints, rankEndpoints } from "./_ranking.ts";
|
|
37
38
|
|
|
38
39
|
const { ModelClass } = model;
|
|
@@ -54,12 +55,12 @@ export const DEFAULT_FUZZY_THRESHOLD = 0.4;
|
|
|
54
55
|
|
|
55
56
|
/** Cache key parts under which endpoint listings are stored. */
|
|
56
57
|
const CACHE_KEY_NAMESPACE = "serving-endpoints";
|
|
58
|
+
const catalogueCache = modelCatalogueCache;
|
|
57
59
|
|
|
58
60
|
/** Options for {@link listServingEndpoints}. */
|
|
59
61
|
export interface ListServingEndpointsOptions {
|
|
60
62
|
/**
|
|
61
|
-
* Override the default cache TTL for this call, in milliseconds.
|
|
62
|
-
* `CacheManager` as seconds.
|
|
63
|
+
* Override the default cache TTL for this call, in milliseconds.
|
|
63
64
|
*/
|
|
64
65
|
ttlMs?: number;
|
|
65
66
|
/**
|
|
@@ -73,30 +74,23 @@ export interface ListServingEndpointsOptions {
|
|
|
73
74
|
cacheIdentity?: string;
|
|
74
75
|
}
|
|
75
76
|
|
|
76
|
-
/** Hash an opaque credential identity before handing it to
|
|
77
|
+
/** Hash an opaque credential identity before handing it to the shared cache. */
|
|
77
78
|
function cacheUserKey(identity: string): string {
|
|
78
79
|
return `model-${createHash("sha256").update(identity).digest("hex")}`;
|
|
79
80
|
}
|
|
80
81
|
|
|
81
82
|
/**
|
|
82
83
|
* List Model Serving endpoints for the workspace owning `client`, routed
|
|
83
|
-
* through
|
|
84
|
-
*
|
|
85
|
-
* per-entry TTL, in-flight request coalescing (concurrent callers share one
|
|
86
|
-
* fetch via the manager's internal `inFlightRequests` map), bounded size,
|
|
87
|
-
* telemetry spans (`cache.getOrExecute`), and optional Lakebase persistence so
|
|
88
|
-
* the catalogue survives restarts when the lakebase plugin is wired up.
|
|
84
|
+
* through the shared memory-first cache, including per-entry TTL, in-flight
|
|
85
|
+
* request coalescing, bounded process memory, and portable persistence.
|
|
89
86
|
*
|
|
90
87
|
* Returns plain {@link ServingEndpointSummary} objects (a stable subset of the
|
|
91
|
-
* SDK type) so cache hits never expose stale SDK internals.
|
|
92
|
-
* `CacheManager` or the SDK fetch propagate to the caller - we don't swallow
|
|
93
|
-
* them so users see the real auth / network issue.
|
|
88
|
+
* SDK type) so cache hits never expose stale SDK internals.
|
|
94
89
|
*
|
|
95
90
|
* @param host - Workspace host used as the cache key. Pass the value resolved
|
|
96
91
|
* from `client.config.getHost()` so multi-host apps share one entry per
|
|
97
92
|
* workspace.
|
|
98
|
-
* @param options.ttlMs - Override the default TTL just for this call.
|
|
99
|
-
* to `CacheManager` as seconds.
|
|
93
|
+
* @param options.ttlMs - Override the default TTL just for this call.
|
|
100
94
|
*/
|
|
101
95
|
export async function listServingEndpoints(
|
|
102
96
|
client: WorkspaceClientLike,
|
|
@@ -104,13 +98,17 @@ export async function listServingEndpoints(
|
|
|
104
98
|
options: ListServingEndpointsOptions = {},
|
|
105
99
|
): Promise<ServingEndpointSummary[]> {
|
|
106
100
|
if (!options.cacheIdentity) return fetchEndpoints(client);
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
101
|
+
return (await getOrSet(
|
|
102
|
+
catalogueCache,
|
|
103
|
+
catalogueCacheKey(host, options.cacheIdentity),
|
|
110
104
|
() => fetchEndpoints(client),
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
105
|
+
{
|
|
106
|
+
ttl: options.ttlMs ?? DEFAULT_MODEL_CACHE_TTL_MS,
|
|
107
|
+
returnCachedOnError: true,
|
|
108
|
+
cachedOnErrorTtl: "7d",
|
|
109
|
+
throwErrors: true,
|
|
110
|
+
},
|
|
111
|
+
))!;
|
|
114
112
|
}
|
|
115
113
|
|
|
116
114
|
/**
|
|
@@ -119,7 +117,7 @@ export async function listServingEndpoints(
|
|
|
119
117
|
* none of the cache-load enrichment ({@link listServingEndpoints} adds the
|
|
120
118
|
* {@link ModelClass} stamp and the embedding-dimension probe). Use this for a
|
|
121
119
|
* one-shot, dependency-light listing - e.g. a CLI that only needs names/tasks
|
|
122
|
-
* for fuzzy resolution and doesn't want
|
|
120
|
+
* for fuzzy resolution and doesn't want shared cache persistence or the
|
|
123
121
|
* per-embedding ping cost. Prefer {@link listServingEndpoints} for the cached,
|
|
124
122
|
* enriched view.
|
|
125
123
|
*/
|
|
@@ -191,30 +189,30 @@ async function pingEmbeddingDimension(
|
|
|
191
189
|
logger.warn("embedding ping returned no vector", { name });
|
|
192
190
|
return undefined;
|
|
193
191
|
} catch (err) {
|
|
194
|
-
logger.warn("embedding ping failed", { name, error: errorUtils.
|
|
192
|
+
logger.warn("embedding ping failed", { name, error: errorUtils.toError(err) });
|
|
195
193
|
return undefined;
|
|
196
194
|
}
|
|
197
195
|
}
|
|
198
196
|
|
|
199
197
|
/**
|
|
200
|
-
* Force-evict cached endpoint listings
|
|
201
|
-
*
|
|
202
|
-
* cannot enumerate a namespace, omitting either value clears the complete
|
|
203
|
-
* manager and should be reserved for tests or administrative refreshes.
|
|
198
|
+
* Force-evict cached endpoint listings. A host and identity delete only that
|
|
199
|
+
* principal's workspace entry. Omitting either value clears this catalogue.
|
|
204
200
|
*/
|
|
205
201
|
export async function clearServingEndpointsCache(
|
|
206
202
|
host?: string,
|
|
207
203
|
cacheIdentity?: string,
|
|
208
204
|
): Promise<void> {
|
|
209
|
-
const cache = CacheManager.getInstanceSync();
|
|
210
205
|
if (host && cacheIdentity) {
|
|
211
|
-
|
|
212
|
-
await cache.delete(key);
|
|
206
|
+
await deleteCachedValue(catalogueCache, catalogueCacheKey(host, cacheIdentity));
|
|
213
207
|
} else {
|
|
214
|
-
await
|
|
208
|
+
await catalogueCache.clear();
|
|
215
209
|
}
|
|
216
210
|
}
|
|
217
211
|
|
|
212
|
+
function catalogueCacheKey(host: string, cacheIdentity: string): string {
|
|
213
|
+
return JSON.stringify([CACHE_KEY_NAMESPACE, host, cacheUserKey(cacheIdentity)]);
|
|
214
|
+
}
|
|
215
|
+
|
|
218
216
|
/**
|
|
219
217
|
* Result of fuzzy-resolving a user-supplied model name against the live
|
|
220
218
|
* endpoint list. `score` is the ranker's distance (`0` is exact, `1` is no match);
|
package/src/model-client.ts
CHANGED
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
} from "@dbx-tools/auth/client";
|
|
16
16
|
import { listProfiles as listAuthProfiles } from "@dbx-tools/auth/profile";
|
|
17
17
|
import type { DatabricksProfileSummary } from "@dbx-tools/shared-auth";
|
|
18
|
+
import * as errorUtils from "@dbx-tools/shared-core/error-utils";
|
|
18
19
|
import * as log from "@dbx-tools/shared-core/log";
|
|
19
20
|
import * as object from "@dbx-tools/shared-core/object";
|
|
20
21
|
import {
|
|
@@ -274,7 +275,7 @@ class DefaultModelClient implements ModelClient {
|
|
|
274
275
|
} catch (error) {
|
|
275
276
|
logger.warn("embedding dimension probe failed", {
|
|
276
277
|
model: endpoint.name,
|
|
277
|
-
error,
|
|
278
|
+
error: errorUtils.toError(error),
|
|
278
279
|
});
|
|
279
280
|
return endpoint;
|
|
280
281
|
}
|
package/lib/package.json
DELETED
|
@@ -1,137 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@dbx-tools/model",
|
|
3
|
-
"description": "Workspace-aware Databricks Model Serving selection",
|
|
4
|
-
"repository": {
|
|
5
|
-
"type": "git",
|
|
6
|
-
"url": "git+https://github.com/reggie-db/dbx-tools.git",
|
|
7
|
-
"directory": "packages/js/node/model"
|
|
8
|
-
},
|
|
9
|
-
"scripts": {
|
|
10
|
-
"build": "projen build",
|
|
11
|
-
"compile": "projen compile",
|
|
12
|
-
"default": "projen default",
|
|
13
|
-
"metadata": "projen metadata",
|
|
14
|
-
"package": "projen package",
|
|
15
|
-
"post-compile": "projen post-compile",
|
|
16
|
-
"pre-compile": "projen pre-compile",
|
|
17
|
-
"prepack": "projen prepack",
|
|
18
|
-
"test": "projen test",
|
|
19
|
-
"watch": "projen watch",
|
|
20
|
-
"projen": "projen"
|
|
21
|
-
},
|
|
22
|
-
"devDependencies": {
|
|
23
|
-
"@types/cacache": "^20.0.1",
|
|
24
|
-
"@types/node": "catalog:",
|
|
25
|
-
"typescript": "^5.9.3"
|
|
26
|
-
},
|
|
27
|
-
"dependencies": {
|
|
28
|
-
"@databricks/appkit": "catalog:",
|
|
29
|
-
"@dbx-tools/appkit": "workspace:^",
|
|
30
|
-
"@dbx-tools/auth": "workspace:^",
|
|
31
|
-
"@dbx-tools/shared-auth": "workspace:^",
|
|
32
|
-
"@dbx-tools/shared-core": "workspace:^",
|
|
33
|
-
"@dbx-tools/shared-model": "workspace:^",
|
|
34
|
-
"cacache": "catalog:",
|
|
35
|
-
"cheerio": "^1.2.0",
|
|
36
|
-
"env-paths": "catalog:",
|
|
37
|
-
"fuse.js": "^7.4.2"
|
|
38
|
-
},
|
|
39
|
-
"main": "index.ts",
|
|
40
|
-
"license": "Apache-2.0",
|
|
41
|
-
"publishConfig": {
|
|
42
|
-
"access": "public",
|
|
43
|
-
"main": "./lib/index.js",
|
|
44
|
-
"types": "./lib/index.d.ts",
|
|
45
|
-
"exports": {
|
|
46
|
-
".": {
|
|
47
|
-
"types": "./lib/index.d.ts",
|
|
48
|
-
"default": "./lib/index.js"
|
|
49
|
-
},
|
|
50
|
-
"./bindings": {
|
|
51
|
-
"types": "./lib/src/bindings.d.ts",
|
|
52
|
-
"default": "./lib/src/bindings.js"
|
|
53
|
-
},
|
|
54
|
-
"./classes": {
|
|
55
|
-
"types": "./lib/src/classes.d.ts",
|
|
56
|
-
"default": "./lib/src/classes.js"
|
|
57
|
-
},
|
|
58
|
-
"./classify": {
|
|
59
|
-
"types": "./lib/src/classify.d.ts",
|
|
60
|
-
"default": "./lib/src/classify.js"
|
|
61
|
-
},
|
|
62
|
-
"./fallback": {
|
|
63
|
-
"types": "./lib/src/fallback.d.ts",
|
|
64
|
-
"default": "./lib/src/fallback.js"
|
|
65
|
-
},
|
|
66
|
-
"./invoke": {
|
|
67
|
-
"types": "./lib/src/invoke.d.ts",
|
|
68
|
-
"default": "./lib/src/invoke.js"
|
|
69
|
-
},
|
|
70
|
-
"./metadata-cache": {
|
|
71
|
-
"types": "./lib/src/metadata-cache.d.ts",
|
|
72
|
-
"default": "./lib/src/metadata-cache.js"
|
|
73
|
-
},
|
|
74
|
-
"./metadata": {
|
|
75
|
-
"types": "./lib/src/metadata.d.ts",
|
|
76
|
-
"default": "./lib/src/metadata.js"
|
|
77
|
-
},
|
|
78
|
-
"./model-catalog": {
|
|
79
|
-
"types": "./lib/src/model-catalog.d.ts",
|
|
80
|
-
"default": "./lib/src/model-catalog.js"
|
|
81
|
-
},
|
|
82
|
-
"./model-client": {
|
|
83
|
-
"types": "./lib/src/model-client.d.ts",
|
|
84
|
-
"default": "./lib/src/model-client.js"
|
|
85
|
-
},
|
|
86
|
-
"./policy": {
|
|
87
|
-
"types": "./lib/src/policy.d.ts",
|
|
88
|
-
"default": "./lib/src/policy.js"
|
|
89
|
-
},
|
|
90
|
-
"./reasoning-translation": {
|
|
91
|
-
"types": "./lib/src/reasoning-translation.d.ts",
|
|
92
|
-
"default": "./lib/src/reasoning-translation.js"
|
|
93
|
-
},
|
|
94
|
-
"./resolve": {
|
|
95
|
-
"types": "./lib/src/resolve.d.ts",
|
|
96
|
-
"default": "./lib/src/resolve.js"
|
|
97
|
-
},
|
|
98
|
-
"./*": {
|
|
99
|
-
"types": "./lib/src/*/index.d.ts",
|
|
100
|
-
"default": "./lib/src/*/index.js"
|
|
101
|
-
},
|
|
102
|
-
"./package.json": "./package.json"
|
|
103
|
-
}
|
|
104
|
-
},
|
|
105
|
-
"version": "0.9.118",
|
|
106
|
-
"types": "index.ts",
|
|
107
|
-
"dbxToolsConfig": {
|
|
108
|
-
"tags": [
|
|
109
|
-
"node"
|
|
110
|
-
]
|
|
111
|
-
},
|
|
112
|
-
"type": "module",
|
|
113
|
-
"exports": {
|
|
114
|
-
".": "./index.ts",
|
|
115
|
-
"./bindings": "./src/bindings.ts",
|
|
116
|
-
"./classes": "./src/classes.ts",
|
|
117
|
-
"./classify": "./src/classify.ts",
|
|
118
|
-
"./fallback": "./src/fallback.ts",
|
|
119
|
-
"./invoke": "./src/invoke.ts",
|
|
120
|
-
"./metadata-cache": "./src/metadata-cache.ts",
|
|
121
|
-
"./metadata": "./src/metadata.ts",
|
|
122
|
-
"./model-catalog": "./src/model-catalog.ts",
|
|
123
|
-
"./model-client": "./src/model-client.ts",
|
|
124
|
-
"./policy": "./src/policy.ts",
|
|
125
|
-
"./reasoning-translation": "./src/reasoning-translation.ts",
|
|
126
|
-
"./resolve": "./src/resolve.ts",
|
|
127
|
-
"./*": "./src/*/index.ts",
|
|
128
|
-
"./package.json": "./package.json"
|
|
129
|
-
},
|
|
130
|
-
"files": [
|
|
131
|
-
"index.ts",
|
|
132
|
-
"src",
|
|
133
|
-
"exports.ts",
|
|
134
|
-
"lib"
|
|
135
|
-
],
|
|
136
|
-
"//": "~~ Generated by projen. To modify, edit .projenrc.js and run \"bunx projen\"."
|
|
137
|
-
}
|