letagents 0.11.1 → 0.12.1
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 +65 -0
- package/README.md +7 -4
- package/dist/mcp/codenames.js +5 -3
- package/dist/mcp/codex-session.js +500 -0
- package/dist/mcp/config-reader.js +1 -1
- package/dist/mcp/git-remote.js +3 -3
- package/dist/mcp/local-state.js +58 -0
- package/dist/mcp/server.js +337 -59
- package/dist/mcp/sse-client.js +19 -3
- package/dist/shared/room-agent-prompts.js +25 -0
- package/package.json +5 -3
package/dist/mcp/sse-client.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { encodeRoomIdPath } from "./room-id.js";
|
|
2
|
+
import { buildRoomAgentPrompt, normalizeAgentPromptKind } from "../shared/room-agent-prompts.js";
|
|
2
3
|
export class SseClient {
|
|
3
4
|
apiUrl;
|
|
4
5
|
getAccessToken;
|
|
@@ -53,7 +54,7 @@ export class SseClient {
|
|
|
53
54
|
}
|
|
54
55
|
async consumeStream(target, signal, onMessage) {
|
|
55
56
|
try {
|
|
56
|
-
await this.openStream(`${this.apiUrl}/rooms/${encodeRoomIdPath(target.roomId)}/messages/stream
|
|
57
|
+
await this.openStream(this.withIncludePromptOnly(`${this.apiUrl}/rooms/${encodeRoomIdPath(target.roomId)}/messages/stream`), signal, onMessage);
|
|
57
58
|
return;
|
|
58
59
|
}
|
|
59
60
|
catch (error) {
|
|
@@ -61,7 +62,10 @@ export class SseClient {
|
|
|
61
62
|
throw error;
|
|
62
63
|
}
|
|
63
64
|
}
|
|
64
|
-
await this.openStream(`${this.apiUrl}/projects/${encodeURIComponent(target.projectId)}/messages/stream
|
|
65
|
+
await this.openStream(this.withIncludePromptOnly(`${this.apiUrl}/projects/${encodeURIComponent(target.projectId)}/messages/stream`), signal, onMessage);
|
|
66
|
+
}
|
|
67
|
+
withIncludePromptOnly(url) {
|
|
68
|
+
return `${url}${url.includes("?") ? "&" : "?"}include_prompt_only=1`;
|
|
65
69
|
}
|
|
66
70
|
async openStream(url, signal, onMessage) {
|
|
67
71
|
const response = await fetch(url, {
|
|
@@ -105,7 +109,19 @@ export class SseClient {
|
|
|
105
109
|
if (dataLines.length === 0) {
|
|
106
110
|
return;
|
|
107
111
|
}
|
|
108
|
-
onMessage(JSON.parse(dataLines.join("\n")));
|
|
112
|
+
onMessage(this.enrichPromptMetadata(JSON.parse(dataLines.join("\n"))));
|
|
113
|
+
}
|
|
114
|
+
enrichPromptMetadata(message) {
|
|
115
|
+
const kind = normalizeAgentPromptKind(message.agent_prompt_kind);
|
|
116
|
+
if (!kind) {
|
|
117
|
+
return message;
|
|
118
|
+
}
|
|
119
|
+
return {
|
|
120
|
+
...message,
|
|
121
|
+
visible_text: message.text,
|
|
122
|
+
agent_prompt: buildRoomAgentPrompt(kind),
|
|
123
|
+
prompt_injected: kind === "inline",
|
|
124
|
+
};
|
|
109
125
|
}
|
|
110
126
|
isMissingRouteError(error) {
|
|
111
127
|
return (error instanceof Error &&
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
// TODO: make room agent prompts configurable per room/project instead of hardcoded
|
|
2
|
+
// constants. The current behavior is intentionally global across rooms.
|
|
3
|
+
const BASE_ROOM_AGENT_PROMPT = "Stay in this room continuously. Keep long-polling for new messages. When messages arrive, read them immediately, act on anything actionable, help with review work when asked, and keep monitoring until the human explicitly redirects you. Do not send a visible 'keep polling' acknowledgement unless the human explicitly asks for that phrase.";
|
|
4
|
+
export function buildRoomAgentPrompt(kind) {
|
|
5
|
+
if (kind === "join") {
|
|
6
|
+
return `You just joined this room. ${BASE_ROOM_AGENT_PROMPT}`;
|
|
7
|
+
}
|
|
8
|
+
if (kind === "auto") {
|
|
9
|
+
return `Background reminder. ${BASE_ROOM_AGENT_PROMPT}`;
|
|
10
|
+
}
|
|
11
|
+
return `Treat the visible user message above as the active instruction. After you handle it, ${BASE_ROOM_AGENT_PROMPT}`;
|
|
12
|
+
}
|
|
13
|
+
export function normalizeAgentPromptKind(value) {
|
|
14
|
+
if (typeof value !== "string") {
|
|
15
|
+
return null;
|
|
16
|
+
}
|
|
17
|
+
const normalized = value.trim().toLowerCase();
|
|
18
|
+
if (normalized === "join" || normalized === "inline" || normalized === "auto") {
|
|
19
|
+
return normalized;
|
|
20
|
+
}
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
export function isPromptOnlyAgentMessage(text, kind) {
|
|
24
|
+
return normalizeAgentPromptKind(kind) === "auto" && !String(text || "").trim();
|
|
25
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "letagents",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.12.1",
|
|
4
4
|
"description": "Let Agents Chat — MCP server for AI agent communication",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/mcp/server.js",
|
|
@@ -14,6 +14,8 @@
|
|
|
14
14
|
],
|
|
15
15
|
"scripts": {
|
|
16
16
|
"build": "tsc",
|
|
17
|
+
"build:web": "cd src/web && npm install && npx vite build",
|
|
18
|
+
"build:all": "npm run build && npm run build:web",
|
|
17
19
|
"db:generate": "drizzle-kit generate",
|
|
18
20
|
"db:migrate": "tsx src/api/migrate.ts",
|
|
19
21
|
"db:studio": "drizzle-kit studio",
|
|
@@ -30,9 +32,9 @@
|
|
|
30
32
|
],
|
|
31
33
|
"repository": {
|
|
32
34
|
"type": "git",
|
|
33
|
-
"url": "https://github.com/
|
|
35
|
+
"url": "https://github.com/BrosInCode/letagents.git"
|
|
34
36
|
},
|
|
35
|
-
"license": "
|
|
37
|
+
"license": "BUSL-1.1",
|
|
36
38
|
"dependencies": {
|
|
37
39
|
"@modelcontextprotocol/sdk": "^1.12.1",
|
|
38
40
|
"drizzle-orm": "^0.45.1",
|