@llumiverse/drivers 0.8.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/lib/cjs/bedrock/index.js +338 -0
- package/lib/cjs/bedrock/index.js.map +1 -0
- package/lib/cjs/bedrock/s3.js +61 -0
- package/lib/cjs/bedrock/s3.js.map +1 -0
- package/lib/cjs/huggingface_ie.js +181 -0
- package/lib/cjs/huggingface_ie.js.map +1 -0
- package/lib/cjs/index.js +24 -0
- package/lib/cjs/index.js.map +1 -0
- package/lib/cjs/openai.js +205 -0
- package/lib/cjs/openai.js.map +1 -0
- package/lib/cjs/package.json +3 -0
- package/lib/cjs/replicate.js +290 -0
- package/lib/cjs/replicate.js.map +1 -0
- package/lib/cjs/test/TestErrorCompletionStream.js +20 -0
- package/lib/cjs/test/TestErrorCompletionStream.js.map +1 -0
- package/lib/cjs/test/TestValidationErrorCompletionStream.js +24 -0
- package/lib/cjs/test/TestValidationErrorCompletionStream.js.map +1 -0
- package/lib/cjs/test/index.js +109 -0
- package/lib/cjs/test/index.js.map +1 -0
- package/lib/cjs/test/utils.js +31 -0
- package/lib/cjs/test/utils.js.map +1 -0
- package/lib/cjs/togetherai/index.js +92 -0
- package/lib/cjs/togetherai/index.js.map +1 -0
- package/lib/cjs/togetherai/interfaces.js +3 -0
- package/lib/cjs/togetherai/interfaces.js.map +1 -0
- package/lib/cjs/vertexai/debug.js +13 -0
- package/lib/cjs/vertexai/debug.js.map +1 -0
- package/lib/cjs/vertexai/index.js +80 -0
- package/lib/cjs/vertexai/index.js.map +1 -0
- package/lib/cjs/vertexai/models/codey-chat.js +65 -0
- package/lib/cjs/vertexai/models/codey-chat.js.map +1 -0
- package/lib/cjs/vertexai/models/codey-text.js +35 -0
- package/lib/cjs/vertexai/models/codey-text.js.map +1 -0
- package/lib/cjs/vertexai/models/gemini.js +140 -0
- package/lib/cjs/vertexai/models/gemini.js.map +1 -0
- package/lib/cjs/vertexai/models/palm-model-base.js +65 -0
- package/lib/cjs/vertexai/models/palm-model-base.js.map +1 -0
- package/lib/cjs/vertexai/models/palm2-chat.js +65 -0
- package/lib/cjs/vertexai/models/palm2-chat.js.map +1 -0
- package/lib/cjs/vertexai/models/palm2-text.js +35 -0
- package/lib/cjs/vertexai/models/palm2-text.js.map +1 -0
- package/lib/cjs/vertexai/models.js +93 -0
- package/lib/cjs/vertexai/models.js.map +1 -0
- package/lib/cjs/vertexai/utils/prompts.js +52 -0
- package/lib/cjs/vertexai/utils/prompts.js.map +1 -0
- package/lib/cjs/vertexai/utils/tensor.js +87 -0
- package/lib/cjs/vertexai/utils/tensor.js.map +1 -0
- package/lib/esm/bedrock/index.js +331 -0
- package/lib/esm/bedrock/index.js.map +1 -0
- package/lib/esm/bedrock/s3.js +53 -0
- package/lib/esm/bedrock/s3.js.map +1 -0
- package/lib/esm/huggingface_ie.js +177 -0
- package/lib/esm/huggingface_ie.js.map +1 -0
- package/lib/esm/index.js +8 -0
- package/lib/esm/index.js.map +1 -0
- package/lib/esm/openai.js +198 -0
- package/lib/esm/openai.js.map +1 -0
- package/lib/esm/replicate.js +283 -0
- package/lib/esm/replicate.js.map +1 -0
- package/lib/esm/test/TestErrorCompletionStream.js +16 -0
- package/lib/esm/test/TestErrorCompletionStream.js.map +1 -0
- package/lib/esm/test/TestValidationErrorCompletionStream.js +20 -0
- package/lib/esm/test/TestValidationErrorCompletionStream.js.map +1 -0
- package/lib/esm/test/index.js +91 -0
- package/lib/esm/test/index.js.map +1 -0
- package/lib/esm/test/utils.js +25 -0
- package/lib/esm/test/utils.js.map +1 -0
- package/lib/esm/togetherai/index.js +88 -0
- package/lib/esm/togetherai/index.js.map +1 -0
- package/lib/esm/togetherai/interfaces.js +2 -0
- package/lib/esm/togetherai/interfaces.js.map +1 -0
- package/lib/esm/vertexai/debug.js +6 -0
- package/lib/esm/vertexai/debug.js.map +1 -0
- package/lib/esm/vertexai/index.js +76 -0
- package/lib/esm/vertexai/index.js.map +1 -0
- package/lib/esm/vertexai/models/codey-chat.js +61 -0
- package/lib/esm/vertexai/models/codey-chat.js.map +1 -0
- package/lib/esm/vertexai/models/codey-text.js +31 -0
- package/lib/esm/vertexai/models/codey-text.js.map +1 -0
- package/lib/esm/vertexai/models/gemini.js +136 -0
- package/lib/esm/vertexai/models/gemini.js.map +1 -0
- package/lib/esm/vertexai/models/palm-model-base.js +61 -0
- package/lib/esm/vertexai/models/palm-model-base.js.map +1 -0
- package/lib/esm/vertexai/models/palm2-chat.js +61 -0
- package/lib/esm/vertexai/models/palm2-chat.js.map +1 -0
- package/lib/esm/vertexai/models/palm2-text.js +31 -0
- package/lib/esm/vertexai/models/palm2-text.js.map +1 -0
- package/lib/esm/vertexai/models.js +87 -0
- package/lib/esm/vertexai/models.js.map +1 -0
- package/lib/esm/vertexai/utils/prompts.js +47 -0
- package/lib/esm/vertexai/utils/prompts.js.map +1 -0
- package/lib/esm/vertexai/utils/tensor.js +82 -0
- package/lib/esm/vertexai/utils/tensor.js.map +1 -0
- package/lib/types/bedrock/index.d.ts +88 -0
- package/lib/types/bedrock/index.d.ts.map +1 -0
- package/lib/types/bedrock/s3.d.ts +20 -0
- package/lib/types/bedrock/s3.d.ts.map +1 -0
- package/lib/types/huggingface_ie.d.ts +36 -0
- package/lib/types/huggingface_ie.d.ts.map +1 -0
- package/lib/types/index.d.ts +8 -0
- package/lib/types/index.d.ts.map +1 -0
- package/lib/types/openai.d.ts +36 -0
- package/lib/types/openai.d.ts.map +1 -0
- package/lib/types/replicate.d.ts +52 -0
- package/lib/types/replicate.d.ts.map +1 -0
- package/lib/types/test/TestErrorCompletionStream.d.ts +9 -0
- package/lib/types/test/TestErrorCompletionStream.d.ts.map +1 -0
- package/lib/types/test/TestValidationErrorCompletionStream.d.ts +9 -0
- package/lib/types/test/TestValidationErrorCompletionStream.d.ts.map +1 -0
- package/lib/types/test/index.d.ts +27 -0
- package/lib/types/test/index.d.ts.map +1 -0
- package/lib/types/test/utils.d.ts +5 -0
- package/lib/types/test/utils.d.ts.map +1 -0
- package/lib/types/togetherai/index.d.ts +23 -0
- package/lib/types/togetherai/index.d.ts.map +1 -0
- package/lib/types/togetherai/interfaces.d.ts +81 -0
- package/lib/types/togetherai/interfaces.d.ts.map +1 -0
- package/lib/types/vertexai/debug.d.ts +2 -0
- package/lib/types/vertexai/debug.d.ts.map +1 -0
- package/lib/types/vertexai/index.d.ts +26 -0
- package/lib/types/vertexai/index.d.ts.map +1 -0
- package/lib/types/vertexai/models/codey-chat.d.ts +51 -0
- package/lib/types/vertexai/models/codey-chat.d.ts.map +1 -0
- package/lib/types/vertexai/models/codey-text.d.ts +39 -0
- package/lib/types/vertexai/models/codey-text.d.ts.map +1 -0
- package/lib/types/vertexai/models/gemini.d.ts +11 -0
- package/lib/types/vertexai/models/gemini.d.ts.map +1 -0
- package/lib/types/vertexai/models/palm-model-base.d.ts +47 -0
- package/lib/types/vertexai/models/palm-model-base.d.ts.map +1 -0
- package/lib/types/vertexai/models/palm2-chat.d.ts +61 -0
- package/lib/types/vertexai/models/palm2-chat.d.ts.map +1 -0
- package/lib/types/vertexai/models/palm2-text.d.ts +39 -0
- package/lib/types/vertexai/models/palm2-text.d.ts.map +1 -0
- package/lib/types/vertexai/models.d.ts +14 -0
- package/lib/types/vertexai/models.d.ts.map +1 -0
- package/lib/types/vertexai/utils/prompts.d.ts +20 -0
- package/lib/types/vertexai/utils/prompts.d.ts.map +1 -0
- package/lib/types/vertexai/utils/tensor.d.ts +6 -0
- package/lib/types/vertexai/utils/tensor.d.ts.map +1 -0
- package/package.json +72 -0
- package/src/bedrock/index.ts +456 -0
- package/src/bedrock/s3.ts +62 -0
- package/src/huggingface_ie.ts +269 -0
- package/src/index.ts +7 -0
- package/src/openai.ts +254 -0
- package/src/replicate.ts +333 -0
- package/src/test/TestErrorCompletionStream.ts +17 -0
- package/src/test/TestValidationErrorCompletionStream.ts +21 -0
- package/src/test/index.ts +102 -0
- package/src/test/utils.ts +28 -0
- package/src/togetherai/index.ts +105 -0
- package/src/togetherai/interfaces.ts +88 -0
- package/src/vertexai/README.md +257 -0
- package/src/vertexai/debug.ts +6 -0
- package/src/vertexai/index.ts +99 -0
- package/src/vertexai/models/codey-chat.ts +115 -0
- package/src/vertexai/models/codey-text.ts +69 -0
- package/src/vertexai/models/gemini.ts +152 -0
- package/src/vertexai/models/palm-model-base.ts +122 -0
- package/src/vertexai/models/palm2-chat.ts +119 -0
- package/src/vertexai/models/palm2-text.ts +69 -0
- package/src/vertexai/models.ts +104 -0
- package/src/vertexai/utils/prompts.ts +66 -0
- package/src/vertexai/utils/tensor.ts +82 -0
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { AIModel, Completion, ExecutionOptions, PromptOptions, PromptSegment } from "@llumiverse/core";
|
|
2
|
+
import { VertexAIDriver } from "../index.js";
|
|
3
|
+
import { ModelDefinition } from "../models.js";
|
|
4
|
+
import { PromptParamatersBase } from "../utils/prompts.js";
|
|
5
|
+
import { generateStreamingPrompt } from "../utils/tensor.js";
|
|
6
|
+
import { ServerSentEvent } from "api-fetch-client";
|
|
7
|
+
|
|
8
|
+
export interface NonStreamingPromptBase<InstanceType = any> {
|
|
9
|
+
instances: InstanceType[];
|
|
10
|
+
parameters: PromptParamatersBase;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export interface StreamingPromptBase<InputType = any> {
|
|
14
|
+
inputs: { structVal: InputType }[];
|
|
15
|
+
parameters: {
|
|
16
|
+
structVal: {
|
|
17
|
+
temperature?: { floatval: number },
|
|
18
|
+
maxOutputTokens?: { intVal: number },
|
|
19
|
+
//TODO more params
|
|
20
|
+
[key: string]: Record<string, any> | undefined
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export interface PalmResponseMetadata {
|
|
26
|
+
tokenMetadata: {
|
|
27
|
+
outputTokenCount: {
|
|
28
|
+
totalBillableCharacters: number,
|
|
29
|
+
totalTokens: number
|
|
30
|
+
},
|
|
31
|
+
inputTokenCount: {
|
|
32
|
+
totalBillableCharacters: number,
|
|
33
|
+
totalTokens: number
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
export abstract class AbstractPalmModelDefinition<NonStreamingPromptT extends NonStreamingPromptBase, StreamingPromptT extends StreamingPromptBase> implements ModelDefinition<NonStreamingPromptT | StreamingPromptT> {
|
|
40
|
+
|
|
41
|
+
abstract model: AIModel;
|
|
42
|
+
|
|
43
|
+
abstract versions?: string[];
|
|
44
|
+
|
|
45
|
+
abstract createNonStreamingPrompt(driver: VertexAIDriver, segments: PromptSegment[], options: PromptOptions): NonStreamingPromptT;
|
|
46
|
+
|
|
47
|
+
abstract extractContentFromResponse(response: any): string;
|
|
48
|
+
|
|
49
|
+
abstract extractContentFromResponseChunk(chunk: any): string;
|
|
50
|
+
|
|
51
|
+
createPrompt(driver: VertexAIDriver, segments: PromptSegment[], options: PromptOptions) {
|
|
52
|
+
return this.createNonStreamingPrompt(driver, segments, options);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
async requestCompletion(driver: VertexAIDriver, prompt: NonStreamingPromptT | StreamingPromptT, options: ExecutionOptions): Promise<Completion<any>> {
|
|
56
|
+
const nonStreamingPrompt = prompt as NonStreamingPromptT;
|
|
57
|
+
Object.assign((nonStreamingPrompt).parameters, {
|
|
58
|
+
temperature: options.temperature,
|
|
59
|
+
maxOutputTokens: options.max_tokens,
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
const response = await driver.fetchClient.post(`/publishers/google/models/${this.model.id}:predict`, {
|
|
63
|
+
payload: nonStreamingPrompt
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
const metadata = response.metadata as PalmResponseMetadata;
|
|
67
|
+
const inputTokens = metadata.tokenMetadata.inputTokenCount.totalTokens;
|
|
68
|
+
const outputTokens = metadata.tokenMetadata.outputTokenCount.totalTokens;
|
|
69
|
+
const result = this.extractContentFromResponse(response);
|
|
70
|
+
return {
|
|
71
|
+
result,
|
|
72
|
+
token_usage: {
|
|
73
|
+
prompt: inputTokens,
|
|
74
|
+
result: outputTokens,
|
|
75
|
+
total: inputTokens && outputTokens ? inputTokens + outputTokens : undefined,
|
|
76
|
+
}
|
|
77
|
+
} as Completion;
|
|
78
|
+
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
async requestCompletionStream(driver: VertexAIDriver, prompt: NonStreamingPromptT | StreamingPromptT, options: ExecutionOptions): Promise<AsyncIterable<string>> {
|
|
82
|
+
const inPrompt = prompt as NonStreamingPromptT;
|
|
83
|
+
Object.assign(inPrompt.parameters, {
|
|
84
|
+
temperature: options.temperature,
|
|
85
|
+
maxOutputTokens: options.max_tokens,
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
const path = `/publishers/google/models/${this.model.id}:serverStreamingPredict?alt=sse`;
|
|
89
|
+
|
|
90
|
+
const newPrompt = generateStreamingPrompt(inPrompt);
|
|
91
|
+
|
|
92
|
+
// we need to modify the existing prompt since it is not the final one
|
|
93
|
+
const outPrompt = prompt as StreamingPromptT;
|
|
94
|
+
delete (outPrompt as any).instances;
|
|
95
|
+
outPrompt.inputs = newPrompt.inputs;
|
|
96
|
+
outPrompt.parameters = newPrompt.parameters;
|
|
97
|
+
|
|
98
|
+
const eventStrean = await driver.fetchClient.post(path, {
|
|
99
|
+
payload: newPrompt,
|
|
100
|
+
reader: 'sse'
|
|
101
|
+
});
|
|
102
|
+
return eventStrean.pipeThrough(new ChunkTransformStream(this));
|
|
103
|
+
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
class ChunkTransformStream<NonStreamingPromptT extends NonStreamingPromptBase, StreamingPromptT extends StreamingPromptBase> extends TransformStream {
|
|
109
|
+
constructor(def: AbstractPalmModelDefinition<NonStreamingPromptT, StreamingPromptT>) {
|
|
110
|
+
super({
|
|
111
|
+
transform(event: ServerSentEvent, controller: TransformStreamDefaultController) {
|
|
112
|
+
if (event.type === 'event' && event.data) {
|
|
113
|
+
const data = JSON.parse(event.data);
|
|
114
|
+
const stringChunk = def.extractContentFromResponseChunk(data);
|
|
115
|
+
controller.enqueue(Array.isArray(stringChunk) ? stringChunk.join('') : stringChunk);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
})
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { AIModel, ModelType, PromptOptions, PromptRole, PromptSegment } from "@llumiverse/core";
|
|
2
|
+
import { VertexAIDriver } from "../index.js";
|
|
3
|
+
import { getJSONSafetyNotice } from "../utils/prompts.js";
|
|
4
|
+
import { AbstractPalmModelDefinition, NonStreamingPromptBase, PalmResponseMetadata, StreamingPromptBase } from "./palm-model-base.js";
|
|
5
|
+
|
|
6
|
+
export interface Palm2ChatMessage {
|
|
7
|
+
author: string,
|
|
8
|
+
content: string
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export type Palm2ChatPrompt = NonStreamingPromptBase<{
|
|
12
|
+
context?: string;
|
|
13
|
+
examples?: [
|
|
14
|
+
{
|
|
15
|
+
input: { content: string },
|
|
16
|
+
output: { content: string }
|
|
17
|
+
}
|
|
18
|
+
],
|
|
19
|
+
messages: Palm2ChatMessage[];
|
|
20
|
+
}>
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
export type Palm2ChatStreamingPrompt = StreamingPromptBase<{
|
|
24
|
+
messages: {
|
|
25
|
+
listVal: {
|
|
26
|
+
structVal: {
|
|
27
|
+
author: {
|
|
28
|
+
stringVal: string
|
|
29
|
+
},
|
|
30
|
+
content: {
|
|
31
|
+
stringVal: string
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}[]
|
|
35
|
+
}
|
|
36
|
+
}>
|
|
37
|
+
|
|
38
|
+
interface Palm2ChatResponsePrediction {
|
|
39
|
+
candidates: Palm2ChatMessage[],
|
|
40
|
+
safetyAttributes: {
|
|
41
|
+
scores: number[],
|
|
42
|
+
blocked: boolean,
|
|
43
|
+
categories: string[],
|
|
44
|
+
errors: number[],
|
|
45
|
+
},
|
|
46
|
+
citationMetadata: {
|
|
47
|
+
citations: any[]
|
|
48
|
+
},
|
|
49
|
+
logprobs: any,
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export interface Palm2ChatResponse {
|
|
53
|
+
predictions: Palm2ChatResponsePrediction[],
|
|
54
|
+
metadata: PalmResponseMetadata
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export class Palm2ChatDefinition extends AbstractPalmModelDefinition<Palm2ChatPrompt, Palm2ChatStreamingPrompt> {
|
|
58
|
+
versions: string[] = [];
|
|
59
|
+
model: AIModel = {
|
|
60
|
+
id: "chat-bison",
|
|
61
|
+
name: "PaLM 2 for Chat",
|
|
62
|
+
provider: "vertexai",
|
|
63
|
+
owner: "google",
|
|
64
|
+
type: ModelType.Chat,
|
|
65
|
+
canStream: true,
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
createNonStreamingPrompt(_driver: VertexAIDriver, segments: PromptSegment[], opts: PromptOptions): Palm2ChatPrompt {
|
|
69
|
+
const system: string[] = [];
|
|
70
|
+
const messages: Palm2ChatMessage[] = [];
|
|
71
|
+
const safety: string[] = [];
|
|
72
|
+
for (const segment of segments) {
|
|
73
|
+
switch (segment.role) {
|
|
74
|
+
case PromptRole.user:
|
|
75
|
+
messages.push({ author: 'user', content: segment.content });
|
|
76
|
+
break;
|
|
77
|
+
case PromptRole.assistant:
|
|
78
|
+
messages.push({ author: 'assistant', content: segment.content });
|
|
79
|
+
break;
|
|
80
|
+
case PromptRole.system:
|
|
81
|
+
system.push(segment.content);
|
|
82
|
+
break;
|
|
83
|
+
case PromptRole.safety:
|
|
84
|
+
safety.push(segment.content);
|
|
85
|
+
break;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
if (opts.resultSchema) {
|
|
90
|
+
safety.push(getJSONSafetyNotice(opts.resultSchema));
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
const context = []
|
|
94
|
+
if (system.length > 0) {
|
|
95
|
+
context.push(system.join('\n'));
|
|
96
|
+
}
|
|
97
|
+
if (safety.length > 0) {
|
|
98
|
+
context.push('IMPORTANT: ' + safety.join('\n'));
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
return {
|
|
102
|
+
instances: [{
|
|
103
|
+
context: context.length > 0 ? context.join('\n') : undefined,
|
|
104
|
+
messages
|
|
105
|
+
}],
|
|
106
|
+
parameters: {
|
|
107
|
+
// put defauilts here
|
|
108
|
+
}
|
|
109
|
+
} as Palm2ChatPrompt;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
extractContentFromResponse(response: Palm2ChatResponse): string {
|
|
113
|
+
return response.predictions[0].candidates[0].content ?? '';
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
extractContentFromResponseChunk(chunk: any): string {
|
|
117
|
+
return chunk.outputs[0]?.structVal.candidates.listVal[0].structVal.content.stringVal || ''
|
|
118
|
+
}
|
|
119
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { AIModel, ModelType, PromptOptions, PromptSegment } from "@llumiverse/core";
|
|
2
|
+
import { VertexAIDriver } from "../index.js";
|
|
3
|
+
import { getPromptAsText } from "../utils/prompts.js";
|
|
4
|
+
import { AbstractPalmModelDefinition, NonStreamingPromptBase, PalmResponseMetadata, StreamingPromptBase } from "./palm-model-base.js";
|
|
5
|
+
|
|
6
|
+
export type Palm2TextPrompt = NonStreamingPromptBase<{
|
|
7
|
+
prompt: string
|
|
8
|
+
}>
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
export type Palm2TextStreamingPrompt = StreamingPromptBase<{
|
|
12
|
+
prompt: {
|
|
13
|
+
stringVal: string
|
|
14
|
+
}
|
|
15
|
+
}>
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
interface Palm2TextResponsePrediction {
|
|
19
|
+
content: string,
|
|
20
|
+
safetyAttributes: {
|
|
21
|
+
scores: number[],
|
|
22
|
+
safetyRatings: {
|
|
23
|
+
severity: string,
|
|
24
|
+
probabilityScore: number,
|
|
25
|
+
severityScore: number,
|
|
26
|
+
category: string
|
|
27
|
+
}[]
|
|
28
|
+
},
|
|
29
|
+
citationMetadata: {
|
|
30
|
+
citations: any[]
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export interface Palm2TextResponse {
|
|
35
|
+
predictions: Palm2TextResponsePrediction[],
|
|
36
|
+
metadata: PalmResponseMetadata
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export class Palm2TextDefinition extends AbstractPalmModelDefinition<Palm2TextPrompt, Palm2TextStreamingPrompt> {
|
|
40
|
+
versions: string[] = [];
|
|
41
|
+
model: AIModel = {
|
|
42
|
+
id: "text-bison",
|
|
43
|
+
name: "PaLM 2 for Text",
|
|
44
|
+
provider: "vertexai",
|
|
45
|
+
owner: "google",
|
|
46
|
+
type: ModelType.Text,
|
|
47
|
+
canStream: true,
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
createNonStreamingPrompt(_driver: VertexAIDriver, segments: PromptSegment[], opts: PromptOptions): Palm2TextPrompt {
|
|
51
|
+
return {
|
|
52
|
+
instances: [{
|
|
53
|
+
prompt: getPromptAsText(segments, opts)
|
|
54
|
+
}],
|
|
55
|
+
parameters: {
|
|
56
|
+
// put defauilts here
|
|
57
|
+
}
|
|
58
|
+
} as Palm2TextPrompt;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
extractContentFromResponse(response: Palm2TextResponse): string {
|
|
62
|
+
return response.predictions[0].content ?? '';
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
extractContentFromResponseChunk(chunk: any): string {
|
|
66
|
+
return chunk.outputs[0]?.structVal.content.stringVal || '';
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { AIModel, Completion, ExecutionOptions, ModelType, PromptOptions, PromptSegment } from "@llumiverse/core";
|
|
2
|
+
import { GeminiModelDefinition } from "./models/gemini.js";
|
|
3
|
+
import { VertexAIDriver } from "./index.js";
|
|
4
|
+
import { Palm2TextDefinition } from "./models/palm2-text.js";
|
|
5
|
+
import { Palm2ChatDefinition } from "./models/palm2-chat.js";
|
|
6
|
+
import { CodeyChatDefinition } from "./models/codey-chat.js";
|
|
7
|
+
import { CodeyTextDefinition } from "./models/codey-text.js";
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
const Models: Record<string, ModelDefinition> = {
|
|
11
|
+
"gemini-pro": new GeminiModelDefinition(),
|
|
12
|
+
"text-bison": new Palm2TextDefinition(),
|
|
13
|
+
"chat-bison": new Palm2ChatDefinition(),
|
|
14
|
+
"code-bison": new CodeyTextDefinition(),
|
|
15
|
+
"codechat-bison": new CodeyChatDefinition(),
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface ModelDefinition<PromptT = any> {
|
|
19
|
+
model: AIModel;
|
|
20
|
+
versions?: string[]; // the versions of the model that are available. ex: ['001', '002']
|
|
21
|
+
createPrompt: (driver: VertexAIDriver, segments: PromptSegment[], options: PromptOptions) => PromptT;
|
|
22
|
+
requestCompletion: (driver: VertexAIDriver, prompt: PromptT, options: ExecutionOptions) => Promise<Completion>;
|
|
23
|
+
requestCompletionStream: (driver: VertexAIDriver, promp: PromptT, options: ExecutionOptions) => Promise<AsyncIterable<string>>;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export function getModelName(model: string) {
|
|
27
|
+
const i = model.lastIndexOf('@');
|
|
28
|
+
return i > -1 ? model.substring(0, i) : model;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export function getModelDefinition(model: string): ModelDefinition {
|
|
32
|
+
const def = Models[getModelName(model)];
|
|
33
|
+
if (!def) {
|
|
34
|
+
throw new Error(`Unknown model ${model}`);
|
|
35
|
+
}
|
|
36
|
+
return def;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export function getAIModels() {
|
|
40
|
+
return Object.values(Models).map(m => m.model);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Builtin models. VertexAI doesn't provide an API to list models. so we have to hardcode them here.
|
|
44
|
+
export const BuiltinModels: AIModel<string>[] = [
|
|
45
|
+
{
|
|
46
|
+
id: "gemini-pro",
|
|
47
|
+
name: "Gemini Pro",
|
|
48
|
+
provider: "vertexai",
|
|
49
|
+
owner: "google",
|
|
50
|
+
type: ModelType.Text,
|
|
51
|
+
},
|
|
52
|
+
{ // ChatModel.from_pretrained("chat-bison@002")
|
|
53
|
+
id: "chat-bison",
|
|
54
|
+
name: "PaLM 2 Chat Bison",
|
|
55
|
+
provider: "vertexai",
|
|
56
|
+
owner: "google",
|
|
57
|
+
type: ModelType.Chat,
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
id: "text-bison", // versions 001, 002
|
|
61
|
+
name: "PaLM 2 Text Bison",
|
|
62
|
+
provider: "vertexai",
|
|
63
|
+
owner: "google",
|
|
64
|
+
type: ModelType.Text,
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
id: "code-gecko",
|
|
68
|
+
name: "Codey for Code Completion",
|
|
69
|
+
provider: "vertexai",
|
|
70
|
+
owner: "google",
|
|
71
|
+
type: ModelType.Code,
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
id: "code-bison",
|
|
75
|
+
name: "Codey for Code Generation",
|
|
76
|
+
provider: "vertexai",
|
|
77
|
+
owner: "google",
|
|
78
|
+
type: ModelType.Code,
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
id: "codechat-bison",
|
|
82
|
+
name: "Codey for Code Chat",
|
|
83
|
+
provider: "vertexai",
|
|
84
|
+
owner: "google",
|
|
85
|
+
type: ModelType.Code,
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
id: "tablextembedding-gecko",
|
|
89
|
+
name: "Gecko Text Embeddings",
|
|
90
|
+
provider: "vertexai",
|
|
91
|
+
owner: "google",
|
|
92
|
+
type: ModelType.Embedding,
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
id: "textembedding-gecko-multilingual",
|
|
96
|
+
name: "Gecko Multilingual Text Embeddings",
|
|
97
|
+
provider: "vertexai",
|
|
98
|
+
owner: "google",
|
|
99
|
+
type: ModelType.Embedding,
|
|
100
|
+
},
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
]
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { PromptOptions, PromptRole, PromptSegment } from "@llumiverse/core";
|
|
2
|
+
import { JSONSchema4 } from "json-schema";
|
|
3
|
+
|
|
4
|
+
export interface PromptParamatersBase {
|
|
5
|
+
temperature?: number,
|
|
6
|
+
maxOutputTokens?: number,
|
|
7
|
+
topK?: number,
|
|
8
|
+
topP?: number,
|
|
9
|
+
groundingConfig?: string,
|
|
10
|
+
stopSequences?: string[],
|
|
11
|
+
candidateCount?: number,
|
|
12
|
+
logprobs?: number,
|
|
13
|
+
presencePenalty?: number,
|
|
14
|
+
frequencyPenalty?: number,
|
|
15
|
+
logitBias?: Record<string, number>,
|
|
16
|
+
seed?: number,
|
|
17
|
+
echo?: boolean
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function getJSONSafetyNotice(schema: JSONSchema4) {
|
|
21
|
+
return "The answer must be a JSON object using the following JSON Schema:\n" + JSON.stringify(schema)
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export function getPromptAsText(segments: PromptSegment[], options: PromptOptions): string {
|
|
25
|
+
const isChat = segments.find(m => m.role === PromptRole.assistant);
|
|
26
|
+
const context: string[] = [];
|
|
27
|
+
const content: string[] = [];
|
|
28
|
+
const safety: string[] = [];
|
|
29
|
+
for (const segment of segments) {
|
|
30
|
+
switch (segment.role) {
|
|
31
|
+
case PromptRole.user:
|
|
32
|
+
if (isChat) {
|
|
33
|
+
content.push('USER: ' + segment.content);
|
|
34
|
+
} else {
|
|
35
|
+
content.push(segment.content);
|
|
36
|
+
}
|
|
37
|
+
break;
|
|
38
|
+
case PromptRole.assistant:
|
|
39
|
+
content.push('ASSISTANT: ' + segment.content);
|
|
40
|
+
break;
|
|
41
|
+
case PromptRole.system:
|
|
42
|
+
context.push(segment.content);
|
|
43
|
+
break;
|
|
44
|
+
case PromptRole.safety:
|
|
45
|
+
safety.push(segment.content);
|
|
46
|
+
break;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
if (options.resultSchema) {
|
|
51
|
+
safety.push(getJSONSafetyNotice(options.resultSchema));
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const out = [];
|
|
55
|
+
if (context.length > 0) {
|
|
56
|
+
out.push('CONTEXT: ' + context.join('\n'));
|
|
57
|
+
}
|
|
58
|
+
if (content.length > 0) {
|
|
59
|
+
const prefix = context.length > 0 && !isChat ? 'INSTRUCTION: ' : '';
|
|
60
|
+
out.push(prefix + content.join('\n'));
|
|
61
|
+
}
|
|
62
|
+
if (safety.length > 0) {
|
|
63
|
+
out.push('IMPORTANT: ' + safety.join('\n'));
|
|
64
|
+
}
|
|
65
|
+
return out.join('\n');
|
|
66
|
+
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
function getTensorType(val: any) {
|
|
4
|
+
if (val == null) {
|
|
5
|
+
return null;
|
|
6
|
+
}
|
|
7
|
+
if (Array.isArray(val)) {
|
|
8
|
+
if (val.length > 0) {
|
|
9
|
+
val = val[0]
|
|
10
|
+
} else {
|
|
11
|
+
return 'listVal';
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
const type = typeof val;
|
|
15
|
+
if (type === 'string') {
|
|
16
|
+
return 'stringVal';
|
|
17
|
+
}
|
|
18
|
+
if (type === 'number') {
|
|
19
|
+
if (val % 1 === 0) { // is interger
|
|
20
|
+
return 'intVal';
|
|
21
|
+
} else {
|
|
22
|
+
return 'floatVal';
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
if (type === 'boolean') {
|
|
26
|
+
return 'boolVal';
|
|
27
|
+
}
|
|
28
|
+
if (type === 'object') {
|
|
29
|
+
return 'structVal';
|
|
30
|
+
}
|
|
31
|
+
return undefined;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export function formatArrayAsTensor(arr: any[]): any {
|
|
35
|
+
return arr.map(item => {
|
|
36
|
+
const type = typeof item;
|
|
37
|
+
if (type === 'string' || type === 'number' || type === 'boolean') {
|
|
38
|
+
return item; // primitve values
|
|
39
|
+
} else {
|
|
40
|
+
return formatObjectAsTensor(item)
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Do not support nested array or nested object arrays
|
|
47
|
+
* @param obj
|
|
48
|
+
* @returns
|
|
49
|
+
*/
|
|
50
|
+
function formatObjectAsTensor(obj: any, isField = false): any {
|
|
51
|
+
const struct: any = {};
|
|
52
|
+
const keys = Object.keys(obj);
|
|
53
|
+
for (const key of keys) {
|
|
54
|
+
//console.log('###', key);
|
|
55
|
+
const val = obj[key];
|
|
56
|
+
const type = getTensorType(val);
|
|
57
|
+
if (type === 'structVal') {
|
|
58
|
+
if (Array.isArray(val)) {
|
|
59
|
+
struct[key] = { listVal: formatArrayAsTensor(val) };
|
|
60
|
+
} else {
|
|
61
|
+
struct[key] = {
|
|
62
|
+
[type]: formatObjectAsTensor(val, true)
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
} else if (type) {
|
|
66
|
+
struct[key] = {
|
|
67
|
+
[type]: val
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return isField ? struct : {
|
|
72
|
+
structVal: struct
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
export function generateStreamingPrompt(prompt: { instances: any, parameters: any }): any {
|
|
78
|
+
return {
|
|
79
|
+
inputs: prompt.instances.map((inst: any) => formatObjectAsTensor(inst)),
|
|
80
|
+
parameters: formatObjectAsTensor(prompt.parameters)
|
|
81
|
+
}
|
|
82
|
+
}
|