@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.
- package/dist/{chunk-3KMOXRTK.mjs → chunk-765DLJMZ.mjs} +24 -3
- package/dist/chunk-765DLJMZ.mjs.map +1 -0
- package/dist/{chunk-Q4IBPW2W.mjs → chunk-AULHRX5C.mjs} +2 -2
- package/dist/{chunk-QJKYNLT4.mjs → chunk-IFV4ECHC.mjs} +3 -3
- package/dist/{chunk-B6EFDYFS.mjs → chunk-VMUT6PIO.mjs} +2 -2
- package/dist/{chunk-P44XWTPA.mjs → chunk-ZUUSBLVP.mjs} +3 -3
- package/dist/{conversation-list-store-DVYgTaaA.d.mts → conversation-list-store-BaeGM2lx.d.mts} +439 -173
- package/dist/{conversation-list-store-DVYgTaaA.d.ts → conversation-list-store-BaeGM2lx.d.ts} +439 -173
- package/dist/{index-BOO1gV6F.d.mts → index-C4pX6FVI.d.mts} +1 -1
- package/dist/{index-AKUurvWQ.d.ts → index-DCtNAWZ0.d.ts} +1 -1
- package/dist/index.d.mts +4 -4
- package/dist/index.d.ts +4 -4
- package/dist/index.js +256 -16
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +238 -19
- package/dist/index.mjs.map +1 -1
- package/dist/react.d.mts +2 -2
- package/dist/react.d.ts +2 -2
- package/dist/react.js +23 -2
- package/dist/react.js.map +1 -1
- package/dist/react.mjs +3 -3
- package/dist/{svelte-sql-B1nLVQuc.d.mts → svelte-sql-BhMxrqn_.d.mts} +1 -1
- package/dist/{svelte-sql-ABIom_Bb.d.ts → svelte-sql-DN3NpM4c.d.ts} +1 -1
- package/dist/svelte.d.mts +2 -2
- package/dist/svelte.d.ts +2 -2
- package/dist/svelte.js +23 -2
- package/dist/svelte.js.map +1 -1
- package/dist/svelte.mjs +3 -3
- package/dist/vue.d.mts +2 -2
- package/dist/vue.d.ts +2 -2
- package/dist/vue.js +23 -2
- package/dist/vue.js.map +1 -1
- package/dist/vue.mjs +2 -2
- package/package.json +1 -1
- package/dist/chunk-3KMOXRTK.mjs.map +0 -1
- /package/dist/{chunk-Q4IBPW2W.mjs.map → chunk-AULHRX5C.mjs.map} +0 -0
- /package/dist/{chunk-QJKYNLT4.mjs.map → chunk-IFV4ECHC.mjs.map} +0 -0
- /package/dist/{chunk-B6EFDYFS.mjs.map → chunk-VMUT6PIO.mjs.map} +0 -0
- /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-
|
|
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-
|
|
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-
|
|
23
|
+
} from "./chunk-AULHRX5C.mjs";
|
|
24
24
|
import {
|
|
25
25
|
createRaisinVue
|
|
26
|
-
} from "./chunk-
|
|
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-
|
|
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
|
*
|