diff --git a/chat-sample/package-lock.json b/chat-sample/package-lock.json index 54818043..5ae89133 100644 --- a/chat-sample/package-lock.json +++ b/chat-sample/package-lock.json @@ -7,8 +7,10 @@ "": { "name": "chat-sample", "version": "0.1.0", + "hasInstallScript": true, "devDependencies": { "@types/node": "^20.5.9", + "@vscode/prompt-tsx": "^0.1.10-alpha", "eslint": "^7.22.0", "tslint": "^6.1.3", "typescript": "^4.0.3" @@ -200,6 +202,15 @@ "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", "dev": true }, + "node_modules/@microsoft/tiktokenizer": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@microsoft/tiktokenizer/-/tiktokenizer-1.0.6.tgz", + "integrity": "sha512-Vi12N9vsU9jP3L95Ji1ZNMZyEbA9zIhLQd3oUPufoPqQZsnH2UGV2e2PDp2auJr7HvuDejGznWzHPj0pIjgBWg==", + "dev": true, + "engines": { + "node": ">=18.0.0" + } + }, "node_modules/@types/node": { "version": "20.9.0", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.9.0.tgz", @@ -209,6 +220,15 @@ "undici-types": "~5.26.4" } }, + "node_modules/@vscode/prompt-tsx": { + "version": "0.1.10-alpha", + "resolved": "https://registry.npmjs.org/@vscode/prompt-tsx/-/prompt-tsx-0.1.10-alpha.tgz", + "integrity": "sha512-iqe1XlYsmxGGle7hmMnKd4DOebjFVmQ2odgoSzCYutOzHcqMzlRPac2sNYDQLpYlvutFi0vXl+VMPg0D3uOvVA==", + "dev": true, + "dependencies": { + "@microsoft/tiktokenizer": "^1.0.6" + } + }, "node_modules/acorn": { "version": "8.11.2", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.2.tgz", diff --git a/chat-sample/package.json b/chat-sample/package.json index 5f585543..3d48856c 100644 --- a/chat-sample/package.json +++ b/chat-sample/package.json @@ -15,15 +15,15 @@ "AI", "Chat" ], - "activationEvents": [ ], + "activationEvents": [], "enabledApiProposals": [ "chatVariableResolver" ], "contributes": { "chatParticipants": [ { - "id": "chat-sample.cat", - "fullName": "Cat", + "id": "chat-sample.cat", + "fullName": "Cat", "name": "cat", "description": "Meow! What can I teach you?", "isSticky": true, @@ -50,10 +50,13 @@ "scripts": { "vscode:prepublish": "npm run compile", "compile": "tsc -p ./", - "watch": "tsc -watch -p ./" + "watch": "tsc -watch -p ./", + "setupTiktoken": "cp node_modules/@vscode/prompt-tsx/dist/base/tokenizer/cl100k_base.tiktoken out/", + "postinstall": "npm run setupTiktoken" }, "devDependencies": { "@types/node": "^20.5.9", + "@vscode/prompt-tsx": "^0.1.10-alpha", "eslint": "^7.22.0", "tslint": "^6.1.3", "typescript": "^4.0.3" diff --git a/chat-sample/src/extension.ts b/chat-sample/src/extension.ts index 5c36a0b9..ad9d22eb 100644 --- a/chat-sample/src/extension.ts +++ b/chat-sample/src/extension.ts @@ -1,4 +1,6 @@ +import { renderPrompt, Cl100KBaseTokenizer } from '@vscode/prompt-tsx'; import * as vscode from 'vscode'; +import { PlayPrompt } from './play'; const CAT_NAMES_COMMAND_ID = 'cat.namesInEditor'; const CAT_PARTICIPANT_ID = 'chat-sample.cat'; @@ -41,12 +43,14 @@ export function activate(context: vscode.ExtensionContext) { return { metadata: { command: 'teach' } }; } else if (request.command == 'play') { stream.progress('Throwing away the computer science books and preparing to play with some Python code...'); - const messages = [ - vscode.LanguageModelChatMessage.User('You are a cat! Reply in the voice of a cat, using cat analogies when appropriate. Be concise to prepare for cat play time.'), - vscode.LanguageModelChatMessage.User('Give a small random python code samples (that have cat names for variables). ' + request.prompt) - ]; const [model] = await vscode.lm.selectChatModels(MODEL_SELECTOR); if (model) { + // Here's an example of how to use the prompt-tsx library to build a prompt + const { messages } = await renderPrompt( + PlayPrompt, + { userQuery: request.prompt }, + { modelMaxPromptTokens: model.maxInputTokens }, + new Cl100KBaseTokenizer()); const chatResponse = await model.sendRequest(messages, {}, token); for await (const fragment of chatResponse.text) { stream.markdown(fragment); diff --git a/chat-sample/src/play.tsx b/chat-sample/src/play.tsx new file mode 100644 index 00000000..4ad4c202 --- /dev/null +++ b/chat-sample/src/play.tsx @@ -0,0 +1,25 @@ +import { + BasePromptElementProps, + PromptElement, + PromptSizing, + UserMessage +} from '@vscode/prompt-tsx'; + +export interface PromptProps extends BasePromptElementProps { + userQuery: string; +} + +export class PlayPrompt extends PromptElement { + render(state: void, sizing: PromptSizing) { + return ( + <> + + You are a cat! Reply in the voice of a cat, using cat analogies when + appropriate. Be concise to prepare for cat play time. Give a small random + python code sample (that has cat names for variables). + + {this.props.userQuery} + + ); + } +} diff --git a/chat-sample/tsconfig.json b/chat-sample/tsconfig.json index 5f02c869..3b1697b2 100644 --- a/chat-sample/tsconfig.json +++ b/chat-sample/tsconfig.json @@ -8,7 +8,10 @@ "sourceMap": true, "rootDir": "src", "strict": true, /* enable all strict type-checking options */ - "outDir": "out" + "outDir": "out", + "jsx": "react", + "jsxFactory": "vscpp", + "jsxFragmentFactory": "vscppf" /* Additional Checks */ // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */