@react-grab/amp 0.0.82
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/LICENSE +21 -0
- package/README.md +46 -0
- package/dist/cli.cjs +613 -0
- package/dist/cli.d.cts +1 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +611 -0
- package/dist/client.cjs +173 -0
- package/dist/client.d.cts +27 -0
- package/dist/client.d.ts +27 -0
- package/dist/client.global.js +4 -0
- package/dist/client.js +170 -0
- package/dist/server.cjs +159 -0
- package/dist/server.d.cts +10 -0
- package/dist/server.d.ts +10 -0
- package/dist/server.js +150 -0
- package/package.json +43 -0
package/dist/server.js
ADDED
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import { execute } from '@sourcegraph/amp-sdk';
|
|
2
|
+
import fkill from 'fkill';
|
|
3
|
+
import { Hono } from 'hono';
|
|
4
|
+
import { cors } from 'hono/cors';
|
|
5
|
+
import { streamSSE } from 'hono/streaming';
|
|
6
|
+
import { serve } from '@hono/node-server';
|
|
7
|
+
import pc from 'picocolors';
|
|
8
|
+
import { pathToFileURL } from 'url';
|
|
9
|
+
|
|
10
|
+
// src/server.ts
|
|
11
|
+
|
|
12
|
+
// src/constants.ts
|
|
13
|
+
var DEFAULT_PORT = 9567;
|
|
14
|
+
var VERSION = "0.0.82";
|
|
15
|
+
var sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
16
|
+
var threadMap = /* @__PURE__ */ new Map();
|
|
17
|
+
var abortControllers = /* @__PURE__ */ new Map();
|
|
18
|
+
var extractTextFromContent = (content) => {
|
|
19
|
+
return content.filter((item) => item.type === "text" && item.text).map((item) => item.text).join(" ").trim();
|
|
20
|
+
};
|
|
21
|
+
var createServer = () => {
|
|
22
|
+
const honoApplication = new Hono();
|
|
23
|
+
honoApplication.use("*", cors());
|
|
24
|
+
honoApplication.post("/agent", async (context) => {
|
|
25
|
+
const requestBody = await context.req.json();
|
|
26
|
+
const { content, prompt, options, sessionId } = requestBody;
|
|
27
|
+
const existingThread = sessionId ? threadMap.get(sessionId) : void 0;
|
|
28
|
+
const isFollowUp = Boolean(existingThread);
|
|
29
|
+
const userPrompt = isFollowUp ? prompt : `${prompt}
|
|
30
|
+
|
|
31
|
+
${content}`;
|
|
32
|
+
return streamSSE(context, async (stream) => {
|
|
33
|
+
const abortController = new AbortController();
|
|
34
|
+
if (sessionId) {
|
|
35
|
+
abortControllers.set(sessionId, abortController);
|
|
36
|
+
}
|
|
37
|
+
const isAborted = () => abortController.signal.aborted;
|
|
38
|
+
try {
|
|
39
|
+
await stream.writeSSE({ data: "Thinking...", event: "status" });
|
|
40
|
+
const executeOptions = {
|
|
41
|
+
dangerouslyAllowAll: true
|
|
42
|
+
};
|
|
43
|
+
if (options?.cwd) {
|
|
44
|
+
executeOptions.cwd = options.cwd;
|
|
45
|
+
} else {
|
|
46
|
+
executeOptions.cwd = process.cwd();
|
|
47
|
+
}
|
|
48
|
+
if (isFollowUp && existingThread) {
|
|
49
|
+
executeOptions.continue = existingThread.threadId;
|
|
50
|
+
}
|
|
51
|
+
let capturedThreadId;
|
|
52
|
+
for await (const message of execute({
|
|
53
|
+
prompt: userPrompt,
|
|
54
|
+
options: executeOptions,
|
|
55
|
+
signal: abortController.signal
|
|
56
|
+
})) {
|
|
57
|
+
if (isAborted()) break;
|
|
58
|
+
switch (message.type) {
|
|
59
|
+
case "system":
|
|
60
|
+
if (message.subtype === "init") {
|
|
61
|
+
const systemMessage = message;
|
|
62
|
+
if (systemMessage.thread_id) {
|
|
63
|
+
capturedThreadId = systemMessage.thread_id;
|
|
64
|
+
}
|
|
65
|
+
await stream.writeSSE({ data: "Session started...", event: "status" });
|
|
66
|
+
}
|
|
67
|
+
break;
|
|
68
|
+
case "assistant": {
|
|
69
|
+
const messageContent = message.message?.content;
|
|
70
|
+
if (messageContent && Array.isArray(messageContent)) {
|
|
71
|
+
const toolUse = messageContent.find((item) => item.type === "tool_use");
|
|
72
|
+
if (toolUse && "name" in toolUse) {
|
|
73
|
+
await stream.writeSSE({
|
|
74
|
+
data: `Using ${toolUse.name}...`,
|
|
75
|
+
event: "status"
|
|
76
|
+
});
|
|
77
|
+
} else {
|
|
78
|
+
const textContent = extractTextFromContent(messageContent);
|
|
79
|
+
if (textContent && !isAborted()) {
|
|
80
|
+
await stream.writeSSE({ data: textContent, event: "status" });
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
break;
|
|
85
|
+
}
|
|
86
|
+
case "result":
|
|
87
|
+
if (message.is_error) {
|
|
88
|
+
await stream.writeSSE({
|
|
89
|
+
data: `Error: ${message.error || "Unknown error"}`,
|
|
90
|
+
event: "error"
|
|
91
|
+
});
|
|
92
|
+
} else {
|
|
93
|
+
await stream.writeSSE({
|
|
94
|
+
data: "Completed successfully",
|
|
95
|
+
event: "status"
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
break;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
if (sessionId && capturedThreadId && !isAborted()) {
|
|
102
|
+
threadMap.set(sessionId, { threadId: capturedThreadId });
|
|
103
|
+
}
|
|
104
|
+
if (!isAborted()) {
|
|
105
|
+
await stream.writeSSE({ data: "", event: "done" });
|
|
106
|
+
}
|
|
107
|
+
} catch (error) {
|
|
108
|
+
if (!isAborted()) {
|
|
109
|
+
const errorMessage = error instanceof Error ? error.message : "Unknown error";
|
|
110
|
+
await stream.writeSSE({
|
|
111
|
+
data: `Error: ${errorMessage}`,
|
|
112
|
+
event: "error"
|
|
113
|
+
});
|
|
114
|
+
await stream.writeSSE({ data: "", event: "done" });
|
|
115
|
+
}
|
|
116
|
+
} finally {
|
|
117
|
+
if (sessionId) {
|
|
118
|
+
abortControllers.delete(sessionId);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
});
|
|
122
|
+
});
|
|
123
|
+
honoApplication.post("/abort/:sessionId", (context) => {
|
|
124
|
+
const { sessionId } = context.req.param();
|
|
125
|
+
const abortController = abortControllers.get(sessionId);
|
|
126
|
+
if (abortController) {
|
|
127
|
+
abortController.abort();
|
|
128
|
+
abortControllers.delete(sessionId);
|
|
129
|
+
}
|
|
130
|
+
return context.json({ status: "ok" });
|
|
131
|
+
});
|
|
132
|
+
honoApplication.get("/health", (context) => {
|
|
133
|
+
return context.json({ status: "ok", provider: "amp" });
|
|
134
|
+
});
|
|
135
|
+
return honoApplication;
|
|
136
|
+
};
|
|
137
|
+
var startServer = async (port = DEFAULT_PORT) => {
|
|
138
|
+
await fkill(`:${port}`, { force: true, silent: true }).catch(() => {
|
|
139
|
+
});
|
|
140
|
+
await sleep(100);
|
|
141
|
+
const honoApplication = createServer();
|
|
142
|
+
serve({ fetch: honoApplication.fetch, port });
|
|
143
|
+
console.log(`${pc.magenta("\u269B")} ${pc.bold("React Grab")} ${pc.gray(VERSION)} ${pc.dim("(Amp)")}`);
|
|
144
|
+
console.log(`- Local: ${pc.cyan(`http://localhost:${port}`)}`);
|
|
145
|
+
};
|
|
146
|
+
if (import.meta.url === pathToFileURL(process.argv[1]).href) {
|
|
147
|
+
startServer(DEFAULT_PORT).catch(console.error);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
export { createServer, startServer };
|
package/package.json
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@react-grab/amp",
|
|
3
|
+
"version": "0.0.82",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"bin": {
|
|
6
|
+
"react-grab-amp": "./dist/cli.cjs"
|
|
7
|
+
},
|
|
8
|
+
"exports": {
|
|
9
|
+
"./client": {
|
|
10
|
+
"types": "./dist/client.d.ts",
|
|
11
|
+
"import": "./dist/client.js",
|
|
12
|
+
"require": "./dist/client.cjs"
|
|
13
|
+
},
|
|
14
|
+
"./server": {
|
|
15
|
+
"types": "./dist/server.d.ts",
|
|
16
|
+
"import": "./dist/server.js",
|
|
17
|
+
"require": "./dist/server.cjs"
|
|
18
|
+
},
|
|
19
|
+
"./dist/*": "./dist/*.js",
|
|
20
|
+
"./dist/*.js": "./dist/*.js"
|
|
21
|
+
},
|
|
22
|
+
"browser": "dist/client.global.js",
|
|
23
|
+
"files": [
|
|
24
|
+
"dist"
|
|
25
|
+
],
|
|
26
|
+
"devDependencies": {
|
|
27
|
+
"@types/cross-spawn": "^6.0.6",
|
|
28
|
+
"tsup": "^8.4.0"
|
|
29
|
+
},
|
|
30
|
+
"dependencies": {
|
|
31
|
+
"@hono/node-server": "^1.19.6",
|
|
32
|
+
"cross-spawn": "^7.0.6",
|
|
33
|
+
"@sourcegraph/amp-sdk": "0.1.0-20251210081226-g90e3892",
|
|
34
|
+
"fkill": "^9.0.0",
|
|
35
|
+
"hono": "^4.0.0",
|
|
36
|
+
"picocolors": "^1.1.1",
|
|
37
|
+
"react-grab": "0.0.82"
|
|
38
|
+
},
|
|
39
|
+
"scripts": {
|
|
40
|
+
"dev": "tsup --watch",
|
|
41
|
+
"build": "rm -rf dist && NODE_ENV=production tsup"
|
|
42
|
+
}
|
|
43
|
+
}
|