@raisindb/client 0.5.3 → 0.5.4

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-Bw1UwRL8.d.mts} +398 -173
  8. package/dist/{conversation-list-store-DVYgTaaA.d.ts → conversation-list-store-Bw1UwRL8.d.ts} +398 -173
  9. package/dist/{index-AKUurvWQ.d.ts → index-B1u8uo8e.d.ts} +1 -1
  10. package/dist/{index-BOO1gV6F.d.mts → index-C-K8H-PW.d.mts} +1 -1
  11. package/dist/index.d.mts +4 -4
  12. package/dist/index.d.ts +4 -4
  13. package/dist/index.js +199 -3
  14. package/dist/index.js.map +1 -1
  15. package/dist/index.mjs +181 -6
  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-Ce8sVO7T.d.mts} +1 -1
  23. package/dist/{svelte-sql-ABIom_Bb.d.ts → svelte-sql-GOSaxlBv.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
  *