@llumiverse/core 0.12.3 → 0.14.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 +13 -11
- package/lib/cjs/CompletionStream.js +6 -8
- package/lib/cjs/CompletionStream.js.map +1 -1
- package/lib/cjs/Driver.js +20 -16
- package/lib/cjs/Driver.js.map +1 -1
- package/lib/cjs/async.js +9 -6
- package/lib/cjs/async.js.map +1 -1
- package/lib/cjs/formatters/claude.js +53 -15
- package/lib/cjs/formatters/claude.js.map +1 -1
- package/lib/cjs/formatters/commons.js +2 -3
- package/lib/cjs/formatters/commons.js.map +1 -1
- package/lib/cjs/formatters/generic.js +2 -2
- package/lib/cjs/formatters/generic.js.map +1 -1
- package/lib/cjs/formatters/index.js +2 -1
- package/lib/cjs/formatters/index.js.map +1 -1
- package/lib/cjs/formatters/llama2.js +1 -2
- package/lib/cjs/formatters/llama2.js.map +1 -1
- package/lib/cjs/formatters/llama3.js +42 -0
- package/lib/cjs/formatters/llama3.js.map +1 -0
- package/lib/cjs/formatters/openai.js +59 -5
- package/lib/cjs/formatters/openai.js.map +1 -1
- package/lib/cjs/index.js +1 -0
- package/lib/cjs/index.js.map +1 -1
- package/lib/cjs/json.js +3 -3
- package/lib/cjs/json.js.map +1 -1
- package/lib/cjs/resolver.js +45 -0
- package/lib/cjs/resolver.js.map +1 -0
- package/lib/cjs/stream.js +11 -0
- package/lib/cjs/stream.js.map +1 -0
- package/lib/cjs/types.js.map +1 -1
- package/lib/cjs/validation.js +43 -6
- package/lib/cjs/validation.js.map +1 -1
- package/lib/esm/CompletionStream.js +6 -8
- package/lib/esm/CompletionStream.js.map +1 -1
- package/lib/esm/Driver.js +19 -15
- package/lib/esm/Driver.js.map +1 -1
- package/lib/esm/async.js +4 -1
- package/lib/esm/async.js.map +1 -1
- package/lib/esm/formatters/claude.js +52 -13
- package/lib/esm/formatters/claude.js.map +1 -1
- package/lib/esm/formatters/commons.js +1 -1
- package/lib/esm/formatters/commons.js.map +1 -1
- package/lib/esm/formatters/index.js +2 -1
- package/lib/esm/formatters/index.js.map +1 -1
- package/lib/esm/formatters/llama3.js +39 -0
- package/lib/esm/formatters/llama3.js.map +1 -0
- package/lib/esm/formatters/openai.js +57 -3
- package/lib/esm/formatters/openai.js.map +1 -1
- package/lib/esm/index.js +1 -0
- package/lib/esm/index.js.map +1 -1
- package/lib/esm/resolver.js +42 -0
- package/lib/esm/resolver.js.map +1 -0
- package/lib/esm/stream.js +8 -0
- package/lib/esm/stream.js.map +1 -0
- package/lib/esm/types.js.map +1 -1
- package/lib/esm/validation.js +38 -4
- package/lib/esm/validation.js.map +1 -1
- package/lib/types/CompletionStream.d.ts +5 -5
- package/lib/types/CompletionStream.d.ts.map +1 -1
- package/lib/types/Driver.d.ts +5 -5
- package/lib/types/Driver.d.ts.map +1 -1
- package/lib/types/async.d.ts +1 -1
- package/lib/types/async.d.ts.map +1 -1
- package/lib/types/formatters/claude.d.ts +12 -6
- package/lib/types/formatters/claude.d.ts.map +1 -1
- package/lib/types/formatters/index.d.ts +2 -1
- package/lib/types/formatters/index.d.ts.map +1 -1
- package/lib/types/formatters/llama3.d.ts +7 -0
- package/lib/types/formatters/llama3.d.ts.map +1 -0
- package/lib/types/formatters/openai.d.ts +18 -1
- package/lib/types/formatters/openai.d.ts.map +1 -1
- package/lib/types/index.d.ts +1 -0
- package/lib/types/index.d.ts.map +1 -1
- package/lib/types/resolver.d.ts +2 -0
- package/lib/types/resolver.d.ts.map +1 -0
- package/lib/types/stream.d.ts +2 -0
- package/lib/types/stream.d.ts.map +1 -0
- package/lib/types/types.d.ts +9 -6
- package/lib/types/types.d.ts.map +1 -1
- package/lib/types/validation.d.ts +1 -2
- package/lib/types/validation.d.ts.map +1 -1
- package/package.json +87 -85
- package/src/CompletionStream.ts +4 -10
- package/src/Driver.ts +28 -27
- package/src/async.ts +5 -1
- package/src/formatters/claude.ts +68 -19
- package/src/formatters/commons.ts +1 -1
- package/src/formatters/index.ts +5 -3
- package/src/formatters/llama3.ts +55 -0
- package/src/formatters/openai.ts +93 -6
- package/src/index.ts +2 -1
- package/src/resolver.ts +39 -0
- package/src/stream.ts +8 -0
- package/src/types.ts +16 -13
- package/src/validation.ts +48 -7
package/src/formatters/openai.ts
CHANGED
|
@@ -1,19 +1,41 @@
|
|
|
1
1
|
import { PromptRole } from "../index.js";
|
|
2
|
+
import { readStreamAsBase64 } from "../stream.js";
|
|
2
3
|
import { PromptSegment } from "../types.js";
|
|
3
4
|
|
|
5
|
+
|
|
4
6
|
export interface OpenAITextMessage {
|
|
5
7
|
content: string;
|
|
6
8
|
role: "system" | "user" | "assistant";
|
|
7
9
|
}
|
|
10
|
+
|
|
11
|
+
export interface OpenAIMessage {
|
|
12
|
+
content: (OpenAIContentPartText | OpenAIContentPartImage)[]
|
|
13
|
+
role: "system" | "user" | "assistant";
|
|
14
|
+
name?: string;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface OpenAIContentPartText {
|
|
18
|
+
type: "text";
|
|
19
|
+
text: string
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export interface OpenAIContentPartImage {
|
|
23
|
+
type: "image_url";
|
|
24
|
+
image_url: {
|
|
25
|
+
detail?: 'auto' | 'low' | 'high'
|
|
26
|
+
url: string
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
8
30
|
/**
|
|
9
31
|
* OpenAI text only prompts
|
|
10
|
-
* @param segments
|
|
11
|
-
* @returns
|
|
32
|
+
* @param segments
|
|
33
|
+
* @returns
|
|
12
34
|
*/
|
|
13
|
-
export function
|
|
35
|
+
export function formatOpenAILikeTextPrompt(segments: PromptSegment[]): OpenAITextMessage[] {
|
|
14
36
|
const system: OpenAITextMessage[] = [];
|
|
15
|
-
const others: OpenAITextMessage[] = [];
|
|
16
37
|
const safety: OpenAITextMessage[] = [];
|
|
38
|
+
const user: OpenAITextMessage[] = [];
|
|
17
39
|
|
|
18
40
|
for (const msg of segments) {
|
|
19
41
|
if (msg.role === PromptRole.system) {
|
|
@@ -21,10 +43,75 @@ export function formatOpenAILikePrompt(segments: PromptSegment[]) {
|
|
|
21
43
|
} else if (msg.role === PromptRole.safety) {
|
|
22
44
|
safety.push({ content: "IMPORTANT: " + msg.content, role: "system" });
|
|
23
45
|
} else {
|
|
24
|
-
|
|
46
|
+
user.push({
|
|
47
|
+
content: msg.content,
|
|
48
|
+
role: msg.role || 'user',
|
|
49
|
+
})
|
|
25
50
|
}
|
|
26
51
|
}
|
|
27
52
|
|
|
28
53
|
// put system mesages first and safety last
|
|
29
|
-
return system.concat(
|
|
54
|
+
return system.concat(user).concat(safety);
|
|
30
55
|
}
|
|
56
|
+
|
|
57
|
+
export async function formatOpenAILikeMultimodalPrompt(segments: PromptSegment[]): Promise<OpenAIMessage[]> {
|
|
58
|
+
const system: OpenAIMessage[] = [];
|
|
59
|
+
const safety: OpenAIMessage[] = [];
|
|
60
|
+
const others: OpenAIMessage[] = [];
|
|
61
|
+
|
|
62
|
+
for (const msg of segments) {
|
|
63
|
+
|
|
64
|
+
const parts: (OpenAIContentPartImage | OpenAIContentPartText)[] = [];
|
|
65
|
+
|
|
66
|
+
//generate the parts based on promptsegment
|
|
67
|
+
if (msg.files) {
|
|
68
|
+
for (const file of msg.files) {
|
|
69
|
+
const stream = await file.getStream();
|
|
70
|
+
const data = await readStreamAsBase64(stream);
|
|
71
|
+
parts.push({
|
|
72
|
+
image_url: { url: `data:${file.mime_type || "image/jpeg"};base64,${data}` },
|
|
73
|
+
type: "image_url"
|
|
74
|
+
})
|
|
75
|
+
}
|
|
76
|
+
} else {
|
|
77
|
+
parts.push({
|
|
78
|
+
text: msg.content,
|
|
79
|
+
type: "text"
|
|
80
|
+
})
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
if (msg.role === PromptRole.system) {
|
|
86
|
+
system.push({
|
|
87
|
+
role: "system",
|
|
88
|
+
content: parts
|
|
89
|
+
})
|
|
90
|
+
|
|
91
|
+
} else if (msg.role === PromptRole.safety) {
|
|
92
|
+
const safetyMsg: OpenAIMessage = {
|
|
93
|
+
role: "system",
|
|
94
|
+
content: parts
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
safetyMsg.content.forEach(c => {
|
|
98
|
+
if (c.type === "text") c.text = "DO NOT IGNORE - IMPORTANT: " + c.text;
|
|
99
|
+
})
|
|
100
|
+
|
|
101
|
+
system.push(safetyMsg)
|
|
102
|
+
|
|
103
|
+
} else {
|
|
104
|
+
others.push({
|
|
105
|
+
role: msg.role ?? 'user',
|
|
106
|
+
content: parts
|
|
107
|
+
})
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// put system mesages first and safety last
|
|
115
|
+
return system.concat(others).concat(safety);
|
|
116
|
+
|
|
117
|
+
}
|
package/src/index.ts
CHANGED
package/src/resolver.ts
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Get the property named by "name" of the given object
|
|
3
|
+
* If an array is idnexed using a string key then a map is done and an array with the content of the properties with that name are returned
|
|
4
|
+
* Ex: docs.text => will return an array of text properties of the docs array
|
|
5
|
+
* @param object the obejct
|
|
6
|
+
* @param name the name of the property.
|
|
7
|
+
* @returns the property value
|
|
8
|
+
*/
|
|
9
|
+
function _prop(object: any, name: string) {
|
|
10
|
+
if (object === undefined) {
|
|
11
|
+
return undefined;
|
|
12
|
+
}
|
|
13
|
+
if (Array.isArray(object)) {
|
|
14
|
+
const index = +name;
|
|
15
|
+
if (isNaN(index)) {
|
|
16
|
+
// map array to property
|
|
17
|
+
return object.map(item => item[name]);
|
|
18
|
+
} else {
|
|
19
|
+
return object[index];
|
|
20
|
+
}
|
|
21
|
+
} else {
|
|
22
|
+
return object[name];
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function resolveField(object: any, path: string[]) {
|
|
28
|
+
let p = object as any;
|
|
29
|
+
if (!p) return p;
|
|
30
|
+
if (!path.length) return p;
|
|
31
|
+
const last = path.length - 1;
|
|
32
|
+
for (let i = 0; i < last; i++) {
|
|
33
|
+
p = _prop(p, path[i])
|
|
34
|
+
if (!p) {
|
|
35
|
+
return undefined;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return _prop(p, path[last]);
|
|
39
|
+
}
|
package/src/stream.ts
ADDED
package/src/types.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { JSONSchema4 } from "json-schema";
|
|
2
|
-
import { JSONObject } from "./json.js";
|
|
3
2
|
import { PromptFormatter } from "./formatters/index.js";
|
|
3
|
+
import { JSONObject } from "./json.js";
|
|
4
4
|
|
|
5
5
|
export interface EmbeddingsOptions {
|
|
6
6
|
/**
|
|
@@ -12,7 +12,7 @@ export interface EmbeddingsOptions {
|
|
|
12
12
|
*/
|
|
13
13
|
model?: string;
|
|
14
14
|
/**
|
|
15
|
-
* Additional options for the embeddings generation. Optional.
|
|
15
|
+
* Additional options for the embeddings generation. Optional.
|
|
16
16
|
* The supported properties depends on the target implementation.
|
|
17
17
|
*/
|
|
18
18
|
[key: string]: any;
|
|
@@ -44,7 +44,7 @@ export interface ResultValidationError {
|
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
export interface Completion<ResultT = any> {
|
|
47
|
-
// the driver impl must return the result and optionally the token_usage. the execution time is computed by the extended abstract driver
|
|
47
|
+
// the driver impl must return the result and optionally the token_usage. the execution time is computed by the extended abstract driver
|
|
48
48
|
result: ResultT;
|
|
49
49
|
token_usage?: ExecutionTokenUsage;
|
|
50
50
|
|
|
@@ -55,7 +55,7 @@ export interface Completion<ResultT = any> {
|
|
|
55
55
|
|
|
56
56
|
/**
|
|
57
57
|
* Set only if a result validation error occured, otherwise if the result is valid the error field is undefined
|
|
58
|
-
* This can only be set if the
|
|
58
|
+
* This can only be set if the result_schema is set and the reuslt could not be parsed as a json or if the result does not match the schema
|
|
59
59
|
*/
|
|
60
60
|
error?: ResultValidationError;
|
|
61
61
|
|
|
@@ -93,18 +93,18 @@ export interface DriverOptions {
|
|
|
93
93
|
export interface PromptOptions {
|
|
94
94
|
model: string;
|
|
95
95
|
/**
|
|
96
|
-
* A custom formatter to use for format the final model prompt from the input prompt segments.
|
|
96
|
+
* A custom formatter to use for format the final model prompt from the input prompt segments.
|
|
97
97
|
* If no one is specified the driver will choose a formatter compatible with the target model
|
|
98
98
|
*/
|
|
99
99
|
format?: PromptFormatter;
|
|
100
|
-
|
|
100
|
+
result_schema?: JSONSchema4;
|
|
101
101
|
}
|
|
102
102
|
export interface ExecutionOptions extends PromptOptions {
|
|
103
103
|
temperature?: number;
|
|
104
104
|
max_tokens?: number;
|
|
105
105
|
stop_sequence?: string | string[];
|
|
106
106
|
|
|
107
|
-
/**
|
|
107
|
+
/**
|
|
108
108
|
* restricts the selection of tokens to the “k” most likely options, based on their probabilities
|
|
109
109
|
* Lower values make the model more deterministic, more focused. Examples:
|
|
110
110
|
* - 10 - result will be highly controlled anc contextually relevant
|
|
@@ -139,7 +139,7 @@ export interface ExecutionOptions extends PromptOptions {
|
|
|
139
139
|
|
|
140
140
|
/**
|
|
141
141
|
* If set to true the original response from the target LLM will be included in the response under the original_response field.
|
|
142
|
-
* This is useful for debugging and for some advanced use cases.
|
|
142
|
+
* This is useful for debugging and for some advanced use cases.
|
|
143
143
|
* It is ignored on streaming requests
|
|
144
144
|
*/
|
|
145
145
|
include_original_response?: boolean;
|
|
@@ -156,6 +156,7 @@ export enum PromptRole {
|
|
|
156
156
|
export interface PromptSegment {
|
|
157
157
|
role: PromptRole;
|
|
158
158
|
content: string;
|
|
159
|
+
files?: DataSource[]
|
|
159
160
|
}
|
|
160
161
|
|
|
161
162
|
export interface ExecutionTokenUsage {
|
|
@@ -177,8 +178,9 @@ export interface AIModel<ProviderKeys = string> {
|
|
|
177
178
|
tags?: string[]; //tags for searching
|
|
178
179
|
owner?: string; //owner of the model
|
|
179
180
|
status?: AIModelStatus; //status of the model
|
|
180
|
-
|
|
181
|
-
|
|
181
|
+
can_stream?: boolean; //if the model's reponse can be streamed
|
|
182
|
+
is_custom?: boolean; //if the model is a custom model (a trained model)
|
|
183
|
+
is_multimodal?: boolean //if the model support files and images
|
|
182
184
|
}
|
|
183
185
|
|
|
184
186
|
export enum AIModelStatus {
|
|
@@ -231,20 +233,21 @@ export enum ModelType {
|
|
|
231
233
|
|
|
232
234
|
export interface DataSource {
|
|
233
235
|
name: string;
|
|
234
|
-
|
|
236
|
+
mime_type?: string;
|
|
237
|
+
getStream(): Promise<ReadableStream<Uint8Array | string>>;
|
|
235
238
|
getURL(): Promise<string>;
|
|
236
239
|
}
|
|
237
240
|
|
|
238
241
|
export interface TrainingOptions {
|
|
239
242
|
name: string; // the new model name
|
|
240
|
-
model: string; // the model to train
|
|
243
|
+
model: string; // the model to train
|
|
241
244
|
params?: JSONObject; // the training parameters
|
|
242
245
|
}
|
|
243
246
|
|
|
244
247
|
export interface TrainingPromptOptions {
|
|
245
248
|
segments: PromptSegment[];
|
|
246
249
|
completion: string | JSONObject;
|
|
247
|
-
model: string; // the model to train
|
|
250
|
+
model: string; // the model to train
|
|
248
251
|
schema?: JSONSchema4; // the resuilt schema f any
|
|
249
252
|
}
|
|
250
253
|
|
package/src/validation.ts
CHANGED
|
@@ -1,7 +1,23 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Ajv } from 'ajv';
|
|
2
|
+
import addFormats from 'ajv-formats';
|
|
2
3
|
import { extractAndParseJSON } from "./json.js";
|
|
4
|
+
import { resolveField } from './resolver.js';
|
|
3
5
|
import { ResultValidationError } from "./types.js";
|
|
4
6
|
|
|
7
|
+
|
|
8
|
+
const ajv = new Ajv({
|
|
9
|
+
coerceTypes: 'array',
|
|
10
|
+
allowDate: true,
|
|
11
|
+
strict: false,
|
|
12
|
+
useDefaults: true,
|
|
13
|
+
removeAdditional: "failing"
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
//use ts ignore to avoid error with ESM and ajv-formats
|
|
17
|
+
// @ts-ignore This expression is not callable
|
|
18
|
+
addFormats(ajv)
|
|
19
|
+
|
|
20
|
+
|
|
5
21
|
export class ValidationError extends Error implements ResultValidationError {
|
|
6
22
|
constructor(
|
|
7
23
|
public code: 'validation_error' | 'json_error',
|
|
@@ -12,8 +28,9 @@ export class ValidationError extends Error implements ResultValidationError {
|
|
|
12
28
|
}
|
|
13
29
|
}
|
|
14
30
|
|
|
15
|
-
export function validateResult(data: any, schema:
|
|
31
|
+
export function validateResult(data: any, schema: Object) {
|
|
16
32
|
let json;
|
|
33
|
+
|
|
17
34
|
if (typeof data === "string") {
|
|
18
35
|
try {
|
|
19
36
|
json = extractAndParseJSON(data);
|
|
@@ -23,11 +40,35 @@ export function validateResult(data: any, schema: JSONSchema4) {
|
|
|
23
40
|
} else {
|
|
24
41
|
json = data;
|
|
25
42
|
}
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
43
|
+
|
|
44
|
+
const validate = ajv.compile(schema);
|
|
45
|
+
const valid = validate(json);
|
|
46
|
+
|
|
47
|
+
if (!valid && validate.errors) {
|
|
48
|
+
let errors = [];
|
|
49
|
+
|
|
50
|
+
for (const e of validate.errors) {
|
|
51
|
+
const path = e.instancePath.split("/").slice(1);
|
|
52
|
+
const value = resolveField(json, path);
|
|
53
|
+
const schemaPath = e.schemaPath.split("/").slice(1);
|
|
54
|
+
const schemaFieldFormat = resolveField(schema, schemaPath);
|
|
55
|
+
const schemaField = resolveField(schema, schemaPath.slice(0, -3));
|
|
56
|
+
|
|
57
|
+
//ignore date if empty or null
|
|
58
|
+
if (!value
|
|
59
|
+
&& ["date", "date-time"].includes(schemaFieldFormat)
|
|
60
|
+
&& !schemaField?.required?.includes(path[path.length - 1])) {
|
|
61
|
+
continue;
|
|
62
|
+
} else {
|
|
63
|
+
errors.push(e);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
//console.log("Errors", errors)
|
|
68
|
+
if (errors.length > 0) {
|
|
69
|
+
const errorsMessage = errors.map(e => `${e.instancePath}: ${e.message}\n${JSON.stringify(e.params)}`).join(",\n\n");
|
|
70
|
+
throw new ValidationError("validation_error", errorsMessage)
|
|
71
|
+
}
|
|
31
72
|
}
|
|
32
73
|
|
|
33
74
|
return json;
|