@mindstudio-ai/agent 0.1.85 → 0.1.87

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/dist/index.js CHANGED
@@ -2112,6 +2112,133 @@ function createFiles(call) {
2112
2112
  };
2113
2113
  }
2114
2114
 
2115
+ // src/datasources/source.ts
2116
+ import { createHash as createHash2 } from "crypto";
2117
+ var DataSource = class {
2118
+ constructor(_slug, _call) {
2119
+ this._slug = _slug;
2120
+ this._call = _call;
2121
+ }
2122
+ get name() {
2123
+ return this._slug;
2124
+ }
2125
+ /**
2126
+ * Search the corpus.
2127
+ *
2128
+ * Returns chunks ranked by relevance, each with a citation. Searching a
2129
+ * source that doesn't exist yet returns no results rather than throwing —
2130
+ * code may name a corpus the build hasn't populated.
2131
+ *
2132
+ * **Deterministic** for a fixed corpus and configuration: the same query
2133
+ * returns the same hits in the same order, so it's safe to build an eval set
2134
+ * or a regression check on top of it. There is no seed to set. Two things do
2135
+ * legitimately move the results: adding or removing documents, and changing
2136
+ * the corpus configuration — both of which you control.
2137
+ */
2138
+ async search(query, options) {
2139
+ const { results, latencyMs } = await this._call("search", {
2140
+ slug: this._slug,
2141
+ query,
2142
+ ...options?.topK !== void 0 ? { topK: options.topK } : {},
2143
+ ...options?.scoreThreshold !== void 0 ? { scoreThreshold: options.scoreThreshold } : {},
2144
+ ...options?.rerank !== void 0 ? { rerank: options.rerank } : {},
2145
+ ...options?.hybrid !== void 0 ? { hybrid: options.hybrid } : {},
2146
+ ...options?.explain !== void 0 ? { explain: options.explain } : {},
2147
+ ...options?.expand !== void 0 ? { expand: options.expand } : {}
2148
+ });
2149
+ return { results: results ?? [], latencyMs: latencyMs ?? 0 };
2150
+ }
2151
+ /**
2152
+ * What is in the corpus, and how it was built.
2153
+ *
2154
+ * Document and chunk counts, storage, and the embedding model and chunking
2155
+ * settings actually in effect — which is not the same as the platform
2156
+ * default, since a corpus keeps the configuration it was built with until
2157
+ * someone migrates it.
2158
+ */
2159
+ async stats() {
2160
+ return this._call("stats", { slug: this._slug });
2161
+ }
2162
+ /**
2163
+ * Every chunk of one document, exactly as it was indexed.
2164
+ *
2165
+ * The direct answer to "why isn't this document coming back?" — search only
2166
+ * shows you the chunks that surface, which is no help when none do. Reading
2167
+ * how a document was actually split usually is.
2168
+ *
2169
+ * Pass `{ vectors: true }` to include each chunk's embedding. Large: roughly
2170
+ * 8KB per chunk, so a 500-chunk document is several megabytes.
2171
+ */
2172
+ async chunks(documentId, options) {
2173
+ const { chunks } = await this._call("chunks", {
2174
+ slug: this._slug,
2175
+ documentId,
2176
+ ...options?.vectors ? { vectors: true } : {}
2177
+ });
2178
+ return chunks ?? [];
2179
+ }
2180
+ /**
2181
+ * Add a document to the corpus.
2182
+ *
2183
+ * Returns as soon as the document is queued — extraction and embedding run
2184
+ * in the background and take a while, so poll {@link documents} for status
2185
+ * rather than assuming the content is searchable on return.
2186
+ *
2187
+ * **Adding the same bytes twice is free.** Documents are content-addressed,
2188
+ * so a re-add is a no-op when this source has already processed those exact
2189
+ * bytes under its current configuration. Reconfiguring the source is what
2190
+ * makes a re-add do work again — and that is an explicit, owner-triggered
2191
+ * migration, never something a deploy causes.
2192
+ */
2193
+ async add(content, options) {
2194
+ const bytes = typeof content === "string" ? Buffer.from(content) : Buffer.from(content);
2195
+ return this._call("add", {
2196
+ slug: this._slug,
2197
+ filename: options.filename,
2198
+ ...options.contentType ? { contentType: options.contentType } : {},
2199
+ body: bytes.toString("base64")
2200
+ });
2201
+ }
2202
+ /** Every document in the corpus, with ingest status. */
2203
+ async documents() {
2204
+ const { documents } = await this._call("documents", { slug: this._slug });
2205
+ return documents ?? [];
2206
+ }
2207
+ /** Remove a document and its vectors. */
2208
+ async remove(documentId) {
2209
+ await this._call("remove", { slug: this._slug, documentId });
2210
+ }
2211
+ /**
2212
+ * Create the data source if it doesn't exist yet.
2213
+ *
2214
+ * Rarely needed — `add` and `search` both handle a missing source. Useful
2215
+ * when you want it to exist (and appear in the dashboard) before any
2216
+ * document has been added.
2217
+ */
2218
+ async ensure(name) {
2219
+ await this._call("ensure", {
2220
+ slug: this._slug,
2221
+ ...name ? { name } : {}
2222
+ });
2223
+ }
2224
+ /**
2225
+ * @internal Content hash of some bytes, matching what the server computes.
2226
+ * Exposed for callers that want to check whether they already added a file.
2227
+ */
2228
+ static contentHash(content) {
2229
+ return createHash2("sha256").update(Buffer.from(content)).digest("hex");
2230
+ }
2231
+ };
2232
+
2233
+ // src/datasources/index.ts
2234
+ function createDataSources(call) {
2235
+ return {
2236
+ defineDataSource(name) {
2237
+ return new DataSource(name, call);
2238
+ }
2239
+ };
2240
+ }
2241
+
2115
2242
  // src/generated/metadata.ts
2116
2243
  var stepMetadata = {
2117
2244
  "activeCampaignAddNote": {
@@ -4126,6 +4253,7 @@ var MindStudioAgent = class {
4126
4253
  _db;
4127
4254
  /** @internal Cached Files namespace instance (lazy; no context hydration needed). */
4128
4255
  _files;
4256
+ _dataSources;
4129
4257
  /** @internal Auth type — 'internal' for CALLBACK_TOKEN (managed mode), 'apiKey' otherwise. */
4130
4258
  _authType;
4131
4259
  /** @internal Usage source sent on step executions (from MINDSTUDIO_REQUEST_SOURCE).
@@ -5017,12 +5145,47 @@ var MindStudioAgent = class {
5017
5145
  get files() {
5018
5146
  return this._files ??= createFiles(this._filesRequest.bind(this));
5019
5147
  }
5148
+ /**
5149
+ * Searchable document corpora.
5150
+ *
5151
+ * @example
5152
+ * ```ts
5153
+ * const Policies = agent.dataSources.defineDataSource('policies');
5154
+ * const { results } = await Policies.search('what are the payment terms?');
5155
+ * ```
5156
+ */
5157
+ get dataSources() {
5158
+ return this._dataSources ??= createDataSources(
5159
+ this._dataSourcesRequest.bind(this)
5160
+ );
5161
+ }
5020
5162
  /**
5021
5163
  * @internal Transport for the `files` namespace — POST /_internal/v2/files/<op>
5022
5164
  * with the raw hook token (mirrors `_executeDbBatch`).
5023
5165
  */
5024
5166
  async _filesRequest(op, body) {
5025
- const url = `${this._currentHttpConfig.baseUrl}/_internal/v2/files/${op}`;
5167
+ return this._brokeredRequest("files", op, body, {
5168
+ fallbackMessage: "File operation failed",
5169
+ fallbackCode: "file_error"
5170
+ });
5171
+ }
5172
+ /**
5173
+ * @internal Transport for the `dataSources` namespace —
5174
+ * POST /_internal/v2/datasources/<op> with the raw hook token.
5175
+ */
5176
+ async _dataSourcesRequest(op, body) {
5177
+ return this._brokeredRequest("datasources", op, body, {
5178
+ fallbackMessage: "Data source operation failed",
5179
+ fallbackCode: "data_source_error"
5180
+ });
5181
+ }
5182
+ /**
5183
+ * @internal Shared shape for the brokered `/_internal/v2/<ns>/<op>` data
5184
+ * planes. Factored out rather than copied per namespace so error handling
5185
+ * can't drift between them.
5186
+ */
5187
+ async _brokeredRequest(namespace, op, body, errors) {
5188
+ const url = `${this._currentHttpConfig.baseUrl}/_internal/v2/${namespace}/${op}`;
5026
5189
  const res = await fetch(url, {
5027
5190
  method: "POST",
5028
5191
  headers: {
@@ -5044,8 +5207,8 @@ var MindStudioAgent = class {
5044
5207
  }
5045
5208
  if (!res.ok) {
5046
5209
  const rawMsg = json?.errorMessage ?? (typeof json?.error === "string" ? json.error : json?.error?.message);
5047
- const message = typeof rawMsg === "string" ? rawMsg : `File operation failed: ${res.status} ${res.statusText}`;
5048
- const code = json?.errorString ?? json?.code ?? "file_error";
5210
+ const message = typeof rawMsg === "string" ? rawMsg : `${errors.fallbackMessage}: ${res.status} ${res.statusText}`;
5211
+ const code = json?.errorString ?? json?.code ?? errors.fallbackCode;
5049
5212
  throw new MindStudioError(message, code, res.status);
5050
5213
  }
5051
5214
  return json;
@@ -5446,6 +5609,12 @@ var MindStudioAgent = class {
5446
5609
  *
5447
5610
  * Gets a presigned upload request from the API, POSTs the file as
5448
5611
  * multipart/form-data, and returns the permanent public URL.
5612
+ *
5613
+ * @deprecated For app file storage use the `files` store
5614
+ * (`files.defineStore(...).put(...)`) — private by default, app-scoped, and
5615
+ * served on the app's own domain. `uploadFile` uploads to the shared account
5616
+ * media CDN; it remains only for account-level assets (e.g. an agent avatar
5617
+ * passed to `changeProfilePicture`).
5449
5618
  */
5450
5619
  async uploadFile(content, options) {
5451
5620
  const filename = options.filename ?? `upload.${options.extension}`;
@@ -5726,6 +5895,16 @@ var files = new Proxy(
5726
5895
  }
5727
5896
  }
5728
5897
  );
5898
+ var dataSources = new Proxy(
5899
+ {},
5900
+ {
5901
+ get(_, prop) {
5902
+ const target = mindstudio.dataSources;
5903
+ const value = Reflect.get(target, prop, target);
5904
+ return typeof value === "function" ? value.bind(target) : value;
5905
+ }
5906
+ }
5907
+ );
5729
5908
  var stream = (data) => mindstudio.stream(data);
5730
5909
  var resolveUser = (userId) => mindstudio.resolveUser(userId);
5731
5910
  var reportIssue = (input) => mindstudio.reportIssue(input);
@@ -5739,6 +5918,7 @@ export {
5739
5918
  Roles,
5740
5919
  auth,
5741
5920
  blockTypeAliases,
5921
+ dataSources,
5742
5922
  db,
5743
5923
  index_default as default,
5744
5924
  files,