UNPKG

weaviate-agents

Version:
256 lines (255 loc) 13.6 kB
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __await = (this && this.__await) || function (v) { return this instanceof __await ? (this.v = v, this) : new __await(v); } var __asyncValues = (this && this.__asyncValues) || function (o) { if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var m = o[Symbol.asyncIterator], i; return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i); function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; } function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); } }; var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) { if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var g = generator.apply(thisArg, _arguments || []), i, q = []; return i = Object.create((typeof AsyncIterator === "function" ? AsyncIterator : Object).prototype), verb("next"), verb("throw"), verb("return", awaitReturn), i[Symbol.asyncIterator] = function () { return this; }, i; function awaitReturn(f) { return function (v) { return Promise.resolve(v).then(f, reject); }; } function verb(n, f) { if (g[n]) { i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; if (f) i[n] = f(i[n]); } } function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } } function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); } function fulfill(value) { resume("next", value); } function reject(value) { resume("throw", value); } function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); } }; import { mapResponse, mapProgressMessageFromSSE, mapStreamedTokensFromSSE, mapAskModeResponse, } from "./response/response-mapping.js"; import { mapApiResponse } from "./response/api-response-mapping.js"; import { fetchServerSentEvents } from "./response/server-sent-events.js"; import { mapCollections, } from "./collection.js"; import { handleError } from "./response/error.js"; import { QueryAgentSearcher } from "./search.js"; import { getHeaders } from "./connection.js"; /** * An agent for executing agentic queries against Weaviate. * For more information, see the [Weaviate Query Agent Docs](https://weaviate.io/developers/agents/query) */ export class QueryAgent { /** * Creates a new QueryAgent instance. * * @param client - The Weaviate client instance. * @param options - Additional options for the QueryAgent. */ constructor(client, { collections, systemPrompt, agentsHost = "https://api.agents.weaviate.io", } = {}) { this.client = client; this.validateCollections = (collections) => { const targetCollections = collections !== null && collections !== void 0 ? collections : this.collections; if (!targetCollections) { throw Error("No collections provided to the query agent."); } return targetCollections; }; this.collections = collections; this.systemPrompt = systemPrompt; this.agentsHost = agentsHost; } /** * Run the query agent. * * @deprecated Use {@link ask} instead. * @param query - The natural language query string for the agent. * @param options - Additional options for the run. * @returns The response from the query agent. */ run(query_1) { return __awaiter(this, arguments, void 0, function* (query, { collections, context } = {}) { const targetCollections = collections !== null && collections !== void 0 ? collections : this.collections; if (!targetCollections) { throw Error("No collections provided to the query agent."); } const { host, bearerToken, headers } = yield this.client.getConnectionDetails(); const response = yield fetch(`${this.agentsHost}/agent/query`, { method: "POST", headers: { "Content-Type": "application/json", Authorization: bearerToken, "X-Weaviate-Cluster-Url": host, "X-Agent-Request-Origin": "typescript-client", }, body: JSON.stringify({ headers, query, collections: mapCollections(targetCollections), system_prompt: this.systemPrompt, previous_response: context ? mapApiResponse(context) : undefined, }), }); if (!response.ok) { yield handleError(yield response.text()); } return mapResponse(yield response.json()); }); } /** * Ask query agent a question. * * @param query - The natural language query string or conversation context for the agent. * @param options - Additional options for the run. * @returns The response from the query agent. */ ask(query_1) { return __awaiter(this, arguments, void 0, function* (query, { collections } = {}) { const targetCollections = this.validateCollections(collections); const { requestHeaders, connectionHeaders } = yield getHeaders(this.client); const response = yield fetch(`${this.agentsHost}/query/ask`, { method: "POST", headers: requestHeaders, body: JSON.stringify({ headers: connectionHeaders, query: typeof query === "string" ? query : { messages: query }, collections: mapCollections(targetCollections), system_prompt: this.systemPrompt, }), }); if (!response.ok) { yield handleError(yield response.text()); } return mapAskModeResponse(yield response.json()); }); } stream(query_1) { return __asyncGenerator(this, arguments, function* stream_1(query, { collections, context, includeProgress, includeFinalState, } = {}) { var _a, e_1, _b, _c; const targetCollections = collections !== null && collections !== void 0 ? collections : this.collections; if (!targetCollections) { throw Error("No collections provided to the query agent."); } const { host, bearerToken, headers } = yield __await(this.client.getConnectionDetails()); const sseStream = fetchServerSentEvents(`${this.agentsHost}/agent/stream_query`, { method: "POST", headers: { "Content-Type": "application/json", Authorization: bearerToken, "X-Weaviate-Cluster-Url": host, "X-Agent-Request-Origin": "typescript-client", }, body: JSON.stringify({ headers, query, collections: mapCollections(targetCollections), system_prompt: this.systemPrompt, previous_response: context ? mapApiResponse(context) : undefined, include_progress: includeProgress !== null && includeProgress !== void 0 ? includeProgress : true, include_final_state: includeFinalState !== null && includeFinalState !== void 0 ? includeFinalState : true, }), }); try { for (var _d = true, sseStream_1 = __asyncValues(sseStream), sseStream_1_1; sseStream_1_1 = yield __await(sseStream_1.next()), _a = sseStream_1_1.done, !_a; _d = true) { _c = sseStream_1_1.value; _d = false; const event = _c; if (event.event === "error") { yield __await(handleError(event.data)); } let output; if (event.event === "progress_message") { output = mapProgressMessageFromSSE(event); } else if (event.event === "streamed_tokens") { output = mapStreamedTokensFromSSE(event); } else if (event.event === "final_state") { output = mapResponse(JSON.parse(event.data)); } else { throw new Error(`Unexpected event type: ${event.event}: ${event.data}`); } yield yield __await(output); } } catch (e_1_1) { e_1 = { error: e_1_1 }; } finally { try { if (!_d && !_a && (_b = sseStream_1.return)) yield __await(_b.call(sseStream_1)); } finally { if (e_1) throw e_1.error; } } }); } askStream(query_1) { return __asyncGenerator(this, arguments, function* askStream_1(query, { collections, includeProgress, includeFinalState, } = {}) { var _a, e_2, _b, _c; const targetCollections = collections !== null && collections !== void 0 ? collections : this.collections; if (!targetCollections) { throw Error("No collections provided to the query agent."); } const { host, bearerToken, headers } = yield __await(this.client.getConnectionDetails()); const sseStream = fetchServerSentEvents(`${this.agentsHost}/query/stream_ask`, { method: "POST", headers: { "Content-Type": "application/json", Authorization: bearerToken, "X-Weaviate-Cluster-Url": host, "X-Agent-Request-Origin": "typescript-client", }, body: JSON.stringify({ headers, query: typeof query === "string" ? query : { messages: query }, collections: mapCollections(targetCollections), system_prompt: this.systemPrompt, include_progress: includeProgress !== null && includeProgress !== void 0 ? includeProgress : true, include_final_state: includeFinalState !== null && includeFinalState !== void 0 ? includeFinalState : true, }), }); try { for (var _d = true, sseStream_2 = __asyncValues(sseStream), sseStream_2_1; sseStream_2_1 = yield __await(sseStream_2.next()), _a = sseStream_2_1.done, !_a; _d = true) { _c = sseStream_2_1.value; _d = false; const event = _c; if (event.event === "error") { yield __await(handleError(event.data)); } let output; if (event.event === "progress_message") { output = mapProgressMessageFromSSE(event); } else if (event.event === "streamed_tokens") { output = mapStreamedTokensFromSSE(event); } else if (event.event === "final_state") { output = mapAskModeResponse(JSON.parse(event.data)); } else { throw new Error(`Unexpected event type: ${event.event}: ${event.data}`); } yield yield __await(output); } } catch (e_2_1) { e_2 = { error: e_2_1 }; } finally { try { if (!_d && !_a && (_b = sseStream_2.return)) yield __await(_b.call(sseStream_2)); } finally { if (e_2) throw e_2.error; } } }); } /** * Run the Query Agent search-only mode. * * Sends the initial search request and returns the first page of results. * The returned response includes a `next` method for pagination which * reuses the same underlying searches to ensure consistency across pages. */ search(query_1) { return __awaiter(this, arguments, void 0, function* (query, { limit = 20, collections } = {}) { const searcher = new QueryAgentSearcher(this.client, query, this.validateCollections(collections), this.systemPrompt, this.agentsHost); return searcher.run({ limit, offset: 0 }); }); } }