prior-cli 1.2.8 → 1.3.0
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/bin/prior.js +21 -3
- package/lib/agent.js +18 -13
- package/package.json +1 -1
- package/lib/systemPrompt.js +0 -81
package/bin/prior.js
CHANGED
|
@@ -606,8 +606,9 @@ async function startChat(opts = {}) {
|
|
|
606
606
|
|
|
607
607
|
// Conversation history (for agent mode, keeps full multi-turn context)
|
|
608
608
|
const chatHistory = [];
|
|
609
|
-
let currentModel
|
|
610
|
-
let uncensored
|
|
609
|
+
let currentModel = opts.model || null;
|
|
610
|
+
let uncensored = opts.uncensored || false;
|
|
611
|
+
let _currentAbortController = null;
|
|
611
612
|
|
|
612
613
|
// ── Live slash-command suggestions ──────────────────────────
|
|
613
614
|
let clearSuggestions = () => {};
|
|
@@ -657,6 +658,11 @@ async function startChat(opts = {}) {
|
|
|
657
658
|
|
|
658
659
|
if (_suggTimer) { clearTimeout(_suggTimer); _suggTimer = null; }
|
|
659
660
|
|
|
661
|
+
if (key.name === 'escape' && _currentAbortController) {
|
|
662
|
+
_currentAbortController.abort();
|
|
663
|
+
return;
|
|
664
|
+
}
|
|
665
|
+
|
|
660
666
|
if (key.name === 'return' || key.name === 'enter' || (key.ctrl && key.name === 'c')) {
|
|
661
667
|
clearSuggestions();
|
|
662
668
|
return;
|
|
@@ -989,6 +995,7 @@ Keep it under 350 words. Write prior.md now.`;
|
|
|
989
995
|
return approved;
|
|
990
996
|
};
|
|
991
997
|
|
|
998
|
+
_currentAbortController = new AbortController();
|
|
992
999
|
await runAgent({
|
|
993
1000
|
messages: [...chatHistory, { role: 'user', content: input }],
|
|
994
1001
|
model: currentModel,
|
|
@@ -996,6 +1003,7 @@ Keep it under 350 words. Write prior.md now.`;
|
|
|
996
1003
|
cwd: process.cwd(),
|
|
997
1004
|
projectContext,
|
|
998
1005
|
confirm,
|
|
1006
|
+
signal: _currentAbortController.signal,
|
|
999
1007
|
send: ev => {
|
|
1000
1008
|
switch (ev.type) {
|
|
1001
1009
|
|
|
@@ -1003,6 +1011,12 @@ Keep it under 350 words. Write prior.md now.`;
|
|
|
1003
1011
|
spinStart('thinking…');
|
|
1004
1012
|
break;
|
|
1005
1013
|
|
|
1014
|
+
case 'cancelled':
|
|
1015
|
+
spinStop();
|
|
1016
|
+
process.stdout.write('\n');
|
|
1017
|
+
console.log(c.muted(' ✗ Cancelled'));
|
|
1018
|
+
break;
|
|
1019
|
+
|
|
1006
1020
|
case 'tool_start':
|
|
1007
1021
|
spinStop();
|
|
1008
1022
|
_progressStarted = false;
|
|
@@ -1065,7 +1079,11 @@ Keep it under 350 words. Write prior.md now.`;
|
|
|
1065
1079
|
});
|
|
1066
1080
|
} catch (err) {
|
|
1067
1081
|
spinStop();
|
|
1068
|
-
|
|
1082
|
+
if (err.name !== 'AbortError') {
|
|
1083
|
+
console.error(c.err(` ✗ ${err.message}`));
|
|
1084
|
+
}
|
|
1085
|
+
} finally {
|
|
1086
|
+
_currentAbortController = null;
|
|
1069
1087
|
}
|
|
1070
1088
|
|
|
1071
1089
|
chatHistory.push({ role: 'user', content: input });
|
package/lib/agent.js
CHANGED
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
const fetch = require('node-fetch');
|
|
4
4
|
const { executeTool, TOOL_NAMES } = require('./tools');
|
|
5
|
-
const { buildSystemPrompt } = require('./systemPrompt');
|
|
6
5
|
const { getToken, getUsername } = require('./config');
|
|
7
6
|
|
|
8
7
|
const CLI_BASE = 'https://prior.ngrok.app/cli-backend';
|
|
@@ -11,12 +10,13 @@ const MAX_ITER = 14;
|
|
|
11
10
|
|
|
12
11
|
// ── Single inference call (server just runs Ollama + returns) ─
|
|
13
12
|
|
|
14
|
-
async function infer(messages, model, token) {
|
|
13
|
+
async function infer(messages, model, token, { cwd, uncensored, projectContext } = {}, signal) {
|
|
15
14
|
const res = await fetch(`${CLI_BASE}/api/infer`, {
|
|
16
15
|
method: 'POST',
|
|
17
16
|
headers: { 'Content-Type': 'application/json' },
|
|
18
|
-
body: JSON.stringify({ messages, model, token }),
|
|
17
|
+
body: JSON.stringify({ messages, model, token, cwd, uncensored, projectContext }),
|
|
19
18
|
timeout: 120000,
|
|
19
|
+
signal,
|
|
20
20
|
});
|
|
21
21
|
if (!res.ok) {
|
|
22
22
|
const err = await res.json().catch(() => ({}));
|
|
@@ -151,28 +151,33 @@ function stripToolTags(text) {
|
|
|
151
151
|
|
|
152
152
|
const CONFIRM_TOOLS = new Set(['run_command', 'file_delete', 'file_write']);
|
|
153
153
|
|
|
154
|
-
async function runAgent({ messages, model, uncensored, cwd, projectContext, send, confirm }) {
|
|
155
|
-
const token
|
|
156
|
-
const
|
|
157
|
-
const sysPrompt = buildSystemPrompt(username, cwd, uncensored, projectContext);
|
|
158
|
-
|
|
159
|
-
const history = [
|
|
160
|
-
{ role: 'system', content: sysPrompt },
|
|
161
|
-
...messages,
|
|
162
|
-
];
|
|
154
|
+
async function runAgent({ messages, model, uncensored, cwd, projectContext, send, confirm, signal }) {
|
|
155
|
+
const token = getToken();
|
|
156
|
+
const history = [...messages];
|
|
163
157
|
|
|
164
158
|
let totalPromptTokens = 0;
|
|
165
159
|
let totalCompletionTokens = 0;
|
|
166
160
|
|
|
167
161
|
for (let iter = 0; iter < MAX_ITER; iter++) {
|
|
168
162
|
|
|
163
|
+
if (signal?.aborted) {
|
|
164
|
+
send({ type: 'cancelled' });
|
|
165
|
+
send({ type: 'done' });
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
169
|
send({ type: 'thinking' });
|
|
170
170
|
|
|
171
171
|
let result;
|
|
172
172
|
try {
|
|
173
|
-
result = await infer(history, model || 'qwen3.5:4b', token);
|
|
173
|
+
result = await infer(history, model || 'qwen3.5:4b', token, { cwd, uncensored, projectContext }, signal);
|
|
174
174
|
} catch (err) {
|
|
175
175
|
await trackTokenUsage(token, totalPromptTokens, totalCompletionTokens);
|
|
176
|
+
if (err.name === 'AbortError' || signal?.aborted) {
|
|
177
|
+
send({ type: 'cancelled' });
|
|
178
|
+
send({ type: 'done' });
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
176
181
|
send({ type: 'error', message: err.message });
|
|
177
182
|
send({ type: 'done' });
|
|
178
183
|
return;
|
package/package.json
CHANGED
package/lib/systemPrompt.js
DELETED
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
function buildSystemPrompt(username, cwd, uncensored, projectContext) {
|
|
4
|
-
const date = new Date().toLocaleDateString('en-US', { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' });
|
|
5
|
-
|
|
6
|
-
return `You are Prior, an AI assistant created by Niceguygamer (Euwin). Be direct, confident, and helpful. Never say "according to my database" or "based on my training data."
|
|
7
|
-
|
|
8
|
-
IMPORTANT: Do NOT assume the person talking to you is Euwin. Euwin is the creator/developer — the user may be anyone.
|
|
9
|
-
|
|
10
|
-
PERSONALITY: Dry wit, genuine character. One short off-script remark when it genuinely fits — don't force it.
|
|
11
|
-
|
|
12
|
-
Origins: Started as a school bot for the BEN friend group. Originally a Jollibee prank bot.
|
|
13
|
-
|
|
14
|
-
---
|
|
15
|
-
|
|
16
|
-
Signed-in user: @${username} | CWD: ${cwd} | ${date}
|
|
17
|
-
|
|
18
|
-
## Tools
|
|
19
|
-
|
|
20
|
-
CRITICAL: When you need to use a tool, you MUST output the tool call immediately. Do NOT say "I'll write that" or "Writing that now..." — just call the tool directly. Describing an action instead of doing it is wrong.
|
|
21
|
-
|
|
22
|
-
Correct tool call format — output this exactly, on its own line:
|
|
23
|
-
<tool>{"name":"TOOL_NAME","args":{"key":"value"}}</tool>
|
|
24
|
-
|
|
25
|
-
You will then receive:
|
|
26
|
-
<tool_result name="TOOL_NAME">result</tool_result>
|
|
27
|
-
|
|
28
|
-
### Writing / Appending Files (ALWAYS use this format — never put file content in JSON)
|
|
29
|
-
<write path="relative/or/C:/absolute/path.ext">
|
|
30
|
-
file content goes here — no escaping needed
|
|
31
|
-
</write>
|
|
32
|
-
|
|
33
|
-
<append path="path/to/file.txt">
|
|
34
|
-
content to add
|
|
35
|
-
</append>
|
|
36
|
-
|
|
37
|
-
### Other Tools (JSON format)
|
|
38
|
-
<tool>{"name":"TOOL_NAME","args":{"key":"value"}}</tool>
|
|
39
|
-
|
|
40
|
-
Available tools:
|
|
41
|
-
- file_read args: {"path":"string"}
|
|
42
|
-
- file_list args: {"path":"string"}
|
|
43
|
-
- file_delete args: {"path":"string"}
|
|
44
|
-
- file_write_docx — Word document. Use this tag format (NEVER put content in JSON):
|
|
45
|
-
<docx path="C:/path/to/file.docx" title="Optional Title">
|
|
46
|
-
# Heading 1
|
|
47
|
-
## Heading 2
|
|
48
|
-
Normal paragraph with **bold** and *italic* supported.
|
|
49
|
-
</docx>
|
|
50
|
-
- web_search args: {"query":"string"}
|
|
51
|
-
- url_fetch args: {"url":"string"}
|
|
52
|
-
- run_command args: {"command":"string"}
|
|
53
|
-
- clipboard_read args: {}
|
|
54
|
-
- clipboard_write args: {"text":"string"}
|
|
55
|
-
- generate_image args: {"prompt":"string","width":896,"height":896,"steps":20}
|
|
56
|
-
- prior_feed args: {}
|
|
57
|
-
- prior_profile args: {}
|
|
58
|
-
|
|
59
|
-
### Image generation notes
|
|
60
|
-
- generate_image queues and polls automatically — it can take 1-3 minutes, this is normal
|
|
61
|
-
- Always confirm where the image was saved after it completes
|
|
62
|
-
- If user says "generate X" or "create an image of X", use generate_image immediately
|
|
63
|
-
- Image saves to the current working directory by default; user can ask to move it after
|
|
64
|
-
- When calling generate_image, extract only the core subject/description the user gave. Strip conversational filler ("can you", "please", "I want", "make me", "draw me", etc.). Do NOT add style tags, quality boosters, or extra descriptors like "high detail", "cinematic", "4k", "in motion", "sleek", etc. Pass only what the user described.
|
|
65
|
-
Examples:
|
|
66
|
-
"generate car" → prompt: "car"
|
|
67
|
-
"can you make me a sunset" → prompt: "sunset"
|
|
68
|
-
"draw a cat sitting on a roof" → prompt: "cat sitting on a roof"
|
|
69
|
-
"I want to see a dragon flying" → prompt: "dragon flying"
|
|
70
|
-
|
|
71
|
-
${projectContext ? `### Project Context (prior.md)\n${projectContext}\n` : ''}### Rules
|
|
72
|
-
- ACT with tools, don't narrate. If asked to create a file — create it immediately.
|
|
73
|
-
- If the user asks for a Word document (.docx), use the <docx> tag format above — NEVER use file_write for .docx.
|
|
74
|
-
- For file_write / file_append ALWAYS use the <write>/<append> tags above — NEVER put file content inside JSON.
|
|
75
|
-
- Paths relative to CWD unless absolute (e.g. C:/Users/ADMIN/Downloads/file.py)
|
|
76
|
-
- After tool results, give a short confirmation
|
|
77
|
-
- Never output <tool_result> yourself — that comes from the system
|
|
78
|
-
${uncensored ? '- Uncensored mode active\n' : ''}`;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
module.exports = { buildSystemPrompt };
|