@oracle/langchain-oracledb 1.0.0 → 1.1.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 +55 -0
- package/dist/cache.cjs +535 -0
- package/dist/cache.cjs.map +1 -0
- package/dist/cache.d.cts +168 -0
- package/dist/cache.d.ts +168 -0
- package/dist/cache.js +527 -0
- package/dist/cache.js.map +1 -0
- package/dist/chatMessageHistories.cjs +345 -0
- package/dist/chatMessageHistories.cjs.map +1 -0
- package/dist/chatMessageHistories.d.cts +107 -0
- package/dist/chatMessageHistories.d.ts +107 -0
- package/dist/chatMessageHistories.js +338 -0
- package/dist/chatMessageHistories.js.map +1 -0
- package/dist/errors.cjs +25 -1
- package/dist/errors.cjs.map +1 -1
- package/dist/errors.d.cts +7 -0
- package/dist/errors.d.ts +7 -0
- package/dist/errors.js +23 -0
- package/dist/errors.js.map +1 -1
- package/dist/index.cjs +11 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/utils.cjs +49 -0
- package/dist/utils.cjs.map +1 -0
- package/dist/utils.d.cts +5 -0
- package/dist/utils.d.ts +5 -0
- package/dist/utils.js +44 -0
- package/dist/utils.js.map +1 -0
- package/dist/vectorstores.cjs +76 -68
- package/dist/vectorstores.cjs.map +1 -1
- package/dist/vectorstores.d.cts +3 -2
- package/dist/vectorstores.d.ts +3 -2
- package/dist/vectorstores.js +61 -53
- package/dist/vectorstores.js.map +1 -1
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -42,6 +42,16 @@ You can do so by adding an appropriate field to your project's `package.json` li
|
|
|
42
42
|
|
|
43
43
|
The field you need depends on the package manager you're using, but we recommend adding a field for the common `yarn`, `npm`, and `pnpm` to maximize compatibility.
|
|
44
44
|
|
|
45
|
+
## Transaction management
|
|
46
|
+
|
|
47
|
+
Database operations may commit or roll back transactions depending on the operation.
|
|
48
|
+
|
|
49
|
+
When an existing `oracledb.Connection` is supplied, the integration uses that connection directly. Any `commit()` or `rollback()` performed by the integration affects all uncommitted work on that connection, including unrelated application statements. Database initialization and other DDL operations may also implicitly commit the current transaction.
|
|
50
|
+
|
|
51
|
+
When an `oracledb.Pool` is supplied, the integration acquires a connection for its operations. Commits and rollbacks on that connection do not affect transactions on other connections checked out from the same pool.
|
|
52
|
+
|
|
53
|
+
For operations that should be independent of application transactions, use an `oracledb.Pool` or a dedicated connection. If using a custom connection provider, ensure it does not return a connection participating in an unrelated transaction.
|
|
54
|
+
|
|
45
55
|
## Document Loaders
|
|
46
56
|
|
|
47
57
|
This package includes a document loader for loading documents from different sources and file formats.
|
|
@@ -99,6 +109,51 @@ await oraclevs.initialize();
|
|
|
99
109
|
await oraclevs.addDocuments(docs);
|
|
100
110
|
const results = await oraclevs.similaritySearch("hello!", 3);
|
|
101
111
|
```
|
|
112
|
+
## Caches
|
|
113
|
+
|
|
114
|
+
Python and TypeScript exact and semantic cache tables are not currently interchangeable. Use separate table names for each implementation.
|
|
115
|
+
|
|
116
|
+
### Exact Cache
|
|
117
|
+
|
|
118
|
+
This package includes an exact cache for storing and retrieving model generations by prompt and model configuration key.
|
|
119
|
+
|
|
120
|
+
```typescript
|
|
121
|
+
import {OracleCache} from "@oracle/langchain-oracledb";
|
|
122
|
+
|
|
123
|
+
const cache = new OracleCache(conn);
|
|
124
|
+
await cache.initialize();
|
|
125
|
+
|
|
126
|
+
await cache.update(prompt, llmKey, generations);
|
|
127
|
+
const cachedGenerations = await cache.lookup(prompt, llmKey);
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### Semantic Cache
|
|
131
|
+
|
|
132
|
+
This package includes a semantic cache for retrieving model generations using vector similarity between prompts.
|
|
133
|
+
|
|
134
|
+
```typescript
|
|
135
|
+
import {OracleSemanticCache} from "@oracle/langchain-oracledb";
|
|
136
|
+
|
|
137
|
+
const cache = new OracleSemanticCache(embedder, dbConfig, {scoreThreshold: 0.2});
|
|
138
|
+
await cache.initialize();
|
|
139
|
+
|
|
140
|
+
await cache.update(prompt, llmKey, generations);
|
|
141
|
+
const cachedGenerations = await cache.lookup(prompt, llmKey);
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
## Chat Message History
|
|
145
|
+
|
|
146
|
+
This package includes a chat message history for storing and retrieving conversation messages by session in the database.
|
|
147
|
+
|
|
148
|
+
```typescript
|
|
149
|
+
import {OracleChatMessageHistory} from "@oracle/langchain-oracledb";
|
|
150
|
+
|
|
151
|
+
await OracleChatMessageHistory.createTables({client: conn});
|
|
152
|
+
const history = new OracleChatMessageHistory({client: conn, sessionId: "session-1"});
|
|
153
|
+
|
|
154
|
+
await history.addMessages(messages);
|
|
155
|
+
const storedMessages = await history.getMessages();
|
|
156
|
+
```
|
|
102
157
|
|
|
103
158
|
## Development
|
|
104
159
|
|
package/dist/cache.cjs
ADDED
|
@@ -0,0 +1,535 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.OracleCache = exports.OracleSemanticCache = void 0;
|
|
7
|
+
const oracledb_1 = __importDefault(require("oracledb"));
|
|
8
|
+
const messages_1 = require("@langchain/core/messages");
|
|
9
|
+
const documents_1 = require("@langchain/core/documents");
|
|
10
|
+
const errors_js_1 = require("./errors.cjs");
|
|
11
|
+
const caches_1 = require("@langchain/core/caches");
|
|
12
|
+
const vectorstores_js_1 = require("./vectorstores.cjs");
|
|
13
|
+
const utils_js_1 = require("./utils.cjs");
|
|
14
|
+
const DEFAULT_TABLE_NAME = "langchain_js_semantic_cache";
|
|
15
|
+
const DISTANCE_EPSILON = 1e-12;
|
|
16
|
+
/** Deserializes cached generations and clears message IDs before reuse. */
|
|
17
|
+
function deserializeGenerations(payload) {
|
|
18
|
+
try {
|
|
19
|
+
const stored = typeof payload === "string" ? JSON.parse(payload) : payload;
|
|
20
|
+
if (!Array.isArray(stored)) {
|
|
21
|
+
console.warn("Ignoring malformed cached generations: expected an array.");
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
const generations = [];
|
|
25
|
+
for (const entry of stored) {
|
|
26
|
+
if (entry === null ||
|
|
27
|
+
typeof entry !== "object" ||
|
|
28
|
+
typeof entry.text !== "string") {
|
|
29
|
+
console.warn("Ignoring malformed cached generations: expected objects with string text.");
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
const generation = (0, caches_1.deserializeStoredGeneration)(entry);
|
|
33
|
+
// Clears cached message IDs before reuse so LangGraph's message reducer does not
|
|
34
|
+
// replace an earlier message with the same ID instead of appending a new one.
|
|
35
|
+
// Messages whose IDs cannot be assigned are left unchanged on TypeError.
|
|
36
|
+
if ("message" in generation &&
|
|
37
|
+
messages_1.BaseMessage.isInstance(generation.message)) {
|
|
38
|
+
try {
|
|
39
|
+
generation.message.id = undefined;
|
|
40
|
+
}
|
|
41
|
+
catch (error) {
|
|
42
|
+
// eslint-disable-next-line no-instanceof/no-instanceof
|
|
43
|
+
if (!(error instanceof TypeError)) {
|
|
44
|
+
throw error;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
generations.push(generation);
|
|
49
|
+
}
|
|
50
|
+
return generations;
|
|
51
|
+
}
|
|
52
|
+
catch (error) {
|
|
53
|
+
// eslint-disable-next-line no-instanceof/no-instanceof
|
|
54
|
+
if (error instanceof SyntaxError || error instanceof TypeError) {
|
|
55
|
+
console.warn(`Ignoring malformed cached generations: ${error.name} during decoding.`);
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
throw (0, errors_js_1.createErrorFromCodeWithCause)(errors_js_1.ErrorCode.CACHE_DESERIALIZATION_FAILED, error);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
/** Detects tool-call responses, which represent agent steps rather than final answers. */
|
|
62
|
+
function hasToolCalls(generations) {
|
|
63
|
+
return generations.some((generation) => "message" in generation &&
|
|
64
|
+
messages_1.AIMessage.isInstance(generation.message) &&
|
|
65
|
+
((generation.message.tool_calls?.length ?? 0) > 0 ||
|
|
66
|
+
(generation.message.invalid_tool_calls?.length ?? 0) > 0));
|
|
67
|
+
}
|
|
68
|
+
function validateClearOptions(options) {
|
|
69
|
+
const unknownKeys = Object.keys(options).filter((key) => key !== "prompt" && key !== "llmKey");
|
|
70
|
+
if (unknownKeys.length > 0) {
|
|
71
|
+
(0, errors_js_1.throwError)(errors_js_1.ErrorCode.VALIDATION_INVALID_INPUT, `Unsupported clear options: ${unknownKeys.join(", ")}`);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Caches model generations in Oracle Database using vector similarity between prompts.
|
|
76
|
+
* @example
|
|
77
|
+
* ```typescript
|
|
78
|
+
* // `embeddings` is an EmbeddingsInterface and `pool` is an Oracle connection pool.
|
|
79
|
+
* const cache = new OracleSemanticCache(embeddings, { client: pool }, {
|
|
80
|
+
* scoreThreshold: 0.2,
|
|
81
|
+
* createIndexIfMissing: true,
|
|
82
|
+
* });
|
|
83
|
+
* ```
|
|
84
|
+
*/
|
|
85
|
+
class OracleSemanticCache extends caches_1.BaseCache {
|
|
86
|
+
/**
|
|
87
|
+
* Creates a semantic cache instance without performing database setup.
|
|
88
|
+
*
|
|
89
|
+
* @param {EmbeddingsInterface} embeddings Embedding model used to vectorize prompts.
|
|
90
|
+
* @param {OracleSemanticCacheDBConfig} dbConfig Oracle vector-store configuration.
|
|
91
|
+
* @param {OracleDBClient | OracleDBClientProvider} dbConfig.client Connection, pool, or async provider to use.
|
|
92
|
+
* @param {string} dbConfig.tableName Cache table name. Defaults to `langchain_semantic_cache`.
|
|
93
|
+
*
|
|
94
|
+
* @param {OracleSemanticCacheOptions} options Optional index and distance threshold settings.
|
|
95
|
+
* @param {boolean} options.createIndexIfMissing Whether initialize() creates a vector index
|
|
96
|
+
* if it does not exist. Defaults to `false`.
|
|
97
|
+
* @param {number} options.scoreThreshold Maximum vector distance accepted for a cache hit.
|
|
98
|
+
* Lower distance values indicate closer matches.
|
|
99
|
+
*
|
|
100
|
+
* @throws If the client is missing, the table identifier is invalid,
|
|
101
|
+
* or the distance threshold is negative.
|
|
102
|
+
*/
|
|
103
|
+
constructor(embeddings, dbConfig, options = {}) {
|
|
104
|
+
super();
|
|
105
|
+
Object.defineProperty(this, "vectorStore", {
|
|
106
|
+
enumerable: true,
|
|
107
|
+
configurable: true,
|
|
108
|
+
writable: true,
|
|
109
|
+
value: void 0
|
|
110
|
+
});
|
|
111
|
+
Object.defineProperty(this, "createIndexIfMissing", {
|
|
112
|
+
enumerable: true,
|
|
113
|
+
configurable: true,
|
|
114
|
+
writable: true,
|
|
115
|
+
value: void 0
|
|
116
|
+
});
|
|
117
|
+
Object.defineProperty(this, "indexName", {
|
|
118
|
+
enumerable: true,
|
|
119
|
+
configurable: true,
|
|
120
|
+
writable: true,
|
|
121
|
+
value: void 0
|
|
122
|
+
});
|
|
123
|
+
Object.defineProperty(this, "indexParams", {
|
|
124
|
+
enumerable: true,
|
|
125
|
+
configurable: true,
|
|
126
|
+
writable: true,
|
|
127
|
+
value: void 0
|
|
128
|
+
});
|
|
129
|
+
Object.defineProperty(this, "scoreThreshold", {
|
|
130
|
+
enumerable: true,
|
|
131
|
+
configurable: true,
|
|
132
|
+
writable: true,
|
|
133
|
+
value: void 0
|
|
134
|
+
});
|
|
135
|
+
Object.defineProperty(this, "LLM_HASH", {
|
|
136
|
+
enumerable: true,
|
|
137
|
+
configurable: true,
|
|
138
|
+
writable: true,
|
|
139
|
+
value: "llm_string_hash"
|
|
140
|
+
});
|
|
141
|
+
Object.defineProperty(this, "PROMPT_HASH", {
|
|
142
|
+
enumerable: true,
|
|
143
|
+
configurable: true,
|
|
144
|
+
writable: true,
|
|
145
|
+
value: "prompt_hash"
|
|
146
|
+
});
|
|
147
|
+
Object.defineProperty(this, "RETURN_VAL", {
|
|
148
|
+
enumerable: true,
|
|
149
|
+
configurable: true,
|
|
150
|
+
writable: true,
|
|
151
|
+
value: "return_val"
|
|
152
|
+
});
|
|
153
|
+
if (options.scoreThreshold !== undefined && options.scoreThreshold < 0) {
|
|
154
|
+
(0, errors_js_1.throwError)(errors_js_1.ErrorCode.VALIDATION_INVALID_INPUT, "scoreThreshold must be non-negative");
|
|
155
|
+
}
|
|
156
|
+
if (dbConfig.client == null) {
|
|
157
|
+
(0, errors_js_1.throwError)(errors_js_1.ErrorCode.VALIDATION_MISSING_REQUIRED_PARAMETER, "client");
|
|
158
|
+
}
|
|
159
|
+
this.vectorStore = new vectorstores_js_1.OracleVS(embeddings, {
|
|
160
|
+
...dbConfig,
|
|
161
|
+
tableName: dbConfig.tableName ?? DEFAULT_TABLE_NAME,
|
|
162
|
+
});
|
|
163
|
+
this.createIndexIfMissing = options.createIndexIfMissing ?? false;
|
|
164
|
+
this.indexName = options.indexName;
|
|
165
|
+
this.indexParams = options.indexParams;
|
|
166
|
+
this.scoreThreshold = options.scoreThreshold;
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Initializes the underlying vector store and creates the optional vector index.
|
|
170
|
+
* @returns Promise that resolves when database setup completes.
|
|
171
|
+
*/
|
|
172
|
+
async initialize() {
|
|
173
|
+
try {
|
|
174
|
+
await this.vectorStore.initialize();
|
|
175
|
+
if (this.createIndexIfMissing) {
|
|
176
|
+
const params = {
|
|
177
|
+
...(this.indexParams ?? {}),
|
|
178
|
+
};
|
|
179
|
+
if (this.indexName !== undefined) {
|
|
180
|
+
params.idxName = this.indexName;
|
|
181
|
+
}
|
|
182
|
+
const connection = await this.vectorStore.getConnection();
|
|
183
|
+
try {
|
|
184
|
+
await (0, vectorstores_js_1.createIndex)(connection, this.vectorStore, params);
|
|
185
|
+
}
|
|
186
|
+
finally {
|
|
187
|
+
await this.vectorStore.retConnection(connection);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
catch (error) {
|
|
192
|
+
(0, errors_js_1.handleError)(error);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
cacheEntryId(prompt, llmKey) {
|
|
196
|
+
const encoded = this.keyEncoder(JSON.stringify([prompt, llmKey])).slice(0, 36);
|
|
197
|
+
const byteLength = Buffer.byteLength(encoded, "utf8");
|
|
198
|
+
// OracleVS defines external_id as VARCHAR2(36), so the derived ID must
|
|
199
|
+
// fit within 36 UTF-8 bytes.
|
|
200
|
+
if (byteLength === 0 || byteLength > 36) {
|
|
201
|
+
(0, errors_js_1.throwError)(errors_js_1.ErrorCode.VALIDATION_INVALID_INPUT, "Semantic cache entry IDs must be between 1 and 36 UTF-8 bytes.");
|
|
202
|
+
}
|
|
203
|
+
return encoded;
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Retrieves the nearest cached response for the given model configuration key.
|
|
207
|
+
* @param {string} prompt Prompt to embed and search for.
|
|
208
|
+
* @param {string} llmKey Key identifying the model and its configuration.
|
|
209
|
+
* @returns Cached generations, or `null` when no match passes the threshold or the payload is malformed.
|
|
210
|
+
* @throws If search fails or deserialization encounters an unexpected error.
|
|
211
|
+
*/
|
|
212
|
+
async lookup(prompt, llmKey) {
|
|
213
|
+
try {
|
|
214
|
+
const filter = {
|
|
215
|
+
[this.LLM_HASH]: {
|
|
216
|
+
$eq: this.keyEncoder(llmKey),
|
|
217
|
+
},
|
|
218
|
+
};
|
|
219
|
+
const searchResponse = await this.vectorStore.similaritySearchWithScore(prompt, 1, filter);
|
|
220
|
+
if (searchResponse.length === 0) {
|
|
221
|
+
return null;
|
|
222
|
+
}
|
|
223
|
+
const [document, score] = searchResponse[0];
|
|
224
|
+
if (this.scoreThreshold != undefined &&
|
|
225
|
+
score > this.scoreThreshold + DISTANCE_EPSILON) {
|
|
226
|
+
return null;
|
|
227
|
+
}
|
|
228
|
+
return deserializeGenerations(document.metadata[this.RETURN_VAL]);
|
|
229
|
+
}
|
|
230
|
+
catch (error) {
|
|
231
|
+
(0, errors_js_1.handleError)(error);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* Inserts or updates the entry for an exact prompt and model configuration key.
|
|
236
|
+
* Skips the entire update if any generation contains valid or invalid tool calls,
|
|
237
|
+
* avoiding reuse of procedural responses within an agent loop.
|
|
238
|
+
* @param {string} prompt Prompt to embed and store.
|
|
239
|
+
* @param {string} llmKey Key identifying the model and its configuration.
|
|
240
|
+
* @param {Generation[]} value Model generations to cache.
|
|
241
|
+
* @returns Promise that resolves when the write completes or the update is skipped.
|
|
242
|
+
*/
|
|
243
|
+
async update(prompt, llmKey, value) {
|
|
244
|
+
try {
|
|
245
|
+
if (hasToolCalls(value)) {
|
|
246
|
+
return;
|
|
247
|
+
}
|
|
248
|
+
const metadata = {
|
|
249
|
+
[this.PROMPT_HASH]: this.keyEncoder(prompt),
|
|
250
|
+
[this.LLM_HASH]: this.keyEncoder(llmKey),
|
|
251
|
+
[this.RETURN_VAL]: value.map(caches_1.serializeGeneration),
|
|
252
|
+
};
|
|
253
|
+
await this.vectorStore.addDocuments([
|
|
254
|
+
new documents_1.Document({
|
|
255
|
+
pageContent: prompt,
|
|
256
|
+
metadata,
|
|
257
|
+
}),
|
|
258
|
+
], {
|
|
259
|
+
ids: [this.cacheEntryId(prompt, llmKey)],
|
|
260
|
+
mutateOnDuplicate: true,
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
catch (error) {
|
|
264
|
+
(0, errors_js_1.handleError)(error);
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
/**
|
|
268
|
+
* Deletes entries matching all supplied exact filters, without similarity search.
|
|
269
|
+
* With no filters, deletes every entry in the table.
|
|
270
|
+
* @param {OracleCacheClearOptions} options Optional prompt and model configuration filters.
|
|
271
|
+
* @param {string} options.prompt Optional prompt to match exactly.
|
|
272
|
+
* @param {string} options.llmKey Optional model configuration key to match exactly.
|
|
273
|
+
* @returns Promise that resolves when deletion has been committed.
|
|
274
|
+
* @throws If an unsupported filter is supplied or deletion fails.
|
|
275
|
+
*/
|
|
276
|
+
async clear(options = {}) {
|
|
277
|
+
try {
|
|
278
|
+
validateClearOptions(options);
|
|
279
|
+
const { prompt, llmKey } = options;
|
|
280
|
+
let query = `DELETE FROM ${this.vectorStore.tableName}`;
|
|
281
|
+
const binds = {};
|
|
282
|
+
const conditions = [];
|
|
283
|
+
if (prompt !== undefined) {
|
|
284
|
+
conditions.push(`JSON_VALUE(metadata, '$.${this.PROMPT_HASH}') = :promptHash`);
|
|
285
|
+
binds.promptHash = this.keyEncoder(prompt);
|
|
286
|
+
}
|
|
287
|
+
if (llmKey !== undefined) {
|
|
288
|
+
conditions.push(`JSON_VALUE(metadata, '$.${this.LLM_HASH}') = :llmHash`);
|
|
289
|
+
binds.llmHash = this.keyEncoder(llmKey);
|
|
290
|
+
}
|
|
291
|
+
if (conditions.length > 0) {
|
|
292
|
+
query += ` WHERE ${conditions.join(" AND ")}`;
|
|
293
|
+
}
|
|
294
|
+
await (0, utils_js_1.withConnection)(this.vectorStore.client, async (connection) => {
|
|
295
|
+
await connection.execute(query, binds);
|
|
296
|
+
await connection.commit();
|
|
297
|
+
});
|
|
298
|
+
}
|
|
299
|
+
catch (error) {
|
|
300
|
+
(0, errors_js_1.handleError)(error);
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
/**
|
|
304
|
+
* Drops and purges the semantic cache table if it exists, removing all entries.
|
|
305
|
+
* @param {OracleDBClient | OracleDBClientProvider} client Connection, pool, or async provider to use.
|
|
306
|
+
* @param {string} tableName Table to drop. Defaults to `langchain_semantic_cache`.
|
|
307
|
+
* @returns Promise that resolves when the table has been dropped or does not exist.
|
|
308
|
+
*/
|
|
309
|
+
static async dropTable(client, tableName = DEFAULT_TABLE_NAME) {
|
|
310
|
+
try {
|
|
311
|
+
await (0, utils_js_1.withConnection)(client, async (connection) => {
|
|
312
|
+
await (0, vectorstores_js_1.dropTablePurge)(connection, tableName);
|
|
313
|
+
});
|
|
314
|
+
}
|
|
315
|
+
catch (error) {
|
|
316
|
+
(0, errors_js_1.handleError)(error);
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
exports.OracleSemanticCache = OracleSemanticCache;
|
|
321
|
+
const DEFAULT_EXACT_TABLE_NAME = "langchain_js_exact_cache";
|
|
322
|
+
/**
|
|
323
|
+
* Caches model generations by exact prompt and model configuration key in Oracle Database.
|
|
324
|
+
* Lookup uses a hashed primary key and does not require an embedding model.
|
|
325
|
+
*
|
|
326
|
+
* @example
|
|
327
|
+
* ```typescript
|
|
328
|
+
* // `pool` is an Oracle connection pool.
|
|
329
|
+
* const cache = new OracleCache(pool);
|
|
330
|
+
* await cache.initialize();
|
|
331
|
+
* await cache.update("Hello", "model-config", [{ text: "Hi!" }]);
|
|
332
|
+
* const generations = await cache.lookup("Hello", "model-config");
|
|
333
|
+
* ```
|
|
334
|
+
*/
|
|
335
|
+
class OracleCache extends caches_1.BaseCache {
|
|
336
|
+
/**
|
|
337
|
+
* Creates an exact cache instance without performing database setup.
|
|
338
|
+
* @param {OracleDBClient | OracleDBClientProvider} client Connection, pool, or async provider to use.
|
|
339
|
+
* @param {string} tableName Cache table name. Defaults to `langchain_exact_cache`.
|
|
340
|
+
* @throws If the client is missing or the table identifier is invalid.
|
|
341
|
+
*/
|
|
342
|
+
constructor(client, tableName = DEFAULT_EXACT_TABLE_NAME) {
|
|
343
|
+
super();
|
|
344
|
+
Object.defineProperty(this, "client", {
|
|
345
|
+
enumerable: true,
|
|
346
|
+
configurable: true,
|
|
347
|
+
writable: true,
|
|
348
|
+
value: void 0
|
|
349
|
+
});
|
|
350
|
+
Object.defineProperty(this, "tableName", {
|
|
351
|
+
enumerable: true,
|
|
352
|
+
configurable: true,
|
|
353
|
+
writable: true,
|
|
354
|
+
value: void 0
|
|
355
|
+
});
|
|
356
|
+
Object.defineProperty(this, "quotedTableName", {
|
|
357
|
+
enumerable: true,
|
|
358
|
+
configurable: true,
|
|
359
|
+
writable: true,
|
|
360
|
+
value: void 0
|
|
361
|
+
});
|
|
362
|
+
if (client == null) {
|
|
363
|
+
(0, errors_js_1.throwError)(errors_js_1.ErrorCode.VALIDATION_MISSING_REQUIRED_PARAMETER, "client");
|
|
364
|
+
}
|
|
365
|
+
this.client = client;
|
|
366
|
+
this.tableName = tableName;
|
|
367
|
+
this.quotedTableName = (0, utils_js_1.quoteIdentifier)(tableName);
|
|
368
|
+
}
|
|
369
|
+
/**
|
|
370
|
+
* Creates the cache table if it does not already exist.
|
|
371
|
+
* @returns Promise that resolves when database setup completes.
|
|
372
|
+
*/
|
|
373
|
+
async initialize() {
|
|
374
|
+
try {
|
|
375
|
+
await this.ensureTable();
|
|
376
|
+
}
|
|
377
|
+
catch (error) {
|
|
378
|
+
(0, errors_js_1.handleError)(error);
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
/** Stores serialized generations in a CLOB, with separate hashes for filtered deletion. */
|
|
382
|
+
async ensureTable() {
|
|
383
|
+
const ddl = `
|
|
384
|
+
CREATE TABLE IF NOT EXISTS ${this.quotedTableName} (
|
|
385
|
+
id VARCHAR2(64) PRIMARY KEY,
|
|
386
|
+
prompt_hash VARCHAR2(64) NOT NULL,
|
|
387
|
+
llm_string_hash VARCHAR2(64) NOT NULL,
|
|
388
|
+
generations CLOB NOT NULL,
|
|
389
|
+
created_at TIMESTAMP DEFAULT SYSTIMESTAMP
|
|
390
|
+
)
|
|
391
|
+
`;
|
|
392
|
+
await (0, utils_js_1.withConnection)(this.client, async (connection) => {
|
|
393
|
+
await connection.execute(ddl);
|
|
394
|
+
await connection.commit();
|
|
395
|
+
});
|
|
396
|
+
}
|
|
397
|
+
encodeKey(value) {
|
|
398
|
+
const encoded = this.keyEncoder(value);
|
|
399
|
+
const byteLength = Buffer.byteLength(encoded, "utf8");
|
|
400
|
+
if (byteLength === 0 || byteLength > 64) {
|
|
401
|
+
(0, errors_js_1.throwError)(errors_js_1.ErrorCode.VALIDATION_INVALID_INPUT, "The cache key encoder must return between 1 and 64 UTF-8 bytes.");
|
|
402
|
+
}
|
|
403
|
+
return encoded;
|
|
404
|
+
}
|
|
405
|
+
cacheEntryId(prompt, llmKey) {
|
|
406
|
+
return this.encodeKey(JSON.stringify([prompt, llmKey]));
|
|
407
|
+
}
|
|
408
|
+
/**
|
|
409
|
+
* Retrieves the cached response for an exact prompt and model configuration key.
|
|
410
|
+
* Restored chat message IDs are cleared before returning the generations.
|
|
411
|
+
* @param {string} prompt Exact prompt used when writing the entry.
|
|
412
|
+
* @param {string} llmKey Key identifying the model and its configuration.
|
|
413
|
+
* @returns Cached generations, or `null` when the entry is absent or its payload is malformed.
|
|
414
|
+
* @throws If the query fails or deserialization encounters an unexpected error.
|
|
415
|
+
*/
|
|
416
|
+
async lookup(prompt, llmKey) {
|
|
417
|
+
try {
|
|
418
|
+
return await (0, utils_js_1.withConnection)(this.client, async (connection) => {
|
|
419
|
+
const result = await connection.execute(`SELECT generations AS "generations"
|
|
420
|
+
FROM ${this.quotedTableName}
|
|
421
|
+
WHERE id = :id`, { id: this.cacheEntryId(prompt, llmKey) }, {
|
|
422
|
+
outFormat: oracledb_1.default.OUT_FORMAT_OBJECT,
|
|
423
|
+
fetchInfo: {
|
|
424
|
+
generations: { type: oracledb_1.default.STRING },
|
|
425
|
+
},
|
|
426
|
+
});
|
|
427
|
+
const row = result.rows?.[0];
|
|
428
|
+
if (typeof row?.generations !== "string") {
|
|
429
|
+
return null;
|
|
430
|
+
}
|
|
431
|
+
return deserializeGenerations(row.generations);
|
|
432
|
+
});
|
|
433
|
+
}
|
|
434
|
+
catch (error) {
|
|
435
|
+
(0, errors_js_1.handleError)(error);
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
/**
|
|
439
|
+
* Inserts or replaces generations for an exact prompt and model configuration key.
|
|
440
|
+
* Skips the entire update if any generation contains valid or invalid tool calls.
|
|
441
|
+
* Successful writes commit the connection's transaction.
|
|
442
|
+
* @param {string} prompt Prompt used to identify the entry.
|
|
443
|
+
* @param {string} llmKey Key identifying the model and its configuration.
|
|
444
|
+
* @param {Generation[]} value Model generations to cache.
|
|
445
|
+
* @returns Promise that resolves when the write is committed or the update is skipped.
|
|
446
|
+
*/
|
|
447
|
+
async update(prompt, llmKey, value) {
|
|
448
|
+
try {
|
|
449
|
+
if (hasToolCalls(value)) {
|
|
450
|
+
return;
|
|
451
|
+
}
|
|
452
|
+
const merge = `
|
|
453
|
+
MERGE INTO ${this.quotedTableName} t
|
|
454
|
+
USING (SELECT :id AS id FROM dual) s
|
|
455
|
+
ON (t.id = s.id)
|
|
456
|
+
WHEN MATCHED THEN UPDATE SET
|
|
457
|
+
t.generations = :generations,
|
|
458
|
+
t.created_at = SYSTIMESTAMP
|
|
459
|
+
WHEN NOT MATCHED THEN INSERT
|
|
460
|
+
(id, prompt_hash, llm_string_hash, generations)
|
|
461
|
+
VALUES (:id, :prompt_hash, :llm_string_hash, :generations)
|
|
462
|
+
`;
|
|
463
|
+
const binds = {
|
|
464
|
+
id: this.cacheEntryId(prompt, llmKey),
|
|
465
|
+
prompt_hash: this.encodeKey(prompt),
|
|
466
|
+
llm_string_hash: this.encodeKey(llmKey),
|
|
467
|
+
generations: {
|
|
468
|
+
val: JSON.stringify(value.map(caches_1.serializeGeneration)),
|
|
469
|
+
type: oracledb_1.default.DB_TYPE_CLOB,
|
|
470
|
+
},
|
|
471
|
+
};
|
|
472
|
+
await (0, utils_js_1.withConnection)(this.client, async (connection) => {
|
|
473
|
+
await connection.execute(merge, binds);
|
|
474
|
+
await connection.commit();
|
|
475
|
+
});
|
|
476
|
+
}
|
|
477
|
+
catch (error) {
|
|
478
|
+
(0, errors_js_1.handleError)(error);
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
/**
|
|
482
|
+
* Deletes entries matching all supplied exact-match filters.
|
|
483
|
+
* With no filters, deletes every entry in the table. Commits the connection's transaction.
|
|
484
|
+
* @param {OracleCacheClearOptions} options Optional prompt and model configuration filters.
|
|
485
|
+
* @param {string} options.prompt Optional prompt to match exactly.
|
|
486
|
+
* @param {string} options.llmKey Optional model configuration key to match exactly.
|
|
487
|
+
* @returns Promise that resolves when deletion has been committed.
|
|
488
|
+
* @throws If an unsupported filter is supplied or deletion fails.
|
|
489
|
+
*/
|
|
490
|
+
async clear(options = {}) {
|
|
491
|
+
try {
|
|
492
|
+
validateClearOptions(options);
|
|
493
|
+
const { prompt, llmKey } = options;
|
|
494
|
+
let query = `DELETE FROM ${this.quotedTableName}`;
|
|
495
|
+
const binds = {};
|
|
496
|
+
const conditions = [];
|
|
497
|
+
if (prompt !== undefined) {
|
|
498
|
+
conditions.push(`prompt_hash = :prompt_hash`);
|
|
499
|
+
binds.prompt_hash = this.encodeKey(prompt);
|
|
500
|
+
}
|
|
501
|
+
if (llmKey !== undefined) {
|
|
502
|
+
conditions.push(`llm_string_hash = :llm_hash`);
|
|
503
|
+
binds.llm_hash = this.encodeKey(llmKey);
|
|
504
|
+
}
|
|
505
|
+
if (conditions.length > 0) {
|
|
506
|
+
query += ` WHERE ${conditions.join(" AND ")}`;
|
|
507
|
+
}
|
|
508
|
+
await (0, utils_js_1.withConnection)(this.client, async (connection) => {
|
|
509
|
+
await connection.execute(query, binds);
|
|
510
|
+
await connection.commit();
|
|
511
|
+
});
|
|
512
|
+
}
|
|
513
|
+
catch (error) {
|
|
514
|
+
(0, errors_js_1.handleError)(error);
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
/**
|
|
518
|
+
* Drops and purges the exact cache table if it exists, removing all entries.
|
|
519
|
+
* @param {OracleDBClient | OracleDBClientProvider} client Connection, pool, or async provider to use.
|
|
520
|
+
* @param {string} tableName Table to drop. Defaults to `langchain_exact_cache`.
|
|
521
|
+
* @returns Promise that resolves when the table has been dropped or does not exist.
|
|
522
|
+
*/
|
|
523
|
+
static async dropTable(client, tableName = DEFAULT_EXACT_TABLE_NAME) {
|
|
524
|
+
try {
|
|
525
|
+
await (0, utils_js_1.withConnection)(client, async (connection) => {
|
|
526
|
+
await (0, vectorstores_js_1.dropTablePurge)(connection, tableName);
|
|
527
|
+
});
|
|
528
|
+
}
|
|
529
|
+
catch (error) {
|
|
530
|
+
(0, errors_js_1.handleError)(error);
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
exports.OracleCache = OracleCache;
|
|
535
|
+
//# sourceMappingURL=cache.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache.cjs","sourceRoot":"","sources":["../src/cache.ts"],"names":[],"mappings":"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"}
|