@llumiverse/core 0.10.0 → 0.11.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.
Files changed (88) hide show
  1. package/README.md +1 -7
  2. package/lib/cjs/CompletionStream.js +1 -7
  3. package/lib/cjs/CompletionStream.js.map +1 -1
  4. package/lib/cjs/Driver.js +16 -2
  5. package/lib/cjs/Driver.js.map +1 -1
  6. package/lib/cjs/formatters/claude.js +5 -7
  7. package/lib/cjs/formatters/claude.js.map +1 -1
  8. package/lib/cjs/formatters/commons.js +8 -0
  9. package/lib/cjs/formatters/commons.js.map +1 -0
  10. package/lib/cjs/formatters/generic.js +52 -20
  11. package/lib/cjs/formatters/generic.js.map +1 -1
  12. package/lib/cjs/formatters/index.js +18 -27
  13. package/lib/cjs/formatters/index.js.map +1 -1
  14. package/lib/cjs/formatters/llama2.js +3 -3
  15. package/lib/cjs/formatters/llama2.js.map +1 -1
  16. package/lib/cjs/formatters/openai.js +9 -4
  17. package/lib/cjs/formatters/openai.js.map +1 -1
  18. package/lib/cjs/formatters.js +117 -0
  19. package/lib/cjs/formatters.js.map +1 -0
  20. package/lib/cjs/index.js +0 -1
  21. package/lib/cjs/index.js.map +1 -1
  22. package/lib/cjs/test.js +55 -0
  23. package/lib/cjs/test.js.map +1 -0
  24. package/lib/cjs/types.js +1 -8
  25. package/lib/cjs/types.js.map +1 -1
  26. package/lib/esm/CompletionStream.js +1 -7
  27. package/lib/esm/CompletionStream.js.map +1 -1
  28. package/lib/esm/Driver.js +17 -3
  29. package/lib/esm/Driver.js.map +1 -1
  30. package/lib/esm/formatters/claude.js +3 -5
  31. package/lib/esm/formatters/claude.js.map +1 -1
  32. package/lib/esm/formatters/commons.js +4 -0
  33. package/lib/esm/formatters/commons.js.map +1 -0
  34. package/lib/esm/formatters/generic.js +50 -18
  35. package/lib/esm/formatters/generic.js.map +1 -1
  36. package/lib/esm/formatters/index.js +5 -26
  37. package/lib/esm/formatters/index.js.map +1 -1
  38. package/lib/esm/formatters/llama2.js +1 -1
  39. package/lib/esm/formatters/llama2.js.map +1 -1
  40. package/lib/esm/formatters/openai.js +7 -2
  41. package/lib/esm/formatters/openai.js.map +1 -1
  42. package/lib/esm/formatters.js +113 -0
  43. package/lib/esm/formatters.js.map +1 -0
  44. package/lib/esm/index.js +0 -1
  45. package/lib/esm/index.js.map +1 -1
  46. package/lib/esm/test.js +50 -0
  47. package/lib/esm/test.js.map +1 -0
  48. package/lib/esm/types.js +0 -7
  49. package/lib/esm/types.js.map +1 -1
  50. package/lib/tsconfig.tsbuildinfo +1 -0
  51. package/lib/types/CompletionStream.d.ts +1 -2
  52. package/lib/types/CompletionStream.d.ts.map +1 -1
  53. package/lib/types/Driver.d.ts +8 -2
  54. package/lib/types/Driver.d.ts.map +1 -1
  55. package/lib/types/formatters/claude.d.ts +1 -1
  56. package/lib/types/formatters/claude.d.ts.map +1 -1
  57. package/lib/types/formatters/commons.d.ts +3 -0
  58. package/lib/types/formatters/commons.d.ts.map +1 -0
  59. package/lib/types/formatters/generic.d.ts +9 -4
  60. package/lib/types/formatters/generic.d.ts.map +1 -1
  61. package/lib/types/formatters/index.d.ts +7 -3
  62. package/lib/types/formatters/index.d.ts.map +1 -1
  63. package/lib/types/formatters/llama2.d.ts +1 -1
  64. package/lib/types/formatters/llama2.d.ts.map +1 -1
  65. package/lib/types/formatters/openai.d.ts +10 -2
  66. package/lib/types/formatters/openai.d.ts.map +1 -1
  67. package/lib/types/formatters.d.ts +5 -0
  68. package/lib/types/formatters.d.ts.map +1 -0
  69. package/lib/types/index.d.ts +0 -1
  70. package/lib/types/index.d.ts.map +1 -1
  71. package/lib/types/json.d.ts +8 -8
  72. package/lib/types/json.d.ts.map +1 -1
  73. package/lib/types/test.d.ts +2 -0
  74. package/lib/types/test.d.ts.map +1 -0
  75. package/lib/types/types.d.ts +10 -13
  76. package/lib/types/types.d.ts.map +1 -1
  77. package/package.json +15 -5
  78. package/src/CompletionStream.ts +1 -8
  79. package/src/Driver.ts +17 -8
  80. package/src/formatters/claude.ts +3 -6
  81. package/src/formatters/commons.ts +5 -0
  82. package/src/formatters/generic.ts +59 -27
  83. package/src/formatters/index.ts +7 -30
  84. package/src/formatters/llama2.ts +1 -1
  85. package/src/formatters/openai.ts +14 -6
  86. package/src/index.ts +0 -1
  87. package/src/json.ts +7 -7
  88. package/src/types.ts +11 -13
@@ -60,7 +60,6 @@ export class DefaultCompletionStream<PromptT = any> implements CompletionStream<
60
60
  export class FallbackCompletionStream<PromptT = any> implements CompletionStream<PromptT> {
61
61
 
62
62
  prompt: PromptT;
63
- chunks: string[];
64
63
  completion: ExecutionResponse<PromptT> | undefined;
65
64
 
66
65
  constructor(public driver: AbstractDriver<DriverOptions, PromptT>,
@@ -68,22 +67,16 @@ export class FallbackCompletionStream<PromptT = any> implements CompletionStream
68
67
  public options: ExecutionOptions) {
69
68
  this.driver = driver;
70
69
  this.prompt = this.driver.createPrompt(segments, options);
71
- this.chunks = [];
72
70
  }
73
71
 
74
72
  async *[Symbol.asyncIterator]() {
75
73
  // reset state
76
74
  this.completion = undefined;
77
- if (this.chunks.length > 0) {
78
- this.chunks = [];
79
- }
80
75
  this.driver.logger.debug(
81
76
  `[${this.driver.provider}] Streaming is not supported, falling back to blocking execution`
82
77
  );
83
78
  const completion = await this.driver._execute(this.prompt, this.options);
84
-
85
- const content = completion.result === 'string' ? completion.result : JSON.stringify(completion.result);
86
- this.chunks.push(content);
79
+ const content = typeof completion.result === 'string' ? completion.result : JSON.stringify(completion.result);
87
80
  yield content;
88
81
 
89
82
  this.completion = completion;
package/src/Driver.ts CHANGED
@@ -5,7 +5,7 @@
5
5
  */
6
6
 
7
7
  import { DefaultCompletionStream, FallbackCompletionStream } from "./CompletionStream.js";
8
- import { PromptFormatters } from "./formatters/index.js";
8
+ import { formatLlama2Prompt, formatTextPrompt } from "./formatters/index.js";
9
9
  import {
10
10
  AIModel,
11
11
  Completion,
@@ -18,7 +18,6 @@ import {
18
18
  ExecutionResponse,
19
19
  Logger,
20
20
  ModelSearchPayload,
21
- PromptFormats,
22
21
  PromptOptions,
23
22
  PromptSegment,
24
23
  TrainingJob,
@@ -54,7 +53,7 @@ export function createLogger(logger: Logger | "console" | undefined) {
54
53
 
55
54
  function applyExecutionDefaults(options: ExecutionOptions): ExecutionOptions {
56
55
  return {
57
- max_tokens: 1024,
56
+ max_tokens: 4096,
58
57
  temperature: 0.7,
59
58
  ...options
60
59
  }
@@ -106,7 +105,6 @@ export abstract class AbstractDriver<OptionsT extends DriverOptions = DriverOpti
106
105
  logger: Logger;
107
106
 
108
107
  abstract provider: string; // the provider name
109
- abstract defaultFormat: PromptFormats;
110
108
 
111
109
  constructor(opts: OptionsT) {
112
110
  this.options = opts;
@@ -181,11 +179,22 @@ export abstract class AbstractDriver<OptionsT extends DriverOptions = DriverOpti
181
179
  }
182
180
  }
183
181
 
182
+ /**
183
+ * Override this method to provide a custom prompt formatter
184
+ * @param segments
185
+ * @param options
186
+ * @returns
187
+ */
188
+ protected formatPrompt(segments: PromptSegment[], opts: PromptOptions): PromptT {
189
+ if (/\bllama2?\b/i.test(opts.model)) {
190
+ return formatLlama2Prompt(segments, opts.resultSchema) as PromptT;
191
+ } else {
192
+ return formatTextPrompt(segments, opts.resultSchema) as PromptT;
193
+ }
194
+ }
195
+
184
196
  public createPrompt(segments: PromptSegment[], opts: PromptOptions): PromptT {
185
- return PromptFormatters[opts.format || this.defaultFormat](
186
- segments,
187
- opts.resultSchema
188
- );
197
+ return opts.format ? opts.format(segments, opts.resultSchema) : this.formatPrompt(segments, opts);
189
198
  }
190
199
 
191
200
  /**
@@ -1,5 +1,6 @@
1
1
  import { JSONSchema4 } from "json-schema";
2
2
  import { PromptRole, PromptSegment } from "../index.js";
3
+ import { getJSONSafetyNotice } from "./commons.js";
3
4
 
4
5
  export interface ClaudeMessage {
5
6
  role: 'user' | 'assistant',
@@ -19,7 +20,7 @@ export interface ClaudeMessagesPrompt {
19
20
  * A formatter user by Bedrock to format prompts for claude related models
20
21
  */
21
22
 
22
- export function claudeMessages(segments: PromptSegment[], schema?: JSONSchema4): ClaudeMessagesPrompt {
23
+ export function formatClaudePrompt(segments: PromptSegment[], schema?: JSONSchema4): ClaudeMessagesPrompt {
23
24
  const system: string[] = [];
24
25
  const safety: string[] = [];
25
26
  const messages: ClaudeMessage[] = [];
@@ -35,13 +36,9 @@ export function claudeMessages(segments: PromptSegment[], schema?: JSONSchema4):
35
36
  }
36
37
 
37
38
  if (schema) {
38
- safety.push(`You must answer using the following JSONSchema:
39
- ---
40
- ${JSON.stringify(schema)}
41
- ---`);
39
+ safety.push(getJSONSafetyNotice(schema));
42
40
  }
43
41
 
44
-
45
42
  // messages must contains at least 1 item. If the prompt doesn;t contains a user message (but only system messages)
46
43
  // we need to put the system messages in the messages array
47
44
 
@@ -0,0 +1,5 @@
1
+ import { JSONSchema4 } from "json-schema";
2
+
3
+ export function getJSONSafetyNotice(schema: JSONSchema4) {
4
+ return "The answer must be a JSON object using the following JSON Schema:\n" + JSON.stringify(schema);
5
+ }
@@ -1,34 +1,66 @@
1
1
  import { JSONSchema4 } from "json-schema";
2
- import { PromptRole, PromptSegment } from "../index.js";
2
+ import { PromptRole, PromptSegment } from "../types.js";
3
+ import { getJSONSafetyNotice } from "./commons.js";
3
4
 
4
- export function genericColonSeparator(
5
- messages: PromptSegment[],
6
- schema?: JSONSchema4,
7
- labels: {
8
- user: string;
9
- assistant: string;
10
- system: string;
11
- } = { user: "User", assistant: "Assistant", system: "System" }
12
- ) {
13
- const promptMessages = [];
14
- for (const m of messages) {
15
- if (m.role === PromptRole.user) {
16
- promptMessages.push(`${labels?.user}: ${m.content.trim()}`);
17
- }
18
- if (m.role === PromptRole.assistant) {
19
- promptMessages.push(`${labels.assistant}: ${m.content.trim()}`);
5
+ interface Labels {
6
+ user: string,
7
+ system: string,
8
+ assistant: string,
9
+ safety: string,
10
+ instruction: string
11
+ }
12
+
13
+ export function createTextPromptFormatter(labels: Labels = {
14
+ user: "USER",
15
+ system: "CONTEXT",
16
+ assistant: "ASSISTANT",
17
+ safety: "IMPORTANT",
18
+ instruction: "INSTRUCTION"
19
+ }) {
20
+ return function genericTextPrompt(segments: PromptSegment[], schema?: JSONSchema4): string {
21
+ const isChat = segments.find(m => m.role === PromptRole.assistant);
22
+ const context: string[] = [];
23
+ const content: string[] = [];
24
+ const safety: string[] = [];
25
+ for (const segment of segments) {
26
+ switch (segment.role) {
27
+ case PromptRole.user:
28
+ if (isChat) {
29
+ content.push(`${labels.user}: ${segment.content}`);
30
+ } else {
31
+ content.push(segment.content);
32
+ }
33
+ break;
34
+ case PromptRole.assistant:
35
+ content.push(`${labels.assistant}: ${segment.content}`);
36
+ break;
37
+ case PromptRole.system:
38
+ context.push(segment.content);
39
+ break;
40
+ case PromptRole.safety:
41
+ safety.push(segment.content);
42
+ break;
43
+ }
20
44
  }
21
- if (m.role === PromptRole.system) {
22
- promptMessages.push(`${labels.system}: ${m.content.trim()}`);
45
+
46
+ if (schema) {
47
+ safety.push(getJSONSafetyNotice(schema));
23
48
  }
24
- }
25
49
 
26
- if (schema) {
27
- promptMessages.push(`${labels.system}: You must answer using the following JSONSchema:
28
- ---
29
- ${JSON.stringify(schema)}
30
- ---`);
50
+ const out = [];
51
+ if (context.length > 0) {
52
+ out.push(`${labels.system}: ${context.join('\n')}`);
53
+ }
54
+ if (content.length > 0) {
55
+ const prefix = context.length > 0 && !isChat ? `${labels.instruction}: ` : '';
56
+ out.push(prefix + content.join('\n'));
57
+ }
58
+ if (safety.length > 0) {
59
+ out.push(`${labels.safety}: ${safety.join('\n')}`);
60
+ }
61
+ return out.join('\n');
31
62
  }
32
-
33
- return promptMessages.join("\n\n");
34
63
  }
64
+
65
+ const formatTextPrompt = createTextPromptFormatter();
66
+ export { formatTextPrompt };
@@ -1,33 +1,10 @@
1
1
  import { JSONSchema4 } from "json-schema";
2
- import { genericColonSeparator } from "./generic.js";
3
- import { llama2 } from "./llama2.js";
4
- import { openAI } from "./openai.js";
5
- import {
6
- PromptFormats,
7
- PromptSegment
8
- } from "../types.js";
9
- import { claudeMessages } from "./claude.js";
2
+ import { PromptSegment } from "../types.js";
10
3
 
11
- export function inferFormatterFromModelName(modelName: string): PromptFormats {
12
- const name = modelName.toLowerCase();
13
- if (name.includes("llama")) {
14
- return PromptFormats.llama2;
15
- } else if (name.includes("gpt")) {
16
- return PromptFormats.openai;
17
- } else if (name.includes("claude")) {
18
- return PromptFormats.claude;
19
- } else {
20
- return PromptFormats.genericTextLLM;
21
- }
22
- }
23
-
24
- export const PromptFormatters: Record<
25
- PromptFormats,
26
- (messages: PromptSegment[], schema?: JSONSchema4) => any
27
- > = {
28
- openai: openAI,
29
- llama2: llama2,
30
- claude: claudeMessages,
31
- genericTextLLM: genericColonSeparator,
32
- };
4
+ export type PromptFormatter<T = any> = (messages: PromptSegment[], schema?: JSONSchema4) => T;
33
5
 
6
+ export * from "./commons.js"
7
+ export * from "./generic.js";
8
+ export * from "./llama2.js";
9
+ export * from "./claude.js";
10
+ export * from "./openai.js";
@@ -1,7 +1,7 @@
1
1
  import { JSONSchema4 } from "json-schema";
2
2
  import { PromptRole, PromptSegment } from "../index.js";
3
3
 
4
- export function llama2(messages: PromptSegment[], schema?: JSONSchema4) {
4
+ export function formatLlama2Prompt(messages: PromptSegment[], schema?: JSONSchema4) {
5
5
  const BOS = "<s>";
6
6
  const EOS = "</s>";
7
7
  const INST = "[INST]";
@@ -1,17 +1,25 @@
1
1
  import { PromptRole } from "../index.js";
2
2
  import { PromptSegment } from "../types.js";
3
- import OpenAI from "openai";
4
3
 
5
- export function openAI(segments: PromptSegment[]) {
6
- const system: OpenAI.Chat.ChatCompletionMessageParam[] = [];
7
- const others: OpenAI.Chat.ChatCompletionMessageParam[] = [];
8
- const safety: OpenAI.Chat.ChatCompletionMessageParam[] = [];
4
+ export interface OpenAITextMessage {
5
+ content: string;
6
+ role: "system" | "user" | "assistant";
7
+ }
8
+ /**
9
+ * OpenAI text only prompts
10
+ * @param segments
11
+ * @returns
12
+ */
13
+ export function formatOpenAILikePrompt(segments: PromptSegment[]) {
14
+ const system: OpenAITextMessage[] = [];
15
+ const others: OpenAITextMessage[] = [];
16
+ const safety: OpenAITextMessage[] = [];
9
17
 
10
18
  for (const msg of segments) {
11
19
  if (msg.role === PromptRole.system) {
12
20
  system.push({ content: msg.content, role: "system" });
13
21
  } else if (msg.role === PromptRole.safety) {
14
- safety.push({ content: msg.content, role: "system" });
22
+ safety.push({ content: "IMPORTANT: " + msg.content, role: "system" });
15
23
  } else {
16
24
  others.push({ content: msg.content, role: "user" });
17
25
  }
package/src/index.ts CHANGED
@@ -1,4 +1,3 @@
1
1
  export * from "./Driver.js";
2
- export * from "./formatters/index.js";
3
2
  export * from "./json.js";
4
3
  export * from "./types.js";
package/src/json.ts CHANGED
@@ -6,15 +6,15 @@ function extractJsonFromText(text: string): string {
6
6
  return text.replace(/\\n/g, "");
7
7
  }
8
8
 
9
- export function extractAndParseJSON(text: string): Json {
9
+ export function extractAndParseJSON(text: string): JSONValue {
10
10
  return parseJSON(extractJsonFromText(text));
11
11
  }
12
12
 
13
- export type JsonPrimative = string | number | boolean | null;
14
- export type JsonArray = Json[];
15
- export type JsonObject = { [key: string]: Json };
16
- export type JsonComposite = JsonArray | JsonObject;
17
- export type Json = JsonPrimative | JsonComposite;
13
+ export type JSONPrimitive = string | number | boolean | null;
14
+ export type JSONArray = JSONValue[];
15
+ export type JSONObject = { [key: string]: JSONValue };
16
+ export type JSONComposite = JSONArray | JSONObject;
17
+ export type JSONValue = JSONPrimitive | JSONComposite;
18
18
 
19
19
 
20
20
 
@@ -184,7 +184,7 @@ export class JsonParser {
184
184
  }
185
185
 
186
186
 
187
- export function parseJSON(text: string): Json {
187
+ export function parseJSON(text: string): JSONValue {
188
188
  text = text.trim();
189
189
  try {
190
190
  return JSON.parse(text);
package/src/types.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { JSONSchema4 } from "json-schema";
2
- import { Readable } from "stream";
3
- import { JsonObject } from "./json.js";
2
+ import { JSONObject } from "./json.js";
3
+ import { PromptFormatter } from "./formatters/index.js";
4
4
 
5
5
  export interface EmbeddingsOptions {
6
6
  /**
@@ -81,7 +81,11 @@ export interface DriverOptions {
81
81
 
82
82
  export interface PromptOptions {
83
83
  model: string;
84
- format?: PromptFormats;
84
+ /**
85
+ * A custom formatter to use for format the final model prompt from the input prompt segments.
86
+ * If no one is specified the driver will choose a formatter compatible with the target model
87
+ */
88
+ format?: PromptFormatter;
85
89
  resultSchema?: JSONSchema4;
86
90
  }
87
91
  export interface ExecutionOptions extends PromptOptions {
@@ -171,13 +175,6 @@ export enum ModelType {
171
175
  // ============== Built-in formats and drivers =====================
172
176
  //TODO
173
177
 
174
- export enum PromptFormats {
175
- openai = "openai",
176
- llama2 = "llama2",
177
- claude = "claude",
178
- genericTextLLM = "genericTextLLM",
179
- }
180
-
181
178
  export enum BuiltinProviders {
182
179
  openai = 'openai',
183
180
  huggingface_ie = 'huggingface_ie',
@@ -193,21 +190,22 @@ export enum BuiltinProviders {
193
190
  // ============== training =====================
194
191
 
195
192
 
193
+
196
194
  export interface DataSource {
197
195
  name: string;
198
- getStream(): Readable;
196
+ getStream(): ReadableStream<Uint8Array | string>;
199
197
  getURL(): Promise<string>;
200
198
  }
201
199
 
202
200
  export interface TrainingOptions {
203
201
  name: string; // the new model name
204
202
  model: string; // the model to train
205
- params?: JsonObject; // the training parameters
203
+ params?: JSONObject; // the training parameters
206
204
  }
207
205
 
208
206
  export interface TrainingPromptOptions {
209
207
  segments: PromptSegment[];
210
- completion: string | JsonObject;
208
+ completion: string | JSONObject;
211
209
  model: string; // the model to train
212
210
  schema?: JSONSchema4; // the resuilt schema f any
213
211
  }