1/**
2 * This val creates an interactive webpage that demonstrates the functionality of the Anthropic API.
3 * It uses a React frontend with an input for the API key and buttons to trigger different operations.
4 * The Anthropic API key is stored in the frontend state and sent with each API request.
5 */
6
10
11function App() {
12 const [apiKey, setApiKey] = useState("");
13 const [outputs, setOutputs] = useState({
14 nonCachedCall: "",
23
24 const runOperation = async (operation: string) => {
25 if (!apiKey) {
26 alert("Please enter your Anthropic API key first.");
27 return;
28 }
35 "Content-Type": "application/json",
36 },
37 body: JSON.stringify({ apiKey }),
38 });
39 const result = await response.text();
52 <a href="https://github.com/anthropics/anthropic-cookbook/blob/7786b9f39db8ba65202792f564c59697a5222531/misc/prompt_caching.ipynb#L402">
53 this python notebook
54 </a>. Enter in your Anthropic API key (which is not saved) and click the buttons to see the results.
55 </p>
56 <p>
60 <input
61 type="password"
62 placeholder="Enter Anthropic API Key"
63 value={apiKey}
64 onChange={(e) => setApiKey(e.target.value)}
65 />
66 </div>
67 <div>
68 <button onClick={() => runOperation("nonCachedCall")} disabled={loading.nonCachedCall}>
69 Non-cached API Call
70 </button>
71 <button onClick={() => runOperation("cachedCall")} disabled={loading.cachedCall}>Cached API Call</button>
72 <button onClick={() => runOperation("multiTurn")} disabled={loading.multiTurn}>Multi-turn Conversation</button>
73 </div>
74 <h2>Non-cached API Call Output:</h2>
75 <pre>{loading.nonCachedCall ? "Loading..." : outputs.nonCachedCall}</pre>
76 <h2>Cached API Call Output:</h2>
77 <pre>{loading.cachedCall ? "Loading..." : outputs.cachedCall}</pre>
78 <h2>Multi-turn Conversation Output:</h2>
95 if (url.pathname === "/run") {
96 const operation = url.searchParams.get("operation");
97 const { apiKey } = await request.json();
98
99 if (!apiKey) {
100 return new Response("API key is required", { status: 400 });
101 }
102
104
105 if (operation === "nonCachedCall") {
106 result = await runNonCachedCall(apiKey);
107 } else if (operation === "cachedCall") {
108 result = "Making two calls, first one to cache...\n\n";
109 result += await runCachedCall(apiKey);
110 result += "\n\nNow the cached call...\n\n";
111 result += await runCachedCall(apiKey);
112 } else if (operation === "multiTurn") {
113 result = await runMultiTurnConversation(apiKey);
114 } else {
115 return new Response("Invalid operation", { status: 400 });
146}
147
148async function runNonCachedCall(apiKey: string): Promise<string> {
149 const { default: anthropic } = await import("npm:@anthropic-ai/sdk@0.26.1");
150 const client = new anthropic.Anthropic({ apiKey });
151 const MODEL_NAME = "claude-3-5-sonnet-20240620";
152
175 const elapsedTime = (endTime - startTime) / 1000;
176
177 return `Non-cached API call time: ${elapsedTime.toFixed(2)} seconds
178Input tokens: ${response.usage.input_tokens}
179Output tokens: ${response.usage.output_tokens}
182}
183
184async function runCachedCall(apiKey: string): Promise<string> {
185 const { default: anthropic } = await import("npm:@anthropic-ai/sdk@0.26.1");
186 const client = new anthropic.Anthropic({ apiKey });
187 const MODEL_NAME = "claude-3-5-sonnet-20240620";
188
212 const elapsedTime = (endTime - startTime) / 1000;
213
214 return `Cached API call time: ${elapsedTime.toFixed(2)} seconds
215Input tokens: ${response.usage.input_tokens}
216Output tokens: ${response.usage.output_tokens}
221}
222
223async function runMultiTurnConversation(apiKey: string): Promise<string> {
224 const { default: anthropic } = await import("npm:@anthropic-ai/sdk@0.26.1");
225 const client = new anthropic.Anthropic({ apiKey });
226 const MODEL_NAME = "claude-3-5-sonnet-20240620";
227