@agi-cli/server 0.1.141 → 0.1.143
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 +3 -3
- package/src/events/types.ts +4 -4
- package/src/index.ts +4 -4
- package/src/openapi/paths/{solforge.ts → setu.ts} +13 -13
- package/src/openapi/spec.ts +3 -3
- package/src/routes/research.ts +2 -2
- package/src/routes/{solforge.ts → setu.ts} +19 -19
- package/src/runtime/ask/service.ts +1 -1
- package/src/runtime/message/compaction-auto.ts +1 -1
- package/src/runtime/provider/index.ts +3 -3
- package/src/runtime/provider/selection.ts +1 -1
- package/src/runtime/provider/{solforge.ts → setu.ts} +14 -14
- package/src/runtime/session/db-operations.ts +1 -1
- package/src/runtime/stream/finish-handler.ts +0 -1
- package/src/tools/database/get-parent-session.ts +3 -3
- package/src/tools/database/query-messages.ts +2 -2
- package/src/tools/database/query-sessions.ts +1 -1
- package/src/tools/database/search-history.ts +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agi-cli/server",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.143",
|
|
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.143",
|
|
33
|
+
"@agi-cli/database": "0.1.143",
|
|
34
34
|
"drizzle-orm": "^0.44.5",
|
|
35
35
|
"hono": "^4.9.9",
|
|
36
36
|
"zod": "^4.1.8"
|
package/src/events/types.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
export type AGIEventType =
|
|
2
2
|
| 'tool.approval.required'
|
|
3
3
|
| 'tool.approval.resolved'
|
|
4
|
-
| '
|
|
5
|
-
| '
|
|
6
|
-
| '
|
|
7
|
-
| '
|
|
4
|
+
| 'setu.payment.required'
|
|
5
|
+
| 'setu.payment.signing'
|
|
6
|
+
| 'setu.payment.complete'
|
|
7
|
+
| 'setu.payment.error'
|
|
8
8
|
| 'session.created'
|
|
9
9
|
| 'session.updated'
|
|
10
10
|
| 'message.created'
|
package/src/index.ts
CHANGED
|
@@ -17,7 +17,7 @@ import { registerSessionFilesRoutes } from './routes/session-files.ts';
|
|
|
17
17
|
import { registerBranchRoutes } from './routes/branch.ts';
|
|
18
18
|
import { registerResearchRoutes } from './routes/research.ts';
|
|
19
19
|
import { registerSessionApprovalRoute } from './routes/session-approval.ts';
|
|
20
|
-
import {
|
|
20
|
+
import { registerSetuRoutes } from './routes/setu.ts';
|
|
21
21
|
import type { AgentConfigEntry } from './runtime/agent/registry.ts';
|
|
22
22
|
|
|
23
23
|
const globalTerminalManager = new TerminalManager();
|
|
@@ -71,7 +71,7 @@ function initApp() {
|
|
|
71
71
|
registerSessionFilesRoutes(app);
|
|
72
72
|
registerBranchRoutes(app);
|
|
73
73
|
registerResearchRoutes(app);
|
|
74
|
-
|
|
74
|
+
registerSetuRoutes(app);
|
|
75
75
|
|
|
76
76
|
return app;
|
|
77
77
|
}
|
|
@@ -141,7 +141,7 @@ export function createStandaloneApp(_config?: StandaloneAppConfig) {
|
|
|
141
141
|
registerSessionFilesRoutes(honoApp);
|
|
142
142
|
registerBranchRoutes(honoApp);
|
|
143
143
|
registerResearchRoutes(honoApp);
|
|
144
|
-
|
|
144
|
+
registerSetuRoutes(honoApp);
|
|
145
145
|
|
|
146
146
|
return honoApp;
|
|
147
147
|
}
|
|
@@ -239,7 +239,7 @@ export function createEmbeddedApp(config: EmbeddedAppConfig = {}) {
|
|
|
239
239
|
registerSessionFilesRoutes(honoApp);
|
|
240
240
|
registerBranchRoutes(honoApp);
|
|
241
241
|
registerResearchRoutes(honoApp);
|
|
242
|
-
|
|
242
|
+
registerSetuRoutes(honoApp);
|
|
243
243
|
|
|
244
244
|
return honoApp;
|
|
245
245
|
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
export const
|
|
2
|
-
'/v1/
|
|
1
|
+
export const setuPaths = {
|
|
2
|
+
'/v1/setu/balance': {
|
|
3
3
|
get: {
|
|
4
|
-
tags: ['
|
|
5
|
-
operationId: '
|
|
6
|
-
summary: 'Get
|
|
4
|
+
tags: ['setu'],
|
|
5
|
+
operationId: 'getSetuBalance',
|
|
6
|
+
summary: 'Get Setu account balance',
|
|
7
7
|
description:
|
|
8
8
|
'Returns wallet balance, total spent, total topups, and request count',
|
|
9
9
|
responses: {
|
|
@@ -44,7 +44,7 @@ export const solforgePaths = {
|
|
|
44
44
|
},
|
|
45
45
|
},
|
|
46
46
|
502: {
|
|
47
|
-
description: 'Failed to fetch balance from
|
|
47
|
+
description: 'Failed to fetch balance from Setu',
|
|
48
48
|
content: {
|
|
49
49
|
'application/json': {
|
|
50
50
|
schema: {
|
|
@@ -58,11 +58,11 @@ export const solforgePaths = {
|
|
|
58
58
|
},
|
|
59
59
|
},
|
|
60
60
|
},
|
|
61
|
-
'/v1/
|
|
61
|
+
'/v1/setu/wallet': {
|
|
62
62
|
get: {
|
|
63
|
-
tags: ['
|
|
64
|
-
operationId: '
|
|
65
|
-
summary: 'Get
|
|
63
|
+
tags: ['setu'],
|
|
64
|
+
operationId: 'getSetuWallet',
|
|
65
|
+
summary: 'Get Setu wallet info',
|
|
66
66
|
description:
|
|
67
67
|
'Returns whether the wallet is configured and its public key',
|
|
68
68
|
responses: {
|
|
@@ -85,10 +85,10 @@ export const solforgePaths = {
|
|
|
85
85
|
},
|
|
86
86
|
},
|
|
87
87
|
},
|
|
88
|
-
'/v1/
|
|
88
|
+
'/v1/setu/usdc-balance': {
|
|
89
89
|
get: {
|
|
90
|
-
tags: ['
|
|
91
|
-
operationId: '
|
|
90
|
+
tags: ['setu'],
|
|
91
|
+
operationId: 'getSetuUsdcBalance',
|
|
92
92
|
summary: 'Get USDC token balance',
|
|
93
93
|
description:
|
|
94
94
|
'Fetches USDC balance from Solana blockchain for the configured wallet',
|
package/src/openapi/spec.ts
CHANGED
|
@@ -8,7 +8,7 @@ import { streamPaths } from './paths/stream';
|
|
|
8
8
|
import { schemas } from './schemas';
|
|
9
9
|
|
|
10
10
|
import { terminalsPath } from './paths/terminals';
|
|
11
|
-
import {
|
|
11
|
+
import { setuPaths } from './paths/setu';
|
|
12
12
|
|
|
13
13
|
export function getOpenAPISpec() {
|
|
14
14
|
const spec = {
|
|
@@ -28,7 +28,7 @@ export function getOpenAPISpec() {
|
|
|
28
28
|
{ name: 'files' },
|
|
29
29
|
{ name: 'git' },
|
|
30
30
|
{ name: 'terminals' },
|
|
31
|
-
{ name: '
|
|
31
|
+
{ name: 'setu' },
|
|
32
32
|
],
|
|
33
33
|
paths: {
|
|
34
34
|
...askPaths,
|
|
@@ -39,7 +39,7 @@ export function getOpenAPISpec() {
|
|
|
39
39
|
...filesPaths,
|
|
40
40
|
...gitPaths,
|
|
41
41
|
...terminalsPath,
|
|
42
|
-
...
|
|
42
|
+
...setuPaths,
|
|
43
43
|
},
|
|
44
44
|
components: {
|
|
45
45
|
schemas,
|
package/src/routes/research.ts
CHANGED
|
@@ -4,7 +4,7 @@ import { getDb } from '@agi-cli/database';
|
|
|
4
4
|
import { sessions, messages, messageParts } from '@agi-cli/database/schema';
|
|
5
5
|
import { desc, eq, and, asc, count } from 'drizzle-orm';
|
|
6
6
|
import type { ProviderId } from '@agi-cli/sdk';
|
|
7
|
-
import { isProviderId
|
|
7
|
+
import { isProviderId } from '@agi-cli/sdk';
|
|
8
8
|
import { serializeError } from '../runtime/errors/api-error.ts';
|
|
9
9
|
import { logger } from '@agi-cli/sdk';
|
|
10
10
|
import { publish } from '../events/bus.ts';
|
|
@@ -207,7 +207,7 @@ export function registerResearchRoutes(app: Hono) {
|
|
|
207
207
|
return c.json({ error: 'Research session not found' }, 404);
|
|
208
208
|
}
|
|
209
209
|
|
|
210
|
-
const
|
|
210
|
+
const _researchSession = researchRows[0];
|
|
211
211
|
|
|
212
212
|
const researchMessages = await db
|
|
213
213
|
.select({
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Hono } from 'hono';
|
|
2
2
|
import {
|
|
3
|
-
|
|
3
|
+
fetchSetuBalance,
|
|
4
4
|
getPublicKeyFromPrivate,
|
|
5
5
|
getAuth,
|
|
6
6
|
loadConfig,
|
|
@@ -9,14 +9,14 @@ import {
|
|
|
9
9
|
import { logger } from '@agi-cli/sdk';
|
|
10
10
|
import { serializeError } from '../runtime/errors/api-error.ts';
|
|
11
11
|
|
|
12
|
-
async function
|
|
13
|
-
if (process.env.
|
|
14
|
-
return process.env.
|
|
12
|
+
async function getSetuPrivateKey(): Promise<string | null> {
|
|
13
|
+
if (process.env.SETU_PRIVATE_KEY) {
|
|
14
|
+
return process.env.SETU_PRIVATE_KEY;
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
try {
|
|
18
18
|
const cfg = await loadConfig(process.cwd());
|
|
19
|
-
const auth = await getAuth('
|
|
19
|
+
const auth = await getAuth('setu', cfg.projectRoot);
|
|
20
20
|
if (auth?.type === 'wallet' && auth.secret) {
|
|
21
21
|
return auth.secret;
|
|
22
22
|
}
|
|
@@ -25,33 +25,33 @@ async function getSolforgePrivateKey(): Promise<string | null> {
|
|
|
25
25
|
return null;
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
export function
|
|
29
|
-
app.get('/v1/
|
|
28
|
+
export function registerSetuRoutes(app: Hono) {
|
|
29
|
+
app.get('/v1/setu/balance', async (c) => {
|
|
30
30
|
try {
|
|
31
|
-
const privateKey = await
|
|
31
|
+
const privateKey = await getSetuPrivateKey();
|
|
32
32
|
if (!privateKey) {
|
|
33
|
-
return c.json({ error: '
|
|
33
|
+
return c.json({ error: 'Setu wallet not configured' }, 401);
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
-
const balance = await
|
|
36
|
+
const balance = await fetchSetuBalance({ privateKey });
|
|
37
37
|
if (!balance) {
|
|
38
|
-
return c.json({ error: 'Failed to fetch balance from
|
|
38
|
+
return c.json({ error: 'Failed to fetch balance from Setu' }, 502);
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
return c.json(balance);
|
|
42
42
|
} catch (error) {
|
|
43
|
-
logger.error('Failed to fetch
|
|
43
|
+
logger.error('Failed to fetch Setu balance', error);
|
|
44
44
|
const errorResponse = serializeError(error);
|
|
45
45
|
return c.json(errorResponse, errorResponse.error.status || 500);
|
|
46
46
|
}
|
|
47
47
|
});
|
|
48
48
|
|
|
49
|
-
app.get('/v1/
|
|
49
|
+
app.get('/v1/setu/wallet', async (c) => {
|
|
50
50
|
try {
|
|
51
|
-
const privateKey = await
|
|
51
|
+
const privateKey = await getSetuPrivateKey();
|
|
52
52
|
if (!privateKey) {
|
|
53
53
|
return c.json(
|
|
54
|
-
{ error: '
|
|
54
|
+
{ error: 'Setu wallet not configured', configured: false },
|
|
55
55
|
200,
|
|
56
56
|
);
|
|
57
57
|
}
|
|
@@ -66,17 +66,17 @@ export function registerSolforgeRoutes(app: Hono) {
|
|
|
66
66
|
publicKey,
|
|
67
67
|
});
|
|
68
68
|
} catch (error) {
|
|
69
|
-
logger.error('Failed to get
|
|
69
|
+
logger.error('Failed to get Setu wallet info', error);
|
|
70
70
|
const errorResponse = serializeError(error);
|
|
71
71
|
return c.json(errorResponse, errorResponse.error.status || 500);
|
|
72
72
|
}
|
|
73
73
|
});
|
|
74
74
|
|
|
75
|
-
app.get('/v1/
|
|
75
|
+
app.get('/v1/setu/usdc-balance', async (c) => {
|
|
76
76
|
try {
|
|
77
|
-
const privateKey = await
|
|
77
|
+
const privateKey = await getSetuPrivateKey();
|
|
78
78
|
if (!privateKey) {
|
|
79
|
-
return c.json({ error: '
|
|
79
|
+
return c.json({ error: 'Setu wallet not configured' }, 401);
|
|
80
80
|
}
|
|
81
81
|
|
|
82
82
|
const network =
|
|
@@ -3,7 +3,7 @@ import { getAnthropicInstance } from './anthropic.ts';
|
|
|
3
3
|
import { resolveOpenAIModel } from './openai.ts';
|
|
4
4
|
import { resolveGoogleModel } from './google.ts';
|
|
5
5
|
import { resolveOpenRouterModel } from './openrouter.ts';
|
|
6
|
-
import {
|
|
6
|
+
import { resolveSetuModel } from './setu.ts';
|
|
7
7
|
import { getZaiInstance, getZaiCodingInstance } from './zai.ts';
|
|
8
8
|
import { resolveOpencodeModel } from './opencode.ts';
|
|
9
9
|
import { getMoonshotInstance } from './moonshot.ts';
|
|
@@ -34,8 +34,8 @@ export async function resolveModel(
|
|
|
34
34
|
if (provider === 'opencode') {
|
|
35
35
|
return resolveOpencodeModel(model, cfg);
|
|
36
36
|
}
|
|
37
|
-
if (provider === '
|
|
38
|
-
return
|
|
37
|
+
if (provider === 'setu') {
|
|
38
|
+
return resolveSetuModel(model, options?.sessionId);
|
|
39
39
|
}
|
|
40
40
|
if (provider === 'zai') {
|
|
41
41
|
return getZaiInstance(cfg, model);
|
|
@@ -1,51 +1,51 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
2
|
+
createSetuModel,
|
|
3
3
|
catalog,
|
|
4
|
-
type
|
|
4
|
+
type SetuPaymentCallbacks,
|
|
5
5
|
} from '@agi-cli/sdk';
|
|
6
6
|
import { publish } from '../../events/bus.ts';
|
|
7
7
|
|
|
8
8
|
function getProviderNpm(model: string): string | undefined {
|
|
9
|
-
const entry = catalog.
|
|
9
|
+
const entry = catalog.setu?.models?.find((m) => m.id === model);
|
|
10
10
|
return entry?.provider?.npm;
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
-
export function
|
|
14
|
-
const privateKey = process.env.
|
|
13
|
+
export function resolveSetuModel(model: string, sessionId?: string) {
|
|
14
|
+
const privateKey = process.env.SETU_PRIVATE_KEY ?? '';
|
|
15
15
|
if (!privateKey) {
|
|
16
16
|
throw new Error(
|
|
17
|
-
'
|
|
17
|
+
'Setu provider requires SETU_PRIVATE_KEY (base58 Solana secret).',
|
|
18
18
|
);
|
|
19
19
|
}
|
|
20
|
-
const baseURL = process.env.
|
|
21
|
-
const rpcURL = process.env.
|
|
20
|
+
const baseURL = process.env.SETU_BASE_URL;
|
|
21
|
+
const rpcURL = process.env.SETU_SOLANA_RPC_URL;
|
|
22
22
|
|
|
23
|
-
const callbacks:
|
|
23
|
+
const callbacks: SetuPaymentCallbacks = sessionId
|
|
24
24
|
? {
|
|
25
25
|
onPaymentRequired: (amountUsd) => {
|
|
26
26
|
publish({
|
|
27
|
-
type: '
|
|
27
|
+
type: 'setu.payment.required',
|
|
28
28
|
sessionId,
|
|
29
29
|
payload: { amountUsd },
|
|
30
30
|
});
|
|
31
31
|
},
|
|
32
32
|
onPaymentSigning: () => {
|
|
33
33
|
publish({
|
|
34
|
-
type: '
|
|
34
|
+
type: 'setu.payment.signing',
|
|
35
35
|
sessionId,
|
|
36
36
|
payload: {},
|
|
37
37
|
});
|
|
38
38
|
},
|
|
39
39
|
onPaymentComplete: (data) => {
|
|
40
40
|
publish({
|
|
41
|
-
type: '
|
|
41
|
+
type: 'setu.payment.complete',
|
|
42
42
|
sessionId,
|
|
43
43
|
payload: data,
|
|
44
44
|
});
|
|
45
45
|
},
|
|
46
46
|
onPaymentError: (error) => {
|
|
47
47
|
publish({
|
|
48
|
-
type: '
|
|
48
|
+
type: 'setu.payment.error',
|
|
49
49
|
sessionId,
|
|
50
50
|
payload: { error },
|
|
51
51
|
});
|
|
@@ -55,7 +55,7 @@ export function resolveSolforgeModel(model: string, sessionId?: string) {
|
|
|
55
55
|
|
|
56
56
|
const providerNpm = getProviderNpm(model);
|
|
57
57
|
|
|
58
|
-
return
|
|
58
|
+
return createSetuModel(
|
|
59
59
|
model,
|
|
60
60
|
{ privateKey },
|
|
61
61
|
{
|
|
@@ -136,12 +136,12 @@ export function buildGetParentSessionTool(
|
|
|
136
136
|
try {
|
|
137
137
|
const parsed = JSON.parse(part.content);
|
|
138
138
|
if (parsed?.text) {
|
|
139
|
-
textContent += parsed.text
|
|
139
|
+
textContent += `${parsed.text}\n`;
|
|
140
140
|
} else {
|
|
141
|
-
textContent += part.content
|
|
141
|
+
textContent += `${part.content}\n`;
|
|
142
142
|
}
|
|
143
143
|
} catch {
|
|
144
|
-
textContent += part.content
|
|
144
|
+
textContent += `${part.content}\n`;
|
|
145
145
|
}
|
|
146
146
|
}
|
|
147
147
|
if (part.type === 'tool_call' && part.toolName) {
|
|
@@ -2,7 +2,7 @@ import { tool } from 'ai';
|
|
|
2
2
|
import { z } from 'zod/v3';
|
|
3
3
|
import { getDb } from '@agi-cli/database';
|
|
4
4
|
import { sessions, messages, messageParts } from '@agi-cli/database/schema';
|
|
5
|
-
import { eq, desc, asc, gte, lte, and,
|
|
5
|
+
import { eq, desc, asc, gte, lte, and, count, sql } from 'drizzle-orm';
|
|
6
6
|
|
|
7
7
|
const inputSchema = z.object({
|
|
8
8
|
sessionId: z.string().optional().describe('Filter by specific session ID'),
|
|
@@ -47,7 +47,7 @@ export function buildQueryMessagesTool(projectRoot: string) {
|
|
|
47
47
|
if (input.sessionId) {
|
|
48
48
|
conditions.push(eq(messages.sessionId, input.sessionId));
|
|
49
49
|
} else {
|
|
50
|
-
const
|
|
50
|
+
const _projectSessions = db
|
|
51
51
|
.select({ id: sessions.id })
|
|
52
52
|
.from(sessions)
|
|
53
53
|
.where(eq(sessions.projectPath, projectRoot));
|
|
@@ -2,7 +2,7 @@ import { tool } from 'ai';
|
|
|
2
2
|
import { z } from 'zod/v3';
|
|
3
3
|
import { getDb } from '@agi-cli/database';
|
|
4
4
|
import { sessions, messages } from '@agi-cli/database/schema';
|
|
5
|
-
import { eq, desc, asc, gte, lte, and,
|
|
5
|
+
import { eq, desc, asc, gte, lte, and, count } from 'drizzle-orm';
|
|
6
6
|
|
|
7
7
|
const inputSchema = z.object({
|
|
8
8
|
limit: z
|
|
@@ -2,7 +2,7 @@ import { tool } from 'ai';
|
|
|
2
2
|
import { z } from 'zod/v3';
|
|
3
3
|
import { getDb } from '@agi-cli/database';
|
|
4
4
|
import { sessions, messages, messageParts } from '@agi-cli/database/schema';
|
|
5
|
-
import { eq,
|
|
5
|
+
import { eq, like, and } from 'drizzle-orm';
|
|
6
6
|
|
|
7
7
|
const inputSchema = z.object({
|
|
8
8
|
query: z.string().min(1).describe('Search term to find in message content'),
|