mirror of
https://github.com/lobehub/lobehub.git
synced 2026-03-27 13:29:15 +07:00
✨ feat: 支持查询天气
This commit is contained in:
@@ -1,8 +1,13 @@
|
||||
import { OpenAIStream, StreamingTextResponse } from 'ai';
|
||||
import { Configuration, OpenAIApi } from 'openai-edge';
|
||||
import { ChatCompletionFunctions, ChatCompletionRequestMessage } from 'openai-edge/types/api';
|
||||
|
||||
import { OpenAIStreamPayload } from '@/types/openai';
|
||||
|
||||
import { plugins } from './plugins';
|
||||
|
||||
export const runtime = 'edge';
|
||||
|
||||
const isDev = process.env.NODE_ENV === 'development';
|
||||
const OPENAI_PROXY_URL = process.env.OPENAI_PROXY_URL;
|
||||
|
||||
@@ -13,19 +18,38 @@ const config = new Configuration({
|
||||
|
||||
const openai = new OpenAIApi(config, isDev && OPENAI_PROXY_URL ? OPENAI_PROXY_URL : undefined);
|
||||
|
||||
export const runtime = 'edge';
|
||||
const functions: ChatCompletionFunctions[] = plugins.map((f) => f.schema);
|
||||
|
||||
export default async function handler(req: Request) {
|
||||
// Extract the `messages` from the body of the request
|
||||
const { messages, ...params } = (await req.json()) as OpenAIStreamPayload;
|
||||
|
||||
console.log(params);
|
||||
const formatMessages = messages.map((m) => ({ content: m.content, role: m.role }));
|
||||
|
||||
const response = await openai.createChatCompletion({
|
||||
functions,
|
||||
messages: formatMessages,
|
||||
stream: true,
|
||||
...params,
|
||||
messages: messages.map((m) => ({ content: m.content, role: m.role })),
|
||||
});
|
||||
|
||||
const stream = OpenAIStream(response);
|
||||
const stream = OpenAIStream(response, {
|
||||
experimental_onFunctionCall: async ({ name, arguments: args }, createFunctionCallMessages) => {
|
||||
const func = plugins.find((f) => f.name === name);
|
||||
|
||||
if (func) {
|
||||
const result = await func.runner(args as any);
|
||||
|
||||
const newMessages = createFunctionCallMessages(result) as ChatCompletionRequestMessage[];
|
||||
|
||||
return openai.createChatCompletion({
|
||||
functions,
|
||||
messages: [...formatMessages, ...newMessages],
|
||||
stream: true,
|
||||
...params,
|
||||
});
|
||||
}
|
||||
},
|
||||
});
|
||||
return new StreamingTextResponse(stream);
|
||||
}
|
||||
|
||||
3
src/pages/api/plugins/index.ts
Normal file
3
src/pages/api/plugins/index.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
import getWeather from './weather';
|
||||
|
||||
export const plugins = [getWeather];
|
||||
20
src/pages/api/plugins/weather/index.ts
Normal file
20
src/pages/api/plugins/weather/index.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
import runner from './runner';
|
||||
|
||||
const schema = {
|
||||
description: '获取当前天气情况',
|
||||
name: 'fetchWeather',
|
||||
parameters: {
|
||||
properties: {
|
||||
city: {
|
||||
description: '城市名称',
|
||||
type: 'string',
|
||||
},
|
||||
},
|
||||
required: ['city'],
|
||||
type: 'object',
|
||||
},
|
||||
};
|
||||
|
||||
const getWeather = { name: 'fetchWeather', runner, schema };
|
||||
|
||||
export default getWeather;
|
||||
30
src/pages/api/plugins/weather/runner.ts
Normal file
30
src/pages/api/plugins/weather/runner.ts
Normal file
@@ -0,0 +1,30 @@
|
||||
const weatherBaseURL = 'https://restapi.amap.com/v3/weather/weatherInfo';
|
||||
|
||||
const citySearchURL = 'https://restapi.amap.com/v3/config/district';
|
||||
|
||||
const KEY = process.env.GAODE_WEATHER_KEY;
|
||||
|
||||
interface WeatherParams {
|
||||
city: string;
|
||||
extensions?: 'base' | 'all';
|
||||
}
|
||||
|
||||
const fetchCityCode = async (keywords: string): Promise<string> => {
|
||||
const URL = `${citySearchURL}?keywords=${keywords}&subdistrict=0&extensions=base&key=${KEY}`;
|
||||
const res = await fetch(URL);
|
||||
|
||||
const data = await res.json();
|
||||
|
||||
return data.districts[0].adcode;
|
||||
};
|
||||
|
||||
const fetchWeather = async ({ city, extensions = 'all' }: WeatherParams) => {
|
||||
const cityCode = await fetchCityCode(city);
|
||||
|
||||
const URL = `${weatherBaseURL}?city=${cityCode}&extensions=${extensions}&key=${KEY}`;
|
||||
const res = await fetch(URL);
|
||||
|
||||
return await res.json();
|
||||
};
|
||||
|
||||
export default fetchWeather;
|
||||
Reference in New Issue
Block a user