@gonzih/cc-tg 0.9.41 → 0.9.42
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/router.d.ts +11 -2
- package/dist/router.js +62 -9
- package/package.json +1 -1
package/dist/router.d.ts
CHANGED
|
@@ -33,10 +33,19 @@ export declare function parseRoutingTag(text: string): RoutingTag | null;
|
|
|
33
33
|
* Ensure a meta-agent for the given namespace is running.
|
|
34
34
|
*
|
|
35
35
|
* Steps:
|
|
36
|
-
* 1. Check
|
|
36
|
+
* 1. Check Redis for readiness via two keys (see below) — return early if already ready.
|
|
37
37
|
* 2. Verify the GitHub repo exists; create it (public) if not.
|
|
38
38
|
* 3. Call the start_meta_agent MCP tool via callTool.
|
|
39
|
-
* 4. Poll
|
|
39
|
+
* 4. Poll both Redis keys every 1s until ready or META_AGENT_TIMEOUT_MS expires.
|
|
40
|
+
*
|
|
41
|
+
* Two Redis keys are checked:
|
|
42
|
+
* cca:meta-agent:status:{namespace} — live-status key written by writeLiveStatus()
|
|
43
|
+
* (only populated after the first message is processed by messageMetaAgent)
|
|
44
|
+
* cca:meta:{namespace} — state key written by startMetaAgent() directly via saveState()
|
|
45
|
+
* (populated as soon as the workspace is created, with status:"idle")
|
|
46
|
+
*
|
|
47
|
+
* Bug context: start_meta_agent writes cca:meta:{namespace} but NOT cca:meta-agent:status:{namespace}.
|
|
48
|
+
* Polling only the status key caused a 10s timeout on every cold start.
|
|
40
49
|
*
|
|
41
50
|
* Throws on failure (repo creation error, tool call failure, or timeout).
|
|
42
51
|
*/
|
package/dist/router.js
CHANGED
|
@@ -51,18 +51,29 @@ export function parseRoutingTag(text) {
|
|
|
51
51
|
* Ensure a meta-agent for the given namespace is running.
|
|
52
52
|
*
|
|
53
53
|
* Steps:
|
|
54
|
-
* 1. Check
|
|
54
|
+
* 1. Check Redis for readiness via two keys (see below) — return early if already ready.
|
|
55
55
|
* 2. Verify the GitHub repo exists; create it (public) if not.
|
|
56
56
|
* 3. Call the start_meta_agent MCP tool via callTool.
|
|
57
|
-
* 4. Poll
|
|
57
|
+
* 4. Poll both Redis keys every 1s until ready or META_AGENT_TIMEOUT_MS expires.
|
|
58
|
+
*
|
|
59
|
+
* Two Redis keys are checked:
|
|
60
|
+
* cca:meta-agent:status:{namespace} — live-status key written by writeLiveStatus()
|
|
61
|
+
* (only populated after the first message is processed by messageMetaAgent)
|
|
62
|
+
* cca:meta:{namespace} — state key written by startMetaAgent() directly via saveState()
|
|
63
|
+
* (populated as soon as the workspace is created, with status:"idle")
|
|
64
|
+
*
|
|
65
|
+
* Bug context: start_meta_agent writes cca:meta:{namespace} but NOT cca:meta-agent:status:{namespace}.
|
|
66
|
+
* Polling only the status key caused a 10s timeout on every cold start.
|
|
58
67
|
*
|
|
59
68
|
* Throws on failure (repo creation error, tool call failure, or timeout).
|
|
60
69
|
*/
|
|
61
70
|
export async function ensureMetaAgent(namespace, repoUrl, callTool, redis) {
|
|
62
71
|
const timeoutMs = parseInt(process.env.META_AGENT_TIMEOUT_MS ?? "10000", 10);
|
|
63
72
|
const statusKey = `cca:meta-agent:status:${namespace}`;
|
|
64
|
-
|
|
65
|
-
|
|
73
|
+
// State key written by startMetaAgent() directly — the source of truth for workspace existence.
|
|
74
|
+
const stateKey = `cca:meta:${namespace}`;
|
|
75
|
+
console.log(`[router] ensureMetaAgent namespace=${namespace}`);
|
|
76
|
+
// Fast path: check live-status key (written by messageMetaAgent after first message)
|
|
66
77
|
const statusRaw = await redis.get(statusKey);
|
|
67
78
|
if (statusRaw) {
|
|
68
79
|
try {
|
|
@@ -73,7 +84,22 @@ export async function ensureMetaAgent(namespace, repoUrl, callTool, redis) {
|
|
|
73
84
|
}
|
|
74
85
|
}
|
|
75
86
|
catch {
|
|
76
|
-
// Corrupt status value — fall through
|
|
87
|
+
// Corrupt status value — fall through
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
// Fast path: also check state key (written by startMetaAgent, persists 30 days).
|
|
91
|
+
// Presence of this key means the workspace was already created — no need to re-run start_meta_agent.
|
|
92
|
+
const stateRaw = await redis.get(stateKey);
|
|
93
|
+
if (stateRaw) {
|
|
94
|
+
try {
|
|
95
|
+
const state = JSON.parse(stateRaw);
|
|
96
|
+
if (state.status === "idle" || state.status === "running") {
|
|
97
|
+
console.log(`[router] meta-agent ${namespace} workspace exists (state.status=${state.status})`);
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
catch {
|
|
102
|
+
// Corrupt state — fall through and re-initialize
|
|
77
103
|
}
|
|
78
104
|
}
|
|
79
105
|
// Derive "org/repo" from the full URL for gh CLI calls
|
|
@@ -92,12 +118,26 @@ export async function ensureMetaAgent(namespace, repoUrl, callTool, redis) {
|
|
|
92
118
|
throw new Error(`Failed to create repo ${orgRepo}: ${createErr.message}`);
|
|
93
119
|
}
|
|
94
120
|
}
|
|
95
|
-
// Start the meta-agent via MCP
|
|
121
|
+
// Start the meta-agent via MCP (clones workspace if needed, writes cca:meta:{namespace})
|
|
96
122
|
const result = await callTool("start_meta_agent", { namespace, repo_url: repoUrl });
|
|
97
123
|
if (result === null) {
|
|
98
124
|
throw new Error(`start_meta_agent returned null — tool may not be available in cc-agent`);
|
|
99
125
|
}
|
|
100
|
-
//
|
|
126
|
+
// Check for explicit failure payload (e.g. git clone error)
|
|
127
|
+
try {
|
|
128
|
+
const parsed = JSON.parse(result);
|
|
129
|
+
if (parsed.ok === false) {
|
|
130
|
+
throw new Error(`start_meta_agent failed: ${parsed.error ?? "unknown error"}`);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
catch (jsonErr) {
|
|
134
|
+
if (!(jsonErr instanceof SyntaxError))
|
|
135
|
+
throw jsonErr;
|
|
136
|
+
// Non-JSON result (e.g. plain "ok") — not an error, continue to poll
|
|
137
|
+
}
|
|
138
|
+
// Poll until ready. Check both keys:
|
|
139
|
+
// - statusKey: written by writeLiveStatus() during messageMetaAgent (may not exist yet on cold start)
|
|
140
|
+
// - stateKey: written by startMetaAgent() above — will appear within 1s of the tool call returning
|
|
101
141
|
const deadline = Date.now() + timeoutMs;
|
|
102
142
|
while (Date.now() < deadline) {
|
|
103
143
|
await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
@@ -105,7 +145,7 @@ export async function ensureMetaAgent(namespace, repoUrl, callTool, redis) {
|
|
|
105
145
|
if (raw) {
|
|
106
146
|
try {
|
|
107
147
|
const s = JSON.parse(raw);
|
|
108
|
-
console.log(`[router] waiting for meta-agent ${namespace} —
|
|
148
|
+
console.log(`[router] waiting for meta-agent ${namespace} — status key: ${s.status}`);
|
|
109
149
|
if (s.status === "running" || s.status === "idle")
|
|
110
150
|
return;
|
|
111
151
|
}
|
|
@@ -113,8 +153,21 @@ export async function ensureMetaAgent(namespace, repoUrl, callTool, redis) {
|
|
|
113
153
|
// ignore parse errors, keep polling
|
|
114
154
|
}
|
|
115
155
|
}
|
|
156
|
+
// Also check state key — startMetaAgent writes this synchronously before responding
|
|
157
|
+
const state = await redis.get(stateKey);
|
|
158
|
+
if (state) {
|
|
159
|
+
try {
|
|
160
|
+
const s = JSON.parse(state);
|
|
161
|
+
console.log(`[router] waiting for meta-agent ${namespace} — state key: ${s.status}`);
|
|
162
|
+
if (s.status === "idle" || s.status === "running")
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
catch {
|
|
166
|
+
// ignore parse errors, keep polling
|
|
167
|
+
}
|
|
168
|
+
}
|
|
116
169
|
else {
|
|
117
|
-
console.log(`[router] waiting for meta-agent ${namespace} —
|
|
170
|
+
console.log(`[router] waiting for meta-agent ${namespace} — neither key present yet`);
|
|
118
171
|
}
|
|
119
172
|
}
|
|
120
173
|
throw new Error(`Meta-agent for ${namespace} did not become ready within ${timeoutMs}ms`);
|