MCPcopy Create free account
hub / github.com/QodeXcli/QodeX / runSubagent

Method runSubagent

src/agent/loop.ts:276–364  ·  view source on GitHub ↗

* Run a sub-agent inline. Used by the `task` tool. * * Architecture: sub-agent gets a fresh AgentLoop with the same router/registry/perms * but a new session id and an isolated message history. Tools run in 'subagent' mode * (task and present_plan filtered). We drain the event stream and

(
    prompt: string,
    opts: {
      maxIterations: number;
      signal?: AbortSignal;
      sessionId: string;
      modelOverride?: string;
      /** Role name — drives model selection, system prompt, tool restriction. Default 'subagent'. */
      role?: string;
    },
  )

Source from the content-addressed store, hash-verified

274 this.cwd = path.resolve(cwd);
275 this.effectiveCwd = undefined;
276 if (this.snapshotService) {
277 this.snapshotService = new SnapshotService(this.cwd, 'pending', {
278 retentionTurns: (this.config as any).safety?.snapshotRetentionTurns ?? 50,
279 });
280 }
281 }
282
283 workingDirectory(): string {
284 return this.effectiveCwd ?? this.cwd;
285 }
286
287 /** Update the snapshot service's session id when a real session starts. */
288 private setSessionForSnapshot(sessionId: string): void {
289 if (this.snapshotService) {
290 // Recreate with the proper session id — cleaner than mutating private state.
291 this.snapshotService = new SnapshotService(this.cwd, sessionId, {
292 retentionTurns: (this.config as any).safety?.snapshotRetentionTurns ?? 50,
293 });
294 }
295 }
296
297 /** Public read accessor for slash commands to operate on snapshots. */
298 getSnapshotService(): SnapshotService | undefined {
299 return this.snapshotService;
300 }
301
302 private insightsFor(sessionId: string): SessionInsights {
303 let s = this.insightsBySession.get(sessionId);
304 if (!s) {
305 s = new SessionInsights(sessionId);
306 this.insightsBySession.set(sessionId, s);
307 }
308 return s;
309 }
310
311 /** Live snapshot for `/insights`. */
312 getInsights(sessionId: string): InsightsSnapshot {
313 return this.insightsFor(sessionId).snapshot();
314 }
315
316 resetInsights(sessionId: string): void {
317 this.insightsBySession.get(sessionId)?.reset();
318 }
319
320 persistInsights(sessionId: string): void {
321 const s = this.insightsBySession.get(sessionId);
322 if (!s || s.isEmpty()) return;
323 try { getSessionStore().saveInsights(sessionId, s.snapshot()); } catch { /* never stall the loop */ }
324 }
325
326 /**
327 * Write a lean episode for THIS turn so the next similar task can recall it.
328 * Must be awaited — headless `process.exit` otherwise kills the append.
329 */
330 private async maybeRecordEpisode(opts: {
331 prompt: string;
332 summary: string;
333 filesChanged: string[];

Callers 1

AppFunction · 0.95

Calls 4

buildInitialMessagesMethod · 0.95
runMethod · 0.95
resolveRoleFunction · 0.85
infoMethod · 0.80

Tested by

no test coverage detected