@columenlabs/lumen-ai 0.1.142 → 0.1.143
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/README.md +1 -1
- package/dist/assistant/engine.js +1 -1
- package/dist/assistant/find.d.ts +7 -2
- package/dist/assistant/find.js +5 -2
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -165,7 +165,7 @@ The standard way to search an app's records (Columen's canonical setup, 2026-10-
|
|
|
165
165
|
- **Words** are matched by an FTS5 index (`porter unicode61`, so "egg" finds "eggs"): `any`, `all`, `none` (leave out: "no milk"), and `in` to say which fields to look in.
|
|
166
166
|
- **Meaning** comes from Vectorize, opt in per app: `like` ("something light for a hot day") asks the index for the nearest rows, and the same filters and words trim them.
|
|
167
167
|
- **Worked-out fields**: a number, date or tag field may be the app's own SQL over the row (`sql: 'json_array_length(t.steps)'`) instead of a column.
|
|
168
|
-
- **Counts**: the result carries `count` (all matches), `returned` and `same_name` (different rows that share a name), so the model says the right number.
|
|
168
|
+
- **Counts**: the result carries `count` (all matches), `returned` and `same_name` (different rows that share a name), so the model says the right number. A search by meaning carries `nearest: true` and no `count`: its rows are the nearest few, not every row that fits, so the model never quotes them as a number of matches.
|
|
169
169
|
|
|
170
170
|
```ts
|
|
171
171
|
import { d1Sql, defineFind, findSql, findTool } from '@columenlabs/lumen-ai/assistant';
|
package/dist/assistant/engine.js
CHANGED
|
@@ -960,7 +960,7 @@ export class Assistant {
|
|
|
960
960
|
'Answer in short plain sentences. Use the tools for facts; never guess a number a tool can give you. Call several tools at once when they do not depend on each other.',
|
|
961
961
|
...([...fns.values()].some((f) => f.def.find)
|
|
962
962
|
? [
|
|
963
|
-
'Questions about an app\'s records go through its find tool (the tool named <app>_find): put every condition of the question in one call (filters, words to include or leave out, which fields to look in), ask only for the fields the answer needs, then judge the rest yourself from what it returns. Never list or open records one by one to filter them. A loose ask (a mood, an occasion, "something light", "good for a party") goes in its like field when the tool has one; then pick from what it returns yourself. How many match is the result\'s count: say that number, and name each row in same_name, which are different records that share a name. Rows a find already returned you use again only when they answer the whole new question; a new condition (another ingredient, a kind of dish, how quick) is a new find call.',
|
|
963
|
+
'Questions about an app\'s records go through its find tool (the tool named <app>_find): put every condition of the question in one call (filters, words to include or leave out, which fields to look in), ask only for the fields the answer needs, then judge the rest yourself from what it returns. Never list or open records one by one to filter them. A loose ask (a mood, an occasion, "something light", "good for a party") goes in its like field when the tool has one; then pick from what it returns yourself. How many match is the result\'s count: say that number (a like search has no count, only the nearest rows: never give a number of matches for it), and name each row in same_name, which are different records that share a name. Rows a find already returned you use again only when they answer the whole new question; a new condition (another ingredient, a kind of dish, how quick) is a new find call.',
|
|
964
964
|
]
|
|
965
965
|
: []),
|
|
966
966
|
...([...fns.values()].some((f) => !f.draft && !f.write) && !fns.has(BATCH)
|
package/dist/assistant/find.d.ts
CHANGED
|
@@ -86,8 +86,13 @@ export interface FindQuery {
|
|
|
86
86
|
[tagOrRange: string]: unknown;
|
|
87
87
|
}
|
|
88
88
|
export interface FindResult {
|
|
89
|
-
/**
|
|
90
|
-
|
|
89
|
+
/**
|
|
90
|
+
* Rows that match, all of them, before `limit`. Say this number when asked how many. Left out
|
|
91
|
+
* of a search by meaning, whose rows are the nearest few, not every row that fits.
|
|
92
|
+
*/
|
|
93
|
+
count?: number;
|
|
94
|
+
/** Set on a search by meaning: the rows are the nearest in meaning, nearest first, to pick from. */
|
|
95
|
+
nearest?: true;
|
|
91
96
|
/** Rows in this answer (at most `limit`). */
|
|
92
97
|
returned: number;
|
|
93
98
|
rows: Record<string, unknown>[];
|
package/dist/assistant/find.js
CHANGED
|
@@ -301,8 +301,11 @@ export async function runFind(def, sql, q, meaning) {
|
|
|
301
301
|
return row;
|
|
302
302
|
});
|
|
303
303
|
const same = sameNames(def, out, built.fields);
|
|
304
|
+
const byMeaning = !!near?.length;
|
|
305
|
+
if (byMeaning)
|
|
306
|
+
notes.push('These are the nearest in meaning, nearest first, not every row that fits: pick from them and do not say how many match.');
|
|
304
307
|
return {
|
|
305
|
-
count,
|
|
308
|
+
...(byMeaning ? { nearest: true } : { count }),
|
|
306
309
|
returned: out.length,
|
|
307
310
|
rows: out,
|
|
308
311
|
...(same.length ? { same_name: same } : {}),
|
|
@@ -407,7 +410,7 @@ export async function findTool(def, sql, opts = {}) {
|
|
|
407
410
|
.join(', ');
|
|
408
411
|
return {
|
|
409
412
|
name: `${def.name}_find`,
|
|
410
|
-
description: `Finds ${def.label}s in one query${def.about ? ` (${def.about})` : ''}: put every condition of the question in one call (filters, words to include or leave out, which fields to look in${meaning ? ', and like for a loose ask' : ''}) and ask only for the fields the answer needs. Fields: ${fields}. Returns the matching ${def.label}s, how many match in all (count) and any that share a name (same_name).`,
|
|
413
|
+
description: `Finds ${def.label}s in one query${def.about ? ` (${def.about})` : ''}: put every condition of the question in one call (filters, words to include or leave out, which fields to look in${meaning ? ', and like for a loose ask' : ''}) and ask only for the fields the answer needs. Fields: ${fields}. Returns the matching ${def.label}s, how many match in all (count; a like search returns the nearest instead, marked nearest, with no count) and any that share a name (same_name).`,
|
|
411
414
|
inputSchema: schemaOf(def, tags, Boolean(meaning)),
|
|
412
415
|
read: true,
|
|
413
416
|
find: true,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@columenlabs/lumen-ai",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.143",
|
|
4
4
|
"description": "Lumen's assistant and agent parts: a chat assistant's server (Claude tiers, tools over MCP, the web, hand off, spend caps), serving an MCP server from a Worker, read-only tool sets and metered tool calls.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -41,8 +41,8 @@
|
|
|
41
41
|
},
|
|
42
42
|
"dependencies": {
|
|
43
43
|
"@anthropic-ai/sdk": "0.133.0",
|
|
44
|
-
"@columenlabs/lumen-ops": "0.1.
|
|
45
|
-
"@columenlabs/lumen-ui-types": "0.1.
|
|
44
|
+
"@columenlabs/lumen-ops": "0.1.143",
|
|
45
|
+
"@columenlabs/lumen-ui-types": "0.1.143",
|
|
46
46
|
"openai": "7.32.0",
|
|
47
47
|
"zod": "^4.3.6"
|
|
48
48
|
},
|