From 5cf12f0ca39c12a82f2c36a2f5a39f39c3c7666f Mon Sep 17 00:00:00 2001 From: Kevin Mingtarja Date: Fri, 19 Jul 2024 15:11:05 +0700 Subject: [PATCH 01/16] Create Message class for Anthropic --- src/models/anthropic/messages.ts | 71 ++++++++++ src/package-lock.json | 219 ++++++++++++++++++++++++++++++- src/package.json | 1 + 3 files changed, 288 insertions(+), 3 deletions(-) create mode 100644 src/models/anthropic/messages.ts diff --git a/src/models/anthropic/messages.ts b/src/models/anthropic/messages.ts new file mode 100644 index 0000000..9faa2d6 --- /dev/null +++ b/src/models/anthropic/messages.ts @@ -0,0 +1,71 @@ +import Anthropic from "@anthropic-ai/sdk"; + +import { Model } from "../.."; + +enum Role { + User = "user", + Assistant = "assistant", +} + +/** + * A message object that can be sent to the model. + */ +@json +abstract class Message implements Anthropic.MessageParam { + /** + * Creates a new message object. + * + * @param role The role of the author of this message. + * @param content The contents of the message. + */ + constructor(role: Role.User | Role.Assistant, content: string) { + this._role = role; + this.content = content; + } + + @alias("role") + protected _role: Role.User | Role.Assistant; + + /** + * The role of the author of this message. + */ + get role() { + return this._role; + } + + /** + * The contents of the message. + * For now it can only be a string, even though Anthropic supports more complex types. + */ + content: string; // TODO: support more complex types +} + +/** + * A user message. + */ +@json +export class UserMessage extends Message { + /** + * Creates a new user message object. + * + * @param content The contents of the message. + */ + constructor(content: string) { + super(Role.User, content); + } +} + +/** + * An assistant message. + */ +@json +export class AssistantMessage extends Message { + /** + * Creates a new assistant message object. + * + * @param content The contents of the message. + */ + constructor(content: string) { + super(Role.Assistant, content); + } +} diff --git a/src/package-lock.json b/src/package-lock.json index 79906d4..78df055 100644 --- a/src/package-lock.json +++ b/src/package-lock.json @@ -9,6 +9,7 @@ "version": "0.2.1", "license": "MIT", "dependencies": { + "@anthropic-ai/sdk": "^0.24.3", "json-as": "^0.9.8" }, "devDependencies": { @@ -23,6 +24,29 @@ "visitor-as": "^0.11.4" } }, + "node_modules/@anthropic-ai/sdk": { + "version": "0.24.3", + "resolved": "https://registry.npmjs.org/@anthropic-ai/sdk/-/sdk-0.24.3.tgz", + "integrity": "sha512-916wJXO6T6k8R6BAAcLhLPv/pnLGy7YSEBZXZ1XTFbLcTZE8oTy3oDW9WJf9KKZwMvVcePIfoTSvzXHRcGxkQQ==", + "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", + "web-streams-polyfill": "^3.2.1" + } + }, + "node_modules/@anthropic-ai/sdk/node_modules/@types/node": { + "version": "18.19.41", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.41.tgz", + "integrity": "sha512-LX84pRJ+evD2e2nrgYCHObGWkiQJ1mL+meAgbvnwk/US6vmMY7S2ygBTGV2Jw91s9vUsLSXeDEkUHZIJGLrhsg==", + "dependencies": { + "undici-types": "~5.26.4" + } + }, "node_modules/@eslint-community/eslint-utils": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", @@ -211,11 +235,19 @@ "version": "20.14.11", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.11.tgz", "integrity": "sha512-kprQpL8MMeszbz6ojB5/tU8PLN4kesnN8Gjzw349rDlNgsSzg90lAVj3llK99Dh7JON+t9AuscPPFW6mPbTnSA==", - "dev": true, "dependencies": { "undici-types": "~5.26.4" } }, + "node_modules/@types/node-fetch": { + "version": "2.6.11", + "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.11.tgz", + "integrity": "sha512-24xFj9R5+rfQJLRyM56qh+wnVSYhyXC2tkoBndtY0U+vubqNsYXGjufB2nn8Q6gt0LrARwL6UBtMCSVCwl4B1g==", + "dependencies": { + "@types/node": "*", + "form-data": "^4.0.0" + } + }, "node_modules/@typescript-eslint/eslint-plugin": { "version": "7.16.1", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.16.1.tgz", @@ -408,6 +440,17 @@ "dev": true, "license": "ISC" }, + "node_modules/abort-controller": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", + "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "dependencies": { + "event-target-shim": "^5.0.0" + }, + "engines": { + "node": ">=6.5" + } + }, "node_modules/acorn": { "version": "8.11.3", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", @@ -431,6 +474,17 @@ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, + "node_modules/agentkeepalive": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.5.0.tgz", + "integrity": "sha512-5GG/5IbQQpC9FpkRGsSvZI5QYeSCzlJHdpBQntCsuTOxhKD8lqKhrleg2Yi7yvMIf82Ycmmqln9U8V9qwEiJew==", + "dependencies": { + "humanize-ms": "^1.2.1" + }, + "engines": { + "node": ">= 8.0.0" + } + }, "node_modules/ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", @@ -532,6 +586,11 @@ "prettier": "^3.0.0" } }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -620,6 +679,17 @@ "dev": true, "license": "MIT" }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -667,6 +737,14 @@ "dev": true, "license": "MIT" }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/dir-glob": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", @@ -880,6 +958,14 @@ "node": ">=0.10.0" } }, + "node_modules/event-target-shim": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", + "engines": { + "node": ">=6" + } + }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -1006,6 +1092,44 @@ "dev": true, "license": "ISC" }, + "node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/form-data-encoder": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-1.7.2.tgz", + "integrity": "sha512-qfqtYan3rxrnCk1VYaA4H+Ms9xdpPqvLZa6xmMgFvhO32x7/3J/ExcTd6qpxM0vH2GdMI+poehyBZvqfMTto8A==" + }, + "node_modules/formdata-node": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/formdata-node/-/formdata-node-4.4.1.tgz", + "integrity": "sha512-0iirZp3uVDjVGt9p49aTaqjk84TrglENEDuqfdlZQ1roC9CWlPk6Avf8EEnZNcAqPonwkG35x4n3ww/1THYAeQ==", + "dependencies": { + "node-domexception": "1.0.0", + "web-streams-polyfill": "4.0.0-beta.3" + }, + "engines": { + "node": ">= 12.20" + } + }, + "node_modules/formdata-node/node_modules/web-streams-polyfill": { + "version": "4.0.0-beta.3", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-4.0.0-beta.3.tgz", + "integrity": "sha512-QW95TCTaHmsYfHDybGMwO5IJIM93I/6vTRk+daHTWFPhwh+C8Cg7j7XyKrwrj8Ib6vYXe0ocYNrmzY4xAAN6ug==", + "engines": { + "node": ">= 14" + } + }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -1126,6 +1250,14 @@ "node": ">=8" } }, + "node_modules/humanize-ms": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", + "integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==", + "dependencies": { + "ms": "^2.0.0" + } + }, "node_modules/ignore": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", @@ -1359,6 +1491,25 @@ "node": ">=8.6" } }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/minimatch": { "version": "9.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", @@ -1379,7 +1530,6 @@ "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true, "license": "MIT" }, "node_modules/natural-compare": { @@ -1389,6 +1539,43 @@ "dev": true, "license": "MIT" }, + "node_modules/node-domexception": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", + "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "github", + "url": "https://paypal.me/jimmywarting" + } + ], + "engines": { + "node": ">=10.5.0" + } + }, + "node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -1738,6 +1925,11 @@ "node": ">=8.0" } }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" + }, "node_modules/ts-api-utils": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", @@ -1801,7 +1993,6 @@ "version": "5.26.5", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", - "dev": true, "license": "MIT" }, "node_modules/uri-js": { @@ -1828,6 +2019,28 @@ "assemblyscript": "^0.25.0" } }, + "node_modules/web-streams-polyfill": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz", + "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", diff --git a/src/package.json b/src/package.json index 15c0f68..57f3410 100644 --- a/src/package.json +++ b/src/package.json @@ -14,6 +14,7 @@ "lint:fix": "eslint --ext .ts --fix ." }, "dependencies": { + "@anthropic-ai/sdk": "^0.24.3", "json-as": "^0.9.8" }, "devDependencies": { From c6da01d3980cd52cc04de9e90a64947177e02ae5 Mon Sep 17 00:00:00 2001 From: Kevin Mingtarja Date: Fri, 19 Jul 2024 22:12:13 +0700 Subject: [PATCH 02/16] Add AnthropicMessagesModel, Input, Output types --- src/models/anthropic/messages.ts | 381 ++++++++++++++++++++++++++++++- src/package-lock.json | 219 +----------------- src/package.json | 1 - 3 files changed, 373 insertions(+), 228 deletions(-) diff --git a/src/models/anthropic/messages.ts b/src/models/anthropic/messages.ts index 9faa2d6..9023620 100644 --- a/src/models/anthropic/messages.ts +++ b/src/models/anthropic/messages.ts @@ -1,35 +1,52 @@ -import Anthropic from "@anthropic-ai/sdk"; - import { Model } from "../.."; -enum Role { - User = "user", - Assistant = "assistant", +/** + * Provides input and output types that conform to the Anthropic Messages API. + * + * Reference: https://docs.anthropic.com/en/api/messages + */ +export class AnthropicMessagesModel extends Model< + AnthropicMessagesInput, + AnthropicMessagesOutput +> { + /** + * Creates an input object for the Anthropic Messages API. + * + * @param messages: An array of messages to send to the model. + * Note that if you want to include a system prompt, you can use the top-level system parameter — + * there is no "system" role for input messages in the Messages API. + * @returns An input object that can be passed to the `invoke` method. + */ + createInput(messages: Message[]): AnthropicMessagesInput { + const model = this.info.fullName; + return { model, messages }; + } } /** * A message object that can be sent to the model. */ @json -abstract class Message implements Anthropic.MessageParam { +export class Message { /** * Creates a new message object. * * @param role The role of the author of this message. * @param content The contents of the message. */ - constructor(role: Role.User | Role.Assistant, content: string) { + constructor(role: string, content: string) { this._role = role; this.content = content; } + @alias("role") - protected _role: Role.User | Role.Assistant; + protected _role: string; /** * The role of the author of this message. */ - get role() { + get role(): string { return this._role; } @@ -51,7 +68,7 @@ export class UserMessage extends Message { * @param content The contents of the message. */ constructor(content: string) { - super(Role.User, content); + super("user", content); } } @@ -66,6 +83,348 @@ export class AssistantMessage extends Message { * @param content The contents of the message. */ constructor(content: string) { - super(Role.Assistant, content); + super("assistant", content); + } +} + +/** + * The input object for the Anthropic Messages API. + */ +@json +class AnthropicMessagesInput { + /** + * The model that will complete your prompt. + * Must be the exact string expected by the model provider. + * For example, "claude-3-5-sonnet-20240620". + * + * See [models](https://docs.anthropic.com/en/docs/models-overview) for additional + * details and options. + * + * @remarks + * This field is automatically set by the `createInput` method when creating this object. + * It does not need to be set manually. + */ + model!: string; + + /** + * Input messages. + * + * We do not currently support image content blocks, which are available starting with + * Claude 3 models. This will be added in a future release. + * + * Note that if you want to include a + * [system prompt](https://docs.anthropic.com/en/docs/system-prompts), you can use + * the top-level `system` parameter — there is no `"system"` role for input + * messages in the Messages API. + */ + messages!: Message[]; + + /** + * The maximum number of tokens to generate before stopping. + * + * Different models have different maximum values for this parameter. See + * [models](https://docs.anthropic.com/en/docs/models-overview) for details. + * + * @default 4096 + */ + @alias("max_tokens") + maxTokens: i32 = 4096; + + /** + * An object describing metadata about the request. + */ + @omitnull() + metadata: Metadata | null = null; + + /** + * Custom text sequences that will cause the model to stop generating. + */ + @alias("stop_sequences") + @omitnull() + stopSequences: string[] | null = null; + + /** + * Streaming is not currently supported. + * + * @default false + */ + @alias("stream") + @omitif("this._stream == false") + private _stream: boolean = false; + + /** + * System prompt. + * + * A system prompt is a way of providing context and instructions to Claude, such + * as specifying a particular goal or role. See [guide to system prompts](https://docs.anthropic.com/en/docs/system-prompts). + */ + @omitnull() + system: string | null = null; + + /** + * A number between `0.0` and `1.0` that controls the randomness injected into the response. + * + * It is recommended to use `temperature` closer to `0.0` + * for analytical / multiple choice, and closer to `1.0` for creative tasks. + * + * Note that even with `temperature` of `0.0`, the results will not be fully + * deterministic. + * + * @default 1.0 + */ + @omitif("this.temperature == 1.0") + temperature: f64 = 1.0; + + /** + * How the model should use the provided tools. + */ + @alias("tool_choice") + @omitnull() + toolChoice: ToolChoice | null = null; + + /** + * Definitions of tools that the model may use. + * + * Tools can be used for workflows that include running client-side tools and + * functions, or more generally whenever you want the model to produce a particular + * JSON structure of output. + * + * See Anthropic's [guide](https://docs.anthropic.com/en/docs/tool-use) for more details. + */ + @omitnull() + tools: Tool[] | null = null; + + /** + * Only sample from the top K options for each subsequent token. + * + * Recommended for advanced use cases only. You usually only need to use + * `temperature`. + */ + // TODO: decide whether to include this field + // @alias("top_k") + // @omitnull() + // topK: i64 | null = null; + + /** + * Use nucleus sampling. + * + * You should either alter `temperature` or `top_p`, but not both. + * + * Recommended for advanced use cases only. You usually only need to use + * `temperature`. + */ + @alias("top_p") + @omitif("this.topP == 0.999") + topP: f64 = 0.999; +} + + +@json +class Metadata { + /** + * An external identifier for the user who is associated with the request. + * + * This should be a uuid, hash value, or other opaque identifier. Anthropic may use + * this id to help detect abuse. Do not include any identifying information such as + * name, email address, or phone number. + */ + @alias("user_id") + userId: string | null = null; +} + +/** + * A tool object that the model may call. + */ +@json +export class Tool { + /** + * Name of the tool. + */ + name!: string; + + /** + * Optional, but strongly-recommended description of the tool. + */ + @omitnull() + description: string | null = null; + + /** + * [JSON schema](https://json-schema.org/) for this tool's input. + * + * This defines the shape of the `input` that your tool accepts and that the model + * will produce. + */ + @alias("input_schema") + inputSchema!: InputSchema; +} + + +@json +abstract class ToolChoice { + type!: string; + + constructor(type: string) { + this.type = type; + } +} + +/** + * The model will automatically decide whether to use tools. + */ +@json +export class ToolChoiceAuto extends ToolChoice { + constructor() { + super("auto"); + } +} + +/** + * The model will use any available tools. + */ +@json +export class ToolChoiceAny extends ToolChoice { + constructor() { + super("any"); + } +} + +/** + * The model will use the specified tool with `tool_choice.name`. + */ +@json +export class ToolChoiceTool extends ToolChoice { + /** + * The name of the tool to use. + */ + name!: string; + + constructor() { + super("tool"); } } + + +@json +class Properties { + [key: string]: any; +} + + +@json +export class InputSchema { + type: string = "object"; + + + @omitnull() + properties: Properties | null = null; +} + +/** + * The output object for the Anthropic Messages API. + */ +@json +class AnthropicMessagesOutput { + /** + * Unique object identifier. + */ + id!: string; + + /** + * Content generated by the model. + * + */ + content!: TextBlock[]; + + /** + * The model that handled the request. + */ + model!: string; + + /** + * Conversational role of the generated message. + * + * This will always be `"assistant"`. + */ + role!: "assistant"; + + /** + * The reason that the model stopped. + */ + @alias("stop_reason") + stopReason!: string; + + /** + * Which custom stop sequence was generated, if any. + * + * This value will be a non-null string if one of your custom stop sequences was + * generated. + */ + @alias("stop_sequence") + stopSequence: string | null = null; + + /** + * Object type. This is always `"message"`. + */ + type!: "message"; + + /** + * Billing and rate-limit usage. + */ + usage!: Usage; +} + + +@json +abstract class ContentBlock { + constructor(type: string) { + this.type = type; + } + + type!: string; +} + + +@json +export class TextBlock extends ContentBlock { + constructor() { + super("text"); + } + + text!: string; +} + + +@json +class ToolUseInput { + [key: string]: any; +} + + +@json +export class ToolUseBlock extends ContentBlock { + constructor() { + super("tool_use"); + } + + id!: string; + + input!: ToolUseInput; + + name!: string; +} + + +@json +class Usage { + /** + * The number of input tokens which were used. + */ + @alias("input_tokens") + inputTokens!: number; + + /** + * The number of output tokens which were used. + */ + @alias("output_tokens") + outputTokens!: number; +} diff --git a/src/package-lock.json b/src/package-lock.json index 78df055..79906d4 100644 --- a/src/package-lock.json +++ b/src/package-lock.json @@ -9,7 +9,6 @@ "version": "0.2.1", "license": "MIT", "dependencies": { - "@anthropic-ai/sdk": "^0.24.3", "json-as": "^0.9.8" }, "devDependencies": { @@ -24,29 +23,6 @@ "visitor-as": "^0.11.4" } }, - "node_modules/@anthropic-ai/sdk": { - "version": "0.24.3", - "resolved": "https://registry.npmjs.org/@anthropic-ai/sdk/-/sdk-0.24.3.tgz", - "integrity": "sha512-916wJXO6T6k8R6BAAcLhLPv/pnLGy7YSEBZXZ1XTFbLcTZE8oTy3oDW9WJf9KKZwMvVcePIfoTSvzXHRcGxkQQ==", - "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", - "web-streams-polyfill": "^3.2.1" - } - }, - "node_modules/@anthropic-ai/sdk/node_modules/@types/node": { - "version": "18.19.41", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.41.tgz", - "integrity": "sha512-LX84pRJ+evD2e2nrgYCHObGWkiQJ1mL+meAgbvnwk/US6vmMY7S2ygBTGV2Jw91s9vUsLSXeDEkUHZIJGLrhsg==", - "dependencies": { - "undici-types": "~5.26.4" - } - }, "node_modules/@eslint-community/eslint-utils": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", @@ -235,19 +211,11 @@ "version": "20.14.11", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.11.tgz", "integrity": "sha512-kprQpL8MMeszbz6ojB5/tU8PLN4kesnN8Gjzw349rDlNgsSzg90lAVj3llK99Dh7JON+t9AuscPPFW6mPbTnSA==", + "dev": true, "dependencies": { "undici-types": "~5.26.4" } }, - "node_modules/@types/node-fetch": { - "version": "2.6.11", - "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.11.tgz", - "integrity": "sha512-24xFj9R5+rfQJLRyM56qh+wnVSYhyXC2tkoBndtY0U+vubqNsYXGjufB2nn8Q6gt0LrARwL6UBtMCSVCwl4B1g==", - "dependencies": { - "@types/node": "*", - "form-data": "^4.0.0" - } - }, "node_modules/@typescript-eslint/eslint-plugin": { "version": "7.16.1", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.16.1.tgz", @@ -440,17 +408,6 @@ "dev": true, "license": "ISC" }, - "node_modules/abort-controller": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", - "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", - "dependencies": { - "event-target-shim": "^5.0.0" - }, - "engines": { - "node": ">=6.5" - } - }, "node_modules/acorn": { "version": "8.11.3", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", @@ -474,17 +431,6 @@ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, - "node_modules/agentkeepalive": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.5.0.tgz", - "integrity": "sha512-5GG/5IbQQpC9FpkRGsSvZI5QYeSCzlJHdpBQntCsuTOxhKD8lqKhrleg2Yi7yvMIf82Ycmmqln9U8V9qwEiJew==", - "dependencies": { - "humanize-ms": "^1.2.1" - }, - "engines": { - "node": ">= 8.0.0" - } - }, "node_modules/ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", @@ -586,11 +532,6 @@ "prettier": "^3.0.0" } }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" - }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -679,17 +620,6 @@ "dev": true, "license": "MIT" }, - "node_modules/combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dependencies": { - "delayed-stream": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -737,14 +667,6 @@ "dev": true, "license": "MIT" }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "engines": { - "node": ">=0.4.0" - } - }, "node_modules/dir-glob": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", @@ -958,14 +880,6 @@ "node": ">=0.10.0" } }, - "node_modules/event-target-shim": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", - "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", - "engines": { - "node": ">=6" - } - }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -1092,44 +1006,6 @@ "dev": true, "license": "ISC" }, - "node_modules/form-data": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", - "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/form-data-encoder": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-1.7.2.tgz", - "integrity": "sha512-qfqtYan3rxrnCk1VYaA4H+Ms9xdpPqvLZa6xmMgFvhO32x7/3J/ExcTd6qpxM0vH2GdMI+poehyBZvqfMTto8A==" - }, - "node_modules/formdata-node": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/formdata-node/-/formdata-node-4.4.1.tgz", - "integrity": "sha512-0iirZp3uVDjVGt9p49aTaqjk84TrglENEDuqfdlZQ1roC9CWlPk6Avf8EEnZNcAqPonwkG35x4n3ww/1THYAeQ==", - "dependencies": { - "node-domexception": "1.0.0", - "web-streams-polyfill": "4.0.0-beta.3" - }, - "engines": { - "node": ">= 12.20" - } - }, - "node_modules/formdata-node/node_modules/web-streams-polyfill": { - "version": "4.0.0-beta.3", - "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-4.0.0-beta.3.tgz", - "integrity": "sha512-QW95TCTaHmsYfHDybGMwO5IJIM93I/6vTRk+daHTWFPhwh+C8Cg7j7XyKrwrj8Ib6vYXe0ocYNrmzY4xAAN6ug==", - "engines": { - "node": ">= 14" - } - }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -1250,14 +1126,6 @@ "node": ">=8" } }, - "node_modules/humanize-ms": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", - "integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==", - "dependencies": { - "ms": "^2.0.0" - } - }, "node_modules/ignore": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", @@ -1491,25 +1359,6 @@ "node": ">=8.6" } }, - "node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, "node_modules/minimatch": { "version": "9.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", @@ -1530,6 +1379,7 @@ "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true, "license": "MIT" }, "node_modules/natural-compare": { @@ -1539,43 +1389,6 @@ "dev": true, "license": "MIT" }, - "node_modules/node-domexception": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", - "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/jimmywarting" - }, - { - "type": "github", - "url": "https://paypal.me/jimmywarting" - } - ], - "engines": { - "node": ">=10.5.0" - } - }, - "node_modules/node-fetch": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", - "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", - "dependencies": { - "whatwg-url": "^5.0.0" - }, - "engines": { - "node": "4.x || >=6.0.0" - }, - "peerDependencies": { - "encoding": "^0.1.0" - }, - "peerDependenciesMeta": { - "encoding": { - "optional": true - } - } - }, "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -1925,11 +1738,6 @@ "node": ">=8.0" } }, - "node_modules/tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" - }, "node_modules/ts-api-utils": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", @@ -1993,6 +1801,7 @@ "version": "5.26.5", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true, "license": "MIT" }, "node_modules/uri-js": { @@ -2019,28 +1828,6 @@ "assemblyscript": "^0.25.0" } }, - "node_modules/web-streams-polyfill": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz", - "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==", - "engines": { - "node": ">= 8" - } - }, - "node_modules/webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" - }, - "node_modules/whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", - "dependencies": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", diff --git a/src/package.json b/src/package.json index 57f3410..15c0f68 100644 --- a/src/package.json +++ b/src/package.json @@ -14,7 +14,6 @@ "lint:fix": "eslint --ext .ts --fix ." }, "dependencies": { - "@anthropic-ai/sdk": "^0.24.3", "json-as": "^0.9.8" }, "devDependencies": { From 2f4cfb7ec09205c8b0b37e381fc6c42ef699fd01 Mon Sep 17 00:00:00 2001 From: Kevin Mingtarja Date: Mon, 22 Jul 2024 11:38:36 +0700 Subject: [PATCH 03/16] stub inputSchema field with nullable string --- src/models/anthropic/messages.ts | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/src/models/anthropic/messages.ts b/src/models/anthropic/messages.ts index 9023620..e00da41 100644 --- a/src/models/anthropic/messages.ts +++ b/src/models/anthropic/messages.ts @@ -255,7 +255,7 @@ export class Tool { * will produce. */ @alias("input_schema") - inputSchema!: InputSchema; + inputSchema: string | null = null; // TODO: fix when https://github.com/JairusSW/as-json/issues/88 is fixed } @@ -303,22 +303,6 @@ export class ToolChoiceTool extends ToolChoice { } } - -@json -class Properties { - [key: string]: any; -} - - -@json -export class InputSchema { - type: string = "object"; - - - @omitnull() - properties: Properties | null = null; -} - /** * The output object for the Anthropic Messages API. */ From 3f4a5209b00cc167b45aea9b7c00231c3aec5b23 Mon Sep 17 00:00:00 2001 From: Kevin Mingtarja Date: Mon, 22 Jul 2024 12:15:02 +0700 Subject: [PATCH 04/16] add back topK field --- src/models/anthropic/messages.ts | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/models/anthropic/messages.ts b/src/models/anthropic/messages.ts index e00da41..56c7e30 100644 --- a/src/models/anthropic/messages.ts +++ b/src/models/anthropic/messages.ts @@ -200,10 +200,9 @@ class AnthropicMessagesInput { * Recommended for advanced use cases only. You usually only need to use * `temperature`. */ - // TODO: decide whether to include this field - // @alias("top_k") - // @omitnull() - // topK: i64 | null = null; + @alias("top_k") + @omitif("this.topK == -1") + topK: i64 = -1; // The default value of top_k is not specified in the API docs /** * Use nucleus sampling. From be64fd32ec31232605b6ee435c1f8dee65357cef Mon Sep 17 00:00:00 2001 From: Kevin Mingtarja Date: Mon, 22 Jul 2024 13:01:13 +0700 Subject: [PATCH 05/16] add missing constructors, constants, exports --- src/models/anthropic/messages.ts | 66 +++++++++++++++++++------------- 1 file changed, 39 insertions(+), 27 deletions(-) diff --git a/src/models/anthropic/messages.ts b/src/models/anthropic/messages.ts index 56c7e30..bf249ab 100644 --- a/src/models/anthropic/messages.ts +++ b/src/models/anthropic/messages.ts @@ -219,13 +219,18 @@ class AnthropicMessagesInput { @json -class Metadata { +export class Metadata { /** - * An external identifier for the user who is associated with the request. + * Creates a new metadata object. * - * This should be a uuid, hash value, or other opaque identifier. Anthropic may use - * this id to help detect abuse. Do not include any identifying information such as - * name, email address, or phone number. + * @param userId An external identifier for the user who is associated with the request. + */ + constructor(userId: string) { + this.userId = userId; + } + + /** + * An external identifier for the user who is associated with the request. */ @alias("user_id") userId: string | null = null; @@ -236,10 +241,26 @@ class Metadata { */ @json export class Tool { + /** + * Creates a new tool object. + * + * @param name Name of the tool. + * @param description Description of the tool. + * @param inputSchema JSON schema for this tool's input. + */ + constructor( + name: string, + description: string | null = null, + inputSchema: string | null = null, + ) { + this.name = name; + this.description = description; + this.inputSchema = inputSchema; + } /** * Name of the tool. */ - name!: string; + name: string; /** * Optional, but strongly-recommended description of the tool. @@ -259,47 +280,38 @@ export class Tool { @json -abstract class ToolChoice { - type!: string; - +class ToolChoice { constructor(type: string) { this.type = type; } + + type: string; } /** * The model will automatically decide whether to use tools. */ -@json -export class ToolChoiceAuto extends ToolChoice { - constructor() { - super("auto"); - } -} +export const ToolChoiceAuto = new ToolChoice("auto"); /** * The model will use any available tools. */ -@json -export class ToolChoiceAny extends ToolChoice { - constructor() { - super("any"); - } -} +export const ToolChoiceAny = new ToolChoice("any"); /** - * The model will use the specified tool with `tool_choice.name`. + * The model will use the specified tool. */ @json export class ToolChoiceTool extends ToolChoice { + constructor(name: string) { + super("tool"); + this.name = name; + } + /** * The name of the tool to use. */ - name!: string; - - constructor() { - super("tool"); - } + name: string; } /** From f2d532d6c11022c245b0526f4a77437b9baef4e4 Mon Sep 17 00:00:00 2001 From: Kevin Mingtarja Date: Mon, 22 Jul 2024 13:03:54 +0700 Subject: [PATCH 06/16] stub ToolUseBlock.input field --- src/models/anthropic/messages.ts | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/models/anthropic/messages.ts b/src/models/anthropic/messages.ts index bf249ab..27d9f11 100644 --- a/src/models/anthropic/messages.ts +++ b/src/models/anthropic/messages.ts @@ -389,12 +389,6 @@ export class TextBlock extends ContentBlock { } -@json -class ToolUseInput { - [key: string]: any; -} - - @json export class ToolUseBlock extends ContentBlock { constructor() { @@ -403,7 +397,7 @@ export class ToolUseBlock extends ContentBlock { id!: string; - input!: ToolUseInput; + input!: string; // TODO: verify this works, as it should be an object name!: string; } From 9f44c095d912f00e7b530ec6bf9365defc5f2d95 Mon Sep 17 00:00:00 2001 From: Kevin Mingtarja Date: Mon, 22 Jul 2024 13:14:02 +0700 Subject: [PATCH 07/16] make ToolChoiceTool an anonymous function --- src/models/anthropic/messages.ts | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/src/models/anthropic/messages.ts b/src/models/anthropic/messages.ts index 27d9f11..1e6792c 100644 --- a/src/models/anthropic/messages.ts +++ b/src/models/anthropic/messages.ts @@ -281,11 +281,18 @@ export class Tool { @json class ToolChoice { - constructor(type: string) { + constructor(type: string, name: string | null = null) { this.type = type; + this.name = name; } type: string; + + /** + * The name of the tool to use. + */ + @omitnull() + name: string | null = null; } /** @@ -301,18 +308,8 @@ export const ToolChoiceAny = new ToolChoice("any"); /** * The model will use the specified tool. */ -@json -export class ToolChoiceTool extends ToolChoice { - constructor(name: string) { - super("tool"); - this.name = name; - } - - /** - * The name of the tool to use. - */ - name: string; -} +export const ToolChoiceTool = (name: string): ToolChoice => + new ToolChoice("tool", name); /** * The output object for the Anthropic Messages API. From 450c450ad42d633daabcac2acbdc32b67dc366f0 Mon Sep 17 00:00:00 2001 From: Kevin Mingtarja Date: Mon, 22 Jul 2024 13:20:12 +0700 Subject: [PATCH 08/16] improve comments --- src/models/anthropic/messages.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/models/anthropic/messages.ts b/src/models/anthropic/messages.ts index 1e6792c..238d3c9 100644 --- a/src/models/anthropic/messages.ts +++ b/src/models/anthropic/messages.ts @@ -131,7 +131,7 @@ class AnthropicMessagesInput { maxTokens: i32 = 4096; /** - * An object describing metadata about the request. + * A `Metadata` object describing the request. */ @omitnull() metadata: Metadata | null = null; @@ -177,6 +177,8 @@ class AnthropicMessagesInput { /** * How the model should use the provided tools. + * + * Use either `ToolChoiceAuto`, `ToolChoiceAny`, or `ToolChoiceTool(name: string)`. */ @alias("tool_choice") @omitnull() From 3694d8518401b2f205cc4ee55c803f2bf4c18307 Mon Sep 17 00:00:00 2001 From: Kevin Mingtarja Date: Mon, 22 Jul 2024 13:24:18 +0700 Subject: [PATCH 09/16] protect name and type field of ToolChoice --- src/models/anthropic/messages.ts | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/models/anthropic/messages.ts b/src/models/anthropic/messages.ts index 238d3c9..4ce5e44 100644 --- a/src/models/anthropic/messages.ts +++ b/src/models/anthropic/messages.ts @@ -284,17 +284,20 @@ export class Tool { @json class ToolChoice { constructor(type: string, name: string | null = null) { - this.type = type; - this.name = name; + this._type = type; + this._name = name; } - type: string; + + @alias("type") + protected _type: string; /** * The name of the tool to use. */ + @alias("name") @omitnull() - name: string | null = null; + protected _name: string | null = null; } /** From 4c0598565e0fd8d7226a8ffb51084710c0e77877 Mon Sep 17 00:00:00 2001 From: Matt Johnson-Pint Date: Mon, 22 Jul 2024 16:55:24 -0700 Subject: [PATCH 10/16] Use JSON.Raw --- src/models/anthropic/messages.ts | 4 +++- src/models/openai/chat.ts | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/models/anthropic/messages.ts b/src/models/anthropic/messages.ts index 4ce5e44..d4ef8ad 100644 --- a/src/models/anthropic/messages.ts +++ b/src/models/anthropic/messages.ts @@ -1,4 +1,5 @@ import { Model } from "../.."; +import { JSON } from "json-as"; /** * Provides input and output types that conform to the Anthropic Messages API. @@ -276,8 +277,9 @@ export class Tool { * This defines the shape of the `input` that your tool accepts and that the model * will produce. */ + @omitnull() @alias("input_schema") - inputSchema: string | null = null; // TODO: fix when https://github.com/JairusSW/as-json/issues/88 is fixed + inputSchema: JSON.Raw | null = null; // TODO: verify this works } diff --git a/src/models/openai/chat.ts b/src/models/openai/chat.ts index d330cb1..95f11a9 100644 --- a/src/models/openai/chat.ts +++ b/src/models/openai/chat.ts @@ -1,4 +1,5 @@ import { Model } from "../.."; +import { JSON } from "json-as"; /** * Provides input and output types that conform to the OpenAI Chat API. @@ -365,7 +366,7 @@ export class FunctionDefinition { * See https://platform.openai.com/docs/guides/function-calling */ @omitnull() - parameters: string | null = null; // TODO: verify this works + parameters: JSON.Raw | null = null; // TODO: verify this works } /** From 4d9a13738ffb2c2a925eef04635249c54421ad7a Mon Sep 17 00:00:00 2001 From: Kevin Mingtarja Date: Tue, 23 Jul 2024 10:53:29 +0700 Subject: [PATCH 11/16] improve API for metadata and tools --- src/models/anthropic/messages.ts | 45 +++++++------------------------- 1 file changed, 10 insertions(+), 35 deletions(-) diff --git a/src/models/anthropic/messages.ts b/src/models/anthropic/messages.ts index d4ef8ad..92158cf 100644 --- a/src/models/anthropic/messages.ts +++ b/src/models/anthropic/messages.ts @@ -223,15 +223,6 @@ class AnthropicMessagesInput { @json export class Metadata { - /** - * Creates a new metadata object. - * - * @param userId An external identifier for the user who is associated with the request. - */ - constructor(userId: string) { - this.userId = userId; - } - /** * An external identifier for the user who is associated with the request. */ @@ -244,32 +235,10 @@ export class Metadata { */ @json export class Tool { - /** - * Creates a new tool object. - * - * @param name Name of the tool. - * @param description Description of the tool. - * @param inputSchema JSON schema for this tool's input. - */ - constructor( - name: string, - description: string | null = null, - inputSchema: string | null = null, - ) { - this.name = name; - this.description = description; - this.inputSchema = inputSchema; - } /** * Name of the tool. */ - name: string; - - /** - * Optional, but strongly-recommended description of the tool. - */ - @omitnull() - description: string | null = null; + name!: string; /** * [JSON schema](https://json-schema.org/) for this tool's input. @@ -278,8 +247,14 @@ export class Tool { * will produce. */ @omitnull() - @alias("input_schema") - inputSchema: JSON.Raw | null = null; // TODO: verify this works + // @alias("input_schema") + inputSchema!: JSON.Raw; + + /** + * Optional, but strongly-recommended description of the tool. + */ + @omitnull() + description: string | null = null; } @@ -401,7 +376,7 @@ export class ToolUseBlock extends ContentBlock { id!: string; - input!: string; // TODO: verify this works, as it should be an object + input!: JSON.Raw; name!: string; } From 48fea735db1d918b5484bb477c540a256f37a154 Mon Sep 17 00:00:00 2001 From: Kevin Mingtarja Date: Tue, 23 Jul 2024 15:49:48 +0700 Subject: [PATCH 12/16] add back alias --- src/models/anthropic/messages.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/models/anthropic/messages.ts b/src/models/anthropic/messages.ts index 92158cf..95deab1 100644 --- a/src/models/anthropic/messages.ts +++ b/src/models/anthropic/messages.ts @@ -247,7 +247,7 @@ export class Tool { * will produce. */ @omitnull() - // @alias("input_schema") + @alias("input_schema") inputSchema!: JSON.Raw; /** From 655b0ce2ea0c42876fd3b1e6a78de6035342dcc8 Mon Sep 17 00:00:00 2001 From: Kevin Mingtarja Date: Tue, 23 Jul 2024 16:07:52 +0700 Subject: [PATCH 13/16] Remove @omitnull from inputSchema as it is a required field --- src/models/anthropic/messages.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/models/anthropic/messages.ts b/src/models/anthropic/messages.ts index 95deab1..8b4c6c8 100644 --- a/src/models/anthropic/messages.ts +++ b/src/models/anthropic/messages.ts @@ -246,7 +246,6 @@ export class Tool { * This defines the shape of the `input` that your tool accepts and that the model * will produce. */ - @omitnull() @alias("input_schema") inputSchema!: JSON.Raw; From 4bd996a1b3a4caee0981d0eaac70ef21cdd63379 Mon Sep 17 00:00:00 2001 From: Kevin Mingtarja Date: Tue, 23 Jul 2024 16:28:54 +0700 Subject: [PATCH 14/16] fix content block type --- src/models/anthropic/messages.ts | 38 ++++++++++---------------------- 1 file changed, 12 insertions(+), 26 deletions(-) diff --git a/src/models/anthropic/messages.ts b/src/models/anthropic/messages.ts index 8b4c6c8..c828354 100644 --- a/src/models/anthropic/messages.ts +++ b/src/models/anthropic/messages.ts @@ -306,7 +306,7 @@ class AnthropicMessagesOutput { * Content generated by the model. * */ - content!: TextBlock[]; + content!: ContentBlock[]; /** * The model that handled the request. @@ -348,36 +348,22 @@ class AnthropicMessagesOutput { @json -abstract class ContentBlock { - constructor(type: string) { - this.type = type; - } - +class ContentBlock { type!: string; -} - - -@json -export class TextBlock extends ContentBlock { - constructor() { - super("text"); - } - - text!: string; -} + // Text block + @omitnull() + text: string | null = null; -@json -export class ToolUseBlock extends ContentBlock { - constructor() { - super("tool_use"); - } - - id!: string; + // Tool use block + @omitnull() + id: string | null = null; - input!: JSON.Raw; + @omitnull() + input: JSON.Raw | null = null; - name!: string; + @omitnull() + name: string | null = null; } From ce898e910abccbe175d1327fcdade13ecc1abf74 Mon Sep 17 00:00:00 2001 From: Kevin Mingtarja Date: Fri, 26 Jul 2024 09:36:42 +0700 Subject: [PATCH 15/16] bump json-as --- src/package-lock.json | 8 ++++---- src/package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/package-lock.json b/src/package-lock.json index 6c768dd..ce0078e 100644 --- a/src/package-lock.json +++ b/src/package-lock.json @@ -9,7 +9,7 @@ "version": "0.2.1", "license": "MIT", "dependencies": { - "json-as": "^0.9.19" + "json-as": "^0.9.20" }, "devDependencies": { "@types/node": "^20.14.12", @@ -1471,9 +1471,9 @@ } }, "node_modules/json-as": { - "version": "0.9.19", - "resolved": "https://registry.npmjs.org/json-as/-/json-as-0.9.19.tgz", - "integrity": "sha512-jH+eiNI2oekOM6c20dmfgvK+gGM10ek0QE0iZ0ju73ODgtqDjEBi2NLi9ud+SsNBuvcL77AE55S7ePgreoAyPQ==", + "version": "0.9.20", + "resolved": "https://registry.npmjs.org/json-as/-/json-as-0.9.20.tgz", + "integrity": "sha512-F4tVjBvfjun1rK+LgiClayHW57E4ERrMdjZWMjCynbNax2PXBzSUWd957ZACZ0DNjbZGUwC+eDunL+5Lj8sbHg==", "dependencies": { "as-virtual": "^0.2.0" } diff --git a/src/package.json b/src/package.json index 6229d39..e096563 100644 --- a/src/package.json +++ b/src/package.json @@ -14,7 +14,7 @@ "lint:fix": "eslint --ext .ts --fix ." }, "dependencies": { - "json-as": "^0.9.19" + "json-as": "^0.9.20" }, "devDependencies": { "@types/node": "^20.14.12", From 8c7dcde7e541802f70edd763169c71bacf3979a6 Mon Sep 17 00:00:00 2001 From: Kevin Mingtarja Date: Fri, 26 Jul 2024 09:39:31 +0700 Subject: [PATCH 16/16] Run prettier --- src/models/anthropic/messages.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/models/anthropic/messages.ts b/src/models/anthropic/messages.ts index c828354..72e491d 100644 --- a/src/models/anthropic/messages.ts +++ b/src/models/anthropic/messages.ts @@ -359,9 +359,11 @@ class ContentBlock { @omitnull() id: string | null = null; + @omitnull() input: JSON.Raw | null = null; + @omitnull() name: string | null = null; }