Skip to content

Commit 571ce11

Browse files
committed
stash code
1 parent d2cb984 commit 571ce11

File tree

5 files changed

+213
-5
lines changed

5 files changed

+213
-5
lines changed

app/client/platforms/openai.ts

+8-2
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import {
1414
useAccessStore,
1515
useAppConfig,
1616
useChatStore,
17+
usePluginStore,
1718
} from "@/app/store";
1819
import { collectModelsWithDefaultModel } from "@/app/utils/model";
1920
import {
@@ -240,6 +241,11 @@ export class ChatGPTApi implements LLMApi {
240241
);
241242
}
242243
if (shouldStream) {
244+
const [tools1, funcs2] = usePluginStore
245+
.getState()
246+
.getAsTools(useChatStore.getState().currentSession().mask?.plugin);
247+
console.log("getAsTools", tools1, funcs2);
248+
// return
243249
// TODO mock tools and funcs
244250
const tools = [
245251
{
@@ -276,8 +282,8 @@ export class ChatGPTApi implements LLMApi {
276282
chatPath,
277283
requestPayload,
278284
getHeaders(),
279-
tools,
280-
funcs,
285+
tools1,
286+
funcs2,
281287
controller,
282288
// parseSSE
283289
(text: string, runTools: ChatMessageTool[]) => {

app/components/chat.tsx

+76-3
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ import {
5454
useAppConfig,
5555
DEFAULT_TOPIC,
5656
ModelType,
57+
usePluginStore,
5758
} from "../store";
5859

5960
import {
@@ -440,6 +441,71 @@ export function ChatActions(props: {
440441
const config = useAppConfig();
441442
const navigate = useNavigate();
442443
const chatStore = useChatStore();
444+
const pluginStore = usePluginStore();
445+
console.log("pluginStore", pluginStore.getAll());
446+
// test
447+
if (pluginStore.getAll().length == 0) {
448+
pluginStore.create({
449+
title: "Pet API",
450+
version: "1.0.0",
451+
content: `{
452+
"openapi": "3.0.2",
453+
"info": {
454+
"title": "Pet API",
455+
"version": "1.0.0"
456+
},
457+
"paths": {
458+
"/api/pets": {
459+
"get": {
460+
"operationId": "getPets",
461+
"description": "Returns all pets from the system that the user has access to",
462+
"responses": {
463+
"200": {
464+
"description": "List of Pets",
465+
"content": {
466+
"application/json": {
467+
"schema": {
468+
"type": "array",
469+
"items": {
470+
"$ref": "#/components/schemas/Pet"
471+
}
472+
}
473+
}
474+
}
475+
}
476+
}
477+
}
478+
}
479+
},
480+
"components": {
481+
"schemas": {
482+
"Pet": {
483+
"type": "object",
484+
"properties": {
485+
"id": {
486+
"type": "string"
487+
},
488+
"type": {
489+
"type": "string",
490+
"enum": [
491+
"cat",
492+
"dog"
493+
]
494+
},
495+
"name": {
496+
"type": "string"
497+
}
498+
},
499+
"required": [
500+
"id",
501+
"type"
502+
]
503+
}
504+
}
505+
}
506+
}`,
507+
});
508+
}
443509

444510
// switch themes
445511
const theme = config.theme;
@@ -738,15 +804,22 @@ export function ChatActions(props: {
738804
title: Locale.Plugin.Artifacts,
739805
value: Plugin.Artifacts,
740806
},
741-
]}
807+
].concat(
808+
pluginStore
809+
.getAll()
810+
.map((item) => ({
811+
title: `${item.title}@${item.version}`,
812+
value: item.id,
813+
})),
814+
)}
742815
onClose={() => setShowPluginSelector(false)}
743816
onSelection={(s) => {
744817
const plugin = s[0];
745818
chatStore.updateCurrentSession((session) => {
746819
session.mask.plugin = s;
747820
});
748-
if (plugin) {
749-
showToast(plugin);
821+
if (s.includes(Plugin.Artifacts)) {
822+
showToast(Plugin.Artifacts);
750823
}
751824
}}
752825
/>

app/constant.ts

+1
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ export enum Plugin {
7878

7979
export enum StoreKey {
8080
Chat = "chat-next-web-store",
81+
Plugin = "chat-next-web-plugin",
8182
Access = "access-control",
8283
Config = "app-config",
8384
Mask = "mask-store",

app/store/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@ export * from "./chat";
22
export * from "./update";
33
export * from "./access";
44
export * from "./config";
5+
export * from "./plugin";

app/store/plugin.ts

+127
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
import OpenAPIClientAxios from "openapi-client-axios";
2+
import { getLang, Lang } from "../locales";
3+
import { StoreKey, Plugin } from "../constant";
4+
import { nanoid } from "nanoid";
5+
import { createPersistStore } from "../utils/store";
6+
import yaml from "js-yaml";
7+
8+
export type Plugin = {
9+
id: string;
10+
createdAt: number;
11+
title: string;
12+
version: string;
13+
context: string;
14+
builtin: boolean;
15+
};
16+
17+
export const createEmptyPlugin = () =>
18+
({
19+
id: nanoid(),
20+
title: "",
21+
version: "",
22+
context: "",
23+
builtin: false,
24+
createdAt: Date.now(),
25+
}) as Plugin;
26+
27+
export const DEFAULT_PLUGIN_STATE = {
28+
plugins: {} as Record<string, Plugin>,
29+
};
30+
31+
export const usePluginStore = createPersistStore(
32+
{ ...DEFAULT_PLUGIN_STATE },
33+
34+
(set, get) => ({
35+
create(plugin?: Partial<Plugin>) {
36+
const plugins = get().plugins;
37+
const id = nanoid();
38+
plugins[id] = {
39+
...createEmptyPlugin(),
40+
...plugin,
41+
id,
42+
builtin: false,
43+
};
44+
45+
set(() => ({ plugins }));
46+
get().markUpdate();
47+
48+
return plugins[id];
49+
},
50+
updatePlugin(id: string, updater: (plugin: Plugin) => void) {
51+
const plugins = get().plugins;
52+
const plugin = plugins[id];
53+
if (!plugin) return;
54+
const updatePlugin = { ...plugin };
55+
updater(updatePlugin);
56+
plugins[id] = updatePlugin;
57+
set(() => ({ plugins }));
58+
get().markUpdate();
59+
},
60+
delete(id: string) {
61+
const plugins = get().plugins;
62+
delete plugins[id];
63+
set(() => ({ plugins }));
64+
get().markUpdate();
65+
},
66+
67+
getAsTools(ids: string[]) {
68+
const plugins = get().plugins;
69+
const selected = ids
70+
.map((id) => plugins[id])
71+
.filter((i) => i)
72+
.map((i) => [
73+
i,
74+
new OpenAPIClientAxios({ definition: yaml.load(i.content) }),
75+
])
76+
.map(([item, api]) => {
77+
api.initSync();
78+
const operations = api.getOperations().map((o) => {
79+
const parameters = o.parameters;
80+
return [
81+
{
82+
type: "function",
83+
function: {
84+
name: o.operationId,
85+
description: o.description,
86+
parameters: o.parameters,
87+
},
88+
},
89+
api.client[o.operationId],
90+
];
91+
// return [{
92+
// }, function(arg) {
93+
// const args = []
94+
// for (const p in parameters) {
95+
// if (p.type === "object") {
96+
// const a = {}
97+
// for (const n of p.)
98+
// }
99+
// }
100+
// }]
101+
});
102+
return [item, api, operations];
103+
});
104+
console.log("selected", selected);
105+
const result = selected.reduce((s, i) => s.concat(i[2]), []);
106+
return [
107+
result.map(([t, _]) => t),
108+
result.reduce((s, i) => {
109+
s[i[0].function.name] = i[1];
110+
return s;
111+
}, {}),
112+
];
113+
},
114+
get(id?: string) {
115+
return get().plugins[id ?? 1145141919810];
116+
},
117+
getAll() {
118+
return Object.values(get().plugins).sort(
119+
(a, b) => b.createdAt - a.createdAt,
120+
);
121+
},
122+
}),
123+
{
124+
name: StoreKey.Plugin,
125+
version: 1,
126+
},
127+
);

0 commit comments

Comments
 (0)