@use-solace/openllm 1.0.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 ADDED
@@ -0,0 +1,185 @@
1
+ # @use-solace/openllm
2
+
3
+ OpenLLM model registry and API client with full TypeScript support for interacting with the OpenLLM inference engine.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @use-solace/openllm@latest # npm
9
+ bun add @use-solace/openllm@latest # bun (recommended)
10
+ pnpm add @use-solace/openllm@latest # pnpm
11
+ deno add @use-solace/openllm@latest # deno
12
+ ```
13
+
14
+ ## Usage
15
+
16
+ ### Model Registry
17
+
18
+ Define your model registry:
19
+
20
+ ```ts
21
+ import { ModelRegistry } from "@use-solace/openllm";
22
+
23
+ export const models = ModelRegistry({
24
+ entries: {
25
+ "llama3.1-70b": {
26
+ inference: "ollama",
27
+ id: "llama3.1:70b",
28
+ context: 8192,
29
+ quant: "Q4_K_M",
30
+ capabilities: ["chat"],
31
+ latency: "slow",
32
+ },
33
+ "llama3.1-8b": {
34
+ inference: "llama",
35
+ id: "llama3.1:8b",
36
+ context: 8192,
37
+ quant: "Q4_K_M",
38
+ capabilities: ["chat", "completion"],
39
+ latency: "fast",
40
+ },
41
+ },
42
+ });
43
+
44
+ // Usage examples
45
+ models.list(); // returns all models
46
+ models.get("llama3.1:70b"); // returns data for llama3.1:70b
47
+ models.find({ capability: "chat", latency: "fast" });
48
+ models.findOne({ capability: "chat" });
49
+ models.has("llama3.1:70b"); // check if model exists
50
+ models.add("new-model", { // add a new model
51
+ inference: "ollama",
52
+ id: "new-model",
53
+ context: 4096,
54
+ capabilities: ["chat"],
55
+ });
56
+ models.remove("new-model"); // remove a model
57
+ ```
58
+
59
+ ### API Client
60
+
61
+ Directly interact with the OpenLLM engine:
62
+
63
+ ```ts
64
+ import { createOpenLLMClient } from "@use-solace/openllm";
65
+
66
+ const client = createOpenLLMClient({ engine: 8080 });
67
+
68
+ // Health check
69
+ const health = await client.health();
70
+
71
+ // List models
72
+ const { models } = await client.listModels();
73
+
74
+ // Register a model
75
+ await client.registerModel({
76
+ id: "llama3.1:8b",
77
+ name: "llama3.1-8b",
78
+ inference: "ollama",
79
+ context: 8192,
80
+ quant: "Q4_K_M",
81
+ capabilities: ["chat"],
82
+ latency: "fast",
83
+ });
84
+
85
+ // Load a model
86
+ await client.loadModel({ model_id: "llama3.1:8b" });
87
+
88
+ // Run inference
89
+ const result = await client.inference({
90
+ model_id: "llama3.1:8b",
91
+ prompt: "Hello, how are you?",
92
+ max_tokens: 512,
93
+ temperature: 0.7,
94
+ });
95
+
96
+ // Stream inference
97
+ await client.inferenceStream(
98
+ {
99
+ model_id: "llama3.1:8b",
100
+ prompt: "Tell me a story",
101
+ max_tokens: 1024,
102
+ },
103
+ {
104
+ onToken: (token) => console.log(token.token),
105
+ onComplete: (response) => console.log("Done:", response),
106
+ onError: (error) => console.error("Error:", error),
107
+ },
108
+ );
109
+
110
+ // Unload a model
111
+ await client.unloadModel("llama3.1:8b");
112
+ ```
113
+
114
+ ### Elysia Plugin
115
+
116
+ ```ts
117
+ import { Elysia } from "elysia";
118
+ import { openllm } from "@use-solace/openllm/elysia";
119
+ import { models } from "./registry.ts";
120
+
121
+ const app = new Elysia().use(
122
+ openllm({
123
+ prefix: "ollm", // routes will be under /ollm/* instead of /openllm/*
124
+ modelrouter: true, // enable model router
125
+ registry: models, // pass the registry instance
126
+ engine: 4292, // openllm-server port
127
+ }),
128
+ );
129
+
130
+ app.listen(3000);
131
+
132
+ console.log("Server running on localhost:3000");
133
+ ```
134
+
135
+ Available endpoints:
136
+ - `GET /openllm/health` - Health check
137
+ - `GET /openllm/models` - List registered models
138
+ - `POST /openllm/models/register` - Register a new model
139
+ - `POST /openllm/models/load` - Load a model
140
+ - `POST /openllm/models/unload/:modelId` - Unload a model
141
+ - `POST /openllm/inference` - Run inference
142
+ - `POST /openllm/router/chat` - Chat with automatic model routing (if `modelrouter: true`)
143
+
144
+ ## Types
145
+
146
+ The package provides full TypeScript type safety for all API interactions:
147
+
148
+ ```ts
149
+ import type {
150
+ InferenceBackend,
151
+ ModelCapability,
152
+ LatencyProfile,
153
+ ModelRegistryEntry,
154
+ InferenceRequest,
155
+ InferenceResponse,
156
+ StreamToken,
157
+ // ... and more
158
+ } from "@use-solace/openllm";
159
+ ```
160
+
161
+ ## Error Handling
162
+
163
+ The package provides typed error classes:
164
+
165
+ ```ts
166
+ import {
167
+ OpenLLMError,
168
+ ModelNotFoundError,
169
+ ModelNotLoadedError,
170
+ InferenceError,
171
+ } from "@use-solace/openllm";
172
+
173
+ try {
174
+ await client.inference({ model_id: "unknown", prompt: "test" });
175
+ } catch (error) {
176
+ if (error instanceof ModelNotFoundError) {
177
+ console.error("Model not found:", error.message);
178
+ console.error("Status code:", error.statusCode);
179
+ }
180
+ }
181
+ ```
182
+
183
+ ## License
184
+
185
+ MIT
@@ -0,0 +1,21 @@
1
+ import type { HealthResponse, InferenceRequest, InferenceResponse, LoadModelRequest, LoadModelResponse, ModelListResponse, OpenLLMConfig, RegisterModelRequest, RegisterModelResponse, StreamOptions, UnloadModelResponse } from "./types.js";
2
+ export declare class OpenLLMClient {
3
+ private baseUrl;
4
+ private timeout;
5
+ constructor(config?: OpenLLMConfig);
6
+ private request;
7
+ private createError;
8
+ health(): Promise<HealthResponse>;
9
+ listModels(): Promise<ModelListResponse>;
10
+ registerModel(data: RegisterModelRequest): Promise<RegisterModelResponse>;
11
+ loadModel(data: LoadModelRequest): Promise<LoadModelResponse>;
12
+ unloadModel(modelId: string): Promise<UnloadModelResponse>;
13
+ inference(data: InferenceRequest): Promise<InferenceResponse>;
14
+ inferenceStream(data: InferenceRequest, options: StreamOptions): Promise<void>;
15
+ setBaseUrl(baseUrl: string): void;
16
+ getBaseUrl(): string;
17
+ setTimeout(timeout: number): void;
18
+ getTimeout(): number;
19
+ }
20
+ export declare function createOpenLLMClient(config?: OpenLLMConfig): OpenLLMClient;
21
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,cAAc,EACd,gBAAgB,EAChB,iBAAiB,EACjB,gBAAgB,EAChB,iBAAiB,EACjB,iBAAiB,EAGjB,aAAa,EAEb,oBAAoB,EACpB,qBAAqB,EACrB,aAAa,EAEb,mBAAmB,EACpB,MAAM,YAAY,CAAC;AAEpB,qBAAa,aAAa;IACxB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,OAAO,CAAS;gBAEZ,MAAM,GAAE,aAAkB;YAKxB,OAAO;IAqCrB,OAAO,CAAC,WAAW;IA6Bb,MAAM,IAAI,OAAO,CAAC,cAAc,CAAC;IAIjC,UAAU,IAAI,OAAO,CAAC,iBAAiB,CAAC;IAIxC,aAAa,CACjB,IAAI,EAAE,oBAAoB,GACzB,OAAO,CAAC,qBAAqB,CAAC;IAO3B,SAAS,CAAC,IAAI,EAAE,gBAAgB,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAO7D,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAS1D,SAAS,CAAC,IAAI,EAAE,gBAAgB,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAO7D,eAAe,CACnB,IAAI,EAAE,gBAAgB,EACtB,OAAO,EAAE,aAAa,GACrB,OAAO,CAAC,IAAI,CAAC;IAwFhB,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAIjC,UAAU,IAAI,MAAM;IAIpB,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAIjC,UAAU,IAAI,MAAM;CAGrB;AAED,wBAAgB,mBAAmB,CAAC,MAAM,CAAC,EAAE,aAAa,GAAG,aAAa,CAEzE"}
package/dist/client.js ADDED
@@ -0,0 +1,189 @@
1
+ export class OpenLLMClient {
2
+ baseUrl;
3
+ timeout;
4
+ constructor(config = {}) {
5
+ this.baseUrl = `http://localhost:${config.engine ?? 8080}`;
6
+ this.timeout = config.timeout ?? 30000;
7
+ }
8
+ async request(endpoint, options = {}) {
9
+ const controller = new AbortController();
10
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
11
+ try {
12
+ const response = await fetch(`${this.baseUrl}${endpoint}`, {
13
+ ...options,
14
+ signal: controller.signal,
15
+ headers: {
16
+ "Content-Type": "application/json",
17
+ ...options.headers,
18
+ },
19
+ });
20
+ clearTimeout(timeoutId);
21
+ if (!response.ok) {
22
+ const errorText = await response.text();
23
+ throw this.createError(response.status, errorText);
24
+ }
25
+ return (await response.json());
26
+ }
27
+ catch (error) {
28
+ clearTimeout(timeoutId);
29
+ if (error instanceof Error) {
30
+ if (error.name === "AbortError") {
31
+ throw new Error(`Request timeout after ${this.timeout}ms`);
32
+ }
33
+ throw error;
34
+ }
35
+ throw error;
36
+ }
37
+ }
38
+ createError(status, message) {
39
+ if (status === 404) {
40
+ const match = message.match(/Model '([^']+)'/);
41
+ if (match) {
42
+ const error = new Error(message);
43
+ error.name = "ModelNotFoundError";
44
+ error.code = "MODEL_NOT_FOUND";
45
+ error.statusCode = status;
46
+ return error;
47
+ }
48
+ }
49
+ if (status === 412) {
50
+ const match = message.match(/Model '([^']+)'/);
51
+ if (match) {
52
+ const error = new Error(message);
53
+ error.name = "ModelNotLoadedError";
54
+ error.code = "MODEL_NOT_LOADED";
55
+ error.statusCode = status;
56
+ return error;
57
+ }
58
+ }
59
+ const error = new Error(message);
60
+ error.name = "OpenLLMError";
61
+ error.code = "API_ERROR";
62
+ error.statusCode = status;
63
+ return error;
64
+ }
65
+ async health() {
66
+ return this.request("/health");
67
+ }
68
+ async listModels() {
69
+ return this.request("/v1/models");
70
+ }
71
+ async registerModel(data) {
72
+ return this.request("/v1/models/register", {
73
+ method: "POST",
74
+ body: JSON.stringify(data),
75
+ });
76
+ }
77
+ async loadModel(data) {
78
+ return this.request("/v1/models/load", {
79
+ method: "POST",
80
+ body: JSON.stringify(data),
81
+ });
82
+ }
83
+ async unloadModel(modelId) {
84
+ return this.request(`/v1/models/unload/${modelId}`, {
85
+ method: "POST",
86
+ });
87
+ }
88
+ async inference(data) {
89
+ return this.request("/v1/inference", {
90
+ method: "POST",
91
+ body: JSON.stringify(data),
92
+ });
93
+ }
94
+ async inferenceStream(data, options) {
95
+ const controller = new AbortController();
96
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
97
+ try {
98
+ const response = await fetch(`${this.baseUrl}/v1/inference/stream`, {
99
+ method: "POST",
100
+ headers: {
101
+ "Content-Type": "application/json",
102
+ },
103
+ body: JSON.stringify(data),
104
+ signal: controller.signal,
105
+ });
106
+ clearTimeout(timeoutId);
107
+ if (!response.ok) {
108
+ const errorText = await response.text();
109
+ const error = this.createError(response.status, errorText);
110
+ options.onError?.(error);
111
+ throw error;
112
+ }
113
+ const reader = response.body?.getReader();
114
+ if (!reader) {
115
+ const error = new Error("No response body");
116
+ options.onError?.(error);
117
+ throw error;
118
+ }
119
+ const decoder = new TextDecoder();
120
+ let buffer = "";
121
+ let accumulatedText = "";
122
+ let tokenCount = 0;
123
+ const modelId = data.model_id;
124
+ while (true) {
125
+ const { done, value } = await reader.read();
126
+ if (done)
127
+ break;
128
+ buffer += decoder.decode(value, { stream: true });
129
+ const lines = buffer.split("\n");
130
+ buffer = lines.pop() ?? "";
131
+ for (const line of lines) {
132
+ if (line.trim().startsWith("event: token")) {
133
+ continue;
134
+ }
135
+ if (line.trim().startsWith("data: ")) {
136
+ const data = line.trim().slice(6);
137
+ if (data) {
138
+ try {
139
+ const token = JSON.parse(data);
140
+ accumulatedText += token.token;
141
+ tokenCount++;
142
+ options.onToken(token);
143
+ if (token.complete) {
144
+ options.onComplete?.({
145
+ model_id: modelId,
146
+ text: accumulatedText,
147
+ tokens_generated: tokenCount,
148
+ finish_reason: "stop",
149
+ });
150
+ }
151
+ }
152
+ catch (e) {
153
+ console.error("Failed to parse SSE data:", data, e);
154
+ }
155
+ }
156
+ }
157
+ }
158
+ }
159
+ }
160
+ catch (error) {
161
+ clearTimeout(timeoutId);
162
+ if (error instanceof Error) {
163
+ if (error.name === "AbortError") {
164
+ const timeoutError = new Error(`Stream timeout after ${this.timeout}ms`);
165
+ options.onError?.(timeoutError);
166
+ throw timeoutError;
167
+ }
168
+ options.onError?.(error);
169
+ throw error;
170
+ }
171
+ }
172
+ }
173
+ setBaseUrl(baseUrl) {
174
+ this.baseUrl = baseUrl;
175
+ }
176
+ getBaseUrl() {
177
+ return this.baseUrl;
178
+ }
179
+ setTimeout(timeout) {
180
+ this.timeout = timeout;
181
+ }
182
+ getTimeout() {
183
+ return this.timeout;
184
+ }
185
+ }
186
+ export function createOpenLLMClient(config) {
187
+ return new OpenLLMClient(config);
188
+ }
189
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ import type { Elysia } from "elysia";
2
+ import type { APIConfig } from "./types.js";
3
+ export declare function openllm(config?: APIConfig): (app: Elysia) => Elysia<"", {
4
+ decorator: {};
5
+ store: {};
6
+ derive: {};
7
+ resolve: {};
8
+ }, {
9
+ typebox: {};
10
+ error: {};
11
+ }, {
12
+ schema: {};
13
+ standaloneSchema: {};
14
+ macro: {};
15
+ macroFn: {};
16
+ parser: {};
17
+ response: {};
18
+ }, {}, {
19
+ derive: {};
20
+ resolve: {};
21
+ schema: {};
22
+ standaloneSchema: {};
23
+ response: {};
24
+ }, {
25
+ derive: {};
26
+ resolve: {};
27
+ schema: {};
28
+ standaloneSchema: {};
29
+ response: {};
30
+ }>;
31
+ //# sourceMappingURL=elysia.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"elysia.d.ts","sourceRoot":"","sources":["../src/elysia.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AACrC,OAAO,KAAK,EACV,SAAS,EAMV,MAAM,YAAY,CAAC;AAGpB,wBAAgB,OAAO,CAAC,MAAM,GAAE,SAAc,SACvB,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsF5B"}
package/dist/elysia.js ADDED
@@ -0,0 +1,66 @@
1
+ import { createOpenLLMClient } from "./client.js";
2
+ export function openllm(config = {}) {
3
+ const plugin = (app) => {
4
+ const enginePort = config.engine ?? 8080;
5
+ const prefix = config.prefix ?? "/openllm";
6
+ const enableRouter = config.modelrouter ?? false;
7
+ const registry = config.registry;
8
+ const client = createOpenLLMClient({ engine: enginePort });
9
+ app.get(`${prefix}/health`, async () => {
10
+ return await client.health();
11
+ });
12
+ app.get(`${prefix}/models`, async () => {
13
+ const result = await client.listModels();
14
+ return result.models;
15
+ });
16
+ app.post(`${prefix}/models/register`, async ({ body }) => {
17
+ const req = body;
18
+ return await client.registerModel(req);
19
+ });
20
+ app.post(`${prefix}/models/load`, async ({ body }) => {
21
+ const req = body;
22
+ return await client.loadModel(req);
23
+ });
24
+ app.post(`${prefix}/models/unload/:modelId`, async ({ params }) => {
25
+ const modelId = params.modelId;
26
+ return await client.unloadModel(modelId);
27
+ });
28
+ app.post(`${prefix}/inference`, async ({ body }) => {
29
+ const req = body;
30
+ return await client.inference(req);
31
+ });
32
+ if (enableRouter && registry) {
33
+ app.post(`${prefix}/router/chat`, async ({ body }) => {
34
+ const request = body;
35
+ const options = request.options ?? {};
36
+ let model;
37
+ if (options.model) {
38
+ model = registry.get(options.model);
39
+ if (!model) {
40
+ throw new Error(`Model '${options.model}' not found in registry`);
41
+ }
42
+ }
43
+ else {
44
+ model = registry.findOne({
45
+ capability: "chat",
46
+ latency: options.latency,
47
+ inference: options.inference,
48
+ minContext: options.minContext,
49
+ });
50
+ if (!model) {
51
+ throw new Error("No suitable model found for the given constraints");
52
+ }
53
+ }
54
+ return await client.inference({
55
+ model_id: model.id,
56
+ prompt: request.prompt,
57
+ max_tokens: options.max_tokens,
58
+ temperature: options.temperature,
59
+ });
60
+ });
61
+ }
62
+ return app;
63
+ };
64
+ return plugin;
65
+ }
66
+ //# sourceMappingURL=elysia.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"elysia.js","sourceRoot":"","sources":["../src/elysia.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ export type { InferenceBackend, ModelCapability, LatencyProfile, ModelRegistryEntry, RegistryEntryInput, ModelRegistryConfig, HealthResponse, ModelListResponse, RegisterModelResponse, LoadModelRequest, LoadModelResponse, UnloadModelResponse, InferenceRequest, InferenceResponse, StreamToken, StreamCallback, StreamCompleteCallback, StreamErrorCallback, StreamOptions, OpenLLMConfig, FindModelOptions, APIConfig, OpenLLMError, ModelNotFoundError, ModelNotLoadedError, InferenceError, ModelRegistryInstance, ModelRegistryImpl, } from "./types.js";
2
+ export { ModelRegistry, } from "./registry.js";
3
+ export type { ModelRegistry as ModelRegistryType } from "./registry.js";
4
+ export { OpenLLMClient, createOpenLLMClient, } from "./client.js";
5
+ export { openllm } from "./elysia.js";
6
+ export declare const openllmAPI: {
7
+ start: (config?: import("./types.js").APIConfig) => {
8
+ start: (apiPort: number) => void;
9
+ };
10
+ };
11
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,gBAAgB,EAChB,eAAe,EACf,cAAc,EACd,kBAAkB,EAClB,kBAAkB,EAClB,mBAAmB,EACnB,cAAc,EACd,iBAAiB,EACjB,qBAAqB,EACrB,gBAAgB,EAChB,iBAAiB,EACjB,mBAAmB,EACnB,gBAAgB,EAChB,iBAAiB,EACjB,WAAW,EACX,cAAc,EACd,sBAAsB,EACtB,mBAAmB,EACnB,aAAa,EACb,aAAa,EACb,gBAAgB,EAChB,SAAS,EACT,YAAY,EACZ,kBAAkB,EAClB,mBAAmB,EACnB,cAAc,EACd,qBAAqB,EACrB,iBAAiB,GAClB,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,aAAa,GACd,MAAM,eAAe,CAAC;AAEvB,YAAY,EAAE,aAAa,IAAI,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAExE,OAAO,EACL,aAAa,EACb,mBAAmB,GACpB,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAEtC,eAAO,MAAM,UAAU;qBACL,OAAO,YAAY,EAAE,SAAS;yBAGzB,MAAM;;CAM5B,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,15 @@
1
+ export { ModelRegistry, } from "./registry.js";
2
+ export { OpenLLMClient, createOpenLLMClient, } from "./client.js";
3
+ export { openllm } from "./elysia.js";
4
+ export const openllmAPI = {
5
+ start: (config = {}) => {
6
+ const port = config.engine ?? 4292;
7
+ return {
8
+ start: (apiPort) => {
9
+ console.log(`Starting OpenLLM API on port ${apiPort}, connected to engine on port ${port}`);
10
+ console.log("Note: This is a client library. To start the actual server, use the Elysia plugin.");
11
+ },
12
+ };
13
+ },
14
+ };
15
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AA+BA,OAAO,EACL,aAAa,GACd,MAAM,eAAe,CAAC;AAIvB,OAAO,EACL,aAAa,EACb,mBAAmB,GACpB,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAEtC,MAAM,CAAC,MAAM,UAAU,GAAG;IACxB,KAAK,EAAE,CAAC,SAAyC,EAAE,EAAE,EAAE;QACrD,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,IAAI,IAAI,CAAC;QACnC,OAAO;YACL,KAAK,EAAE,CAAC,OAAe,EAAE,EAAE;gBACzB,OAAO,CAAC,GAAG,CAAC,gCAAgC,OAAO,iCAAiC,IAAI,EAAE,CAAC,CAAC;gBAC5F,OAAO,CAAC,GAAG,CAAC,oFAAoF,CAAC,CAAC;YACpG,CAAC;SACF,CAAC;IACJ,CAAC;CACF,CAAC"}
@@ -0,0 +1,20 @@
1
+ import type { FindModelOptions, ModelRegistryConfig, ModelRegistryEntry, RegistryEntryInput } from "./types.js";
2
+ export declare class ModelRegistryImpl {
3
+ private entries;
4
+ constructor(config: ModelRegistryConfig);
5
+ private registerEntry;
6
+ list(): ModelRegistryEntry[];
7
+ get(id: string): ModelRegistryEntry | undefined;
8
+ find(options?: FindModelOptions): ModelRegistryEntry[];
9
+ findOne(options?: FindModelOptions): ModelRegistryEntry | undefined;
10
+ has(id: string): boolean;
11
+ count(): number;
12
+ add(id: string, entry: RegistryEntryInput): ModelRegistryEntry;
13
+ update(id: string, updates: Partial<RegistryEntryInput>): ModelRegistryEntry;
14
+ remove(id: string): boolean;
15
+ clear(): void;
16
+ toObject(): Record<string, ModelRegistryEntry>;
17
+ fromObject(obj: Record<string, ModelRegistryEntry>): void;
18
+ }
19
+ export declare function ModelRegistry(config: ModelRegistryConfig): ModelRegistryImpl;
20
+ //# sourceMappingURL=registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,gBAAgB,EAChB,mBAAmB,EACnB,kBAAkB,EAClB,kBAAkB,EACnB,MAAM,YAAY,CAAC;AAEpB,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,OAAO,CAA8C;gBAEjD,MAAM,EAAE,mBAAmB;IAOvC,OAAO,CAAC,aAAa;IAiBrB,IAAI,IAAI,kBAAkB,EAAE;IAI5B,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,kBAAkB,GAAG,SAAS;IAI/C,IAAI,CAAC,OAAO,GAAE,gBAAqB,GAAG,kBAAkB,EAAE;IAsB1D,OAAO,CAAC,OAAO,GAAE,gBAAqB,GAAG,kBAAkB,GAAG,SAAS;IAIvE,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAIxB,KAAK,IAAI,MAAM;IAIf,GAAG,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,kBAAkB,GAAG,kBAAkB;IAO9D,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,kBAAkB,CAAC,GAAG,kBAAkB;IAe5E,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAI3B,KAAK,IAAI,IAAI;IAIb,QAAQ,IAAI,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAAC;IAI9C,UAAU,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAAC,GAAG,IAAI;CAM1D;AAED,wBAAgB,aAAa,CAC3B,MAAM,EAAE,mBAAmB,GAC1B,iBAAiB,CAEnB"}