@runuai/host 0.2.0 → 0.2.2
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/lib/github-tokens.ts +9 -0
- package/lib/orchestrator.ts +20 -1
- package/package.json +1 -1
- package/src/protocol.ts +9 -0
package/lib/github-tokens.ts
CHANGED
|
@@ -278,6 +278,11 @@ export interface SetupTaskDeps {
|
|
|
278
278
|
* a failure emits the auth-expired note but never aborts task-up. Returns true
|
|
279
279
|
* iff a token was injected.
|
|
280
280
|
*/
|
|
281
|
+
/** Tasks whose gh setup is currently in flight. task-up and the first
|
|
282
|
+
* channel-ensure both kick this off and can overlap; a second concurrent
|
|
283
|
+
* `gh auth login` would race the container's gh config, so we dedupe. */
|
|
284
|
+
const setupInFlight = new Set<string>();
|
|
285
|
+
|
|
281
286
|
export async function setupTaskGithub(
|
|
282
287
|
taskId: string,
|
|
283
288
|
userId: string,
|
|
@@ -288,6 +293,8 @@ export async function setupTaskGithub(
|
|
|
288
293
|
const _inject =
|
|
289
294
|
deps.inject ?? ((t: string, tok: string) => injectIntoContainer(t, tok));
|
|
290
295
|
const _schedule = deps.schedule ?? scheduleRefresh;
|
|
296
|
+
if (setupInFlight.has(taskId)) return false;
|
|
297
|
+
setupInFlight.add(taskId);
|
|
291
298
|
try {
|
|
292
299
|
if (_hasToken(userId)) {
|
|
293
300
|
const tok = await _request(userId);
|
|
@@ -311,6 +318,8 @@ export async function setupTaskGithub(
|
|
|
311
318
|
console.warn(`[github] task ${taskId}: gh setup failed: ${reason}`);
|
|
312
319
|
authExpiredHandler?.(taskId, userId, reason);
|
|
313
320
|
return false;
|
|
321
|
+
} finally {
|
|
322
|
+
setupInFlight.delete(taskId);
|
|
314
323
|
}
|
|
315
324
|
}
|
|
316
325
|
|
package/lib/orchestrator.ts
CHANGED
|
@@ -181,6 +181,16 @@ class Orchestrator {
|
|
|
181
181
|
// container), using the creator's per-user key. Best-effort.
|
|
182
182
|
setupTaskGitIdentity(channel.taskId, task.ownerName, task.ownerEmail);
|
|
183
183
|
|
|
184
|
+
// GitHub auth for `gh` (ADR-027): mint + inject the access token and
|
|
185
|
+
// (re)start its refresh schedule. Done here — not only at task-up — so it
|
|
186
|
+
// survives a host restart: recovery recreates the channel and re-runs
|
|
187
|
+
// ensureSessions, whereas the in-memory refresh timer from the original
|
|
188
|
+
// task-up is gone. Guarded + best-effort + non-blocking; the token lands
|
|
189
|
+
// before the agents (spawned just below) make their first `gh` call.
|
|
190
|
+
if (task.ownerUserId) {
|
|
191
|
+
void setupTaskGithub(channel.taskId, task.ownerUserId);
|
|
192
|
+
}
|
|
193
|
+
|
|
184
194
|
for (const agent of channel.roster) {
|
|
185
195
|
const session = await this.factory.create({
|
|
186
196
|
taskId: channel.taskId,
|
|
@@ -365,7 +375,16 @@ class Orchestrator {
|
|
|
365
375
|
});
|
|
366
376
|
break;
|
|
367
377
|
}
|
|
368
|
-
case "turn_complete":
|
|
378
|
+
case "turn_complete": {
|
|
379
|
+
// Turn boundary — the cloud flushes any @-mentions buffered across this
|
|
380
|
+
// turn's messages and wakes the mentioned peers with the full turn.
|
|
381
|
+
this.emitHost({
|
|
382
|
+
kind: "agent.turn_complete",
|
|
383
|
+
taskId: channel.taskId,
|
|
384
|
+
agentId,
|
|
385
|
+
});
|
|
386
|
+
break;
|
|
387
|
+
}
|
|
369
388
|
case "exit":
|
|
370
389
|
break;
|
|
371
390
|
}
|
package/package.json
CHANGED
package/src/protocol.ts
CHANGED
|
@@ -399,6 +399,15 @@ export type HostEvent =
|
|
|
399
399
|
fullText: string;
|
|
400
400
|
mentions: string[];
|
|
401
401
|
}
|
|
402
|
+
// The agent finished a turn (it may have emitted several message_complete
|
|
403
|
+
// items within it). The cloud waits for this before waking @-mentioned peers,
|
|
404
|
+
// so a peer is handed the agent's COMPLETE turn rather than a mid-turn
|
|
405
|
+
// fragment that happened to contain the mention.
|
|
406
|
+
| {
|
|
407
|
+
kind: "agent.turn_complete";
|
|
408
|
+
taskId: string;
|
|
409
|
+
agentId: string;
|
|
410
|
+
}
|
|
402
411
|
| {
|
|
403
412
|
kind: "agent.tool_call";
|
|
404
413
|
taskId: string;
|