@mitsein-ai/cli 0.2.1 → 0.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/README.md +75 -41
- package/dist/index.js +138 -140
- package/package.json +1 -1
- package/src/commands/agent.ts +90 -108
- package/src/commands/api-auto.ts +1 -1
- package/src/commands/dev.ts +1 -1
- package/src/commands/files.ts +1 -1
- package/src/commands/project.ts +6 -6
- package/src/commands/thread.ts +66 -143
- package/src/core/chat-output.ts +93 -0
- package/src/core/chat-run.ts +156 -0
- package/src/core/chat-stream.ts +188 -0
- package/src/core/client.ts +9 -2
- package/src/core/config.ts +1 -1
- package/src/core/credentials.ts +1 -1
- package/src/core/output.ts +14 -1
- package/src/index.ts +1 -3
- package/src/commands/messages.ts +0 -61
- package/src/core/sse.ts +0 -135
- package/src/core/waiters-output.ts +0 -95
- package/src/core/waiters.ts +0 -169
package/package.json
CHANGED
package/src/commands/agent.ts
CHANGED
|
@@ -1,33 +1,42 @@
|
|
|
1
1
|
import type { Command } from 'commander';
|
|
2
2
|
import { ApiClient } from '../core/client.js';
|
|
3
|
+
import { runChat } from '../core/chat-run.js';
|
|
3
4
|
import { resolveCredentials } from '../core/credentials.js';
|
|
4
5
|
import { CliError, ExitCode, handleErrors } from '../core/errors.js';
|
|
5
6
|
import { emit, setJsonMode } from '../core/output.js';
|
|
6
|
-
import { waitForRun } from '../core/waiters.js';
|
|
7
7
|
import { commaSet, httpTimeoutSec, readGlobals } from './command-opts.js';
|
|
8
8
|
|
|
9
|
+
type InvokeOpts = {
|
|
10
|
+
wait?: boolean;
|
|
11
|
+
stream?: boolean;
|
|
12
|
+
cancelOnInterrupt?: boolean;
|
|
13
|
+
filter?: string;
|
|
14
|
+
model?: string;
|
|
15
|
+
timeout?: string;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
function effectiveTimeout(raw: string | undefined, fallback: number): number | null {
|
|
19
|
+
const v = Number.parseFloat(raw ?? String(fallback));
|
|
20
|
+
if (!Number.isFinite(v)) return fallback;
|
|
21
|
+
return v === 0 ? null : v;
|
|
22
|
+
}
|
|
23
|
+
|
|
9
24
|
export function registerAgent(program: Command): void {
|
|
10
25
|
const agent = program.command('agent').description('Agent operations');
|
|
11
26
|
|
|
12
27
|
agent
|
|
13
28
|
.command('invoke <thread_id> <prompt>')
|
|
14
|
-
.description('Send a message
|
|
15
|
-
.option('--wait', 'Block until run completes', false)
|
|
16
|
-
.option('--stream', 'Stream
|
|
17
|
-
.option('--cancel-on-interrupt', 'Cancel run on Ctrl-C (
|
|
18
|
-
.option('--filter <types>', 'Comma-separated
|
|
29
|
+
.description('Send a message and run the agent (default: wait silently)')
|
|
30
|
+
.option('--wait', 'Block until run completes (default mode)', false)
|
|
31
|
+
.option('--stream', 'Stream events live to stdout', false)
|
|
32
|
+
.option('--cancel-on-interrupt', 'Cancel the run on Ctrl-C (default: detach)', false)
|
|
33
|
+
.option('--filter <types>', 'Comma-separated event types (text,tool_call,...)')
|
|
19
34
|
.option('--model <name>', 'Model override')
|
|
20
|
-
.option('--timeout <sec>', '
|
|
35
|
+
.option('--timeout <sec>', 'Stream timeout (0 = no limit)', '120')
|
|
21
36
|
.action(
|
|
22
37
|
handleErrors(async function agentInvokeAction(this: Command, threadId: string, prompt: string) {
|
|
23
38
|
const g = readGlobals(this);
|
|
24
|
-
const opts = this.opts() as
|
|
25
|
-
wait?: boolean;
|
|
26
|
-
stream?: boolean;
|
|
27
|
-
filter?: string;
|
|
28
|
-
model?: string;
|
|
29
|
-
timeout?: string;
|
|
30
|
-
};
|
|
39
|
+
const opts = this.opts() as InvokeOpts;
|
|
31
40
|
setJsonMode(Boolean(g.json));
|
|
32
41
|
|
|
33
42
|
if (opts.wait && opts.stream) {
|
|
@@ -37,181 +46,154 @@ export function registerAgent(program: Command): void {
|
|
|
37
46
|
const creds = resolveCredentials({
|
|
38
47
|
token: g.token,
|
|
39
48
|
endpoint: g.endpoint,
|
|
40
|
-
profile: g.profile ?? '
|
|
49
|
+
profile: g.profile ?? 'default',
|
|
41
50
|
real: g.real,
|
|
42
51
|
});
|
|
43
|
-
const client = new ApiClient(creds, {
|
|
44
|
-
debug: g.debug,
|
|
45
|
-
timeoutSec: httpTimeoutSec(g),
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
const addResult = await client.post('/api/message/add', {
|
|
49
|
-
thread_id: threadId,
|
|
50
|
-
content: prompt,
|
|
51
|
-
});
|
|
52
52
|
|
|
53
|
-
const
|
|
54
|
-
if (opts.model) {
|
|
55
|
-
startData.model_name = opts.model;
|
|
56
|
-
}
|
|
57
|
-
const startResult = (await client.postForm(`/api/thread/${threadId}/agent/start`, startData)) as {
|
|
58
|
-
agent_run_id?: string;
|
|
59
|
-
};
|
|
60
|
-
const agentRunId = startResult.agent_run_id ?? '';
|
|
61
|
-
|
|
62
|
-
if (!opts.wait && !opts.stream) {
|
|
63
|
-
emit({
|
|
64
|
-
message: addResult,
|
|
65
|
-
agent_run_id: agentRunId,
|
|
66
|
-
status: 'started',
|
|
67
|
-
});
|
|
68
|
-
return;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
const rawT = opts.timeout ?? '120';
|
|
72
|
-
const tNum = Number.parseFloat(rawT);
|
|
73
|
-
const effectiveTimeout = Number.isFinite(tNum) && tNum === 0 ? null : Number.isFinite(tNum) ? tNum : 120;
|
|
74
|
-
|
|
75
|
-
const result = await waitForRun({
|
|
53
|
+
const result = await runChat({
|
|
76
54
|
endpoint: creds.endpoint,
|
|
77
55
|
token: creds.token,
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
56
|
+
threadId,
|
|
57
|
+
content: [{ type: 'text', text: prompt }],
|
|
58
|
+
model: opts.model ?? null,
|
|
59
|
+
timeoutSec: effectiveTimeout(opts.timeout, 120),
|
|
82
60
|
debug: g.debug,
|
|
83
|
-
|
|
61
|
+
streamOutput: Boolean(opts.stream),
|
|
62
|
+
jsonMode: Boolean(g.json),
|
|
63
|
+
eventFilter: commaSet(opts.filter),
|
|
64
|
+
cancelOnInterrupt: Boolean(opts.cancelOnInterrupt),
|
|
84
65
|
});
|
|
85
66
|
|
|
86
|
-
if (
|
|
87
|
-
|
|
88
|
-
}
|
|
89
|
-
})
|
|
67
|
+
if (!opts.stream) emit(result);
|
|
68
|
+
}),
|
|
90
69
|
);
|
|
91
70
|
|
|
92
|
-
/* ── running
|
|
71
|
+
/* ── agent running ─────────────────────────────────────────────────────── */
|
|
93
72
|
const running = agent.command('running').description('Agent run management');
|
|
94
73
|
|
|
95
74
|
running
|
|
96
|
-
.command('list
|
|
97
|
-
.description('List agent runs for
|
|
75
|
+
.command('list')
|
|
76
|
+
.description('List all active agent runs for the current account')
|
|
98
77
|
.action(
|
|
99
|
-
handleErrors(async function runListAction(this: Command
|
|
78
|
+
handleErrors(async function runListAction(this: Command) {
|
|
100
79
|
const g = readGlobals(this);
|
|
101
80
|
setJsonMode(Boolean(g.json));
|
|
102
81
|
const client = ApiClient.fromOptions({
|
|
103
82
|
token: g.token,
|
|
104
83
|
endpoint: g.endpoint,
|
|
105
|
-
profile: g.profile ?? '
|
|
84
|
+
profile: g.profile ?? 'default',
|
|
106
85
|
real: g.real,
|
|
107
86
|
timeoutSec: httpTimeoutSec(g),
|
|
108
87
|
debug: g.debug,
|
|
109
88
|
});
|
|
110
|
-
const result = await client.
|
|
111
|
-
|
|
112
|
-
|
|
89
|
+
const result = (await client.get('/api/next/runs/active')) as {
|
|
90
|
+
runs?: unknown[];
|
|
91
|
+
} | null;
|
|
92
|
+
emit(result?.runs ?? result);
|
|
93
|
+
}),
|
|
113
94
|
);
|
|
114
95
|
|
|
115
96
|
running
|
|
116
|
-
.command('status <
|
|
117
|
-
.description('Get
|
|
97
|
+
.command('status <thread_id>')
|
|
98
|
+
.description('Get active-run status for a thread')
|
|
118
99
|
.action(
|
|
119
|
-
handleErrors(async function runStatusAction(this: Command,
|
|
100
|
+
handleErrors(async function runStatusAction(this: Command, threadId: string) {
|
|
120
101
|
const g = readGlobals(this);
|
|
121
102
|
setJsonMode(Boolean(g.json));
|
|
122
103
|
const client = ApiClient.fromOptions({
|
|
123
104
|
token: g.token,
|
|
124
105
|
endpoint: g.endpoint,
|
|
125
|
-
profile: g.profile ?? '
|
|
106
|
+
profile: g.profile ?? 'default',
|
|
126
107
|
real: g.real,
|
|
127
108
|
timeoutSec: httpTimeoutSec(g),
|
|
128
109
|
debug: g.debug,
|
|
129
110
|
});
|
|
130
|
-
const
|
|
131
|
-
|
|
132
|
-
|
|
111
|
+
const detail = (await client.get(`/api/next/threads/${threadId}`)) as {
|
|
112
|
+
active_run?: unknown;
|
|
113
|
+
} | null;
|
|
114
|
+
emit(detail?.active_run ?? { status: 'idle', last_event_id: null, error: null });
|
|
115
|
+
}),
|
|
133
116
|
);
|
|
134
117
|
|
|
135
118
|
running
|
|
136
|
-
.command('tail <
|
|
137
|
-
.description(
|
|
119
|
+
.command('tail <thread_id>')
|
|
120
|
+
.description("Reconnect to a running agent's event stream (tail -f)")
|
|
138
121
|
.option('--filter <types>', 'Comma-separated event types')
|
|
139
|
-
.option('--
|
|
122
|
+
.option('--since <event_id>', 'Resume from this SSE event id')
|
|
123
|
+
.option('--timeout <sec>', 'Stream timeout (0 = no limit)', '120')
|
|
140
124
|
.action(
|
|
141
|
-
handleErrors(async function runTailAction(this: Command,
|
|
125
|
+
handleErrors(async function runTailAction(this: Command, threadId: string) {
|
|
142
126
|
const g = readGlobals(this);
|
|
143
|
-
const opts = this.opts() as { filter?: string; timeout?: string };
|
|
127
|
+
const opts = this.opts() as { filter?: string; since?: string; timeout?: string };
|
|
144
128
|
setJsonMode(Boolean(g.json));
|
|
145
129
|
const creds = resolveCredentials({
|
|
146
130
|
token: g.token,
|
|
147
131
|
endpoint: g.endpoint,
|
|
148
|
-
profile: g.profile ?? '
|
|
132
|
+
profile: g.profile ?? 'default',
|
|
149
133
|
real: g.real,
|
|
150
134
|
});
|
|
151
|
-
|
|
152
|
-
const tNum = Number.parseFloat(rawT);
|
|
153
|
-
const effectiveTimeout = Number.isFinite(tNum) && tNum === 0 ? null : Number.isFinite(tNum) ? tNum : 120;
|
|
154
|
-
await waitForRun({
|
|
135
|
+
await runChat({
|
|
155
136
|
endpoint: creds.endpoint,
|
|
156
137
|
token: creds.token,
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
138
|
+
threadId,
|
|
139
|
+
// no `content` → reconnect mode
|
|
140
|
+
lastEventId: opts.since ?? null,
|
|
141
|
+
timeoutSec: effectiveTimeout(opts.timeout, 120),
|
|
161
142
|
debug: g.debug,
|
|
162
|
-
|
|
143
|
+
streamOutput: true,
|
|
144
|
+
jsonMode: Boolean(g.json),
|
|
145
|
+
eventFilter: commaSet(opts.filter),
|
|
163
146
|
});
|
|
164
|
-
})
|
|
147
|
+
}),
|
|
165
148
|
);
|
|
166
149
|
|
|
167
150
|
running
|
|
168
|
-
.command('wait <
|
|
169
|
-
.description('Block until
|
|
170
|
-
.option('--
|
|
151
|
+
.command('wait <thread_id>')
|
|
152
|
+
.description('Block until the active run for a thread completes')
|
|
153
|
+
.option('--since <event_id>', 'Resume from this SSE event id')
|
|
154
|
+
.option('--timeout <sec>', 'Wait timeout (0 = no limit)', '120')
|
|
171
155
|
.action(
|
|
172
|
-
handleErrors(async function runWaitAction(this: Command,
|
|
156
|
+
handleErrors(async function runWaitAction(this: Command, threadId: string) {
|
|
173
157
|
const g = readGlobals(this);
|
|
174
|
-
const opts = this.opts() as { timeout?: string };
|
|
158
|
+
const opts = this.opts() as { since?: string; timeout?: string };
|
|
175
159
|
setJsonMode(Boolean(g.json));
|
|
176
160
|
const creds = resolveCredentials({
|
|
177
161
|
token: g.token,
|
|
178
162
|
endpoint: g.endpoint,
|
|
179
|
-
profile: g.profile ?? '
|
|
163
|
+
profile: g.profile ?? 'default',
|
|
180
164
|
real: g.real,
|
|
181
165
|
});
|
|
182
|
-
const
|
|
183
|
-
const tNum = Number.parseFloat(rawT);
|
|
184
|
-
const effectiveTimeout = Number.isFinite(tNum) && tNum === 0 ? null : Number.isFinite(tNum) ? tNum : 120;
|
|
185
|
-
const result = await waitForRun({
|
|
166
|
+
const result = await runChat({
|
|
186
167
|
endpoint: creds.endpoint,
|
|
187
168
|
token: creds.token,
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
json_mode: Boolean(g.json),
|
|
169
|
+
threadId,
|
|
170
|
+
lastEventId: opts.since ?? null,
|
|
171
|
+
timeoutSec: effectiveTimeout(opts.timeout, 120),
|
|
192
172
|
debug: g.debug,
|
|
173
|
+
streamOutput: false,
|
|
174
|
+
jsonMode: Boolean(g.json),
|
|
193
175
|
});
|
|
194
176
|
emit(result);
|
|
195
|
-
})
|
|
177
|
+
}),
|
|
196
178
|
);
|
|
197
179
|
|
|
198
180
|
running
|
|
199
|
-
.command('cancel <
|
|
200
|
-
.description(
|
|
181
|
+
.command('cancel <thread_id>')
|
|
182
|
+
.description("Cancel a thread's running agent")
|
|
201
183
|
.action(
|
|
202
|
-
handleErrors(async function runCancelAction(this: Command,
|
|
184
|
+
handleErrors(async function runCancelAction(this: Command, threadId: string) {
|
|
203
185
|
const g = readGlobals(this);
|
|
204
186
|
setJsonMode(Boolean(g.json));
|
|
205
187
|
const client = ApiClient.fromOptions({
|
|
206
188
|
token: g.token,
|
|
207
189
|
endpoint: g.endpoint,
|
|
208
|
-
profile: g.profile ?? '
|
|
190
|
+
profile: g.profile ?? 'default',
|
|
209
191
|
real: g.real,
|
|
210
192
|
timeoutSec: httpTimeoutSec(g),
|
|
211
193
|
debug: g.debug,
|
|
212
194
|
});
|
|
213
|
-
const result = await client.post(`/api/
|
|
195
|
+
const result = await client.post(`/api/next/chat/${threadId}/cancel`);
|
|
214
196
|
emit(result);
|
|
215
|
-
})
|
|
197
|
+
}),
|
|
216
198
|
);
|
|
217
199
|
}
|
package/src/commands/api-auto.ts
CHANGED
|
@@ -232,7 +232,7 @@ export function registerApi(program: Command): void {
|
|
|
232
232
|
const client = ApiClient.fromOptions({
|
|
233
233
|
token: opts.token ?? g.token,
|
|
234
234
|
endpoint: opts.endpoint ?? g.endpoint,
|
|
235
|
-
profile: g.profile ?? '
|
|
235
|
+
profile: g.profile ?? 'default',
|
|
236
236
|
real: g.real,
|
|
237
237
|
timeoutSec: effectiveTimeout,
|
|
238
238
|
debug: Boolean(opts.debug ?? g.debug),
|
package/src/commands/dev.ts
CHANGED
package/src/commands/files.ts
CHANGED
|
@@ -13,7 +13,7 @@ function makeClient(cmd: Command): ApiClient {
|
|
|
13
13
|
return ApiClient.fromOptions({
|
|
14
14
|
token: g.token,
|
|
15
15
|
endpoint: g.endpoint,
|
|
16
|
-
profile: g.profile ?? '
|
|
16
|
+
profile: g.profile ?? 'default',
|
|
17
17
|
real: g.real,
|
|
18
18
|
timeoutSec: httpTimeoutSec(g),
|
|
19
19
|
debug: g.debug,
|
package/src/commands/project.ts
CHANGED
|
@@ -20,18 +20,18 @@ export function registerProject(program: Command): void {
|
|
|
20
20
|
const client = ApiClient.fromOptions({
|
|
21
21
|
token: g.token,
|
|
22
22
|
endpoint: g.endpoint,
|
|
23
|
-
profile: g.profile ?? '
|
|
23
|
+
profile: g.profile ?? 'default',
|
|
24
24
|
real: g.real,
|
|
25
25
|
timeoutSec: httpTimeoutSec(g),
|
|
26
26
|
debug: g.debug,
|
|
27
27
|
});
|
|
28
28
|
const offset = Number.parseInt(String(opts.offset ?? '0'), 10);
|
|
29
29
|
const limit = Number.parseInt(String(opts.limit ?? '20'), 10);
|
|
30
|
-
const result = await client.post('/api/project/list', {
|
|
30
|
+
const result = (await client.post('/api/project/list', {
|
|
31
31
|
offset: Number.isFinite(offset) ? offset : 0,
|
|
32
32
|
limit: Number.isFinite(limit) ? limit : 20,
|
|
33
|
-
});
|
|
34
|
-
emit(result);
|
|
33
|
+
})) as { data?: unknown[] } | null;
|
|
34
|
+
emit(result?.data ?? result);
|
|
35
35
|
})
|
|
36
36
|
);
|
|
37
37
|
|
|
@@ -45,7 +45,7 @@ export function registerProject(program: Command): void {
|
|
|
45
45
|
const client = ApiClient.fromOptions({
|
|
46
46
|
token: g.token,
|
|
47
47
|
endpoint: g.endpoint,
|
|
48
|
-
profile: g.profile ?? '
|
|
48
|
+
profile: g.profile ?? 'default',
|
|
49
49
|
real: g.real,
|
|
50
50
|
timeoutSec: httpTimeoutSec(g),
|
|
51
51
|
debug: g.debug,
|
|
@@ -65,7 +65,7 @@ export function registerProject(program: Command): void {
|
|
|
65
65
|
const client = ApiClient.fromOptions({
|
|
66
66
|
token: g.token,
|
|
67
67
|
endpoint: g.endpoint,
|
|
68
|
-
profile: g.profile ?? '
|
|
68
|
+
profile: g.profile ?? 'default',
|
|
69
69
|
real: g.real,
|
|
70
70
|
timeoutSec: httpTimeoutSec(g),
|
|
71
71
|
debug: g.debug,
|
package/src/commands/thread.ts
CHANGED
|
@@ -1,13 +1,24 @@
|
|
|
1
1
|
import type { Command } from 'commander';
|
|
2
2
|
import { ApiClient } from '../core/client.js';
|
|
3
|
-
import {
|
|
4
|
-
import { CliError, ExitCode, handleErrors } from '../core/errors.js';
|
|
3
|
+
import { handleErrors } from '../core/errors.js';
|
|
5
4
|
import { emit, setJsonMode } from '../core/output.js';
|
|
6
|
-
import {
|
|
7
|
-
|
|
5
|
+
import { httpTimeoutSec, readGlobals } from './command-opts.js';
|
|
6
|
+
|
|
7
|
+
function makeClient(cmd: Command): ApiClient {
|
|
8
|
+
const g = readGlobals(cmd);
|
|
9
|
+
setJsonMode(Boolean(g.json));
|
|
10
|
+
return ApiClient.fromOptions({
|
|
11
|
+
token: g.token,
|
|
12
|
+
endpoint: g.endpoint,
|
|
13
|
+
profile: g.profile ?? 'default',
|
|
14
|
+
real: g.real,
|
|
15
|
+
timeoutSec: httpTimeoutSec(g),
|
|
16
|
+
debug: g.debug,
|
|
17
|
+
});
|
|
18
|
+
}
|
|
8
19
|
|
|
9
20
|
export function registerThread(program: Command): void {
|
|
10
|
-
const thread = program.command('thread').description('Thread management
|
|
21
|
+
const thread = program.command('thread').description('Thread management');
|
|
11
22
|
|
|
12
23
|
thread
|
|
13
24
|
.command('list')
|
|
@@ -16,24 +27,15 @@ export function registerThread(program: Command): void {
|
|
|
16
27
|
.option('--limit <n>', 'Max results', '20')
|
|
17
28
|
.action(
|
|
18
29
|
handleErrors(async function threadListAction(this: Command) {
|
|
19
|
-
const
|
|
20
|
-
setJsonMode(Boolean(g.json));
|
|
21
|
-
const client = ApiClient.fromOptions({
|
|
22
|
-
token: g.token,
|
|
23
|
-
endpoint: g.endpoint,
|
|
24
|
-
profile: g.profile ?? 'e2e',
|
|
25
|
-
real: g.real,
|
|
26
|
-
timeoutSec: httpTimeoutSec(g),
|
|
27
|
-
debug: g.debug,
|
|
28
|
-
});
|
|
30
|
+
const client = makeClient(this);
|
|
29
31
|
const offset = Number.parseInt(String(this.opts().offset ?? '0'), 10);
|
|
30
32
|
const limit = Number.parseInt(String(this.opts().limit ?? '20'), 10);
|
|
31
|
-
const result = await client.
|
|
33
|
+
const result = (await client.get('/api/threads', {
|
|
32
34
|
offset: Number.isFinite(offset) ? offset : 0,
|
|
33
35
|
limit: Number.isFinite(limit) ? limit : 20,
|
|
34
|
-
});
|
|
35
|
-
emit(result);
|
|
36
|
-
})
|
|
36
|
+
})) as { threads?: unknown[] } | null;
|
|
37
|
+
emit(result?.threads ?? result);
|
|
38
|
+
}),
|
|
37
39
|
);
|
|
38
40
|
|
|
39
41
|
thread
|
|
@@ -41,147 +43,68 @@ export function registerThread(program: Command): void {
|
|
|
41
43
|
.description('Get thread details')
|
|
42
44
|
.action(
|
|
43
45
|
handleErrors(async function threadGetAction(this: Command, threadId: string) {
|
|
44
|
-
const
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
real: g.real,
|
|
51
|
-
timeoutSec: httpTimeoutSec(g),
|
|
52
|
-
debug: g.debug,
|
|
53
|
-
});
|
|
54
|
-
const result = await client.post('/api/thread/get', { thread_id: threadId });
|
|
55
|
-
emit(result);
|
|
56
|
-
})
|
|
46
|
+
const client = makeClient(this);
|
|
47
|
+
const result = (await client.get(`/api/threads/${threadId}`)) as {
|
|
48
|
+
thread?: unknown;
|
|
49
|
+
} | null;
|
|
50
|
+
emit(result?.thread ?? result);
|
|
51
|
+
}),
|
|
57
52
|
);
|
|
58
53
|
|
|
59
54
|
thread
|
|
60
55
|
.command('create')
|
|
61
56
|
.description('Create a new thread')
|
|
62
|
-
.option('--
|
|
57
|
+
.option('--name <name>', 'Thread name', '')
|
|
58
|
+
.option('--agent <id>', 'Agent id to bind to the thread')
|
|
63
59
|
.action(
|
|
64
60
|
handleErrors(async function threadCreateAction(this: Command) {
|
|
65
|
-
const
|
|
66
|
-
const
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
profile: g.profile ?? 'e2e',
|
|
72
|
-
real: g.real,
|
|
73
|
-
timeoutSec: httpTimeoutSec(g),
|
|
74
|
-
debug: g.debug,
|
|
75
|
-
});
|
|
76
|
-
const result = await client.post('/api/threads', { title: title ?? '' });
|
|
61
|
+
const client = makeClient(this);
|
|
62
|
+
const opts = this.opts() as { name?: string; agent?: string };
|
|
63
|
+
const body: Record<string, unknown> = {};
|
|
64
|
+
if (opts.name) body.name = opts.name;
|
|
65
|
+
if (opts.agent) body.agent_id = opts.agent;
|
|
66
|
+
const result = await client.post('/api/next/threads', body);
|
|
77
67
|
emit(result);
|
|
78
|
-
})
|
|
68
|
+
}),
|
|
79
69
|
);
|
|
80
70
|
|
|
81
71
|
thread
|
|
82
|
-
.command('
|
|
83
|
-
.description('
|
|
84
|
-
.option('--limit <n>', 'Max messages', '50')
|
|
72
|
+
.command('rename <thread_id> <name>')
|
|
73
|
+
.description('Rename a thread')
|
|
85
74
|
.action(
|
|
86
|
-
handleErrors(async function
|
|
87
|
-
const
|
|
88
|
-
const
|
|
89
|
-
setJsonMode(Boolean(g.json));
|
|
90
|
-
const client = ApiClient.fromOptions({
|
|
91
|
-
token: g.token,
|
|
92
|
-
endpoint: g.endpoint,
|
|
93
|
-
profile: g.profile ?? 'e2e',
|
|
94
|
-
real: g.real,
|
|
95
|
-
timeoutSec: httpTimeoutSec(g),
|
|
96
|
-
debug: g.debug,
|
|
97
|
-
});
|
|
98
|
-
const limit = Number.parseInt(String(lim ?? '50'), 10);
|
|
99
|
-
const result = await client.post('/api/message/list', {
|
|
100
|
-
thread_id: threadId,
|
|
101
|
-
limit: Number.isFinite(limit) ? limit : 50,
|
|
102
|
-
});
|
|
75
|
+
handleErrors(async function threadRenameAction(this: Command, threadId: string, name: string) {
|
|
76
|
+
const client = makeClient(this);
|
|
77
|
+
const result = await client.patch(`/api/next/threads/${threadId}`, { name });
|
|
103
78
|
emit(result);
|
|
104
|
-
})
|
|
79
|
+
}),
|
|
105
80
|
);
|
|
106
81
|
|
|
107
82
|
thread
|
|
108
|
-
.command('
|
|
109
|
-
.description('
|
|
110
|
-
.option('--wait', 'Block until run completes', false)
|
|
111
|
-
.option('--stream', 'Stream run events', false)
|
|
112
|
-
.option('--cancel-on-interrupt', 'Cancel run on Ctrl-C (reserved)', false)
|
|
113
|
-
.option('--filter <types>', 'Comma-separated SSE event types')
|
|
114
|
-
.option('--agent <name>', 'Agent name (reserved)', '')
|
|
115
|
-
.option('--model <name>', 'Model override')
|
|
116
|
-
.option('--timeout <sec>', 'Wait/stream timeout (0 = no limit)', '120')
|
|
83
|
+
.command('delete <thread_id>')
|
|
84
|
+
.description('Delete a thread')
|
|
117
85
|
.action(
|
|
118
|
-
handleErrors(async function
|
|
119
|
-
const
|
|
120
|
-
const
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
model?: string;
|
|
125
|
-
timeout?: string;
|
|
126
|
-
};
|
|
127
|
-
setJsonMode(Boolean(g.json));
|
|
128
|
-
|
|
129
|
-
if (opts.wait && opts.stream) {
|
|
130
|
-
throw new CliError('--wait and --stream are mutually exclusive', ExitCode.USAGE_ERROR);
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
const creds = resolveCredentials({
|
|
134
|
-
token: g.token,
|
|
135
|
-
endpoint: g.endpoint,
|
|
136
|
-
profile: g.profile ?? 'e2e',
|
|
137
|
-
real: g.real,
|
|
138
|
-
});
|
|
139
|
-
const client = new ApiClient(creds, {
|
|
140
|
-
debug: g.debug,
|
|
141
|
-
timeoutSec: httpTimeoutSec(g),
|
|
142
|
-
});
|
|
143
|
-
|
|
144
|
-
const addResult = await client.post('/api/message/add', {
|
|
145
|
-
thread_id: threadId,
|
|
146
|
-
content: message,
|
|
147
|
-
});
|
|
148
|
-
|
|
149
|
-
const startData: Record<string, string> = {};
|
|
150
|
-
if (opts.model) {
|
|
151
|
-
startData.model_name = opts.model;
|
|
152
|
-
}
|
|
153
|
-
const startResult = (await client.postForm(`/api/thread/${threadId}/agent/start`, startData)) as {
|
|
154
|
-
agent_run_id?: string;
|
|
155
|
-
};
|
|
156
|
-
const agentRunId = startResult.agent_run_id ?? '';
|
|
157
|
-
|
|
158
|
-
if (!opts.wait && !opts.stream) {
|
|
159
|
-
emit({
|
|
160
|
-
message: addResult,
|
|
161
|
-
agent_run_id: agentRunId,
|
|
162
|
-
status: 'started',
|
|
163
|
-
});
|
|
164
|
-
return;
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
const rawT = opts.timeout ?? '120';
|
|
168
|
-
const tNum = Number.parseFloat(rawT);
|
|
169
|
-
const effectiveTimeout = Number.isFinite(tNum) && tNum === 0 ? null : Number.isFinite(tNum) ? tNum : 120;
|
|
170
|
-
|
|
171
|
-
const result = await waitForRun({
|
|
172
|
-
endpoint: creds.endpoint,
|
|
173
|
-
token: creds.token,
|
|
174
|
-
agent_run_id: agentRunId,
|
|
175
|
-
timeout: effectiveTimeout ?? undefined,
|
|
176
|
-
stream_output: Boolean(opts.stream),
|
|
177
|
-
json_mode: Boolean(g.json),
|
|
178
|
-
debug: g.debug,
|
|
179
|
-
event_filter: commaSet(opts.filter),
|
|
180
|
-
});
|
|
86
|
+
handleErrors(async function threadDeleteAction(this: Command, threadId: string) {
|
|
87
|
+
const client = makeClient(this);
|
|
88
|
+
const result = await client.delete(`/api/next/threads/${threadId}`);
|
|
89
|
+
emit(result);
|
|
90
|
+
}),
|
|
91
|
+
);
|
|
181
92
|
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
93
|
+
thread
|
|
94
|
+
.command('history <thread_id>')
|
|
95
|
+
.description('Show message history for a thread')
|
|
96
|
+
.option('--limit <n>', 'Max messages', '50')
|
|
97
|
+
.action(
|
|
98
|
+
handleErrors(async function threadHistoryAction(this: Command, threadId: string) {
|
|
99
|
+
const client = makeClient(this);
|
|
100
|
+
const { limit: lim } = this.opts() as { limit?: string };
|
|
101
|
+
const limit = Number.parseInt(String(lim ?? '50'), 10);
|
|
102
|
+
const result = (await client.get(`/api/next/threads/${threadId}`)) as {
|
|
103
|
+
messages?: unknown[];
|
|
104
|
+
} | null;
|
|
105
|
+
const messages = Array.isArray(result?.messages) ? result!.messages : [];
|
|
106
|
+
const take = Number.isFinite(limit) && limit > 0 ? limit : 50;
|
|
107
|
+
emit(messages.slice(-take));
|
|
108
|
+
}),
|
|
186
109
|
);
|
|
187
110
|
}
|