@query-farm/vgi 0.10.0 → 0.12.0
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/functions/aggregate.d.ts +8 -0
- package/dist/functions/table.d.ts +8 -0
- package/dist/index.js +16 -5
- package/dist/index.js.map +5 -5
- package/dist/worker-cf-entry.js +197 -186
- package/dist/worker-cf-entry.js.map +7 -7
- package/package.json +1 -1
- package/src/functions/aggregate.ts +13 -1
- package/src/functions/table.ts +17 -1
- package/src/protocol/handlers/aggregate.ts +12 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@query-farm/vgi",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.12.0",
|
|
4
4
|
"description": "TypeScript framework for extending DuckDB with user-defined functions via the Vector Gateway Interface (VGI) over Arrow IPC.",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE",
|
|
6
6
|
"author": "Query Farm LLC (https://query.farm)",
|
|
@@ -15,7 +15,11 @@
|
|
|
15
15
|
|
|
16
16
|
import { type VgiSchema, schema, type VgiField, field, type VgiBatch, type VgiDataType, nullType, isNull } from "../arrow/index.js";
|
|
17
17
|
import type { Arguments } from "../arguments/arguments.js";
|
|
18
|
-
import
|
|
18
|
+
import {
|
|
19
|
+
constraintSpecFields,
|
|
20
|
+
type ArgumentSpec,
|
|
21
|
+
type ArgumentConstraints,
|
|
22
|
+
} from "../arguments/argument-spec.js";
|
|
19
23
|
import type {
|
|
20
24
|
FunctionMeta,
|
|
21
25
|
VgiFunction,
|
|
@@ -123,6 +127,13 @@ export interface AggregateFunctionConfig<TArgs = Record<string, any>, TState = a
|
|
|
123
127
|
onBind?: (params: AggregateBindParams<TArgs>) => VgiDataType | Promise<VgiDataType>;
|
|
124
128
|
/** Optional per-arg default values (positional only here). */
|
|
125
129
|
argDefaults?: Record<string, any>;
|
|
130
|
+
/**
|
|
131
|
+
* Per-argument discovery constraints (choices / ge / le / gt / lt / pattern),
|
|
132
|
+
* keyed by argument name. Surfaced via `vgi_function_arguments()` and enforced
|
|
133
|
+
* at aggregate_bind for const params: a value violating a declared constraint
|
|
134
|
+
* fails the bind with an ArgumentValidationError.
|
|
135
|
+
*/
|
|
136
|
+
argConstraints?: Record<string, ArgumentConstraints>;
|
|
126
137
|
|
|
127
138
|
initialState: (params: AggregateBindParams<TArgs>) => TState;
|
|
128
139
|
/**
|
|
@@ -342,6 +353,7 @@ export function defineAggregate<TArgs = Record<string, any>, TState = any>(
|
|
|
342
353
|
isAnyType,
|
|
343
354
|
isVarargs: varargsSet.has(name),
|
|
344
355
|
isConst,
|
|
356
|
+
...constraintSpecFields(config.argConstraints?.[name]),
|
|
345
357
|
});
|
|
346
358
|
}
|
|
347
359
|
}
|
package/src/functions/table.ts
CHANGED
|
@@ -29,7 +29,12 @@ import type {
|
|
|
29
29
|
StreamHandlers,
|
|
30
30
|
FunctionExample,
|
|
31
31
|
} from "./types.js";
|
|
32
|
-
import
|
|
32
|
+
import {
|
|
33
|
+
constraintSpecFields,
|
|
34
|
+
validateConstConstraints,
|
|
35
|
+
type ArgumentSpec,
|
|
36
|
+
type ArgumentConstraints,
|
|
37
|
+
} from "../arguments/argument-spec.js";
|
|
33
38
|
import { batchToScalarDict, batchToSecretDict, projectSchema, safeNumber } from "../util/arrow/index.js";
|
|
34
39
|
import {
|
|
35
40
|
buildJoinKeysLookup,
|
|
@@ -166,6 +171,13 @@ export interface TableFunctionConfig<
|
|
|
166
171
|
argDocs?: Record<string, string>;
|
|
167
172
|
/** Argument defaults */
|
|
168
173
|
argDefaults?: Record<string, any>;
|
|
174
|
+
/**
|
|
175
|
+
* Per-argument discovery constraints (choices / ge / le / gt / lt / pattern),
|
|
176
|
+
* keyed by argument name. Surfaced via `vgi_function_arguments()` for agent
|
|
177
|
+
* discovery AND enforced at bind: a value violating a declared constraint
|
|
178
|
+
* fails the bind with an ArgumentValidationError.
|
|
179
|
+
*/
|
|
180
|
+
argConstraints?: Record<string, ArgumentConstraints>;
|
|
169
181
|
/** Names of args that accept variable number of arguments */
|
|
170
182
|
varargs?: string[];
|
|
171
183
|
/** Bind: return output schema. May be async — handlers `await` the result. */
|
|
@@ -273,6 +285,7 @@ export function defineTableFunction<
|
|
|
273
285
|
isAnyType: isAny,
|
|
274
286
|
isVarargs: varargsSet.has(name),
|
|
275
287
|
doc: config.argDocs?.[name],
|
|
288
|
+
...constraintSpecFields(config.argConstraints?.[name]),
|
|
276
289
|
});
|
|
277
290
|
}
|
|
278
291
|
}
|
|
@@ -318,6 +331,9 @@ export function defineTableFunction<
|
|
|
318
331
|
}
|
|
319
332
|
// Arrow Int64 values come through as BigInt — coerce to number
|
|
320
333
|
if (typeof val === "bigint") val = safeNumber(val);
|
|
334
|
+
// Enforce declared constraints at bind (table args are all bind-time).
|
|
335
|
+
const constraints = config.argConstraints?.[spec.name];
|
|
336
|
+
if (constraints) validateConstConstraints(spec.name, constraints, val);
|
|
321
337
|
args[spec.name] = val;
|
|
322
338
|
}
|
|
323
339
|
return args as TArgs;
|
|
@@ -32,6 +32,7 @@ import {
|
|
|
32
32
|
type AggregateBindParams,
|
|
33
33
|
} from "../../functions/aggregate.js";
|
|
34
34
|
import { Arguments } from "../../arguments/arguments.js";
|
|
35
|
+
import { validateConstConstraints } from "../../arguments/argument-spec.js";
|
|
35
36
|
import {
|
|
36
37
|
REQUEST_PARAMS_SCHEMA,
|
|
37
38
|
RESULT_BINARY_SCHEMA,
|
|
@@ -310,8 +311,9 @@ function extractArgMap(
|
|
|
310
311
|
}
|
|
311
312
|
}
|
|
312
313
|
for (let i = 0; i < constNames.length; i++) {
|
|
314
|
+
let v: any;
|
|
313
315
|
try {
|
|
314
|
-
|
|
316
|
+
v = args.get(i);
|
|
315
317
|
// Decode DECIMAL scalars (DuckDB serializes 0.5-style literals as
|
|
316
318
|
// DECIMAL(2,1), which Arrow stores as the unscaled integer — a raw
|
|
317
319
|
// BigInt here). Scale back to float using the declared scale.
|
|
@@ -323,14 +325,22 @@ function extractArgMap(
|
|
|
323
325
|
} else if (typeof v === "bigint") {
|
|
324
326
|
v = Number(v);
|
|
325
327
|
}
|
|
326
|
-
out[constNames[i]] = v;
|
|
327
328
|
} catch {
|
|
328
329
|
// args.get throws when the arg isn't set — fall back to the declared
|
|
329
330
|
// default so aggregates called without an explicit const value still
|
|
330
331
|
// see it in update/finalize.
|
|
331
332
|
const def = cfg.argDefaults?.[constNames[i]];
|
|
332
333
|
if (def !== undefined) out[constNames[i]] = def;
|
|
334
|
+
continue;
|
|
333
335
|
}
|
|
336
|
+
// Enforce declared constraints on the supplied value. This sits OUTSIDE the
|
|
337
|
+
// try above so a constraint violation propagates as a bind error rather than
|
|
338
|
+
// being swallowed and silently replaced by the default.
|
|
339
|
+
const constraints = cfg.argConstraints?.[constNames[i]];
|
|
340
|
+
if (constraints !== undefined) {
|
|
341
|
+
validateConstConstraints(constNames[i], constraints, v);
|
|
342
|
+
}
|
|
343
|
+
out[constNames[i]] = v;
|
|
334
344
|
}
|
|
335
345
|
// Non-const args aren't in the wire Arguments, but users may still want
|
|
336
346
|
// defaults surfaced for `params.args` — apply them here.
|