@itsoltech/basal-client 0.1.0 → 0.3.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/README.md +54 -2
- package/dist/cjs/index.cjs +2 -0
- package/dist/cjs/index.d.cts +81 -7
- package/dist/cjs/media.cjs +20 -0
- package/dist/cjs/media.d.cts +5 -0
- package/dist/cjs/questions.cjs +135 -25
- package/dist/cjs/questions.d.cts +22 -13
- package/dist/cjs/tasks.cjs +175 -0
- package/dist/cjs/tasks.d.cts +108 -0
- package/dist/esm/index.d.ts +81 -7
- package/dist/esm/index.js +2 -0
- package/dist/esm/media.d.ts +5 -0
- package/dist/esm/media.js +16 -0
- package/dist/esm/questions.d.ts +22 -13
- package/dist/esm/questions.js +131 -23
- package/dist/esm/tasks.d.ts +108 -0
- package/dist/esm/tasks.js +164 -0
- package/package.json +1 -1
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ExtractQuestion = exports.CompressQuestion = exports.VerifyQuestion = exports.ClassifyQuestion = void 0;
|
|
4
|
+
exports.classify = classify;
|
|
5
|
+
exports.verify = verify;
|
|
6
|
+
exports.compress = compress;
|
|
7
|
+
exports.extract = extract;
|
|
8
|
+
const questions_cjs_1 = require("./questions.cjs");
|
|
9
|
+
function object(v) {
|
|
10
|
+
if (!v || typeof v !== 'object' || Array.isArray(v))
|
|
11
|
+
throw new TypeError('expected task object');
|
|
12
|
+
return v;
|
|
13
|
+
}
|
|
14
|
+
function probability(v) { if (typeof v !== 'number' || !Number.isFinite(v) || v < 0 || v > 1)
|
|
15
|
+
throw new TypeError('invalid probability'); }
|
|
16
|
+
function probabilities(v) { for (const n of Object.values(object(v)))
|
|
17
|
+
probability(n); }
|
|
18
|
+
function automation(v) { if (Object.values(object(v)).some(n => n !== null && typeof n !== 'boolean'))
|
|
19
|
+
throw new TypeError('invalid automation'); }
|
|
20
|
+
function strings(v) { if (!Array.isArray(v) || v.some(k => typeof k !== 'string'))
|
|
21
|
+
throw new TypeError('expected string list'); }
|
|
22
|
+
function offset(v) { if (!Number.isSafeInteger(v) || v < 0)
|
|
23
|
+
throw new TypeError('invalid Unicode code point offset/count'); }
|
|
24
|
+
function span(v) { offset(v.start); offset(v.end); if (v.end < v.start)
|
|
25
|
+
throw new TypeError('reversed source span'); }
|
|
26
|
+
function risks(v) {
|
|
27
|
+
if (v === undefined)
|
|
28
|
+
return;
|
|
29
|
+
const a = Array.isArray(v) ? v : [v];
|
|
30
|
+
if (a.length > 64 || a.some(n => typeof n !== 'number' || !Number.isFinite(n) || n <= 0 || n >= 1))
|
|
31
|
+
throw new TypeError('invalid max_error');
|
|
32
|
+
}
|
|
33
|
+
function instructions(v) { if (typeof v !== 'string')
|
|
34
|
+
throw new TypeError('instructions must be a string'); return v; }
|
|
35
|
+
class TaskQuestion extends questions_cjs_1.QuestionSpec {
|
|
36
|
+
constructor(kind, text, fields) { super(kind, instructions(text), fields); }
|
|
37
|
+
read(response, id) {
|
|
38
|
+
const d = object(response.answers?.[id]);
|
|
39
|
+
if (d.type !== this.toJSON().type || d.experimental !== true)
|
|
40
|
+
throw new TypeError('Basal returned a missing or mismatched task');
|
|
41
|
+
if (d.type === 'classify') {
|
|
42
|
+
probabilities(d.scores);
|
|
43
|
+
const scores = object(d.scores);
|
|
44
|
+
if (this.toJSON().multi_label) {
|
|
45
|
+
strings(d.labels);
|
|
46
|
+
if (d.labels.some(k => !Object.hasOwn(scores, k)))
|
|
47
|
+
throw new TypeError('unknown label');
|
|
48
|
+
probability(d.set_confidence);
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
if (typeof d.label !== 'string' || !Object.hasOwn(scores, d.label) || d.top_label !== d.label)
|
|
52
|
+
throw new TypeError('invalid label');
|
|
53
|
+
probability(d.confidence);
|
|
54
|
+
automation(d.automated);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
else if (d.type === 'verify') {
|
|
58
|
+
const claims = object(d.claims);
|
|
59
|
+
for (const raw of Object.values(claims)) {
|
|
60
|
+
const c = object(raw);
|
|
61
|
+
const p = object(c.probabilities);
|
|
62
|
+
probabilities(p);
|
|
63
|
+
if (typeof c.verdict !== 'string' || !['supported', 'contradicted', 'not_stated', 'not_supported'].includes(c.verdict) || !Object.hasOwn(p, c.verdict))
|
|
64
|
+
throw new TypeError('invalid verdict');
|
|
65
|
+
probability(c.confidence);
|
|
66
|
+
automation(c.automated);
|
|
67
|
+
}
|
|
68
|
+
strings(d.not_supported);
|
|
69
|
+
if (typeof d.all_supported !== 'boolean' || d.not_supported.some(k => !Object.hasOwn(claims, k)))
|
|
70
|
+
throw new TypeError('invalid verification summary');
|
|
71
|
+
}
|
|
72
|
+
else if (d.type === 'compress') {
|
|
73
|
+
if (typeof d.compressed !== 'string' || !['sentence', 'line', 'paragraph'].includes(d.unit) || !Array.isArray(d.units) || !Array.isArray(d.kept))
|
|
74
|
+
throw new TypeError('invalid compression');
|
|
75
|
+
for (const u of d.units) {
|
|
76
|
+
const v = object(u);
|
|
77
|
+
span(v);
|
|
78
|
+
probability(v.probability);
|
|
79
|
+
}
|
|
80
|
+
for (const k of d.kept) {
|
|
81
|
+
offset(k);
|
|
82
|
+
if (k >= d.units.length)
|
|
83
|
+
throw new TypeError('invalid kept unit');
|
|
84
|
+
}
|
|
85
|
+
offset(d.original_chars);
|
|
86
|
+
offset(d.compressed_chars);
|
|
87
|
+
if (typeof d.ratio !== 'number' || !Number.isFinite(d.ratio) || d.ratio < 0)
|
|
88
|
+
throw new TypeError('invalid ratio');
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
object(d.data);
|
|
92
|
+
for (const raw of Object.values(object(d.fields))) {
|
|
93
|
+
const f = object(raw);
|
|
94
|
+
if (!Object.hasOwn(f, 'value') || !['choice', 'span'].includes(f.source) || !['validated', 'per decision'].includes(f.calibration))
|
|
95
|
+
throw new TypeError('invalid extraction field');
|
|
96
|
+
probability(f.confidence);
|
|
97
|
+
if (f.probabilities !== undefined)
|
|
98
|
+
probabilities(f.probabilities);
|
|
99
|
+
for (const k of ['present_probability', 'line_probability', 'span_probability'])
|
|
100
|
+
if (f[k] !== undefined)
|
|
101
|
+
probability(f[k]);
|
|
102
|
+
if (f.text !== undefined) {
|
|
103
|
+
if (typeof f.text !== 'string')
|
|
104
|
+
throw new TypeError('invalid source text');
|
|
105
|
+
span(f);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
return structuredClone(d);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
class ClassifyQuestion extends TaskQuestion {
|
|
113
|
+
constructor(text, labels, options = {}) {
|
|
114
|
+
if (!labels || typeof labels !== 'object' || Object.keys(labels).length < 1 || Object.keys(labels).length > 256)
|
|
115
|
+
throw new TypeError('classify requires 1..256 labels');
|
|
116
|
+
risks(options.max_error);
|
|
117
|
+
for (const k of ['multi_label', 'none'])
|
|
118
|
+
if (options[k] !== undefined && typeof options[k] !== 'boolean')
|
|
119
|
+
throw new TypeError(`invalid ${k}`);
|
|
120
|
+
if (options.option_keys !== undefined && !['show', 'hide'].includes(options.option_keys))
|
|
121
|
+
throw new TypeError('invalid option_keys');
|
|
122
|
+
if (options.threshold !== undefined) {
|
|
123
|
+
probability(options.threshold);
|
|
124
|
+
if (options.objective !== undefined && options.objective !== 'threshold')
|
|
125
|
+
throw new TypeError('threshold requires threshold objective');
|
|
126
|
+
}
|
|
127
|
+
for (const k of ['min', 'max'])
|
|
128
|
+
if (options[k] !== undefined)
|
|
129
|
+
offset(options[k]);
|
|
130
|
+
if (options.min !== undefined && options.max !== undefined && options.min > options.max)
|
|
131
|
+
throw new TypeError('min exceeds max');
|
|
132
|
+
if (options.objective !== undefined && !['threshold', 'exact', 'iou', 'f1'].includes(options.objective))
|
|
133
|
+
throw new TypeError('invalid objective');
|
|
134
|
+
if (!options.multi_label && ['threshold', 'min', 'max', 'objective'].some(k => Object.hasOwn(options, k)))
|
|
135
|
+
throw new TypeError('selection options require multi_label');
|
|
136
|
+
super('classify', text, { labels: structuredClone(labels), ...options });
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
exports.ClassifyQuestion = ClassifyQuestion;
|
|
140
|
+
class VerifyQuestion extends TaskQuestion {
|
|
141
|
+
constructor(text, claims, options = {}) {
|
|
142
|
+
if (!claims || typeof claims !== 'object' || !Object.keys(claims).length)
|
|
143
|
+
throw new TypeError('verify requires claims');
|
|
144
|
+
risks(options.max_error);
|
|
145
|
+
if (options.binary !== undefined && typeof options.binary !== 'boolean')
|
|
146
|
+
throw new TypeError('invalid binary');
|
|
147
|
+
super('verify', text, { claims: structuredClone(claims), ...options });
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
exports.VerifyQuestion = VerifyQuestion;
|
|
151
|
+
class CompressQuestion extends TaskQuestion {
|
|
152
|
+
constructor(text = '', options = {}) {
|
|
153
|
+
if (options.unit !== undefined && !['sentence', 'line', 'paragraph'].includes(options.unit))
|
|
154
|
+
throw new TypeError('invalid unit');
|
|
155
|
+
if (options.keep_ratio !== undefined) {
|
|
156
|
+
probability(options.keep_ratio);
|
|
157
|
+
if (options.keep_ratio === 0)
|
|
158
|
+
throw new TypeError('keep_ratio must be positive');
|
|
159
|
+
}
|
|
160
|
+
if (options.threshold !== undefined)
|
|
161
|
+
probability(options.threshold);
|
|
162
|
+
if (options.min_keep !== undefined)
|
|
163
|
+
offset(options.min_keep);
|
|
164
|
+
super('compress', text, options);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
exports.CompressQuestion = CompressQuestion;
|
|
168
|
+
class ExtractQuestion extends TaskQuestion {
|
|
169
|
+
constructor(text, schema) { object(schema); super('extract', text, { schema }); }
|
|
170
|
+
}
|
|
171
|
+
exports.ExtractQuestion = ExtractQuestion;
|
|
172
|
+
function classify(text, labels, options) { return new ClassifyQuestion(text, labels, options); }
|
|
173
|
+
function verify(text, claims, options) { return new VerifyQuestion(text, claims, options); }
|
|
174
|
+
function compress(text = '', options) { return new CompressQuestion(text, options); }
|
|
175
|
+
function extract(text, schema) { return new ExtractQuestion(text, schema); }
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { QuestionSpec } from './questions.cjs';
|
|
2
|
+
import type { DecisionResponse, JsonValue, Question, MultiObjective } from './index.cjs';
|
|
3
|
+
/** Task automation is unknown (null) without a threshold certified for that task/error target. */
|
|
4
|
+
export type Automation = Record<string, boolean | null>;
|
|
5
|
+
export interface ClassifyAnswer<K extends string = string> {
|
|
6
|
+
type: 'classify';
|
|
7
|
+
experimental: true;
|
|
8
|
+
scores: Record<K, number>;
|
|
9
|
+
label?: K;
|
|
10
|
+
top_label?: K;
|
|
11
|
+
confidence?: number;
|
|
12
|
+
automated?: Automation;
|
|
13
|
+
labels?: K[];
|
|
14
|
+
set_confidence?: number;
|
|
15
|
+
}
|
|
16
|
+
export interface ClaimResult {
|
|
17
|
+
verdict: 'supported' | 'contradicted' | 'not_stated' | 'not_supported';
|
|
18
|
+
probabilities: Record<string, number>;
|
|
19
|
+
confidence: number;
|
|
20
|
+
automated: Automation;
|
|
21
|
+
}
|
|
22
|
+
export interface VerifyAnswer {
|
|
23
|
+
type: 'verify';
|
|
24
|
+
experimental: true;
|
|
25
|
+
claims: Record<string, ClaimResult>;
|
|
26
|
+
all_supported: boolean;
|
|
27
|
+
not_supported: string[];
|
|
28
|
+
}
|
|
29
|
+
/** Inclusive start/exclusive end count Unicode code points, not JavaScript UTF-16 units. */
|
|
30
|
+
export interface CompressionUnit {
|
|
31
|
+
start: number;
|
|
32
|
+
end: number;
|
|
33
|
+
probability: number;
|
|
34
|
+
}
|
|
35
|
+
export interface CompressAnswer {
|
|
36
|
+
type: 'compress';
|
|
37
|
+
experimental: true;
|
|
38
|
+
compressed: string;
|
|
39
|
+
kept: number[];
|
|
40
|
+
units: CompressionUnit[];
|
|
41
|
+
unit: 'sentence' | 'line' | 'paragraph';
|
|
42
|
+
original_chars: number;
|
|
43
|
+
compressed_chars: number;
|
|
44
|
+
ratio: number;
|
|
45
|
+
}
|
|
46
|
+
export interface ExtractField {
|
|
47
|
+
value: JsonValue;
|
|
48
|
+
confidence: number;
|
|
49
|
+
source: 'choice' | 'span';
|
|
50
|
+
calibration: 'validated' | 'per decision';
|
|
51
|
+
probabilities?: Record<string, number>;
|
|
52
|
+
present_probability?: number;
|
|
53
|
+
text?: string;
|
|
54
|
+
start?: number;
|
|
55
|
+
end?: number;
|
|
56
|
+
line_probability?: number;
|
|
57
|
+
span_probability?: number;
|
|
58
|
+
error?: string;
|
|
59
|
+
}
|
|
60
|
+
export interface ExtractAnswer {
|
|
61
|
+
type: 'extract';
|
|
62
|
+
experimental: true;
|
|
63
|
+
data: Record<string, JsonValue>;
|
|
64
|
+
fields: Record<string, ExtractField>;
|
|
65
|
+
}
|
|
66
|
+
export type TaskAnswer = ClassifyAnswer | VerifyAnswer | CompressAnswer | ExtractAnswer;
|
|
67
|
+
export interface ClassifyOptions {
|
|
68
|
+
multi_label?: boolean;
|
|
69
|
+
none?: boolean;
|
|
70
|
+
max_error?: number | readonly number[];
|
|
71
|
+
option_keys?: 'show' | 'hide';
|
|
72
|
+
threshold?: number;
|
|
73
|
+
min?: number;
|
|
74
|
+
max?: number;
|
|
75
|
+
objective?: MultiObjective;
|
|
76
|
+
}
|
|
77
|
+
export interface VerifyOptions {
|
|
78
|
+
binary?: boolean;
|
|
79
|
+
max_error?: number | readonly number[];
|
|
80
|
+
}
|
|
81
|
+
export interface CompressOptions {
|
|
82
|
+
unit?: 'sentence' | 'line' | 'paragraph';
|
|
83
|
+
keep_ratio?: number;
|
|
84
|
+
threshold?: number;
|
|
85
|
+
min_keep?: number;
|
|
86
|
+
}
|
|
87
|
+
declare abstract class TaskQuestion<A extends TaskAnswer> extends QuestionSpec<A> {
|
|
88
|
+
protected constructor(kind: A['type'], text: string, fields: Question);
|
|
89
|
+
read(response: DecisionResponse, id: string): A;
|
|
90
|
+
}
|
|
91
|
+
export declare class ClassifyQuestion<K extends string = string> extends TaskQuestion<ClassifyAnswer<K>> {
|
|
92
|
+
constructor(text: string, labels: Record<K, JsonValue> | readonly JsonValue[], options?: ClassifyOptions);
|
|
93
|
+
}
|
|
94
|
+
export declare class VerifyQuestion extends TaskQuestion<VerifyAnswer> {
|
|
95
|
+
constructor(text: string, claims: Record<string, JsonValue> | readonly JsonValue[], options?: VerifyOptions);
|
|
96
|
+
}
|
|
97
|
+
export declare class CompressQuestion extends TaskQuestion<CompressAnswer> {
|
|
98
|
+
constructor(text?: string, options?: CompressOptions);
|
|
99
|
+
}
|
|
100
|
+
export declare class ExtractQuestion extends TaskQuestion<ExtractAnswer> {
|
|
101
|
+
constructor(text: string, schema: Record<string, JsonValue>);
|
|
102
|
+
}
|
|
103
|
+
export declare function classify<const K extends string>(text: string, labels: Record<K, JsonValue>, options?: ClassifyOptions): ClassifyQuestion<K>;
|
|
104
|
+
export declare function classify(text: string, labels: readonly JsonValue[], options?: ClassifyOptions): ClassifyQuestion;
|
|
105
|
+
export declare function verify(text: string, claims: Record<string, JsonValue> | readonly JsonValue[], options?: VerifyOptions): VerifyQuestion;
|
|
106
|
+
export declare function compress(text?: string, options?: CompressOptions): CompressQuestion;
|
|
107
|
+
export declare function extract(text: string, schema: Record<string, JsonValue>): ExtractQuestion;
|
|
108
|
+
export {};
|
package/dist/esm/index.d.ts
CHANGED
|
@@ -1,11 +1,31 @@
|
|
|
1
1
|
import { type QuestionSet, type TypedDecisionResponse, type DecisionOptions } from "./questions.js";
|
|
2
2
|
export * from "./questions.js";
|
|
3
|
+
export * from "./media.js";
|
|
4
|
+
export * from "./tasks.js";
|
|
5
|
+
import type { TaskAnswer } from "./tasks.js";
|
|
3
6
|
/** Native Basal wire types. Criterion order is significant; do not sort keys. */
|
|
4
7
|
export type JsonValue = string | number | boolean | null | JsonValue[] | {
|
|
5
8
|
[key: string]: JsonValue;
|
|
6
9
|
};
|
|
10
|
+
export type Calibration = "validated" | "unvalidated" | "text";
|
|
11
|
+
export type MultiObjective = "threshold" | "exact" | "iou" | "f1";
|
|
12
|
+
export interface MediaInput {
|
|
13
|
+
type: "image" | "audio";
|
|
14
|
+
data: string;
|
|
15
|
+
}
|
|
16
|
+
export interface MediaUsage {
|
|
17
|
+
images: number;
|
|
18
|
+
audio: number;
|
|
19
|
+
media_tokens: number;
|
|
20
|
+
detail: "default" | "high";
|
|
21
|
+
}
|
|
22
|
+
export interface ToolRanking {
|
|
23
|
+
tool: string;
|
|
24
|
+
probability: number;
|
|
25
|
+
}
|
|
26
|
+
export type ToolDefinition = Record<string, JsonValue>;
|
|
7
27
|
export interface Question {
|
|
8
|
-
type?: "choice" | "noul" | "score" | "multi" | "act";
|
|
28
|
+
type?: "choice" | "noul" | "score" | "multi" | "act" | "tool" | "classify" | "verify" | "compress" | "extract";
|
|
9
29
|
instructions?: JsonValue;
|
|
10
30
|
criteria?: Record<string, JsonValue> | JsonValue[];
|
|
11
31
|
levels?: Record<string, JsonValue> | JsonValue[];
|
|
@@ -17,13 +37,34 @@ export interface Question {
|
|
|
17
37
|
base?: "noul" | "choice" | "score";
|
|
18
38
|
costs?: Record<string, number> | Record<string, Record<string, number>>;
|
|
19
39
|
defer_action?: string;
|
|
20
|
-
max_error?: number;
|
|
40
|
+
max_error?: number | readonly number[];
|
|
41
|
+
objective?: MultiObjective;
|
|
42
|
+
exclusive?: readonly string[];
|
|
43
|
+
fallback?: string;
|
|
44
|
+
fallback_threshold?: number;
|
|
45
|
+
tools?: readonly ToolDefinition[];
|
|
46
|
+
extra?: readonly ("answer_directly" | "ask_user" | "none")[];
|
|
47
|
+
rank?: number;
|
|
48
|
+
description_chars?: number;
|
|
49
|
+
multi?: boolean;
|
|
50
|
+
labels?: Record<string, JsonValue> | JsonValue[];
|
|
51
|
+
multi_label?: boolean;
|
|
52
|
+
none?: boolean;
|
|
53
|
+
claims?: Record<string, JsonValue> | JsonValue[];
|
|
54
|
+
binary?: boolean;
|
|
55
|
+
unit?: 'sentence' | 'line' | 'paragraph';
|
|
56
|
+
keep_ratio?: number;
|
|
57
|
+
min_keep?: number;
|
|
58
|
+
schema?: Record<string, JsonValue>;
|
|
21
59
|
}
|
|
22
60
|
export interface DecisionRequest {
|
|
23
61
|
state: JsonValue;
|
|
24
62
|
questions: Record<string, Question>;
|
|
25
63
|
model?: string;
|
|
26
64
|
facts?: "off" | "auto";
|
|
65
|
+
lang?: "pl" | "en";
|
|
66
|
+
media?: readonly MediaInput[];
|
|
67
|
+
detail?: "default" | "high";
|
|
27
68
|
}
|
|
28
69
|
export interface EvidenceSpan {
|
|
29
70
|
text: string;
|
|
@@ -34,6 +75,7 @@ export interface EvidenceSpan {
|
|
|
34
75
|
interface BaseAnswer<K extends string = string> {
|
|
35
76
|
probabilities: Record<K, number>;
|
|
36
77
|
evidence?: EvidenceSpan[];
|
|
78
|
+
calibration?: Calibration;
|
|
37
79
|
}
|
|
38
80
|
export interface ChoiceAnswer<K extends string = string> extends BaseAnswer<K> {
|
|
39
81
|
type: "choice";
|
|
@@ -51,29 +93,57 @@ export interface ScoreAnswer extends BaseAnswer {
|
|
|
51
93
|
legend: Record<string, string>;
|
|
52
94
|
confidence: number;
|
|
53
95
|
}
|
|
54
|
-
export interface
|
|
96
|
+
export interface SelectionResult<K extends string = string> {
|
|
97
|
+
threshold?: number;
|
|
98
|
+
objective?: MultiObjective;
|
|
99
|
+
expected_score?: number | null;
|
|
100
|
+
constraints_applied?: JsonValue;
|
|
101
|
+
set_confidence: number;
|
|
102
|
+
}
|
|
103
|
+
export interface MultiAnswer<K extends string = string> extends BaseAnswer<K>, SelectionResult<K> {
|
|
55
104
|
type: "multi";
|
|
56
105
|
selected: K[];
|
|
57
|
-
threshold: number;
|
|
58
|
-
set_confidence: number;
|
|
59
106
|
}
|
|
107
|
+
export interface SingleToolAnswer extends BaseAnswer {
|
|
108
|
+
type: "tool";
|
|
109
|
+
multi?: false;
|
|
110
|
+
tool: string | null;
|
|
111
|
+
call: boolean;
|
|
112
|
+
confidence: number;
|
|
113
|
+
ranking?: ToolRanking[];
|
|
114
|
+
deferred?: boolean;
|
|
115
|
+
refused?: string;
|
|
116
|
+
max_error?: string;
|
|
117
|
+
}
|
|
118
|
+
export interface MultiToolAnswer extends BaseAnswer, SelectionResult {
|
|
119
|
+
type: "tool";
|
|
120
|
+
multi: true;
|
|
121
|
+
tools: string[];
|
|
122
|
+
call: boolean;
|
|
123
|
+
ranking?: ToolRanking[];
|
|
124
|
+
}
|
|
125
|
+
export type ToolAnswer = SingleToolAnswer | MultiToolAnswer;
|
|
60
126
|
export interface ActAnswer<K extends string = string, A extends string = string> extends BaseAnswer<K> {
|
|
61
127
|
type: "act";
|
|
62
128
|
action: A;
|
|
63
129
|
answer: K;
|
|
64
130
|
expected_costs: Record<A, number>;
|
|
65
131
|
confidence: number;
|
|
66
|
-
calibration:
|
|
132
|
+
calibration: Calibration;
|
|
67
133
|
refused?: string;
|
|
68
134
|
max_error?: string;
|
|
135
|
+
deferred?: boolean;
|
|
69
136
|
}
|
|
70
|
-
export type Answer = ChoiceAnswer | NoulAnswer | ScoreAnswer | MultiAnswer | ActAnswer;
|
|
137
|
+
export type Answer = ChoiceAnswer | NoulAnswer | ScoreAnswer | MultiAnswer | ActAnswer | ToolAnswer | TaskAnswer;
|
|
71
138
|
export interface Usage {
|
|
72
139
|
input_tokens: number;
|
|
73
140
|
output_tokens: number;
|
|
74
141
|
questions?: number;
|
|
75
142
|
branches?: number;
|
|
76
143
|
latency_ms?: number;
|
|
144
|
+
longest_prompt_tokens?: number;
|
|
145
|
+
second_order_branches?: number;
|
|
146
|
+
media?: MediaUsage;
|
|
77
147
|
}
|
|
78
148
|
export interface DecisionResponse {
|
|
79
149
|
model: string;
|
|
@@ -86,6 +156,10 @@ export interface ModelMetadata {
|
|
|
86
156
|
release_date?: string;
|
|
87
157
|
mode?: string;
|
|
88
158
|
early_exit?: JsonValue[];
|
|
159
|
+
prompt_format?: number;
|
|
160
|
+
orders?: JsonValue;
|
|
161
|
+
temperature_per_prim?: Record<string, number>;
|
|
162
|
+
media?: ("image" | "audio")[];
|
|
89
163
|
}
|
|
90
164
|
export interface ModelsResponse {
|
|
91
165
|
models: ModelMetadata[];
|
package/dist/esm/index.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { buildRequest } from "./questions.js";
|
|
2
2
|
export * from "./questions.js";
|
|
3
|
+
export * from "./media.js";
|
|
4
|
+
export * from "./tasks.js";
|
|
3
5
|
export class BasalError extends Error {
|
|
4
6
|
}
|
|
5
7
|
/** Non-2xx response. Server body and Retry-After are available without logging them. */
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { MediaInput } from './index.js';
|
|
2
|
+
/** Inline image; never fetches a URL or reads a file. */
|
|
3
|
+
export declare function image(data: Uint8Array | string): MediaInput;
|
|
4
|
+
/** Inline audio; never fetches a URL or reads a file. */
|
|
5
|
+
export declare function audio(data: Uint8Array | string): MediaInput;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
function media(type, data) {
|
|
2
|
+
if (data instanceof Uint8Array) {
|
|
3
|
+
// Bounded chunks avoid the argument limit of spreading a whole image/audio file.
|
|
4
|
+
const chunks = [];
|
|
5
|
+
for (let offset = 0; offset < data.length; offset += 8192)
|
|
6
|
+
chunks.push(String.fromCharCode(...data.subarray(offset, offset + 8192)));
|
|
7
|
+
data = btoa(chunks.join(''));
|
|
8
|
+
}
|
|
9
|
+
if (typeof data !== 'string' || !data.trim() || /^https?:\/\//i.test(data))
|
|
10
|
+
throw new TypeError('media data must be bytes, base64 or a data URL');
|
|
11
|
+
return { type, data };
|
|
12
|
+
}
|
|
13
|
+
/** Inline image; never fetches a URL or reads a file. */
|
|
14
|
+
export function image(data) { return media('image', data); }
|
|
15
|
+
/** Inline audio; never fetches a URL or reads a file. */
|
|
16
|
+
export function audio(data) { return media('audio', data); }
|
package/dist/esm/questions.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ActAnswer, Answer, ChoiceAnswer, DecisionResponse, EvidenceSpan, JsonValue, MultiAnswer, NoulAnswer, Question, ScoreAnswer } from './index.js';
|
|
1
|
+
import type { ActAnswer, Answer, ChoiceAnswer, DecisionResponse, EvidenceSpan, JsonValue, MultiAnswer, NoulAnswer, Question, ScoreAnswer, ToolAnswer, ToolDefinition, MultiObjective, DecisionRequest } from './index.js';
|
|
2
2
|
/** Required result metadata on the typed path; missing spans become an empty array. */
|
|
3
3
|
export type TypedChoiceAnswer<K extends string = string> = ChoiceAnswer<K> & {
|
|
4
4
|
evidence: EvidenceSpan[];
|
|
@@ -19,19 +19,29 @@ export interface EvidenceOptions {
|
|
|
19
19
|
export interface ChoiceOptions extends EvidenceOptions {
|
|
20
20
|
option_keys?: 'show' | 'hide';
|
|
21
21
|
}
|
|
22
|
-
export interface MultiOptions {
|
|
22
|
+
export interface MultiOptions<K extends string = string> {
|
|
23
23
|
threshold?: number;
|
|
24
24
|
min?: number;
|
|
25
25
|
max?: number;
|
|
26
|
+
objective?: MultiObjective;
|
|
27
|
+
exclusive?: readonly K[];
|
|
28
|
+
fallback?: K;
|
|
29
|
+
fallback_threshold?: number;
|
|
30
|
+
}
|
|
31
|
+
export interface ToolOptions extends MultiOptions {
|
|
32
|
+
extra?: readonly ("answer_directly" | "ask_user" | "none")[];
|
|
33
|
+
rank?: number;
|
|
34
|
+
multi?: boolean;
|
|
35
|
+
max_error?: number;
|
|
36
|
+
/** Tool-description truncation cap; omitted keeps the server default (300), zero disables truncation. */
|
|
37
|
+
description_chars?: number;
|
|
26
38
|
}
|
|
27
39
|
export interface ActOptions<K extends string = string, A extends string = string> extends EvidenceOptions {
|
|
28
40
|
criteria?: Record<K, string>;
|
|
29
41
|
defer_action?: A;
|
|
30
42
|
max_error?: number;
|
|
31
43
|
}
|
|
32
|
-
export interface DecisionOptions {
|
|
33
|
-
model?: string;
|
|
34
|
-
facts?: 'off' | 'auto';
|
|
44
|
+
export interface DecisionOptions extends Pick<DecisionRequest, 'model' | 'facts' | 'lang' | 'media' | 'detail'> {
|
|
35
45
|
signal?: AbortSignal;
|
|
36
46
|
}
|
|
37
47
|
/** Immutable snapshot of a typed question. Use factories or the concrete constructors. */
|
|
@@ -52,7 +62,10 @@ export declare class ScoreQuestion extends QuestionSpec<TypedScoreAnswer> {
|
|
|
52
62
|
constructor(instructions: string, levels: readonly string[], options?: EvidenceOptions);
|
|
53
63
|
}
|
|
54
64
|
export declare class MultiQuestion<K extends string = string> extends QuestionSpec<TypedMultiAnswer<K>> {
|
|
55
|
-
constructor(instructions: string, values: Record<K, string>, options?: MultiOptions);
|
|
65
|
+
constructor(instructions: string, values: Record<K, string>, options?: MultiOptions<K>);
|
|
66
|
+
}
|
|
67
|
+
export declare class ToolQuestion extends QuestionSpec<ToolAnswer> {
|
|
68
|
+
constructor(instructions: string, tools: readonly ToolDefinition[], options?: ToolOptions);
|
|
56
69
|
}
|
|
57
70
|
export declare class ActQuestion<K extends string = 'true' | 'false', A extends string = string> extends QuestionSpec<TypedActAnswer<K, A>> {
|
|
58
71
|
constructor(instructions: string, costs: Record<A, Record<NoInfer<K>, number>>, options?: ActOptions<K, NoInfer<A>>);
|
|
@@ -60,8 +73,9 @@ export declare class ActQuestion<K extends string = 'true' | 'false', A extends
|
|
|
60
73
|
export declare function choice<const K extends string>(instructions: string, values: Record<K, string>, options?: ChoiceOptions): ChoiceQuestion<K>;
|
|
61
74
|
export declare function noul(instructions: string, options?: EvidenceOptions): NoulQuestion;
|
|
62
75
|
export declare function score(instructions: string, levels: readonly string[], options?: EvidenceOptions): ScoreQuestion;
|
|
63
|
-
export declare function multi<const K extends string>(instructions: string, values: Record<K, string>, options?: MultiOptions): MultiQuestion<K>;
|
|
76
|
+
export declare function multi<const K extends string>(instructions: string, values: Record<K, string>, options?: MultiOptions<K>): MultiQuestion<K>;
|
|
64
77
|
export declare function act<const K extends string = 'true' | 'false', const A extends string = string>(instructions: string, costs: Record<A, Record<NoInfer<K>, number>>, options?: ActOptions<K, NoInfer<A>>): ActQuestion<K, A>;
|
|
78
|
+
export declare function tool(instructions: string, tools: readonly ToolDefinition[], options?: ToolOptions): ToolQuestion;
|
|
65
79
|
export type QuestionSet = Record<string, QuestionSpec>;
|
|
66
80
|
export type TypedDecisionResponse<Q extends QuestionSet> = Omit<DecisionResponse, 'answers'> & {
|
|
67
81
|
answers: {
|
|
@@ -70,9 +84,4 @@ export type TypedDecisionResponse<Q extends QuestionSet> = Omit<DecisionResponse
|
|
|
70
84
|
answer<K extends keyof Q & (string | number)>(key: K): Q[K] extends QuestionSpec<infer A> ? A : never;
|
|
71
85
|
raw: DecisionResponse;
|
|
72
86
|
};
|
|
73
|
-
export declare function buildRequest(state: JsonValue, questions: QuestionSet, options: DecisionOptions):
|
|
74
|
-
state: JsonValue;
|
|
75
|
-
questions: Record<string, Question>;
|
|
76
|
-
model?: string;
|
|
77
|
-
facts?: 'off' | 'auto';
|
|
78
|
-
};
|
|
87
|
+
export declare function buildRequest(state: JsonValue, questions: QuestionSet, options: DecisionOptions): DecisionRequest;
|