@agi-cli/server 0.1.73 → 0.1.74
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agi-cli/server",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.74",
|
|
4
4
|
"description": "HTTP API server for AGI CLI",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./src/index.ts",
|
|
@@ -29,8 +29,8 @@
|
|
|
29
29
|
"typecheck": "tsc --noEmit"
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"@agi-cli/sdk": "0.1.
|
|
33
|
-
"@agi-cli/database": "0.1.
|
|
32
|
+
"@agi-cli/sdk": "0.1.74",
|
|
33
|
+
"@agi-cli/database": "0.1.74",
|
|
34
34
|
"drizzle-orm": "^0.44.5",
|
|
35
35
|
"hono": "^4.9.9",
|
|
36
36
|
"zod": "^4.1.8"
|
|
@@ -99,6 +99,7 @@ export function registerSessionMessagesRoutes(app: Hono) {
|
|
|
99
99
|
const modelName = body?.model ?? sess.model ?? cfg.defaults.model;
|
|
100
100
|
const agent = body?.agent ?? sess.agent ?? cfg.defaults.agent;
|
|
101
101
|
const content = body?.content ?? '';
|
|
102
|
+
const userContext = body?.userContext;
|
|
102
103
|
|
|
103
104
|
// Validate model capabilities if tools are allowed for this agent
|
|
104
105
|
const wantsToolCalls = true; // agent toolset may be non-empty
|
|
@@ -131,6 +132,7 @@ export function registerSessionMessagesRoutes(app: Hono) {
|
|
|
131
132
|
model: modelName,
|
|
132
133
|
content,
|
|
133
134
|
oneShot: Boolean(body?.oneShot),
|
|
135
|
+
userContext,
|
|
134
136
|
});
|
|
135
137
|
return c.json({ messageId: assistantMessageId }, 202);
|
|
136
138
|
} catch (error) {
|
package/src/runtime/api-error.ts
CHANGED
|
@@ -70,8 +70,14 @@ export function serializeError(err: unknown): APIErrorResponse {
|
|
|
70
70
|
const payload = toErrorPayload(err);
|
|
71
71
|
|
|
72
72
|
// Determine HTTP status code
|
|
73
|
-
|
|
74
|
-
if
|
|
73
|
+
// Default to 400 for generic errors (client errors)
|
|
74
|
+
// Only use 500 if explicitly set or for APIError instances without a status
|
|
75
|
+
let status = 400;
|
|
76
|
+
|
|
77
|
+
// Handle APIError instances first
|
|
78
|
+
if (err instanceof APIError) {
|
|
79
|
+
status = err.status;
|
|
80
|
+
} else if (err && typeof err === 'object') {
|
|
75
81
|
const errObj = err as Record<string, unknown>;
|
|
76
82
|
if (typeof errObj.status === 'number') {
|
|
77
83
|
status = errObj.status;
|
|
@@ -86,11 +92,6 @@ export function serializeError(err: unknown): APIErrorResponse {
|
|
|
86
92
|
}
|
|
87
93
|
}
|
|
88
94
|
|
|
89
|
-
// Handle APIError instances
|
|
90
|
-
if (err instanceof APIError) {
|
|
91
|
-
status = err.status;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
95
|
// Extract code if available
|
|
95
96
|
let code: string | undefined;
|
|
96
97
|
if (err && typeof err === 'object') {
|
|
@@ -20,13 +20,23 @@ type DispatchOptions = {
|
|
|
20
20
|
model: string;
|
|
21
21
|
content: string;
|
|
22
22
|
oneShot?: boolean;
|
|
23
|
+
userContext?: string;
|
|
23
24
|
};
|
|
24
25
|
|
|
25
26
|
export async function dispatchAssistantMessage(
|
|
26
27
|
options: DispatchOptions,
|
|
27
28
|
): Promise<{ assistantMessageId: string }> {
|
|
28
|
-
const {
|
|
29
|
-
|
|
29
|
+
const {
|
|
30
|
+
cfg,
|
|
31
|
+
db,
|
|
32
|
+
session,
|
|
33
|
+
agent,
|
|
34
|
+
provider,
|
|
35
|
+
model,
|
|
36
|
+
content,
|
|
37
|
+
oneShot,
|
|
38
|
+
userContext,
|
|
39
|
+
} = options;
|
|
30
40
|
const sessionId = session.id;
|
|
31
41
|
const now = Date.now();
|
|
32
42
|
const userMessageId = crypto.randomUUID();
|
|
@@ -99,6 +109,7 @@ export async function dispatchAssistantMessage(
|
|
|
99
109
|
model,
|
|
100
110
|
projectRoot: cfg.projectRoot,
|
|
101
111
|
oneShot: Boolean(oneShot),
|
|
112
|
+
userContext,
|
|
102
113
|
});
|
|
103
114
|
|
|
104
115
|
void touchSessionLastActive({ db, sessionId });
|
|
@@ -385,8 +396,8 @@ function deriveTitle(text: string): string {
|
|
|
385
396
|
|
|
386
397
|
function sanitizeTitle(s: string): string {
|
|
387
398
|
let t = s.trim();
|
|
388
|
-
t = t.replace(/^['"""''()[
|
|
389
|
-
t = t.replace(/[
|
|
399
|
+
t = t.replace(/^['"""''()[\\]]+|['"""''()[\\]]+$/g, '').trim();
|
|
400
|
+
t = t.replace(/[\\s\\-_:–—]+$/g, '').trim();
|
|
390
401
|
if (t.length > 64) t = `${t.slice(0, 63).trimEnd()}…`;
|
|
391
402
|
return t;
|
|
392
403
|
}
|
package/src/runtime/prompt.ts
CHANGED
|
@@ -20,6 +20,7 @@ export async function composeSystemPrompt(options: {
|
|
|
20
20
|
spoofPrompt?: string;
|
|
21
21
|
includeEnvironment?: boolean;
|
|
22
22
|
includeProjectTree?: boolean;
|
|
23
|
+
userContext?: string;
|
|
23
24
|
}): Promise<string> {
|
|
24
25
|
if (options.spoofPrompt) {
|
|
25
26
|
return options.spoofPrompt.trim();
|
|
@@ -61,6 +62,16 @@ export async function composeSystemPrompt(options: {
|
|
|
61
62
|
}
|
|
62
63
|
}
|
|
63
64
|
|
|
65
|
+
// Add user-provided context if present
|
|
66
|
+
if (options.userContext?.trim()) {
|
|
67
|
+
const userContextBlock = [
|
|
68
|
+
'<user-provided-state-context>',
|
|
69
|
+
options.userContext.trim(),
|
|
70
|
+
'</user-provided-state-context>',
|
|
71
|
+
].join('\n');
|
|
72
|
+
parts.push(userContextBlock);
|
|
73
|
+
}
|
|
74
|
+
|
|
64
75
|
const composed = parts.filter(Boolean).join('\n\n').trim();
|
|
65
76
|
if (composed) return composed;
|
|
66
77
|
|
package/src/runtime/runner.ts
CHANGED
|
@@ -146,6 +146,7 @@ async function runAssistant(opts: RunOpts) {
|
|
|
146
146
|
oneShot: opts.oneShot,
|
|
147
147
|
spoofPrompt: undefined,
|
|
148
148
|
includeProjectTree: isFirstMessage,
|
|
149
|
+
userContext: opts.userContext,
|
|
149
150
|
});
|
|
150
151
|
additionalSystemMessages = [{ role: 'system', content: fullPrompt }];
|
|
151
152
|
} else {
|
|
@@ -157,6 +158,7 @@ async function runAssistant(opts: RunOpts) {
|
|
|
157
158
|
oneShot: opts.oneShot,
|
|
158
159
|
spoofPrompt: undefined,
|
|
159
160
|
includeProjectTree: isFirstMessage,
|
|
161
|
+
userContext: opts.userContext,
|
|
160
162
|
});
|
|
161
163
|
}
|
|
162
164
|
systemTimer.end();
|
|
@@ -9,6 +9,7 @@ export type RunOpts = {
|
|
|
9
9
|
model: string;
|
|
10
10
|
projectRoot: string;
|
|
11
11
|
oneShot?: boolean;
|
|
12
|
+
userContext?: string;
|
|
12
13
|
abortSignal?: AbortSignal;
|
|
13
14
|
};
|
|
14
15
|
|
|
@@ -39,7 +40,8 @@ export function enqueueAssistantRun(
|
|
|
39
40
|
}
|
|
40
41
|
|
|
41
42
|
/**
|
|
42
|
-
*
|
|
43
|
+
* Signals the abort controller for a session.
|
|
44
|
+
* This will trigger the abortSignal in the streamText call.
|
|
43
45
|
*/
|
|
44
46
|
export function abortSession(sessionId: string) {
|
|
45
47
|
const controller = sessionAbortControllers.get(sessionId);
|
|
@@ -49,34 +51,25 @@ export function abortSession(sessionId: string) {
|
|
|
49
51
|
}
|
|
50
52
|
}
|
|
51
53
|
|
|
52
|
-
/**
|
|
53
|
-
* Gets the current state of a session's queue.
|
|
54
|
-
*/
|
|
55
54
|
export function getRunnerState(sessionId: string): RunnerState | undefined {
|
|
56
55
|
return runners.get(sessionId);
|
|
57
56
|
}
|
|
58
57
|
|
|
59
|
-
/**
|
|
60
|
-
* Marks a session queue as running.
|
|
61
|
-
*/
|
|
62
58
|
export function setRunning(sessionId: string, running: boolean) {
|
|
63
59
|
const state = runners.get(sessionId);
|
|
64
|
-
if (state)
|
|
65
|
-
state.running = running;
|
|
66
|
-
}
|
|
60
|
+
if (state) state.running = running;
|
|
67
61
|
}
|
|
68
62
|
|
|
69
|
-
/**
|
|
70
|
-
* Dequeues the next job from a session's queue.
|
|
71
|
-
*/
|
|
72
63
|
export function dequeueJob(sessionId: string): RunOpts | undefined {
|
|
73
64
|
const state = runners.get(sessionId);
|
|
74
65
|
return state?.queue.shift();
|
|
75
66
|
}
|
|
76
67
|
|
|
77
|
-
/**
|
|
78
|
-
* Cleanup abort controller for a session (called when queue is done).
|
|
79
|
-
*/
|
|
80
68
|
export function cleanupSession(sessionId: string) {
|
|
81
|
-
|
|
69
|
+
const state = runners.get(sessionId);
|
|
70
|
+
if (state && state.queue.length === 0 && !state.running) {
|
|
71
|
+
runners.delete(sessionId);
|
|
72
|
+
// Clean up any lingering abort controller
|
|
73
|
+
sessionAbortControllers.delete(sessionId);
|
|
74
|
+
}
|
|
82
75
|
}
|