percher 0.5.22 → 0.5.24
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/dist/bin/percher.js +778 -532
- package/dist/package.json +4 -4
- package/dist/src/cli-utils.d.ts.map +1 -1
- package/dist/src/cli-utils.js.map +1 -1
- package/dist/src/commands/analytics.d.ts +4 -0
- package/dist/src/commands/analytics.d.ts.map +1 -0
- package/dist/src/commands/analytics.js +66 -0
- package/dist/src/commands/analytics.js.map +1 -0
- package/dist/src/commands/apps.js.map +1 -1
- package/dist/src/context.d.ts.map +1 -1
- package/dist/src/context.js +2 -1
- package/dist/src/context.js.map +1 -1
- package/dist/src/env-set-input.d.ts.map +1 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +2 -0
- package/dist/src/index.js.map +1 -1
- package/dist/templates/capsule/src/lib/ai-client.ts +193 -0
- package/dist/templates/capsule/src/lib/ai.ts +13 -89
- package/package.json +4 -4
|
@@ -1,91 +1,15 @@
|
|
|
1
|
+
import { createManagedInferenceClient } from "./ai-client";
|
|
1
2
|
import { pb } from "./db";
|
|
2
3
|
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
const
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
export
|
|
15
|
-
prompt: string,
|
|
16
|
-
opts?: { model?: string; maxTokens?: number },
|
|
17
|
-
): Promise<string> {
|
|
18
|
-
if (!AI_URL) throw new Error("Managed inference isn't configured for this app.");
|
|
19
|
-
if (!pb.authStore.isValid) throw new Error("Sign in to use AI.");
|
|
20
|
-
const res = await fetch(AI_URL, {
|
|
21
|
-
method: "POST",
|
|
22
|
-
headers: { "content-type": "application/json", authorization: pb.authStore.token },
|
|
23
|
-
body: JSON.stringify({
|
|
24
|
-
model: opts?.model,
|
|
25
|
-
max_tokens: opts?.maxTokens ?? 512,
|
|
26
|
-
messages: [{ role: "user", content: prompt }],
|
|
27
|
-
}),
|
|
28
|
-
});
|
|
29
|
-
if (!res.ok) throw new Error(`AI request failed (${res.status})`);
|
|
30
|
-
const data = (await res.json()) as { choices?: Array<{ message?: { content?: string } }> };
|
|
31
|
-
return data.choices?.[0]?.message?.content ?? "";
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* Streaming variant of {@link complete} — calls `onToken` with each text delta
|
|
36
|
-
* as it arrives and resolves with the full text. Same auth + billing as
|
|
37
|
-
* `complete` (keyless, billed to the app owner). Use it for a typewriter UI:
|
|
38
|
-
*
|
|
39
|
-
* const full = await streamComplete("Write a haiku", (t) => { output.value += t; });
|
|
40
|
-
*/
|
|
41
|
-
export async function streamComplete(
|
|
42
|
-
prompt: string,
|
|
43
|
-
onToken: (delta: string) => void,
|
|
44
|
-
opts?: { model?: string; maxTokens?: number },
|
|
45
|
-
): Promise<string> {
|
|
46
|
-
if (!AI_URL) throw new Error("Managed inference isn't configured for this app.");
|
|
47
|
-
if (!pb.authStore.isValid) throw new Error("Sign in to use AI.");
|
|
48
|
-
const res = await fetch(AI_URL, {
|
|
49
|
-
method: "POST",
|
|
50
|
-
headers: { "content-type": "application/json", authorization: pb.authStore.token },
|
|
51
|
-
body: JSON.stringify({
|
|
52
|
-
model: opts?.model,
|
|
53
|
-
max_tokens: opts?.maxTokens ?? 512,
|
|
54
|
-
messages: [{ role: "user", content: prompt }],
|
|
55
|
-
stream: true,
|
|
56
|
-
}),
|
|
57
|
-
});
|
|
58
|
-
if (!res.ok || !res.body) throw new Error(`AI request failed (${res.status})`);
|
|
59
|
-
|
|
60
|
-
const reader = res.body.getReader();
|
|
61
|
-
const decoder = new TextDecoder();
|
|
62
|
-
let buffer = "";
|
|
63
|
-
let full = "";
|
|
64
|
-
for (;;) {
|
|
65
|
-
const { done, value } = await reader.read();
|
|
66
|
-
if (done) break;
|
|
67
|
-
buffer += decoder.decode(value, { stream: true });
|
|
68
|
-
// SSE events are separated by a blank line; parse each complete one.
|
|
69
|
-
let sep = buffer.indexOf("\n\n");
|
|
70
|
-
while (sep !== -1) {
|
|
71
|
-
const event = buffer.slice(0, sep);
|
|
72
|
-
buffer = buffer.slice(sep + 2);
|
|
73
|
-
sep = buffer.indexOf("\n\n");
|
|
74
|
-
const line = event.startsWith("data:") ? event.slice(5).trim() : "";
|
|
75
|
-
if (!line || line === "[DONE]") continue;
|
|
76
|
-
try {
|
|
77
|
-
const chunk = JSON.parse(line) as {
|
|
78
|
-
choices?: Array<{ delta?: { content?: string } }>;
|
|
79
|
-
};
|
|
80
|
-
const delta = chunk.choices?.[0]?.delta?.content ?? "";
|
|
81
|
-
if (delta) {
|
|
82
|
-
full += delta;
|
|
83
|
-
onToken(delta);
|
|
84
|
-
}
|
|
85
|
-
} catch {
|
|
86
|
-
/* ignore keep-alive / non-JSON lines */
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
return full;
|
|
91
|
-
}
|
|
4
|
+
// This is a public URL, never a provider credential. Percher injects it only
|
|
5
|
+
// when the shared server-side feature gate is operational.
|
|
6
|
+
const client = createManagedInferenceClient({
|
|
7
|
+
endpoint: import.meta.env.VITE_PERCHER_AI_URL as string | undefined,
|
|
8
|
+
getSession: () => ({ valid: pb.authStore.isValid, token: pb.authStore.token }),
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
export { ManagedInferenceError } from "./ai-client";
|
|
12
|
+
export type { ManagedInferenceOptions } from "./ai-client";
|
|
13
|
+
export const isManagedInferenceConfigured = client.isConfigured;
|
|
14
|
+
export const complete = client.complete;
|
|
15
|
+
export const streamComplete = client.streamComplete;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "percher",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.24",
|
|
4
4
|
"description": "CLI for the Percher hosting platform — publish apps with one command",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -27,9 +27,9 @@
|
|
|
27
27
|
"typecheck": "tsc --noEmit"
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@percher/client": "^0.
|
|
31
|
-
"@percher/core": "^0.4.
|
|
32
|
-
"@percher/toml": "^0.1.
|
|
30
|
+
"@percher/client": "^0.3.1",
|
|
31
|
+
"@percher/core": "^0.4.29",
|
|
32
|
+
"@percher/toml": "^0.1.11",
|
|
33
33
|
"cac": "^7.0.0",
|
|
34
34
|
"picocolors": "^1.1.1"
|
|
35
35
|
},
|