naiad-cli 0.1.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/dist/api/client.d.ts +81 -0
- package/dist/api/client.js +130 -0
- package/dist/api/client.js.map +1 -0
- package/dist/callback/server.d.ts +11 -0
- package/dist/callback/server.js +53 -0
- package/dist/callback/server.js.map +1 -0
- package/dist/callback/server.test.d.ts +1 -0
- package/dist/callback/server.test.js +79 -0
- package/dist/callback/server.test.js.map +1 -0
- package/dist/commands/exec.d.ts +10 -0
- package/dist/commands/exec.js +94 -0
- package/dist/commands/exec.js.map +1 -0
- package/dist/commands/interactive.d.ts +6 -0
- package/dist/commands/interactive.js +137 -0
- package/dist/commands/interactive.js.map +1 -0
- package/dist/config/config.d.ts +5 -0
- package/dist/config/config.js +21 -0
- package/dist/config/config.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +137 -0
- package/dist/index.js.map +1 -0
- package/dist/lifecycle/setup.d.ts +11 -0
- package/dist/lifecycle/setup.js +49 -0
- package/dist/lifecycle/setup.js.map +1 -0
- package/dist/lifecycle/teardown.d.ts +6 -0
- package/dist/lifecycle/teardown.js +34 -0
- package/dist/lifecycle/teardown.js.map +1 -0
- package/dist/lifecycle/types.d.ts +21 -0
- package/dist/lifecycle/types.js +2 -0
- package/dist/lifecycle/types.js.map +1 -0
- package/dist/lifecycle/workers.d.ts +2 -0
- package/dist/lifecycle/workers.js +22 -0
- package/dist/lifecycle/workers.js.map +1 -0
- package/dist/pi/launcher.d.ts +26 -0
- package/dist/pi/launcher.js +109 -0
- package/dist/pi/launcher.js.map +1 -0
- package/dist/sync/events.d.ts +14 -0
- package/dist/sync/events.js +44 -0
- package/dist/sync/events.js.map +1 -0
- package/dist/sync/heartbeat.d.ts +12 -0
- package/dist/sync/heartbeat.js +33 -0
- package/dist/sync/heartbeat.js.map +1 -0
- package/dist/sync/session-upload.d.ts +12 -0
- package/dist/sync/session-upload.js +69 -0
- package/dist/sync/session-upload.js.map +1 -0
- package/dist/utils/package-root.d.ts +1 -0
- package/dist/utils/package-root.js +13 -0
- package/dist/utils/package-root.js.map +1 -0
- package/extensions/naiad-extension.ts +330 -0
- package/package.json +31 -0
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import type { NaiadConfig } from "../config/config.js";
|
|
2
|
+
export declare class APIClient {
|
|
3
|
+
private baseUrl;
|
|
4
|
+
private apiKey;
|
|
5
|
+
constructor(config: NaiadConfig);
|
|
6
|
+
private request;
|
|
7
|
+
listModels(): Promise<{
|
|
8
|
+
models: Array<{
|
|
9
|
+
id: string;
|
|
10
|
+
display_name: string;
|
|
11
|
+
}>;
|
|
12
|
+
}>;
|
|
13
|
+
createThread(prompt: string, opts?: {
|
|
14
|
+
source?: string;
|
|
15
|
+
trigger?: string;
|
|
16
|
+
context?: Record<string, unknown>;
|
|
17
|
+
replyTarget?: Record<string, unknown>;
|
|
18
|
+
}): Promise<{
|
|
19
|
+
id: string;
|
|
20
|
+
status: string;
|
|
21
|
+
}>;
|
|
22
|
+
updateThread(threadId: string, update: {
|
|
23
|
+
status?: string;
|
|
24
|
+
error?: string;
|
|
25
|
+
result?: unknown;
|
|
26
|
+
}): Promise<{
|
|
27
|
+
id: string;
|
|
28
|
+
status: string;
|
|
29
|
+
}>;
|
|
30
|
+
createSession(threadId: string, agentId: string, runtime?: string): Promise<{
|
|
31
|
+
id: string;
|
|
32
|
+
}>;
|
|
33
|
+
updateSession(sessionId: string, status: string): Promise<void>;
|
|
34
|
+
postEvents(threadId: string, sessionId: string, events: Array<{
|
|
35
|
+
client_seq: number;
|
|
36
|
+
event_type: string;
|
|
37
|
+
data: unknown;
|
|
38
|
+
}>): Promise<{
|
|
39
|
+
accepted: number;
|
|
40
|
+
duplicates: number;
|
|
41
|
+
}>;
|
|
42
|
+
postHeartbeat(agentId: string, threadId: string, sessionId: string, status: string, metrics?: Record<string, unknown>): Promise<void>;
|
|
43
|
+
getUploadUrls(sessionId: string, chunks: Array<{
|
|
44
|
+
start: number;
|
|
45
|
+
end: number;
|
|
46
|
+
sha256_hex: string;
|
|
47
|
+
}>): Promise<{
|
|
48
|
+
urls: Array<{
|
|
49
|
+
start: number;
|
|
50
|
+
end: number;
|
|
51
|
+
url: string;
|
|
52
|
+
}>;
|
|
53
|
+
}>;
|
|
54
|
+
finalizeSession(sessionId: string, totalBytes: number, chunkCount: number, sha256: string): Promise<void>;
|
|
55
|
+
getSession(sessionId: string): Promise<{
|
|
56
|
+
id: string;
|
|
57
|
+
thread_id: string;
|
|
58
|
+
attempt: number;
|
|
59
|
+
status: string;
|
|
60
|
+
}>;
|
|
61
|
+
listThreadSessions(threadId: string): Promise<Array<{
|
|
62
|
+
id: string;
|
|
63
|
+
thread_id: string;
|
|
64
|
+
attempt: number;
|
|
65
|
+
status: string;
|
|
66
|
+
started_at: string;
|
|
67
|
+
}>>;
|
|
68
|
+
downloadSession(sessionId: string): Promise<Buffer>;
|
|
69
|
+
listThreads(params?: {
|
|
70
|
+
status?: string;
|
|
71
|
+
limit?: number;
|
|
72
|
+
offset?: number;
|
|
73
|
+
}): Promise<{
|
|
74
|
+
threads: Array<{
|
|
75
|
+
id: string;
|
|
76
|
+
status: string;
|
|
77
|
+
created_at: string;
|
|
78
|
+
}>;
|
|
79
|
+
total: number;
|
|
80
|
+
}>;
|
|
81
|
+
}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
export class APIClient {
|
|
2
|
+
baseUrl;
|
|
3
|
+
apiKey;
|
|
4
|
+
constructor(config) {
|
|
5
|
+
this.baseUrl = config.apiUrl;
|
|
6
|
+
this.apiKey = config.apiKey;
|
|
7
|
+
}
|
|
8
|
+
async request(method, path, body) {
|
|
9
|
+
const url = `${this.baseUrl}${path}`;
|
|
10
|
+
const res = await fetch(url, {
|
|
11
|
+
method,
|
|
12
|
+
headers: {
|
|
13
|
+
"Content-Type": "application/json",
|
|
14
|
+
"Authorization": `Bearer ${this.apiKey}`,
|
|
15
|
+
},
|
|
16
|
+
body: body ? JSON.stringify(body) : undefined,
|
|
17
|
+
});
|
|
18
|
+
return res;
|
|
19
|
+
}
|
|
20
|
+
async listModels() {
|
|
21
|
+
const res = await this.request("GET", "/api/v1/models");
|
|
22
|
+
if (!res.ok)
|
|
23
|
+
throw new Error(`Failed to list models: ${res.status} ${await res.text()}`);
|
|
24
|
+
return res.json();
|
|
25
|
+
}
|
|
26
|
+
async createThread(prompt, opts) {
|
|
27
|
+
const body = {
|
|
28
|
+
prompt,
|
|
29
|
+
source: opts?.source || "cli",
|
|
30
|
+
trigger: opts?.trigger || "cli",
|
|
31
|
+
context: opts?.context || {},
|
|
32
|
+
};
|
|
33
|
+
if (opts?.replyTarget) {
|
|
34
|
+
body.reply_target = opts.replyTarget;
|
|
35
|
+
}
|
|
36
|
+
const res = await this.request("POST", "/api/v1/threads", body);
|
|
37
|
+
if (!res.ok)
|
|
38
|
+
throw new Error(`Failed to create thread: ${res.status} ${await res.text()}`);
|
|
39
|
+
return res.json();
|
|
40
|
+
}
|
|
41
|
+
async updateThread(threadId, update) {
|
|
42
|
+
const res = await this.request("PATCH", `/api/v1/threads/${threadId}`, update);
|
|
43
|
+
if (!res.ok)
|
|
44
|
+
throw new Error(`Failed to update thread: ${res.status} ${await res.text()}`);
|
|
45
|
+
return res.json();
|
|
46
|
+
}
|
|
47
|
+
async createSession(threadId, agentId, runtime = "local_cli") {
|
|
48
|
+
const res = await this.request("POST", `/api/v1/threads/${threadId}/sessions`, {
|
|
49
|
+
runtime,
|
|
50
|
+
agent_id: agentId,
|
|
51
|
+
});
|
|
52
|
+
if (!res.ok)
|
|
53
|
+
throw new Error(`Failed to create session: ${res.status} ${await res.text()}`);
|
|
54
|
+
return res.json();
|
|
55
|
+
}
|
|
56
|
+
async updateSession(sessionId, status) {
|
|
57
|
+
const res = await this.request("PATCH", `/api/v1/sessions/${sessionId}`, { status });
|
|
58
|
+
if (!res.ok)
|
|
59
|
+
throw new Error(`Failed to update session: ${res.status} ${await res.text()}`);
|
|
60
|
+
}
|
|
61
|
+
async postEvents(threadId, sessionId, events) {
|
|
62
|
+
const res = await this.request("POST", `/api/v1/threads/${threadId}/events`, {
|
|
63
|
+
session_id: sessionId,
|
|
64
|
+
events,
|
|
65
|
+
});
|
|
66
|
+
if (!res.ok)
|
|
67
|
+
throw new Error(`Failed to post events: ${res.status} ${await res.text()}`);
|
|
68
|
+
return res.json();
|
|
69
|
+
}
|
|
70
|
+
async postHeartbeat(agentId, threadId, sessionId, status, metrics = {}) {
|
|
71
|
+
const res = await this.request("POST", "/api/v1/agents/heartbeat", {
|
|
72
|
+
agent_id: agentId,
|
|
73
|
+
thread_id: threadId,
|
|
74
|
+
session_id: sessionId,
|
|
75
|
+
status,
|
|
76
|
+
metrics,
|
|
77
|
+
});
|
|
78
|
+
if (!res.ok)
|
|
79
|
+
throw new Error(`Failed to post heartbeat: ${res.status} ${await res.text()}`);
|
|
80
|
+
}
|
|
81
|
+
async getUploadUrls(sessionId, chunks) {
|
|
82
|
+
const res = await this.request("POST", `/api/v1/sessions/${sessionId}/upload-urls`, { chunks });
|
|
83
|
+
if (!res.ok)
|
|
84
|
+
throw new Error(`Failed to get upload urls: ${res.status} ${await res.text()}`);
|
|
85
|
+
return res.json();
|
|
86
|
+
}
|
|
87
|
+
async finalizeSession(sessionId, totalBytes, chunkCount, sha256) {
|
|
88
|
+
const res = await this.request("POST", `/api/v1/sessions/${sessionId}/finalize`, {
|
|
89
|
+
total_bytes: totalBytes,
|
|
90
|
+
chunk_count: chunkCount,
|
|
91
|
+
sha256,
|
|
92
|
+
});
|
|
93
|
+
if (!res.ok)
|
|
94
|
+
throw new Error(`Failed to finalize session: ${res.status} ${await res.text()}`);
|
|
95
|
+
}
|
|
96
|
+
async getSession(sessionId) {
|
|
97
|
+
const res = await this.request("GET", `/api/v1/sessions/${sessionId}`);
|
|
98
|
+
if (!res.ok)
|
|
99
|
+
throw new Error(`Failed to get session: ${res.status} ${await res.text()}`);
|
|
100
|
+
return res.json();
|
|
101
|
+
}
|
|
102
|
+
async listThreadSessions(threadId) {
|
|
103
|
+
const res = await this.request("GET", `/api/v1/threads/${threadId}/sessions`);
|
|
104
|
+
if (!res.ok)
|
|
105
|
+
throw new Error(`Failed to list sessions: ${res.status} ${await res.text()}`);
|
|
106
|
+
const data = await res.json();
|
|
107
|
+
return data.sessions;
|
|
108
|
+
}
|
|
109
|
+
async downloadSession(sessionId) {
|
|
110
|
+
const res = await this.request("GET", `/api/v1/sessions/${sessionId}/download`);
|
|
111
|
+
if (!res.ok)
|
|
112
|
+
throw new Error(`Failed to download session: ${res.status} ${await res.text()}`);
|
|
113
|
+
return Buffer.from(await res.arrayBuffer());
|
|
114
|
+
}
|
|
115
|
+
async listThreads(params) {
|
|
116
|
+
const searchParams = new URLSearchParams();
|
|
117
|
+
if (params?.status)
|
|
118
|
+
searchParams.set("status", params.status);
|
|
119
|
+
if (params?.limit)
|
|
120
|
+
searchParams.set("limit", String(params.limit));
|
|
121
|
+
if (params?.offset)
|
|
122
|
+
searchParams.set("offset", String(params.offset));
|
|
123
|
+
const qs = searchParams.toString();
|
|
124
|
+
const res = await this.request("GET", `/api/v1/threads${qs ? `?${qs}` : ""}`);
|
|
125
|
+
if (!res.ok)
|
|
126
|
+
throw new Error(`Failed to list threads: ${res.status} ${await res.text()}`);
|
|
127
|
+
return res.json();
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/api/client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export interface CallbackEvent {
|
|
2
|
+
type: string;
|
|
3
|
+
data: unknown;
|
|
4
|
+
timestamp: number;
|
|
5
|
+
}
|
|
6
|
+
export interface CallbackServer {
|
|
7
|
+
url: string;
|
|
8
|
+
drain(): CallbackEvent[];
|
|
9
|
+
close(): Promise<void>;
|
|
10
|
+
}
|
|
11
|
+
export declare function startCallbackServer(): Promise<CallbackServer>;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { createServer } from "node:http";
|
|
2
|
+
export async function startCallbackServer() {
|
|
3
|
+
const events = [];
|
|
4
|
+
const server = createServer((req, res) => {
|
|
5
|
+
if (req.method !== "POST" || req.url !== "/events") {
|
|
6
|
+
res.writeHead(404);
|
|
7
|
+
res.end();
|
|
8
|
+
return;
|
|
9
|
+
}
|
|
10
|
+
let body = "";
|
|
11
|
+
req.on("data", (chunk) => {
|
|
12
|
+
body += chunk.toString();
|
|
13
|
+
});
|
|
14
|
+
req.on("end", () => {
|
|
15
|
+
try {
|
|
16
|
+
const parsed = JSON.parse(body);
|
|
17
|
+
events.push({
|
|
18
|
+
type: parsed.type,
|
|
19
|
+
data: parsed.data,
|
|
20
|
+
timestamp: Date.now(),
|
|
21
|
+
});
|
|
22
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
23
|
+
res.end(JSON.stringify({ ok: true }));
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
res.writeHead(400, { "Content-Type": "application/json" });
|
|
27
|
+
res.end(JSON.stringify({ ok: false, error: "invalid json" }));
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
});
|
|
31
|
+
await new Promise((resolve) => {
|
|
32
|
+
server.listen(0, "127.0.0.1", () => resolve());
|
|
33
|
+
});
|
|
34
|
+
const addr = server.address();
|
|
35
|
+
const url = `http://127.0.0.1:${addr.port}/events`;
|
|
36
|
+
return {
|
|
37
|
+
url,
|
|
38
|
+
drain() {
|
|
39
|
+
return events.splice(0);
|
|
40
|
+
},
|
|
41
|
+
close() {
|
|
42
|
+
return new Promise((resolve, reject) => {
|
|
43
|
+
server.close((err) => {
|
|
44
|
+
if (err)
|
|
45
|
+
reject(err);
|
|
46
|
+
else
|
|
47
|
+
resolve();
|
|
48
|
+
});
|
|
49
|
+
});
|
|
50
|
+
},
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/callback/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAA0D,MAAM,WAAW,CAAC;AAcjG,MAAM,CAAC,KAAK,UAAU,mBAAmB;IACvC,MAAM,MAAM,GAAoB,EAAE,CAAC;IAEnC,MAAM,MAAM,GAAG,YAAY,CAAC,CAAC,GAAoB,EAAE,GAAmB,EAAE,EAAE;QACxE,IAAI,GAAG,CAAC,MAAM,KAAK,MAAM,IAAI,GAAG,CAAC,GAAG,KAAK,SAAS,EAAE,CAAC;YACnD,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;YACnB,GAAG,CAAC,GAAG,EAAE,CAAC;YACV,OAAO;QACT,CAAC;QAED,IAAI,IAAI,GAAG,EAAE,CAAC;QACd,GAAG,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE;YAC/B,IAAI,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;QAC3B,CAAC,CAAC,CAAC;QACH,GAAG,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE;YACjB,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAoC,CAAC;gBACnE,MAAM,CAAC,IAAI,CAAC;oBACV,IAAI,EAAE,MAAM,CAAC,IAAI;oBACjB,IAAI,EAAE,MAAM,CAAC,IAAI;oBACjB,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;iBACtB,CAAC,CAAC;gBACH,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC,CAAC;gBAC3D,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;YACxC,CAAC;YAAC,MAAM,CAAC;gBACP,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC,CAAC;gBAC3D,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,cAAc,EAAE,CAAC,CAAC,CAAC;YAChE,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;QAClC,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,WAAW,EAAE,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC;IACjD,CAAC,CAAC,CAAC;IAEH,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,EAAsB,CAAC;IAClD,MAAM,GAAG,GAAG,oBAAoB,IAAI,CAAC,IAAI,SAAS,CAAC;IAEnD,OAAO;QACL,GAAG;QACH,KAAK;YACH,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QAC1B,CAAC;QACD,KAAK;YACH,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;gBACrC,MAAM,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;oBACnB,IAAI,GAAG;wBAAE,MAAM,CAAC,GAAG,CAAC,CAAC;;wBAChB,OAAO,EAAE,CAAC;gBACjB,CAAC,CAAC,CAAC;YACL,CAAC,CAAC,CAAC;QACL,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { describe, it } from "node:test";
|
|
2
|
+
import assert from "node:assert/strict";
|
|
3
|
+
import { startCallbackServer } from "./server.js";
|
|
4
|
+
describe("CallbackServer", () => {
|
|
5
|
+
it("receives a single event and drains it", async () => {
|
|
6
|
+
const server = await startCallbackServer();
|
|
7
|
+
try {
|
|
8
|
+
const res = await fetch(server.url, {
|
|
9
|
+
method: "POST",
|
|
10
|
+
headers: { "Content-Type": "application/json" },
|
|
11
|
+
body: JSON.stringify({ type: "agent_start", data: { foo: 1 } }),
|
|
12
|
+
});
|
|
13
|
+
assert.equal(res.status, 200);
|
|
14
|
+
const events = server.drain();
|
|
15
|
+
assert.equal(events.length, 1);
|
|
16
|
+
assert.equal(events[0].type, "agent_start");
|
|
17
|
+
assert.deepEqual(events[0].data, { foo: 1 });
|
|
18
|
+
assert.equal(typeof events[0].timestamp, "number");
|
|
19
|
+
}
|
|
20
|
+
finally {
|
|
21
|
+
await server.close();
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
it("buffers multiple events and drain clears them", async () => {
|
|
25
|
+
const server = await startCallbackServer();
|
|
26
|
+
try {
|
|
27
|
+
for (let i = 0; i < 3; i++) {
|
|
28
|
+
await fetch(server.url, {
|
|
29
|
+
method: "POST",
|
|
30
|
+
headers: { "Content-Type": "application/json" },
|
|
31
|
+
body: JSON.stringify({ type: `event_${i}`, data: { i } }),
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
const events = server.drain();
|
|
35
|
+
assert.equal(events.length, 3);
|
|
36
|
+
assert.equal(events[0].type, "event_0");
|
|
37
|
+
assert.equal(events[1].type, "event_1");
|
|
38
|
+
assert.equal(events[2].type, "event_2");
|
|
39
|
+
// Drain again should be empty
|
|
40
|
+
const empty = server.drain();
|
|
41
|
+
assert.equal(empty.length, 0);
|
|
42
|
+
}
|
|
43
|
+
finally {
|
|
44
|
+
await server.close();
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
it("shuts down cleanly", async () => {
|
|
48
|
+
const server = await startCallbackServer();
|
|
49
|
+
await server.close();
|
|
50
|
+
// Server should no longer accept connections
|
|
51
|
+
try {
|
|
52
|
+
await fetch(server.url, {
|
|
53
|
+
method: "POST",
|
|
54
|
+
headers: { "Content-Type": "application/json" },
|
|
55
|
+
body: JSON.stringify({ type: "test", data: {} }),
|
|
56
|
+
});
|
|
57
|
+
assert.fail("Should have thrown on closed server");
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
// Expected — connection refused
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
it("returns 400 on invalid JSON", async () => {
|
|
64
|
+
const server = await startCallbackServer();
|
|
65
|
+
try {
|
|
66
|
+
const res = await fetch(server.url, {
|
|
67
|
+
method: "POST",
|
|
68
|
+
headers: { "Content-Type": "application/json" },
|
|
69
|
+
body: "not json",
|
|
70
|
+
});
|
|
71
|
+
assert.equal(res.status, 400);
|
|
72
|
+
assert.equal(server.drain().length, 0);
|
|
73
|
+
}
|
|
74
|
+
finally {
|
|
75
|
+
await server.close();
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
});
|
|
79
|
+
//# sourceMappingURL=server.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.test.js","sourceRoot":"","sources":["../../src/callback/server.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { NaiadConfig } from "../config/config.js";
|
|
2
|
+
export interface ExecOptions {
|
|
3
|
+
model?: string;
|
|
4
|
+
source?: string;
|
|
5
|
+
trigger?: string;
|
|
6
|
+
context?: string;
|
|
7
|
+
replyTarget?: string;
|
|
8
|
+
output?: string;
|
|
9
|
+
}
|
|
10
|
+
export declare function execCommand(config: NaiadConfig, prompt: string, opts?: ExecOptions): Promise<void>;
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { writeFileSync } from "fs";
|
|
2
|
+
import { launchPi } from "../pi/launcher.js";
|
|
3
|
+
import { setupLifecycle } from "../lifecycle/setup.js";
|
|
4
|
+
import { startWorkers } from "../lifecycle/workers.js";
|
|
5
|
+
import { teardownLifecycle } from "../lifecycle/teardown.js";
|
|
6
|
+
export async function execCommand(config, prompt, opts = {}) {
|
|
7
|
+
const ctx = await setupLifecycle({
|
|
8
|
+
config,
|
|
9
|
+
modelFlag: opts.model,
|
|
10
|
+
threadPrompt: prompt,
|
|
11
|
+
source: opts.source,
|
|
12
|
+
trigger: opts.trigger,
|
|
13
|
+
context: opts.context,
|
|
14
|
+
replyTarget: opts.replyTarget,
|
|
15
|
+
});
|
|
16
|
+
// Phase 1 output: write partial result immediately after thread creation
|
|
17
|
+
if (opts.output) {
|
|
18
|
+
const partial = {
|
|
19
|
+
thread_id: ctx.threadId,
|
|
20
|
+
thread_url: `${config.apiUrl}/app/threads/${ctx.threadId}`,
|
|
21
|
+
session_id: ctx.sessionId,
|
|
22
|
+
status: "RUNNING",
|
|
23
|
+
model: ctx.model,
|
|
24
|
+
};
|
|
25
|
+
writeFileSync(opts.output, JSON.stringify(partial, null, 2));
|
|
26
|
+
}
|
|
27
|
+
// Launch pi in RPC mode
|
|
28
|
+
const pi = launchPi({
|
|
29
|
+
model: ctx.model,
|
|
30
|
+
sessionDir: ctx.sessionDir,
|
|
31
|
+
extensionPath: ctx.extensionPath,
|
|
32
|
+
env: {
|
|
33
|
+
NAIAD_INFERENCE_URL: `${config.apiUrl}/api/v1/inference`,
|
|
34
|
+
NAIAD_API_KEY: config.apiKey,
|
|
35
|
+
NAIAD_THREAD_ID: ctx.threadId,
|
|
36
|
+
NAIAD_SESSION_ID: ctx.sessionId,
|
|
37
|
+
NAIAD_MODEL: ctx.model,
|
|
38
|
+
},
|
|
39
|
+
});
|
|
40
|
+
// Start background workers
|
|
41
|
+
const workers = startWorkers(ctx);
|
|
42
|
+
// Process pi events
|
|
43
|
+
let agentEnded = false;
|
|
44
|
+
pi.onEvent((event) => {
|
|
45
|
+
// Forward all events to the spool
|
|
46
|
+
workers.eventSpool.pushEvent(event.type, event);
|
|
47
|
+
// Print assistant message content to stdout
|
|
48
|
+
if (event.type === "message_update") {
|
|
49
|
+
const assistantEvent = event.assistantMessageEvent;
|
|
50
|
+
if (assistantEvent?.type === "text_delta") {
|
|
51
|
+
process.stdout.write(assistantEvent.delta ?? "");
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
if (event.type === "agent_end") {
|
|
55
|
+
agentEnded = true;
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
// Send prompt (with a small delay for pi to initialize)
|
|
59
|
+
await new Promise((resolve) => setTimeout(resolve, 500));
|
|
60
|
+
pi.sendPrompt(prompt);
|
|
61
|
+
// Wait for agent to finish
|
|
62
|
+
const exitCode = await new Promise((resolve) => {
|
|
63
|
+
pi.process.on("exit", (code, signal) => {
|
|
64
|
+
resolve(signal ? 1 : (code ?? 0));
|
|
65
|
+
});
|
|
66
|
+
// Also listen for agent_end to trigger shutdown
|
|
67
|
+
const checkInterval = setInterval(() => {
|
|
68
|
+
if (agentEnded) {
|
|
69
|
+
clearInterval(checkInterval);
|
|
70
|
+
pi.shutdown().then(() => {
|
|
71
|
+
// process exit event will resolve the promise
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
}, 100);
|
|
75
|
+
});
|
|
76
|
+
// Flush and finalize
|
|
77
|
+
process.stdout.write("\n");
|
|
78
|
+
console.error("[naiad] Agent finished, flushing...");
|
|
79
|
+
await workers.stop();
|
|
80
|
+
await teardownLifecycle({ ctx, exitCode });
|
|
81
|
+
// Phase 2 output: write final result before exit
|
|
82
|
+
if (opts.output) {
|
|
83
|
+
const result = {
|
|
84
|
+
thread_id: ctx.threadId,
|
|
85
|
+
thread_url: `${config.apiUrl}/app/threads/${ctx.threadId}`,
|
|
86
|
+
session_id: ctx.sessionId,
|
|
87
|
+
status: exitCode === 0 ? "COMPLETED" : "FAILED",
|
|
88
|
+
model: ctx.model,
|
|
89
|
+
};
|
|
90
|
+
writeFileSync(opts.output, JSON.stringify(result, null, 2));
|
|
91
|
+
}
|
|
92
|
+
process.exit(exitCode);
|
|
93
|
+
}
|
|
94
|
+
//# sourceMappingURL=exec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exec.js","sourceRoot":"","sources":["../../src/commands/exec.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import { mkdtempSync, writeFileSync } from "fs";
|
|
2
|
+
import { join } from "path";
|
|
3
|
+
import { tmpdir } from "os";
|
|
4
|
+
import { randomUUID } from "crypto";
|
|
5
|
+
import { APIClient } from "../api/client.js";
|
|
6
|
+
import { launchPiInteractive } from "../pi/launcher.js";
|
|
7
|
+
import { startCallbackServer } from "../callback/server.js";
|
|
8
|
+
import { startWorkers } from "../lifecycle/workers.js";
|
|
9
|
+
import { teardownLifecycle } from "../lifecycle/teardown.js";
|
|
10
|
+
import { findPackageRoot } from "../utils/package-root.js";
|
|
11
|
+
export async function interactiveCommand(config, options) {
|
|
12
|
+
const client = new APIClient(config);
|
|
13
|
+
// Validate API key by listing models
|
|
14
|
+
console.error("[naiad] Validating API key...");
|
|
15
|
+
const { models } = await client.listModels();
|
|
16
|
+
if (models.length === 0) {
|
|
17
|
+
console.error("[naiad] No models available");
|
|
18
|
+
process.exit(1);
|
|
19
|
+
}
|
|
20
|
+
const model = options.modelFlag || models[0].id;
|
|
21
|
+
console.error(`[naiad] Using model: ${model}`);
|
|
22
|
+
const sessionDir = mkdtempSync(join(tmpdir(), "naiad-session-"));
|
|
23
|
+
const pkgRoot = findPackageRoot();
|
|
24
|
+
const extensionPath = join(pkgRoot, "extensions", "naiad-extension.ts");
|
|
25
|
+
const agentId = randomUUID();
|
|
26
|
+
let threadId;
|
|
27
|
+
let sessionId;
|
|
28
|
+
let resumeSessionFile;
|
|
29
|
+
if (options.sessionId || options.continueRecent) {
|
|
30
|
+
// Resume flow
|
|
31
|
+
const resolved = await resolveResumeSession(client, options);
|
|
32
|
+
threadId = resolved.threadId;
|
|
33
|
+
// Download previous session JSONL
|
|
34
|
+
console.error(`[naiad] Downloading session ${resolved.previousSessionId}...`);
|
|
35
|
+
const jsonlData = await client.downloadSession(resolved.previousSessionId);
|
|
36
|
+
const jsonlFilename = `${new Date().toISOString().replace(/[:.]/g, "-")}_${randomUUID()}.jsonl`;
|
|
37
|
+
resumeSessionFile = join(sessionDir, jsonlFilename);
|
|
38
|
+
writeFileSync(resumeSessionFile, jsonlData);
|
|
39
|
+
console.error(`[naiad] Session data written to ${resumeSessionFile}`);
|
|
40
|
+
// Create new session on existing thread
|
|
41
|
+
const session = await client.createSession(threadId, agentId);
|
|
42
|
+
sessionId = session.id;
|
|
43
|
+
console.error(`[naiad] Created session: ${sessionId} (resuming thread ${threadId})`);
|
|
44
|
+
// Transition thread back to RUNNING
|
|
45
|
+
await client.updateThread(threadId, { status: "RUNNING" });
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
// New session flow
|
|
49
|
+
const thread = await client.createThread("[interactive session]");
|
|
50
|
+
threadId = thread.id;
|
|
51
|
+
console.error(`[naiad] Created thread: ${threadId}`);
|
|
52
|
+
const session = await client.createSession(threadId, agentId);
|
|
53
|
+
sessionId = session.id;
|
|
54
|
+
console.error(`[naiad] Created session: ${sessionId}`);
|
|
55
|
+
await client.updateThread(threadId, { status: "RUNNING" });
|
|
56
|
+
}
|
|
57
|
+
const ctx = {
|
|
58
|
+
config,
|
|
59
|
+
client,
|
|
60
|
+
model,
|
|
61
|
+
agentId,
|
|
62
|
+
threadId,
|
|
63
|
+
sessionId,
|
|
64
|
+
sessionDir,
|
|
65
|
+
extensionPath,
|
|
66
|
+
};
|
|
67
|
+
// Start callback server
|
|
68
|
+
const callbackServer = await startCallbackServer();
|
|
69
|
+
console.error(`[naiad] Callback server listening at ${callbackServer.url}`);
|
|
70
|
+
// Guard against EIO on inherited stdin after pi exits and releases the PTY
|
|
71
|
+
process.stdin.on("error", () => { });
|
|
72
|
+
// Launch pi in interactive mode
|
|
73
|
+
const pi = launchPiInteractive({
|
|
74
|
+
model,
|
|
75
|
+
sessionDir,
|
|
76
|
+
extensionPath,
|
|
77
|
+
resumeSessionFile,
|
|
78
|
+
env: {
|
|
79
|
+
NAIAD_INFERENCE_URL: `${config.apiUrl}/api/v1/inference`,
|
|
80
|
+
NAIAD_API_KEY: config.apiKey,
|
|
81
|
+
NAIAD_THREAD_ID: threadId,
|
|
82
|
+
NAIAD_SESSION_ID: sessionId,
|
|
83
|
+
NAIAD_MODEL: model,
|
|
84
|
+
NAIAD_CALLBACK_URL: callbackServer.url,
|
|
85
|
+
},
|
|
86
|
+
});
|
|
87
|
+
// Start background workers
|
|
88
|
+
const workers = startWorkers(ctx);
|
|
89
|
+
// Event pump: drain callback buffer → event spool
|
|
90
|
+
const eventPump = setInterval(() => {
|
|
91
|
+
const events = callbackServer.drain();
|
|
92
|
+
for (const ev of events) {
|
|
93
|
+
workers.eventSpool.pushEvent(ev.type, ev.data);
|
|
94
|
+
}
|
|
95
|
+
}, 200);
|
|
96
|
+
// Wait for pi to exit
|
|
97
|
+
const exitCode = await new Promise((resolve) => {
|
|
98
|
+
pi.process.on("exit", (code, signal) => {
|
|
99
|
+
resolve(signal ? 1 : (code ?? 0));
|
|
100
|
+
});
|
|
101
|
+
});
|
|
102
|
+
// Clean up event pump
|
|
103
|
+
clearInterval(eventPump);
|
|
104
|
+
// Drain any remaining callback events
|
|
105
|
+
const remaining = callbackServer.drain();
|
|
106
|
+
for (const ev of remaining) {
|
|
107
|
+
workers.eventSpool.pushEvent(ev.type, ev.data);
|
|
108
|
+
}
|
|
109
|
+
console.error("[naiad] Pi exited, flushing...");
|
|
110
|
+
// Stop workers and callback server
|
|
111
|
+
await workers.stop();
|
|
112
|
+
await callbackServer.close();
|
|
113
|
+
// Teardown
|
|
114
|
+
await teardownLifecycle({ ctx, exitCode });
|
|
115
|
+
process.exit(exitCode);
|
|
116
|
+
}
|
|
117
|
+
async function resolveResumeSession(client, options) {
|
|
118
|
+
if (options.sessionId) {
|
|
119
|
+
const session = await client.getSession(options.sessionId);
|
|
120
|
+
return { threadId: session.thread_id, previousSessionId: session.id };
|
|
121
|
+
}
|
|
122
|
+
// -c: find most recent thread, then its most recent session
|
|
123
|
+
const { threads } = await client.listThreads({ limit: 1 });
|
|
124
|
+
if (threads.length === 0) {
|
|
125
|
+
console.error("[naiad] No previous sessions found. Run `naiad` first to create a session.");
|
|
126
|
+
process.exit(1);
|
|
127
|
+
}
|
|
128
|
+
const thread = threads[0];
|
|
129
|
+
const sessions = await client.listThreadSessions(thread.id);
|
|
130
|
+
if (sessions.length === 0) {
|
|
131
|
+
console.error(`[naiad] Thread ${thread.id} has no sessions. Run \`naiad\` first to create a session.`);
|
|
132
|
+
process.exit(1);
|
|
133
|
+
}
|
|
134
|
+
console.error(`[naiad] Continuing thread ${thread.id}, session ${sessions[0].id}`);
|
|
135
|
+
return { threadId: thread.id, previousSessionId: sessions[0].id };
|
|
136
|
+
}
|
|
137
|
+
//# sourceMappingURL=interactive.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"interactive.js","sourceRoot":"","sources":["../../src/commands/interactive.ts"],"names":[],"mappings":"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"}
|