@raingor/pi-web-switch 0.3.1 → 0.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +0 -1
- package/README.zh-CN.md +0 -1
- package/package.json +1 -1
- package/server/pi-reader.ts +403 -4
- package/src/App.tsx +3 -0
- package/src/components/dashboard/DashboardPage.tsx +275 -117
- package/src/components/layout/Sidebar.tsx +2 -0
- package/src/components/providers/ProvidersModelsPage.tsx +1387 -0
- package/src/components/sessions/MemoryPage.tsx +480 -85
- package/src/components/sessions/SessionsPage.tsx +473 -89
- package/src/components/settings/SettingsPage.tsx +555 -243
- package/src/data/builtin-providers.ts +0 -12
- package/src/data/mock-config.ts +1 -15
- package/src/data/mock-usage.ts +0 -2
- package/src/lib/translations/en.ts +114 -23
- package/src/lib/translations/ja.ts +114 -23
- package/src/lib/translations/zh-CN.ts +114 -23
- package/src/lib/translations/zh-TW.ts +114 -23
- package/src/main.tsx +9 -0
- package/src/store/config-store.ts +18 -12
- package/src/types/index.ts +14 -0
- package/tsconfig.tsbuildinfo +1 -0
- package/vite.config.ts +115 -3
- package/src/components/models/ModelsPage.tsx +0 -570
- package/src/components/providers/ProvidersPage.tsx +0 -466
package/vite.config.ts
CHANGED
|
@@ -87,6 +87,116 @@ function piApiPlugin(): Plugin {
|
|
|
87
87
|
res.setHeader("Content-Type", "application/json");
|
|
88
88
|
res.end(JSON.stringify(memory));
|
|
89
89
|
},
|
|
90
|
+
"POST /api/pi/memory/delete-entry"(req, res) {
|
|
91
|
+
let body = "";
|
|
92
|
+
req.on("data", (chunk: string) => (body += chunk));
|
|
93
|
+
req.on("end", () => {
|
|
94
|
+
try {
|
|
95
|
+
const { filename, text } = JSON.parse(body) as { filename: string; text: string };
|
|
96
|
+
const ok = pi.deleteMemoryEntry(filename, text);
|
|
97
|
+
res.setHeader("Content-Type", "application/json");
|
|
98
|
+
res.end(JSON.stringify({ success: ok }));
|
|
99
|
+
} catch {
|
|
100
|
+
res.statusCode = 400;
|
|
101
|
+
res.setHeader("Content-Type", "application/json");
|
|
102
|
+
res.end(JSON.stringify({ success: false, error: "Invalid request body" }));
|
|
103
|
+
}
|
|
104
|
+
});
|
|
105
|
+
},
|
|
106
|
+
"GET /api/pi/trash"(_, res) {
|
|
107
|
+
res.setHeader("Content-Type", "application/json");
|
|
108
|
+
res.end(JSON.stringify(pi.listTrash()));
|
|
109
|
+
},
|
|
110
|
+
"POST /api/pi/session/trash"(req, res) {
|
|
111
|
+
let body = "";
|
|
112
|
+
req.on("data", (chunk: string) => (body += chunk));
|
|
113
|
+
req.on("end", () => {
|
|
114
|
+
try {
|
|
115
|
+
const { path: p } = JSON.parse(body) as { path: string };
|
|
116
|
+
const ok = pi.trashSessionFile(p);
|
|
117
|
+
res.setHeader("Content-Type", "application/json");
|
|
118
|
+
res.end(JSON.stringify({ success: ok }));
|
|
119
|
+
} catch {
|
|
120
|
+
res.statusCode = 400;
|
|
121
|
+
res.setHeader("Content-Type", "application/json");
|
|
122
|
+
res.end(JSON.stringify({ success: false, error: "Invalid request body" }));
|
|
123
|
+
}
|
|
124
|
+
});
|
|
125
|
+
},
|
|
126
|
+
"POST /api/pi/session/restore"(req, res) {
|
|
127
|
+
let body = "";
|
|
128
|
+
req.on("data", (chunk: string) => (body += chunk));
|
|
129
|
+
req.on("end", () => {
|
|
130
|
+
try {
|
|
131
|
+
const { trashPath } = JSON.parse(body) as { trashPath: string };
|
|
132
|
+
const ok = pi.restoreFromTrash(trashPath);
|
|
133
|
+
res.setHeader("Content-Type", "application/json");
|
|
134
|
+
res.end(JSON.stringify({ success: ok }));
|
|
135
|
+
} catch {
|
|
136
|
+
res.statusCode = 400;
|
|
137
|
+
res.setHeader("Content-Type", "application/json");
|
|
138
|
+
res.end(JSON.stringify({ success: false, error: "Invalid request body" }));
|
|
139
|
+
}
|
|
140
|
+
});
|
|
141
|
+
},
|
|
142
|
+
"GET /api/pi/session-preview"(req, res) {
|
|
143
|
+
const parsedUrl = new URL(req.url!, "http://localhost");
|
|
144
|
+
const p = parsedUrl.searchParams.get("path") || "";
|
|
145
|
+
const preview = pi.readSessionPreview(decodeURIComponent(p));
|
|
146
|
+
if (!preview) {
|
|
147
|
+
res.statusCode = 404;
|
|
148
|
+
res.setHeader("Content-Type", "application/json");
|
|
149
|
+
return res.end(JSON.stringify({ error: "Session not found" }));
|
|
150
|
+
}
|
|
151
|
+
res.setHeader("Content-Type", "application/json");
|
|
152
|
+
res.end(JSON.stringify(preview));
|
|
153
|
+
},
|
|
154
|
+
"GET /api/pi/check-updates"(_, res) {
|
|
155
|
+
pi.checkUpdates()
|
|
156
|
+
.then((result) => {
|
|
157
|
+
res.setHeader("Content-Type", "application/json");
|
|
158
|
+
res.end(JSON.stringify(result));
|
|
159
|
+
})
|
|
160
|
+
.catch(() => {
|
|
161
|
+
res.statusCode = 500;
|
|
162
|
+
res.setHeader("Content-Type", "application/json");
|
|
163
|
+
res.end(JSON.stringify({ error: "Update check failed" }));
|
|
164
|
+
});
|
|
165
|
+
},
|
|
166
|
+
"POST /api/pi/apply-updates"(req, res) {
|
|
167
|
+
let body = "";
|
|
168
|
+
req.on("data", (chunk: string) => (body += chunk));
|
|
169
|
+
req.on("end", () => {
|
|
170
|
+
try {
|
|
171
|
+
const { names } = JSON.parse(body) as { names: string[] };
|
|
172
|
+
const results = pi.applyExtensionUpdates(Array.isArray(names) ? names : []);
|
|
173
|
+
res.setHeader("Content-Type", "application/json");
|
|
174
|
+
res.end(JSON.stringify({ results }));
|
|
175
|
+
} catch {
|
|
176
|
+
res.statusCode = 400;
|
|
177
|
+
res.setHeader("Content-Type", "application/json");
|
|
178
|
+
res.end(JSON.stringify({ error: "Invalid request body" }));
|
|
179
|
+
}
|
|
180
|
+
});
|
|
181
|
+
},
|
|
182
|
+
"POST /api/pi/provider-test"(req, res) {
|
|
183
|
+
let body = "";
|
|
184
|
+
req.on("data", (chunk: string) => (body += chunk));
|
|
185
|
+
req.on("end", () => {
|
|
186
|
+
try {
|
|
187
|
+
const { baseUrl, apiKey } = JSON.parse(body) as { baseUrl: string; apiKey?: string };
|
|
188
|
+
if (!baseUrl) throw new Error("missing baseUrl");
|
|
189
|
+
pi.testProviderConnection(baseUrl, apiKey).then((result) => {
|
|
190
|
+
res.setHeader("Content-Type", "application/json");
|
|
191
|
+
res.end(JSON.stringify(result));
|
|
192
|
+
});
|
|
193
|
+
} catch {
|
|
194
|
+
res.statusCode = 400;
|
|
195
|
+
res.setHeader("Content-Type", "application/json");
|
|
196
|
+
res.end(JSON.stringify({ success: false, message: "Invalid request body" }));
|
|
197
|
+
}
|
|
198
|
+
});
|
|
199
|
+
},
|
|
90
200
|
};
|
|
91
201
|
|
|
92
202
|
// Middleware: match API routes
|
|
@@ -99,8 +209,8 @@ function piApiPlugin(): Plugin {
|
|
|
99
209
|
// Strip query string
|
|
100
210
|
const pathOnly = url.split("?")[0];
|
|
101
211
|
|
|
102
|
-
// Handle DELETE /api/pi/session?path=...
|
|
103
|
-
if (method === "DELETE" && pathOnly === "/api/pi/session") {
|
|
212
|
+
// Handle DELETE /api/pi/session?path=... (move to trash) and /api/pi/trash?path=... (permanent)
|
|
213
|
+
if (method === "DELETE" && (pathOnly === "/api/pi/session" || pathOnly === "/api/pi/trash")) {
|
|
104
214
|
const parsedUrl = new URL(url, "http://localhost");
|
|
105
215
|
const filePath = parsedUrl.searchParams.get("path");
|
|
106
216
|
if (!filePath) {
|
|
@@ -109,7 +219,9 @@ function piApiPlugin(): Plugin {
|
|
|
109
219
|
return res.end(JSON.stringify({ success: false, error: "Missing path" }));
|
|
110
220
|
}
|
|
111
221
|
const decodedPath = decodeURIComponent(filePath);
|
|
112
|
-
const ok = pi
|
|
222
|
+
const ok = pathOnly === "/api/pi/session"
|
|
223
|
+
? pi.trashSessionFile(decodedPath)
|
|
224
|
+
: pi.permanentlyDeleteTrash(decodedPath);
|
|
113
225
|
res.setHeader("Content-Type", "application/json");
|
|
114
226
|
return res.end(JSON.stringify({ success: ok }));
|
|
115
227
|
}
|