feat(puterai): add claude

This commit is contained in:
KernelDeimos 2024-08-20 22:23:27 -04:00 committed by Eric Dubé
parent 9d5963cdf5
commit d009cd0aaf
4 changed files with 141 additions and 1 deletions

27
package-lock.json generated
View File

@ -263,6 +263,30 @@
"node": ">=6.0.0"
}
},
"node_modules/@anthropic-ai/sdk": {
"version": "0.26.1",
"resolved": "https://registry.npmjs.org/@anthropic-ai/sdk/-/sdk-0.26.1.tgz",
"integrity": "sha512-HeMJP1bDFfQPQS3XTJAmfXkFBdZ88wvfkE05+vsoA9zGn5dHqEaHOPsqkazf/i0gXYg2XlLxxZrf6rUAarSqzw==",
"license": "MIT",
"dependencies": {
"@types/node": "^18.11.18",
"@types/node-fetch": "^2.6.4",
"abort-controller": "^3.0.0",
"agentkeepalive": "^4.2.1",
"form-data-encoder": "1.7.2",
"formdata-node": "^4.3.2",
"node-fetch": "^2.6.7"
}
},
"node_modules/@anthropic-ai/sdk/node_modules/@types/node": {
"version": "18.19.45",
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.45.tgz",
"integrity": "sha512-VZxPKNNhjKmaC1SUYowuXSRSMGyQGmQjvvA1xE4QZ0xce2kLtEhPDS+kqpCPBZYgqblCLQ2DAjSzmgCM5auvhA==",
"license": "MIT",
"dependencies": {
"undici-types": "~5.26.4"
}
},
"node_modules/@aws-crypto/sha256-browser": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/@aws-crypto/sha256-browser/-/sha256-browser-5.2.0.tgz",
@ -16561,9 +16585,10 @@
},
"src/backend": {
"name": "@heyputer/backend",
"version": "2.1.0",
"version": "2.4.1",
"license": "AGPL-3.0-only",
"dependencies": {
"@anthropic-ai/sdk": "^0.26.1",
"@aws-sdk/client-polly": "^3.622.0",
"@aws-sdk/client-textract": "^3.621.0",
"@heyputer/kv.js": "^0.1.3",

View File

@ -7,6 +7,7 @@
"test": "npx mocha"
},
"dependencies": {
"@anthropic-ai/sdk": "^0.26.1",
"@aws-sdk/client-polly": "^3.622.0",
"@aws-sdk/client-textract": "^3.621.0",
"@heyputer/kv.js": "^0.1.3",

View File

@ -0,0 +1,109 @@
const { default: Anthropic } = require("@anthropic-ai/sdk");
const BaseService = require("../../services/BaseService");
const { whatis } = require("../../util/langutil");
const { PassThrough } = require("stream");
const { TypedValue } = require("../../services/drivers/meta/Runtime");
const PUTER_PROMPT = `
You are running on an open-source platform called Puter,
as the Claude implementation for a driver interface
called puter-chat-completion.
The following JSON contains system messages from the
user of the driver interface (typically an app on Puter):
`.replace('\n', ' ').trim();
class ClaudeService extends BaseService {
static MODULES = {
Anthropic: require('@anthropic-ai/sdk'),
}
async _init () {
this.anthropic = new Anthropic({
apiKey: this.config.apiKey
});
}
static IMPLEMENTS = {
['puter-chat-completion']: {
async complete ({ messages, stream }) {
const adapted_messages = [];
const system_prompts = [];
let previous_was_user = false;
for ( const message of messages ) {
if ( typeof message.content === 'string' ) {
message.content = {
type: 'text',
text: message.content,
};
}
if ( whatis(message.content) !== 'array' ) {
message.content = [message.content];
}
if ( message.role === 'user' && previous_was_user ) {
const last_msg = adapted_messages[adapted_messages.length-1];
last_msg.content.push(
...(Array.isArray ? message.content : [message.content])
);
continue;
}
if ( message.role === 'system' ) {
system_prompts.push(...message.content);
continue;
}
adapted_messages.push(message);
if ( message.role === 'user' ) {
previous_was_user = true;
}
}
if ( stream ) {
const stream = new PassThrough();
const retval = new TypedValue({
$: 'stream',
content_type: 'application/x-ndjson',
chunked: true,
}, stream);
(async () => {
const completion = await this.anthropic.messages.stream({
model: 'claude-3-5-sonnet-20240620',
max_tokens: 1000,
temperature: 0,
system: PUTER_PROMPT + JSON.stringify(system_prompts),
messages: adapted_messages,
});
for await ( const event of completion ) {
if (
event.type !== 'content_block_delta' ||
event.delta.type !== 'text_delta'
) continue;
const str = JSON.stringify({
text: event.delta.text,
});
stream.write(str + '\n');
}
})();
return retval;
}
const msg = await this.anthropic.messages.create({
model: 'claude-3-5-sonnet-20240620',
max_tokens: 1000,
temperature: 0,
system: PUTER_PROMPT + JSON.stringify(system_prompts),
messages: adapted_messages,
});
return {
message: msg,
finish_reason: 'stop'
};
}
}
}
}
module.exports = {
ClaudeService,
};

View File

@ -28,6 +28,11 @@ class PuterAIModule extends AdvancedBase {
const { OpenAIImageGenerationService } = require('./OpenAIImageGenerationService');
services.registerService('openai-image-generation', OpenAIImageGenerationService);
}
if ( !! config?.services?.claude ) {
const { ClaudeService } = require('./ClaudeService');
services.registerService('claude', ClaudeService);
}
}
}