-
-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathinteractive-example.js
More file actions
159 lines (141 loc) · 6.08 KB
/
Copy pathinteractive-example.js
File metadata and controls
159 lines (141 loc) · 6.08 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
// Clear terminal
console.clear();
// ================================================================================
// == AWS Bedrock Example: Invoke a Model with a Streamed or Unstreamed Response ==
// ================================================================================
// ---------------------------------------------------------------------
// -- import environment variables from .env file or define them here --
// ---------------------------------------------------------------------
import dotenv from 'dotenv';
dotenv.config();
const AWS_REGION = process.env.AWS_REGION;
const AWS_ACCESS_KEY_ID = process.env.AWS_ACCESS_KEY_ID;
const AWS_SECRET_ACCESS_KEY = process.env.AWS_SECRET_ACCESS_KEY;
const LLM_MAX_GEN_TOKENS = parseInt(process.env.LLM_MAX_GEN_TOKENS);
const LLM_TEMPERATURE = parseFloat(process.env.LLM_TEMPERATURE);
// --------------------------------------------
// -- import functions from bedrock-wrapper --
// -- - bedrockWrapper --
// -- - listBedrockWrapperSupportedModels --
// --------------------------------------------
import {
bedrockWrapper,
listBedrockWrapperSupportedModels
} from "./bedrock-wrapper.js";
// ----------------------------------------------
// -- Get and process supported models --
// ----------------------------------------------
const supportedModels = await listBedrockWrapperSupportedModels();
const availableModels = supportedModels.map(model => {
// Fix both modelName and modelId by adding quotes
const fixedJson = model
.replace(/modelName": ([^,]+),/, 'modelName": "$1",')
.replace(/modelId": ([^}]+)}/, 'modelId": "$1"}');
return JSON.parse(fixedJson).modelName;
});
// Display models with numbers
console.log('\nAvailable Models:');
availableModels.forEach((model, index) => {
console.log(`${index + 1}. ${model}`);
});
// Prompt user for input
import readline from 'readline';
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
// Get user selection
const selectedModel = await new Promise((resolve) => {
rl.question('\nEnter the number of the model you want to use: ', (answer) => {
const selection = parseInt(answer) - 1;
if (selection >= 0 && selection < availableModels.length) {
resolve(availableModels[selection]);
} else {
console.log('Invalid selection, defaulting to Claude-3-5-Sonnet');
resolve('Claude-3-5-Sonnet-v2');
}
});
});
// Ask for streaming preference
const shouldStream = await new Promise((resolve) => {
rl.question('\nDo you want streamed responses? (Y/n): ', (answer) => {
resolve(answer.toLowerCase() !== 'n');
});
});
// Ask for API preference
const useConverseAPI = await new Promise((resolve) => {
rl.question('\nUse Converse API instead of Invoke API? (Y/n): ', (answer) => {
resolve(answer.toLowerCase() !== 'n');
});
});
console.log(`\nUsing model: ${selectedModel}`);
console.log(`Streaming: ${shouldStream ? 'enabled' : 'disabled'}`);
console.log(`API: ${useConverseAPI ? 'Converse API' : 'Invoke API'}\n`);
const defaultPrompt = "Describe what the openai api standard used by lots of serverless LLM api providers is and why it has been widely adopted.";
// Get user prompt
const userPrompt = await new Promise((resolve) => {
rl.question(`\nEnter your prompt (press Enter to use default):\n> `, (answer) => {
resolve(answer.trim() || defaultPrompt);
rl.close(); // Only close after all prompts are complete
});
});
// -----------------------------------------------
// -- example prompt in `messages` array format --
// -----------------------------------------------
const messages = [
{
role: "user",
content: userPrompt,
},
];
// Only add empty assistant message for Invoke API (Converse API handles this automatically)
if (!useConverseAPI) {
messages.push({
role: "assistant",
content: "",
});
}
// ---------------------------------------------------
// -- create an object to hold your AWS credentials --
// ---------------------------------------------------
const awsCreds = {
region: AWS_REGION,
accessKeyId: AWS_ACCESS_KEY_ID,
secretAccessKey: AWS_SECRET_ACCESS_KEY,
};
// ----------------------------------------------------------------------
// -- create an object that copies your openai chat completions object --
// ----------------------------------------------------------------------
const openaiChatCompletionsCreateObject = {
"messages": messages,
"model": selectedModel,
"max_tokens": LLM_MAX_GEN_TOKENS,
"stream": shouldStream,
"temperature": LLM_TEMPERATURE,
"include_thinking_data": true,
};
// ------------------------------------------------------------
// -- invoke the streamed or unstreamed bedrock api response --
// ------------------------------------------------------------
// create a variable to hold the complete response
let completeResponse = "";
// streamed call
if (openaiChatCompletionsCreateObject.stream) {
for await (const chunk of bedrockWrapper(awsCreds, openaiChatCompletionsCreateObject, { logging:true, useConverseAPI })) {
completeResponse += chunk;
// ---------------------------------------------------
// -- each chunk is streamed as it is received here --
// ---------------------------------------------------
process.stdout.write(chunk); // ⇠ do stuff with the streamed chunk
}
} else { // unstreamed call
const response = await bedrockWrapper(awsCreds, openaiChatCompletionsCreateObject, { logging:true, useConverseAPI });
for await (const data of response) {
completeResponse += data;
}
// ----------------------------------------------------
// -- unstreamed complete response is available here --
// ----------------------------------------------------
console.log(`\n\completeResponse:\n${completeResponse}\n`); // ⇠ do stuff with the complete response
}
// console.log(`\n\completeResponse:\n${completeResponse}\n`); // ⇠ optional do stuff with the complete response returned from the API reguardless of stream or not