@bedrockio/ai 0.2.1 → 0.4.2
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/.claude/settings.local.json +11 -0
- package/CHANGELOG.md +34 -0
- package/README.md +59 -17
- package/__mocks__/@anthropic-ai/sdk.js +16 -22
- package/__mocks__/@google/generative-ai.js +1 -1
- package/__mocks__/openai.js +33 -28
- package/dist/cjs/BaseClient.js +242 -126
- package/dist/cjs/anthropic.js +115 -93
- package/dist/cjs/google.js +74 -86
- package/dist/cjs/index.js +24 -25
- package/dist/cjs/openai.js +114 -69
- package/dist/cjs/package.json +1 -0
- package/dist/cjs/utils/code.js +11 -0
- package/dist/cjs/utils/json.js +53 -0
- package/dist/cjs/utils/templates.js +83 -0
- package/dist/cjs/xai.js +14 -0
- package/dist/esm/BaseClient.js +243 -0
- package/dist/esm/anthropic.js +116 -0
- package/dist/esm/google.js +75 -0
- package/dist/esm/index.js +25 -0
- package/dist/esm/openai.js +113 -0
- package/dist/esm/utils/code.js +8 -0
- package/dist/esm/utils/json.js +50 -0
- package/dist/esm/utils/templates.js +76 -0
- package/dist/esm/xai.js +10 -0
- package/eslint.config.js +2 -0
- package/package.json +18 -17
- package/src/BaseClient.js +239 -89
- package/src/anthropic.js +96 -56
- package/src/google.js +6 -12
- package/src/index.js +20 -16
- package/src/openai.js +97 -31
- package/src/utils/code.js +9 -0
- package/src/utils/json.js +58 -0
- package/src/utils/templates.js +87 -0
- package/src/xai.js +12 -0
- package/tsconfig.cjs.json +8 -0
- package/tsconfig.esm.json +8 -0
- package/tsconfig.types.json +9 -0
- package/types/BaseClient.d.ts +68 -26
- package/types/BaseClient.d.ts.map +1 -1
- package/types/anthropic.d.ts +26 -2
- package/types/anthropic.d.ts.map +1 -1
- package/types/google.d.ts.map +1 -1
- package/types/index.d.ts +4 -3
- package/types/index.d.ts.map +1 -1
- package/types/openai.d.ts +45 -2
- package/types/openai.d.ts.map +1 -1
- package/types/util.d.ts +1 -1
- package/types/util.d.ts.map +1 -1
- package/types/utils/code.d.ts +2 -0
- package/types/utils/code.d.ts.map +1 -0
- package/types/utils/json.d.ts +2 -0
- package/types/utils/json.d.ts.map +1 -0
- package/types/utils/templates.d.ts +3 -0
- package/types/utils/templates.d.ts.map +1 -0
- package/types/utils.d.ts +4 -0
- package/types/utils.d.ts.map +1 -0
- package/types/xai.d.ts +4 -0
- package/types/xai.d.ts.map +1 -0
- package/vitest.config.js +10 -0
- package/dist/cjs/util.js +0 -47
- package/src/util.js +0 -42
package/dist/cjs/BaseClient.js
CHANGED
|
@@ -1,130 +1,246 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
exports.default = void 0;
|
|
7
|
-
var _mustache = _interopRequireDefault(require("mustache"));
|
|
8
|
-
var _util = require("./util.js");
|
|
9
|
-
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
10
|
-
const MESSAGES_REG = /(?:^|\n)-{3,}\s*(\w+)\s*-{3,}(.*?)(?=\n-{3,}|$)/gs;
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const code_js_1 = require("./utils/code.js");
|
|
4
|
+
const json_js_1 = require("./utils/json.js");
|
|
5
|
+
const templates_js_1 = require("./utils/templates.js");
|
|
11
6
|
class BaseClient {
|
|
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
|
-
|
|
7
|
+
constructor(options) {
|
|
8
|
+
this.options = {
|
|
9
|
+
// @ts-ignore
|
|
10
|
+
model: this.constructor.DEFAULT_MODEL,
|
|
11
|
+
...options,
|
|
12
|
+
};
|
|
13
|
+
this.templates = null;
|
|
14
|
+
}
|
|
15
|
+
// Public
|
|
16
|
+
/**
|
|
17
|
+
* Interpolates vars into the provided template as instructions and runs the
|
|
18
|
+
* prompt.
|
|
19
|
+
*
|
|
20
|
+
* @param {PromptOptions} options
|
|
21
|
+
*/
|
|
22
|
+
async prompt(options) {
|
|
23
|
+
options = await this.normalizeOptions(options);
|
|
24
|
+
const { input, output, stream, schema } = options;
|
|
25
|
+
const response = await this.runPrompt(options);
|
|
26
|
+
if (!stream) {
|
|
27
|
+
this.debug('Response:', response);
|
|
28
|
+
}
|
|
29
|
+
if (output === 'raw') {
|
|
30
|
+
return response;
|
|
31
|
+
}
|
|
32
|
+
let result;
|
|
33
|
+
if (schema) {
|
|
34
|
+
result = this.getStructuredResponse(response);
|
|
35
|
+
// @ts-ignore
|
|
36
|
+
if (options.hasWrappedSchema) {
|
|
37
|
+
result = result.items;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
else if (output === 'json') {
|
|
41
|
+
result = JSON.parse((0, code_js_1.parseCode)(this.getTextResponse(response)));
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
result = (0, code_js_1.parseCode)(this.getTextResponse(response));
|
|
45
|
+
}
|
|
46
|
+
if (output === 'messages') {
|
|
47
|
+
return {
|
|
48
|
+
result,
|
|
49
|
+
...this.getMessagesResponse(input, response),
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
return result;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Streams the prompt response.
|
|
58
|
+
*
|
|
59
|
+
* @param {PromptOptions & StreamOptions} options
|
|
60
|
+
* @returns {AsyncIterator}
|
|
61
|
+
*/
|
|
62
|
+
async *stream(options) {
|
|
63
|
+
options = await this.normalizeOptions(options);
|
|
64
|
+
const extractor = this.getMessageExtractor(options);
|
|
65
|
+
try {
|
|
66
|
+
const stream = await this.runStream(options);
|
|
67
|
+
// @ts-ignore
|
|
68
|
+
for await (let event of stream) {
|
|
69
|
+
this.debug('Event:', event);
|
|
70
|
+
event = this.normalizeStreamEvent(event);
|
|
71
|
+
if (event) {
|
|
72
|
+
yield event;
|
|
73
|
+
}
|
|
74
|
+
const extractedMessages = extractor?.(event) || [];
|
|
75
|
+
for (let message of extractedMessages) {
|
|
76
|
+
const { key, delta, text, done } = message;
|
|
77
|
+
let extractEvent;
|
|
78
|
+
if (done) {
|
|
79
|
+
extractEvent = {
|
|
80
|
+
type: 'extract:done',
|
|
81
|
+
text,
|
|
82
|
+
key,
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
extractEvent = {
|
|
87
|
+
type: 'extract:delta',
|
|
88
|
+
delta,
|
|
89
|
+
key,
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
this.debug('Extract:', extractEvent);
|
|
93
|
+
yield extractEvent;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
catch (error) {
|
|
98
|
+
const { message, code } = error;
|
|
99
|
+
yield {
|
|
100
|
+
type: 'error',
|
|
101
|
+
code,
|
|
102
|
+
message,
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
async buildTemplate(options) {
|
|
107
|
+
const template = await this.resolveTemplate(options);
|
|
108
|
+
return (0, templates_js_1.renderTemplate)(template, options);
|
|
109
|
+
}
|
|
110
|
+
// Protected
|
|
111
|
+
runPrompt(options) {
|
|
112
|
+
void options;
|
|
113
|
+
throw new Error('Method not implemented.');
|
|
114
|
+
}
|
|
115
|
+
runStream(options) {
|
|
116
|
+
void options;
|
|
117
|
+
throw new Error('Method not implemented.');
|
|
118
|
+
}
|
|
119
|
+
getTextResponse(response) {
|
|
120
|
+
void response;
|
|
121
|
+
throw new Error('Method not implemented.');
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* @returns {Object}
|
|
125
|
+
*/
|
|
126
|
+
getStructuredResponse(response) {
|
|
127
|
+
void response;
|
|
128
|
+
throw new Error('Method not implemented.');
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* @returns {Object}
|
|
132
|
+
*/
|
|
133
|
+
getMessagesResponse(input, response) {
|
|
134
|
+
void response;
|
|
135
|
+
throw new Error('Method not implemented.');
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* @returns {Object}
|
|
139
|
+
*/
|
|
140
|
+
normalizeStreamEvent(event) {
|
|
141
|
+
void event;
|
|
142
|
+
throw new Error('Method not implemented.');
|
|
143
|
+
}
|
|
144
|
+
// Private
|
|
145
|
+
async normalizeOptions(options) {
|
|
146
|
+
options = {
|
|
147
|
+
input: '',
|
|
148
|
+
output: 'text',
|
|
149
|
+
...this.options,
|
|
150
|
+
...options,
|
|
151
|
+
};
|
|
152
|
+
options.input = this.normalizeInput(options);
|
|
153
|
+
options.schema = this.normalizeSchema(options);
|
|
154
|
+
options.instructions ||= await this.resolveInstructions(options);
|
|
155
|
+
return options;
|
|
156
|
+
}
|
|
157
|
+
normalizeInput(options) {
|
|
158
|
+
let { input = '', output } = options;
|
|
159
|
+
if (typeof input === 'string') {
|
|
160
|
+
if (output === 'json') {
|
|
161
|
+
input += '\nOutput only valid JSON.';
|
|
162
|
+
}
|
|
163
|
+
input = [
|
|
164
|
+
{
|
|
165
|
+
role: 'user',
|
|
166
|
+
content: input,
|
|
167
|
+
},
|
|
168
|
+
];
|
|
169
|
+
}
|
|
170
|
+
return input;
|
|
171
|
+
}
|
|
172
|
+
normalizeSchema(options) {
|
|
173
|
+
let { schema } = options;
|
|
174
|
+
if (!schema) {
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
// Convert to JSON schema.
|
|
178
|
+
schema = schema.toJSON?.() || schema;
|
|
179
|
+
if (schema?.type === 'array') {
|
|
180
|
+
schema = {
|
|
181
|
+
type: 'object',
|
|
182
|
+
properties: {
|
|
183
|
+
items: schema,
|
|
184
|
+
},
|
|
185
|
+
required: ['items'],
|
|
186
|
+
additionalProperties: false,
|
|
187
|
+
};
|
|
188
|
+
options.hasWrappedSchema = true;
|
|
189
|
+
}
|
|
190
|
+
return schema;
|
|
191
|
+
}
|
|
192
|
+
getMessageExtractor(options) {
|
|
193
|
+
const { extractMessages } = options;
|
|
194
|
+
if (!extractMessages) {
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
const messageExtractor = (0, json_js_1.createMessageExtractor)([extractMessages]);
|
|
198
|
+
return (event) => {
|
|
199
|
+
if (event?.type === 'delta') {
|
|
200
|
+
return messageExtractor(event.delta);
|
|
201
|
+
}
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
debug(message, arg) {
|
|
205
|
+
if (this.options.debug) {
|
|
206
|
+
// TODO: replace with logger when opentelemetry is removed
|
|
207
|
+
// eslint-disable-next-line
|
|
208
|
+
console.debug(`${message}\n${JSON.stringify(arg, null, 2)}\n`);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
async resolveInstructions(options) {
|
|
212
|
+
if (options.template) {
|
|
213
|
+
const template = await this.resolveTemplate(options);
|
|
214
|
+
return (0, templates_js_1.renderTemplate)(template, options);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
async resolveTemplate(options) {
|
|
218
|
+
const { template } = options;
|
|
219
|
+
await this.loadTemplates();
|
|
220
|
+
return this.templates[template] || template;
|
|
221
|
+
}
|
|
222
|
+
async loadTemplates() {
|
|
223
|
+
const { templates } = this.options;
|
|
224
|
+
this.templates ||= await (0, templates_js_1.loadTemplates)(templates);
|
|
225
|
+
}
|
|
115
226
|
}
|
|
116
227
|
exports.default = BaseClient;
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
228
|
+
/**
|
|
229
|
+
* @typedef {Object} PromptOptions
|
|
230
|
+
* @property {string|PromptMessage[]} input - Input to use.
|
|
231
|
+
* @property {string} [model] - The model to use.
|
|
232
|
+
* @property {boolean} stream - Stream response.
|
|
233
|
+
* @property {Object} [schema] - A JSON schema compatible object that defines the output shape.
|
|
234
|
+
* @property {"raw" | "text" | "json" | "messages"} [output] - The return value type.
|
|
235
|
+
* @property {Object} [params] - Params to be interpolated into the template.
|
|
236
|
+
* May also be passed as additional props to options.
|
|
237
|
+
*/
|
|
238
|
+
/**
|
|
239
|
+
* @typedef {Object} StreamOptions
|
|
240
|
+
* @property {string} [extractMessages] - Key in JSON response to extract a message stream from.
|
|
241
|
+
*/
|
|
242
|
+
/**
|
|
243
|
+
* @typedef {Object} PromptMessage
|
|
244
|
+
* @property {"system" | "user" | "assistant"} role
|
|
245
|
+
* @property {string} content
|
|
246
|
+
*/
|
package/dist/cjs/anthropic.js
CHANGED
|
@@ -1,101 +1,123 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
});
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.AnthropicClient = void 0;
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
super(options);
|
|
16
|
-
this.client = new _sdk.default({
|
|
17
|
-
...options
|
|
18
|
-
});
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* Lists available models.
|
|
23
|
-
* {@link https://docs.anthropic.com/en/docs/about-claude/models Documentation}
|
|
24
|
-
*/
|
|
25
|
-
async models() {
|
|
26
|
-
const {
|
|
27
|
-
data
|
|
28
|
-
} = await this.client.models.list();
|
|
29
|
-
return data.map(o => o.id);
|
|
30
|
-
}
|
|
31
|
-
async getCompletion(options) {
|
|
32
|
-
const {
|
|
33
|
-
model = DEFAULT_MODEL,
|
|
34
|
-
max_tokens = 2048,
|
|
35
|
-
output = 'text',
|
|
36
|
-
stream = false,
|
|
37
|
-
messages
|
|
38
|
-
} = options;
|
|
39
|
-
const {
|
|
40
|
-
client
|
|
41
|
-
} = this;
|
|
42
|
-
const {
|
|
43
|
-
system,
|
|
44
|
-
user
|
|
45
|
-
} = splitMessages(messages);
|
|
46
|
-
if (!model) {
|
|
47
|
-
throw new Error(`No model specified. Available models are here: ${MODELS_URL}.`);
|
|
7
|
+
const sdk_1 = __importDefault(require("@anthropic-ai/sdk"));
|
|
8
|
+
const BaseClient_js_1 = __importDefault(require("./BaseClient.js"));
|
|
9
|
+
const DEFAULT_TOKENS = 4096;
|
|
10
|
+
class AnthropicClient extends BaseClient_js_1.default {
|
|
11
|
+
static DEFAULT_MODEL = 'claude-sonnet-4-5';
|
|
12
|
+
constructor(options) {
|
|
13
|
+
super(options);
|
|
14
|
+
this.client = new sdk_1.default(options);
|
|
48
15
|
}
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
if (output === 'raw') {
|
|
57
|
-
return response;
|
|
16
|
+
/**
|
|
17
|
+
* Lists available models.
|
|
18
|
+
* {@link https://docs.anthropic.com/en/docs/about-claude/models Documentation}
|
|
19
|
+
*/
|
|
20
|
+
async models() {
|
|
21
|
+
const { data } = await this.client.models.list();
|
|
22
|
+
return data.map((o) => o.id);
|
|
58
23
|
}
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
if (chunk.type === 'content_block_start') {
|
|
72
|
-
type = 'start';
|
|
73
|
-
} else if (chunk.type === 'content_block_delta') {
|
|
74
|
-
type = 'chunk';
|
|
75
|
-
} else if (chunk.type === 'message_stop') {
|
|
76
|
-
type = 'stop';
|
|
24
|
+
async runPrompt(options) {
|
|
25
|
+
const { input, model, temperature, instructions, stream = false, tokens = DEFAULT_TOKENS, } = options;
|
|
26
|
+
// @ts-ignore
|
|
27
|
+
return await this.client.messages.create({
|
|
28
|
+
model,
|
|
29
|
+
stream,
|
|
30
|
+
temperature,
|
|
31
|
+
max_tokens: tokens,
|
|
32
|
+
system: instructions,
|
|
33
|
+
...this.getSchemaOptions(options),
|
|
34
|
+
messages: input,
|
|
35
|
+
});
|
|
77
36
|
}
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
37
|
+
async runStream(options) {
|
|
38
|
+
return await this.runPrompt({
|
|
39
|
+
...options,
|
|
40
|
+
output: 'raw',
|
|
41
|
+
stream: true,
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
getTextResponse(response) {
|
|
45
|
+
const textBlock = response.content.find((block) => {
|
|
46
|
+
return block.type === 'text';
|
|
47
|
+
});
|
|
48
|
+
return textBlock?.text || null;
|
|
49
|
+
}
|
|
50
|
+
getStructuredResponse(response) {
|
|
51
|
+
const toolBlock = response.content.find((block) => {
|
|
52
|
+
return block.type === 'tool_use';
|
|
53
|
+
});
|
|
54
|
+
return toolBlock?.input || null;
|
|
55
|
+
}
|
|
56
|
+
getMessagesResponse(input, response) {
|
|
57
|
+
return {
|
|
58
|
+
messages: [
|
|
59
|
+
...input,
|
|
60
|
+
...response.content
|
|
61
|
+
.filter((item) => {
|
|
62
|
+
return item.type === 'text';
|
|
63
|
+
})
|
|
64
|
+
.map((item) => {
|
|
65
|
+
return {
|
|
66
|
+
role: 'assistant',
|
|
67
|
+
content: item.text,
|
|
68
|
+
};
|
|
69
|
+
}),
|
|
70
|
+
],
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
normalizeStreamEvent(event) {
|
|
74
|
+
let { type } = event;
|
|
75
|
+
if (type === 'content_block_start') {
|
|
76
|
+
return {
|
|
77
|
+
type: 'start',
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
else if (type === 'content_block_stop') {
|
|
81
|
+
return {
|
|
82
|
+
type: 'stop',
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
else if (type === 'content_block_delta') {
|
|
86
|
+
return {
|
|
87
|
+
type: 'delta',
|
|
88
|
+
text: event.delta.text,
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
// Private
|
|
93
|
+
getSchemaOptions(options) {
|
|
94
|
+
const { output } = options;
|
|
95
|
+
if (output?.type) {
|
|
96
|
+
let schema = output;
|
|
97
|
+
if (schema.type === 'array') {
|
|
98
|
+
schema = {
|
|
99
|
+
type: 'object',
|
|
100
|
+
properties: {
|
|
101
|
+
items: schema,
|
|
102
|
+
},
|
|
103
|
+
required: ['items'],
|
|
104
|
+
additionalProperties: false,
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
return {
|
|
108
|
+
tools: [
|
|
109
|
+
{
|
|
110
|
+
name: 'schema',
|
|
111
|
+
description: 'Follow the schema for JSON output.',
|
|
112
|
+
input_schema: schema,
|
|
113
|
+
},
|
|
114
|
+
],
|
|
115
|
+
tool_choice: {
|
|
116
|
+
type: 'tool',
|
|
117
|
+
name: 'schema',
|
|
118
|
+
},
|
|
119
|
+
};
|
|
120
|
+
}
|
|
83
121
|
}
|
|
84
|
-
}
|
|
85
122
|
}
|
|
86
123
|
exports.AnthropicClient = AnthropicClient;
|
|
87
|
-
function splitMessages(messages) {
|
|
88
|
-
const system = [];
|
|
89
|
-
const user = [];
|
|
90
|
-
for (let message of messages) {
|
|
91
|
-
if (message.role === 'system') {
|
|
92
|
-
system.push(message);
|
|
93
|
-
} else {
|
|
94
|
-
user.push(message);
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
return {
|
|
98
|
-
system: system.join('\n'),
|
|
99
|
-
user
|
|
100
|
-
};
|
|
101
|
-
}
|