@goodandready/dsh-moa 0.2.7 → 0.2.9

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.
@@ -92,7 +92,7 @@ function sanitizePath(filePath) {
92
92
  export async function collectProjectContext(baseDir, maxCharBudget = 16000) {
93
93
  if (!baseDir) return { files: [], totalChars: 0 }
94
94
 
95
- const ignoreDirs = new Set(['node_modules', '.git', '.moa', '.worktrees', 'dist', 'build', '.dsh'])
95
+ const ignoreDirs = new Set(['node_modules', '.git', '.moa', '.worktrees', 'dist', 'build', '.dsh', '.next', '.nuxt', '.cache', 'coverage', '.turbo', '.idea', '.vscode'])
96
96
  const codeExts = new Set([
97
97
  '.html', '.htm', '.css', '.js', '.mjs', '.cjs', '.jsx', '.ts', '.tsx',
98
98
  '.vue', '.svelte', '.json', '.py', '.md', '.txt', '.sh', '.yaml', '.yml',
package/lib/index.js CHANGED
@@ -44,6 +44,7 @@ export const ModelSlotSchema = z.object({
44
44
  export const PresetSchema = z.object({
45
45
  name: z.string(),
46
46
  enabled: z.boolean().default(true),
47
+ ask_clarifying_questions: z.boolean().default(true),
47
48
  reference_models: z.array(ModelSlotSchema).default([]),
48
49
  aggregator: ModelSlotSchema.default({ provider: 'codex', model: 'gpt-5.6-sol' }),
49
50
  reference_temperature: z.number().default(0.6),
@@ -61,6 +62,7 @@ export const Config = z.object({
61
62
  {
62
63
  name: 'default',
63
64
  enabled: true,
65
+ ask_clarifying_questions: true,
64
66
  reference_models: [
65
67
  { provider: 'opencode-go', model: 'deepseek-v4-flash' },
66
68
  { provider: 'grok', model: 'grok-build-0.1' },
@@ -75,6 +77,7 @@ export const Config = z.object({
75
77
  {
76
78
  name: 'fast',
77
79
  enabled: true,
80
+ ask_clarifying_questions: false,
78
81
  reference_models: [
79
82
  { provider: 'opencode-go', model: 'deepseek-v4-flash' },
80
83
  ],
@@ -88,6 +91,7 @@ export const Config = z.object({
88
91
  {
89
92
  name: 'deep-reasoning',
90
93
  enabled: true,
94
+ ask_clarifying_questions: true,
91
95
  reference_models: [
92
96
  { provider: 'grok', model: 'grok-build-0.1' },
93
97
  { provider: 'commandcode', model: 'deepseek/deepseek-v4-flash' },
@@ -449,11 +453,39 @@ export function apply(ctx, config) {
449
453
  },
450
454
  })
451
455
  }, 'dsh-moa: run pipeline route')
452
-
453
456
  // Session turn interceptor: route turn to real aggregator model & stream MoA synthesis
454
457
  const moaPendingTurns = new WeakMap()
455
458
  const moaSessionTurns = new Map()
456
459
 
460
+ function setSessionTurn(sessionId, turnContext) {
461
+ if (!sessionId) return
462
+ const existing = moaSessionTurns.get(sessionId)
463
+ if (existing?.ttlTimer) clearTimeout(existing.ttlTimer)
464
+
465
+ // TTL (3 minutes) to prevent memory leaks if turn is aborted or skipped before llm/stream
466
+ const ttlTimer = setTimeout(() => {
467
+ moaSessionTurns.delete(sessionId)
468
+ }, 180000)
469
+ ttlTimer.unref?.()
470
+
471
+ moaSessionTurns.set(sessionId, { ...turnContext, ttlTimer })
472
+ }
473
+
474
+ function getSessionTurn(sessionId) {
475
+ if (!sessionId) return null
476
+ return moaSessionTurns.get(sessionId) || null
477
+ }
478
+
479
+ function consumeSessionTurn(sessionId) {
480
+ if (!sessionId) return null
481
+ const entry = moaSessionTurns.get(sessionId)
482
+ if (entry) {
483
+ if (entry.ttlTimer) clearTimeout(entry.ttlTimer)
484
+ moaSessionTurns.delete(sessionId)
485
+ }
486
+ return entry
487
+ }
488
+
457
489
  ctx.on('agent/pre-step', async (event, next) => {
458
490
  const messages = event.messages || []
459
491
  const lastUserMsg = [...messages].reverse().find((m) => m && m.role === 'user')
@@ -485,7 +517,7 @@ export function apply(ctx, config) {
485
517
  moaPendingTurns.set(event.signal, turnContext)
486
518
  }
487
519
  if (event.session?.id) {
488
- moaSessionTurns.set(event.session.id, turnContext)
520
+ setSessionTurn(event.session.id, turnContext)
489
521
  }
490
522
  }
491
523
  }
@@ -496,7 +528,7 @@ export function apply(ctx, config) {
496
528
  ctx.on('agent/request', async (payload, next) => {
497
529
  const resolved = await next()
498
530
  const turnContext = (payload.signal ? moaPendingTurns.get(payload.signal) : null)
499
- || (payload.session?.id ? moaSessionTurns.get(payload.session.id) : null)
531
+ || (payload.session?.id ? getSessionTurn(payload.session.id) : null)
500
532
 
501
533
  if (turnContext) {
502
534
  return {
@@ -511,11 +543,11 @@ export function apply(ctx, config) {
511
543
  ctx.effect(() => {
512
544
  return ctx.on('llm/stream', (options, next) => {
513
545
  const turnContext = (options.signal ? moaPendingTurns.get(options.signal) : null)
514
- || (options.session?.id ? moaSessionTurns.get(options.session.id) : null)
546
+ || (options.session?.id ? consumeSessionTurn(options.session.id) : null)
515
547
 
516
548
  if (turnContext) {
517
549
  if (options.signal) moaPendingTurns.delete(options.signal)
518
- if (options.session?.id) moaSessionTurns.delete(options.session.id)
550
+ if (options.session?.id) consumeSessionTurn(options.session.id)
519
551
 
520
552
  return streamMoATurn(turnContext, options)
521
553
  }