35import { blob } from "https://esm.town/v/std/blob";
36import { sqlite } from "https://esm.town/v/std/sqlite";
37import { OpenAI } from "https://esm.town/v/std/openai";
38import { email } from "https://esm.town/v/std/email";
39```
1import { OpenAI } from "https://esm.town/v/std/openai";
2
3const openai = new OpenAI();
4
5const completion = await openai.chat.completions.create({
6 messages: [
7 { role: "user", content: "Say hello in a creative way" },
88Note: When changing a SQLite table's schema, change the table's name (e.g., add _2 or _3) to create a fresh table.
89
90### OpenAI
91
92```ts
93import { OpenAI } from "https://esm.town/v/std/openai";
94const openai = new OpenAI();
95const completion = await openai.chat.completions.create({
96 messages: [
97 { role: "user", content: "Say hello in a creative way" },
94Note: When changing a SQLite table's schema, change the table's name (e.g., add _2 or _3) to create a fresh table.
95
96### OpenAI
97
98```ts
99import { OpenAI } from "https://esm.town/v/std/openai";
100const openai = new OpenAI();
101const completion = await openai.chat.completions.create({
102 messages: [
103 { role: "user", content: "Say hello in a creative way" },
680// --- SERVER-SIDE LOGIC ---
681export default async function(req: Request) {
682 const { OpenAI } = await import("https://esm.town/v/std/openai");
683 const { PDFExtract } = await import("npm:pdf.js-extract");
684
694 const action = url.searchParams.get("action");
695 const sourceUrl = import.meta.url.replace("esm.town", "val.town");
696 const openai = new OpenAI();
697 const MAX_TEXT_ANALYZE = 30000;
698
722 agentName: string,
723 ): Promise<object> {
724 log.push({ agent: agentName, type: "step", message: `Calling OpenAI gpt-4o...` });
725 try {
726 const response = await openai.chat.completions.create({
727 model: "gpt-4o",
728 messages: [{ role: "system", content: systemPrompt }, { role: "user", content: userMessage }],
852
853export default async function(req: Request) {
854 const { OpenAI } = await import("https://esm.town/v/std/openai");
855 const { PDFExtract } = await import("npm:pdf.js-extract");
856
866 const action = url.searchParams.get("action");
867 const sourceUrl = import.meta.url.replace("esm.town", "val.town");
868 const openai = new OpenAI();
869 const MAX_TEXT_SUGGEST = 20000;
870 const MAX_TEXT_ANALYZE = 30000;
895 agentName: string,
896 ): Promise<object> {
897 log.push({ agent: agentName, type: "step", message: `Calling OpenAI gpt-4o...` });
898 try {
899 const response = await openai.chat.completions.create({
900 model: "gpt-4o",
901 messages: [{ role: "system", content: systemPrompt }, { role: "user", content: userMessage }],
100Note: When changing a SQLite table's schema, change the table's name (e.g., add _2 or _3) to create a fresh table.
101
102### OpenAI
103```ts
104import { OpenAI } from "https://esm.town/v/std/openai";
105const openai = new OpenAI();
106const completion = await openai.chat.completions.create({
107 messages: [
108 { role: "user", content: "Say hello in a creative way" },
100Note: When changing a SQLite table's schema, change the table's name (e.g., add _2 or _3) to create a fresh table.
101
102### OpenAI
103```ts
104import { OpenAI } from "https://esm.town/v/std/openai";
105const openai = new OpenAI();
106const completion = await openai.chat.completions.create({
107 messages: [
108 { role: "user", content: "Say hello in a creative way" },
100Note: When changing a SQLite table's schema, change the table's name (e.g., add _2 or _3) to create a fresh table.
101
102### OpenAI
103```ts
104import { OpenAI } from "https://esm.town/v/std/openai";
105const openai = new OpenAI();
106const completion = await openai.chat.completions.create({
107 messages: [
108 { role: "user", content: "Say hello in a creative way" },
1# Plant Information API
2
3A REST API that provides detailed plant information using OpenAI's GPT model with intelligent caching for improved performance and reduced API costs.
4
5## Features
7- Get comprehensive plant information by name
8- Structured JSON response with 8 key plant characteristics
9- Powered by OpenAI GPT-4o-mini for accurate plant data
10- **Intelligent caching system** - stores successful responses and serves cached data for repeated requests
11- Cache management endpoints for monitoring and administration
24
25### GET /plant/:name
26Returns detailed information about a specific plant. If the plant information is already cached, returns the cached response immediately. Otherwise, fetches new information from OpenAI and caches it for future requests.
27
28**Parameters:**
46
47**Cache Indicators:**
48- `_cached`: Boolean indicating if the response came from cache (true) or OpenAI (false)
49- `_cacheTimestamp`: ISO timestamp of when the response was generated
50
152- `200`: Success
153- `400`: Bad request (missing plant name)
154- `500`: Server error (OpenAI API issues, parsing errors)
155
156Error responses include descriptive error messages and may include additional debugging information.
188- **Plant name normalization**: Plant names are normalized (lowercased, special characters removed, spaces converted to underscores) for consistent caching
189- **Cache hits**: Subsequent requests for the same plant (even with different capitalization or spacing) will return cached responses instantly
190- **Cache misses**: New plants trigger OpenAI API calls and the responses are automatically cached
191- **Performance**: Cached responses are served in milliseconds vs. seconds for OpenAI API calls
192- **Cost efficiency**: Reduces OpenAI API usage and associated costs
193
194## Technical Details
195
196- Built with Hono framework
197- Uses OpenAI GPT-4o-mini model
198- SQLite database for caching with automatic table creation
199- Includes input validation and error handling