Skip to content

Commit a1725c4

Browse files
committed
Merge branch 'table-v2-picker-enrichment' into table-v2-cutover
2 parents ab67d38 + 4ead120 commit a1725c4

2 files changed

Lines changed: 22 additions & 4 deletions

File tree

apps/sim/lib/table/llm/enrichment.test.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,24 @@ describe('enrichTableToolDescription for table_query_rows_v2', () => {
8080
expect(enriched).not.toContain('{"field":"name"')
8181
})
8282

83+
/**
84+
* `buildPatternClause` ESCAPES `%` before translating `*`, so a model that
85+
* sends `%` gets a literal-percent match and silently wrong rows rather than
86+
* an error. All four pattern operators share that translation.
87+
*/
88+
it('covers every pattern operator in the wildcard rule and warns off %', () => {
89+
expect(enriched).toContain('like, ilike, nlike and nilike all use * as the wildcard - never %')
90+
})
91+
92+
/**
93+
* A question with no condition ("the 5 most recent rows") is answered with
94+
* order and limit; the model must not invent a predicate to satisfy it.
95+
*/
96+
it('tells the model a filter is optional when no condition was asked for', () => {
97+
expect(enriched).toContain('omit filter entirely and use order and limit')
98+
expect(enriched).toContain('omit it whenever the question carries no condition')
99+
})
100+
83101
it('drops the wildcard example when the table has no text column', () => {
84102
const numeric = enrichTableToolDescription(
85103
'Query rows.',

apps/sim/lib/table/llm/enrichment.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -134,8 +134,8 @@ export function enrichTableToolDescription(
134134
*/
135135
const textCol = table.columns.find((c) => c.type === 'string')
136136
const wildcardRule = textCol
137-
? `5. like/ilike use * as the wildcard, e.g. {"field":"${textCol.name}","op":"ilike","value":"*jo*"}`
138-
: '5. like/ilike use * as the wildcard, matching anywhere in a text value'
137+
? `5. like, ilike, nlike and nilike all use * as the wildcard - never % - e.g. {"field":"${textCol.name}","op":"ilike","value":"*jo*"}`
138+
: '5. like, ilike, nlike and nilike all use * as the wildcard - never % - matching anywhere in a text value'
139139
const numberCol = table.columns.find((c) => c.type === 'number')
140140
const orderExample = numberCol
141141
? `
@@ -145,7 +145,7 @@ Example order: [{"field":"${numberCol.name}","direction":"desc"}] for highest fi
145145
return `${originalDescription}
146146
147147
INSTRUCTIONS:
148-
1. Build the filter yourself from the user's question - do NOT ask for confirmation
148+
1. Build the filter yourself from the user's question - do NOT ask for confirmation. If the question names no condition at all ("the 5 most recent rows"), omit filter entirely and use order and limit instead of inventing one
149149
2. A single condition is a plain object: {"field":"<column>","op":"<operator>","value":<value>}
150150
3. For multiple conditions wrap them in {"all":[...]} for AND or {"any":[...]} for OR; groups nest
151151
4. Operators: eq, ne, gt, gte, lt, lte, in, nin, like, ilike, nlike, nilike, contains, ncontains, startsWith, endsWith, isNull, isNotNull, isEmpty, isNotEmpty
@@ -155,7 +155,7 @@ ${wildcardRule}
155155
8. For ranking queries (highest, lowest, Nth, top N) set order and a small limit, e.g. limit 1 for the highest, 2 for the second highest
156156
9. Omit limit to return every matching row; the query fails if the result exceeds 5MB, so narrow with a filter instead of guessing a limit
157157
10. With a limit, a page can end early at the byte budget - a non-null nextCursor means more rows remain, so pass it back as cursor and loop until it is null. Never infer completion from page size
158-
11. Omit the filter only when the user genuinely wants every row
158+
11. A filter is optional: omit it whenever the question carries no condition, not only when the user wants every row
159159
160160
Table "${table.name}" columns:
161161
${v2ColumnList}

0 commit comments

Comments
 (0)