@raisindb/client 0.5.3 → 0.5.5

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.
Files changed (39) hide show
  1. package/dist/{chunk-3KMOXRTK.mjs → chunk-765DLJMZ.mjs} +24 -3
  2. package/dist/chunk-765DLJMZ.mjs.map +1 -0
  3. package/dist/{chunk-Q4IBPW2W.mjs → chunk-AULHRX5C.mjs} +2 -2
  4. package/dist/{chunk-QJKYNLT4.mjs → chunk-IFV4ECHC.mjs} +3 -3
  5. package/dist/{chunk-B6EFDYFS.mjs → chunk-VMUT6PIO.mjs} +2 -2
  6. package/dist/{chunk-P44XWTPA.mjs → chunk-ZUUSBLVP.mjs} +3 -3
  7. package/dist/{conversation-list-store-DVYgTaaA.d.mts → conversation-list-store-BaeGM2lx.d.mts} +439 -173
  8. package/dist/{conversation-list-store-DVYgTaaA.d.ts → conversation-list-store-BaeGM2lx.d.ts} +439 -173
  9. package/dist/{index-BOO1gV6F.d.mts → index-C4pX6FVI.d.mts} +1 -1
  10. package/dist/{index-AKUurvWQ.d.ts → index-DCtNAWZ0.d.ts} +1 -1
  11. package/dist/index.d.mts +4 -4
  12. package/dist/index.d.ts +4 -4
  13. package/dist/index.js +256 -16
  14. package/dist/index.js.map +1 -1
  15. package/dist/index.mjs +238 -19
  16. package/dist/index.mjs.map +1 -1
  17. package/dist/react.d.mts +2 -2
  18. package/dist/react.d.ts +2 -2
  19. package/dist/react.js +23 -2
  20. package/dist/react.js.map +1 -1
  21. package/dist/react.mjs +3 -3
  22. package/dist/{svelte-sql-B1nLVQuc.d.mts → svelte-sql-BhMxrqn_.d.mts} +1 -1
  23. package/dist/{svelte-sql-ABIom_Bb.d.ts → svelte-sql-DN3NpM4c.d.ts} +1 -1
  24. package/dist/svelte.d.mts +2 -2
  25. package/dist/svelte.d.ts +2 -2
  26. package/dist/svelte.js +23 -2
  27. package/dist/svelte.js.map +1 -1
  28. package/dist/svelte.mjs +3 -3
  29. package/dist/vue.d.mts +2 -2
  30. package/dist/vue.d.ts +2 -2
  31. package/dist/vue.js +23 -2
  32. package/dist/vue.js.map +1 -1
  33. package/dist/vue.mjs +2 -2
  34. package/package.json +1 -1
  35. package/dist/chunk-3KMOXRTK.mjs.map +0 -1
  36. /package/dist/{chunk-Q4IBPW2W.mjs.map → chunk-AULHRX5C.mjs.map} +0 -0
  37. /package/dist/{chunk-QJKYNLT4.mjs.map → chunk-IFV4ECHC.mjs.map} +0 -0
  38. /package/dist/{chunk-B6EFDYFS.mjs.map → chunk-VMUT6PIO.mjs.map} +0 -0
  39. /package/dist/{chunk-P44XWTPA.mjs.map → chunk-ZUUSBLVP.mjs.map} +0 -0
package/dist/index.mjs CHANGED
@@ -3,13 +3,13 @@ import {
3
3
  useConversation,
4
4
  useConversationList,
5
5
  useFlow
6
- } from "./chunk-QJKYNLT4.mjs";
6
+ } from "./chunk-IFV4ECHC.mjs";
7
7
  import {
8
8
  RAISIN_CONTEXT_KEY,
9
9
  createConversationAdapter,
10
10
  createConversationListAdapter,
11
11
  createFlowAdapter
12
- } from "./chunk-P44XWTPA.mjs";
12
+ } from "./chunk-ZUUSBLVP.mjs";
13
13
  import {
14
14
  FlowClient,
15
15
  RaisinAbortError,
@@ -20,10 +20,10 @@ import {
20
20
  RaisinTimeoutError,
21
21
  SSEClient,
22
22
  classifyHttpError
23
- } from "./chunk-Q4IBPW2W.mjs";
23
+ } from "./chunk-AULHRX5C.mjs";
24
24
  import {
25
25
  createRaisinVue
26
- } from "./chunk-B6EFDYFS.mjs";
26
+ } from "./chunk-VMUT6PIO.mjs";
27
27
  import {
28
28
  createAuthAdapter,
29
29
  createConnectionAdapter,
@@ -48,7 +48,7 @@ import {
48
48
  normalizeHomePath,
49
49
  projectPlansFromMessages,
50
50
  setLogLevel
51
- } from "./chunk-3KMOXRTK.mjs";
51
+ } from "./chunk-765DLJMZ.mjs";
52
52
 
53
53
  // src/client.ts
54
54
  import { EventEmitter as EventEmitter2 } from "events";
@@ -3064,6 +3064,104 @@ var HttpFunctionsApi = class {
3064
3064
  }
3065
3065
  };
3066
3066
 
3067
+ // src/search-api.ts
3068
+ var ASK_FUNCTION = "ask";
3069
+ var DEFAULT_LIMIT = 8;
3070
+ var MAX_LIMIT = 50;
3071
+ var SearchApi = class {
3072
+ constructor(runSql, runFunction) {
3073
+ this.runSql = runSql;
3074
+ this.runFunction = runFunction;
3075
+ }
3076
+ /**
3077
+ * Find the passages that match a query, by meaning and by keyword at once.
3078
+ *
3079
+ * No model is involved, so this is the call for a search box, a "related
3080
+ * content" list, or anything assembling its own context.
3081
+ */
3082
+ async search(query, options) {
3083
+ if (!query || !query.trim()) {
3084
+ throw new Error("search(query) requires a non-empty query");
3085
+ }
3086
+ if (!options || !options.workspaces || !options.workspaces.trim()) {
3087
+ throw new Error(
3088
+ "search() requires `workspaces` \u2014 name a workspace, a list, a glob, or 'ALL READABLE'. An unscoped search on a public site is how draft content reaches a visitor."
3089
+ );
3090
+ }
3091
+ const limit = Math.min(
3092
+ Math.max(Math.floor(options.limit ?? DEFAULT_LIMIT), 1),
3093
+ MAX_LIMIT
3094
+ );
3095
+ const distance = Number.isFinite(options.maxDistance) ? `, max_distance => ${Number(options.maxDistance)}` : "";
3096
+ const sql = `
3097
+ SELECT node_id, path, name, score, chunk_index, chunk_text, chunk_text_source
3098
+ FROM HYBRID_SEARCH($1, ${limit},
3099
+ workspaces => $2,
3100
+ granularity => 'chunk'${distance})
3101
+ `;
3102
+ const result = await this.runSql(sql, [query.trim(), options.workspaces.trim()]);
3103
+ const rows = result?.rows ?? [];
3104
+ return rows.map((row) => ({
3105
+ path: String(row.path ?? ""),
3106
+ nodeId: String(row.node_id ?? ""),
3107
+ name: String(row.name ?? ""),
3108
+ // `0` is a real chunk index — a document that was never split — so it
3109
+ // must not be collapsed into "missing" by a falsy check.
3110
+ chunkIndex: row.chunk_index == null ? 0 : Number(row.chunk_index),
3111
+ text: String(row.chunk_text ?? ""),
3112
+ textIsExact: row.chunk_text_source === "exact",
3113
+ score: Number(row.score ?? 0)
3114
+ })).filter((passage) => passage.text.length > 0);
3115
+ }
3116
+ /**
3117
+ * Answer a question from the stored content, with citations.
3118
+ *
3119
+ * Retrieves, judges whether what came back answers the question, rewrites the
3120
+ * query once if it does not, and answers from those passages only.
3121
+ */
3122
+ async ask(question, options) {
3123
+ if (!question || !question.trim()) {
3124
+ throw new Error("ask(question) requires a non-empty question");
3125
+ }
3126
+ if (!options || !options.workspaces || !options.workspaces.trim()) {
3127
+ throw new Error(
3128
+ "ask() requires `workspaces` \u2014 name a workspace, a list, a glob, or 'ALL READABLE'. An answer is quoted back to whoever asked, so the corpus it may be drawn from is stated, never assumed."
3129
+ );
3130
+ }
3131
+ const raw = await this.runFunction(ASK_FUNCTION, {
3132
+ question: question.trim(),
3133
+ workspaces: options.workspaces.trim(),
3134
+ limit: options.limit,
3135
+ model: options.model,
3136
+ use_graph: options.useGraph
3137
+ });
3138
+ if (raw && typeof raw === "object" && "error" in raw && raw.error) {
3139
+ throw new Error(`ask failed: ${String(raw.error)}`);
3140
+ }
3141
+ const citations = Array.isArray(raw?.citations) ? raw.citations : [];
3142
+ return {
3143
+ answer: String(raw?.answer ?? ""),
3144
+ // Absent counts as NOT grounded. This flag is the one a caller branches
3145
+ // on before showing an answer, so an unexpected response shape must fail
3146
+ // towards "we found nothing", never towards "trust this".
3147
+ grounded: raw?.grounded === true,
3148
+ citations: citations.map((c) => ({
3149
+ marker: Number(c.marker ?? 0),
3150
+ path: String(c.path ?? ""),
3151
+ nodeId: String(c.node_id ?? ""),
3152
+ name: String(c.title ?? ""),
3153
+ chunkIndex: c.chunk_index == null ? 0 : Number(c.chunk_index),
3154
+ textIsExact: c.text_is_exact === true
3155
+ })),
3156
+ attempts: Array.isArray(raw?.attempts) ? raw.attempts.map((a) => ({
3157
+ query: String(a.query ?? ""),
3158
+ passages: Number(a.passages ?? 0)
3159
+ })) : [],
3160
+ model: String(raw?.model ?? "")
3161
+ };
3162
+ }
3163
+ };
3164
+
3067
3165
  // src/conversations.ts
3068
3166
  var DEFAULT_SEND_MESSAGE_INACTIVITY_TIMEOUT_MS = 12e4;
3069
3167
  var ConversationManager = class {
@@ -3571,7 +3669,17 @@ var ConversationManager = class {
3571
3669
  tasks.push({
3572
3670
  id: row.id,
3573
3671
  title: row.properties?.title ?? row.name,
3574
- status: row.properties?.status ?? "pending"
3672
+ status: row.properties?.status ?? "pending",
3673
+ delegation: row.properties?.delegation_id ? {
3674
+ id: row.properties.delegation_id,
3675
+ status: row.properties.delegation_status ?? "unknown",
3676
+ agentRef: row.properties.delegated_agent_ref?.["raisin:path"] ?? row.properties.delegated_agent_ref?.["raisin:ref"] ?? (typeof row.properties.delegated_agent_ref === "string" ? row.properties.delegated_agent_ref : void 0),
3677
+ flowInstanceId: row.properties.delegation_flow_instance_id ?? void 0,
3678
+ branch: row.properties.delegation_branch ?? void 0,
3679
+ baseBranch: row.properties.delegation_base_branch ?? void 0,
3680
+ result: row.properties.delegation_result,
3681
+ error: row.properties.delegation_error ?? void 0
3682
+ } : void 0
3575
3683
  });
3576
3684
  tasksByPlan.set(planPath, tasks);
3577
3685
  continue;
@@ -4185,6 +4293,73 @@ var Database = class _Database {
4185
4293
  }
4186
4294
  return this._functionsApi;
4187
4295
  }
4296
+ /**
4297
+ * The retrieval implementation behind {@link search} and {@link ask}.
4298
+ *
4299
+ * Private: callers get the two verbs, not the object, so how retrieval is
4300
+ * served stays ours to change.
4301
+ */
4302
+ searchApi() {
4303
+ if (!this._searchApi) {
4304
+ this._searchApi = new SearchApi(
4305
+ (sql, params) => this.executeSql(sql, params),
4306
+ async (name, input) => {
4307
+ const run = await this.functions().invoke(name, input, {
4308
+ waitForResult: true
4309
+ });
4310
+ return run?.result ?? run;
4311
+ }
4312
+ );
4313
+ }
4314
+ return this._searchApi;
4315
+ }
4316
+ /**
4317
+ * Find the passages matching a query, by meaning and by keyword at once.
4318
+ *
4319
+ * No model is involved — this is the call for a search box or for assembling
4320
+ * your own context. Returns one entry per PASSAGE, so several may come from
4321
+ * one document.
4322
+ *
4323
+ * @example
4324
+ * ```typescript
4325
+ * const passages = await db.search('how much notice to terminate', {
4326
+ * workspaces: 'stories',
4327
+ * });
4328
+ * passages[0].text; // the passage itself
4329
+ * passages[0].chunkIndex; // where in the document it came from
4330
+ * ```
4331
+ */
4332
+ async search(query, options) {
4333
+ return this.searchApi().search(query, options);
4334
+ }
4335
+ /**
4336
+ * Answer a question from the stored content, with citations.
4337
+ *
4338
+ * Retrieves, judges whether what came back answers the question, rewrites the
4339
+ * query once if it does not, and answers from those passages only. Check
4340
+ * `grounded` before showing the answer: when it is false nothing relevant was
4341
+ * found and the model was never asked.
4342
+ *
4343
+ * `workspaces` is required, the same as on {@link search}: an answer is
4344
+ * quoted back to whoever asked, so the corpus it may be drawn from is stated
4345
+ * rather than assumed. One name, a comma-separated list, a glob, or
4346
+ * `'ALL READABLE'`.
4347
+ *
4348
+ * A method rather than `functions().invoke('ask', ...)` on purpose — see the
4349
+ * note at the top of `search-api.ts`. `invoke` is the escape hatch for
4350
+ * functions YOU wrote.
4351
+ *
4352
+ * @example
4353
+ * ```typescript
4354
+ * const { answer, citations, grounded } = await db.ask(
4355
+ * 'How much notice do we have to give?',
4356
+ * { workspaces: 'stories, handbook' }, // one name, a list, a glob, or 'ALL READABLE'
4357
+ * );
4358
+ * ```
4359
+ */
4360
+ async ask(question, options) {
4361
+ return this.searchApi().ask(question, options);
4362
+ }
4188
4363
  /**
4189
4364
  * Get a pre-configured ConversationManager for managing conversations.
4190
4365
  *
@@ -6729,19 +6904,6 @@ var HttpDatabase = class _HttpDatabase {
6729
6904
  getBranch() {
6730
6905
  return this.branch;
6731
6906
  }
6732
- /**
6733
- * Create a new HttpDatabase instance scoped to a specific branch.
6734
- *
6735
- * @param branch - Branch name
6736
- * @returns New HttpDatabase instance with branch context
6737
- *
6738
- * @example
6739
- * ```typescript
6740
- * const db = client.database('my-repo');
6741
- * const staging = db.onBranch('staging');
6742
- * const result = await staging.executeSql('SELECT * FROM content');
6743
- * ```
6744
- */
6745
6907
  onBranch(branch) {
6746
6908
  return new _HttpDatabase(this.repository, this.client, branch);
6747
6909
  }
@@ -6789,6 +6951,63 @@ var HttpDatabase = class _HttpDatabase {
6789
6951
  (repo, name, input) => this.client.invokeFunctionSync(repo, name, input)
6790
6952
  );
6791
6953
  }
6954
+ /**
6955
+ * The retrieval implementation behind {@link search} and {@link ask}.
6956
+ *
6957
+ * The SAME `SearchApi` the WebSocket client uses, handed this transport's SQL
6958
+ * and function runners. Retrieval is one behaviour — the query shape, the
6959
+ * limit clamp, the required scope, the `grounded` fail-closed mapping — and a
6960
+ * second copy written against HTTP would drift from the first the moment
6961
+ * either is touched. Only the two runners differ.
6962
+ */
6963
+ searchApi() {
6964
+ if (!this._searchApi) {
6965
+ this._searchApi = new SearchApi(
6966
+ (sql, params) => this.executeSql(sql, params),
6967
+ async (name, input) => {
6968
+ const run = await this.functions().invoke(name, input, {
6969
+ waitForResult: true
6970
+ });
6971
+ return run?.result ?? run;
6972
+ }
6973
+ );
6974
+ }
6975
+ return this._searchApi;
6976
+ }
6977
+ /**
6978
+ * Find the passages matching a query, by meaning and by keyword at once.
6979
+ *
6980
+ * Available on this HTTP client as well as the WebSocket one, because this is
6981
+ * the client a server-side route handler reaches for — and a route handler is
6982
+ * exactly where retrieval belongs when the page is public: the browser must
6983
+ * not hold a credential that can read the repository.
6984
+ *
6985
+ * @example
6986
+ * ```typescript
6987
+ * const passages = await db.search('how much notice to terminate', {
6988
+ * workspaces: 'stories',
6989
+ * });
6990
+ * ```
6991
+ */
6992
+ async search(query, options) {
6993
+ return this.searchApi().search(query, options);
6994
+ }
6995
+ /**
6996
+ * Answer a question from the stored content, with citations.
6997
+ *
6998
+ * Check `grounded` before showing the answer: when it is false nothing
6999
+ * relevant was retrieved and the model was never asked.
7000
+ *
7001
+ * @example
7002
+ * ```typescript
7003
+ * const { answer, citations, grounded } = await db.ask(question, {
7004
+ * workspaces: 'stories, handbook',
7005
+ * });
7006
+ * ```
7007
+ */
7008
+ async ask(question, options) {
7009
+ return this.searchApi().ask(question, options);
7010
+ }
6792
7011
  /**
6793
7012
  * Get an {@link McpClient} for a content-declared MCP server on this database.
6794
7013
  *