@mindot/will 0.8.0 → 0.10.0

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.
Files changed (142) hide show
  1. package/README.md +15 -11
  2. package/dist/index.d.ts +188 -141
  3. package/dist/index.js +6985 -3337
  4. package/dist/index.js.map +1 -1
  5. package/dist/surface/channels/discord.d.ts +177 -0
  6. package/dist/surface/channels/discord.js +394 -0
  7. package/dist/surface/channels/discord.js.map +1 -0
  8. package/dist/{channels → surface/channels}/whatsapp.d.ts +2 -2
  9. package/dist/{channels → surface/channels}/whatsapp.js +11 -5
  10. package/dist/surface/channels/whatsapp.js.map +1 -0
  11. package/dist/{cli.js → surface/cli.js} +5382 -1573
  12. package/dist/surface/cli.js.map +1 -0
  13. package/dist/{mcp → surface/mcp}/effectors.d.ts +1 -1
  14. package/dist/{mcp → surface/mcp}/effectors.js +10 -4
  15. package/dist/surface/mcp/effectors.js.map +1 -0
  16. package/dist/{will-cS6k4uiJ.d.ts → will-evj9_vrd.d.ts} +6658 -5078
  17. package/package.json +11 -12
  18. package/src/cognition/agency/consequence.ts +356 -1
  19. package/src/cognition/agency/conversation.aim.ts +292 -0
  20. package/src/cognition/agency/engines/action.selector.ts +142 -5
  21. package/src/cognition/agency/engines/affordance.synthesizer.ts +200 -7
  22. package/src/cognition/agency/engines/deliberation.engine.ts +76 -3
  23. package/src/cognition/agency/engines/motor.schema.executor.ts +509 -32
  24. package/src/cognition/agency/engines/reafference.engine.ts +160 -4
  25. package/src/cognition/agency/execution.primitives.ts +17 -4
  26. package/src/cognition/agency/proactive.communicator.ts +19 -3
  27. package/src/cognition/agency/reconcile.learning.ts +5 -4
  28. package/src/cognition/agency/restart.ts +66 -0
  29. package/src/cognition/agency/schemas/innate.ts +96 -1
  30. package/src/cognition/agency/schemas/repertoire.ts +19 -1
  31. package/src/cognition/agency/selection.scoring.ts +49 -0
  32. package/src/cognition/agency/settlement.ts +203 -0
  33. package/src/cognition/agency/types.ts +73 -1
  34. package/src/cognition/cache/composition.ts +232 -0
  35. package/src/cognition/cache/deliberation.cache.ts +219 -0
  36. package/src/cognition/cache/fingerprint.ts +120 -0
  37. package/src/cognition/cache/types.ts +105 -0
  38. package/src/cognition/config.mirror.entities.ts +108 -1
  39. package/src/cognition/event.schemas.ts +22 -8
  40. package/src/cognition/faculties/affective.blender.ts +21 -4
  41. package/src/cognition/faculties/autobiographical.narrator.ts +5 -10
  42. package/src/cognition/faculties/circadian.oscillator.ts +36 -7
  43. package/src/cognition/faculties/episodic.consolidator.ts +59 -3
  44. package/src/cognition/faculties/executive.engine/action.record.ts +129 -0
  45. package/src/cognition/faculties/executive.engine/commands.ts +189 -14
  46. package/src/cognition/faculties/executive.engine/context.ts +106 -46
  47. package/src/cognition/faculties/executive.engine/deliberate.reasoning.ts +1 -1
  48. package/src/cognition/faculties/executive.engine/engine.ts +714 -136
  49. package/src/cognition/faculties/executive.engine/escalation.buffer.ts +230 -45
  50. package/src/cognition/faculties/executive.engine/facet.supervisor.ts +320 -65
  51. package/src/cognition/faculties/executive.engine/facet.ts +81 -26
  52. package/src/cognition/faculties/executive.engine/gating.ts +14 -14
  53. package/src/cognition/faculties/executive.engine/parser.ts +120 -38
  54. package/src/cognition/faculties/executive.engine/prompt.factory.ts +331 -38
  55. package/src/cognition/faculties/executive.engine/types.ts +84 -12
  56. package/src/cognition/faculties/exteroception.ts +99 -98
  57. package/src/cognition/faculties/goal.manager.ts +144 -16
  58. package/src/cognition/faculties/known.entity.tracker.ts +287 -29
  59. package/src/cognition/faculties/moral.evaluator.ts +8 -3
  60. package/src/cognition/faculties/persona.consolidator.ts +141 -0
  61. package/src/cognition/faculties/planning.engine/engine.ts +4 -4
  62. package/src/cognition/faculties/planning.engine/plan.frontier.ts +1 -1
  63. package/src/cognition/faculties/reputation.tracker.ts +66 -2
  64. package/src/cognition/faculties/self.model.updater.ts +19 -12
  65. package/src/cognition/faculties/semantic.engine/integrator.ts +1 -1
  66. package/src/cognition/faculties/social.perception.ts +47 -3
  67. package/src/cognition/faculties/threat.evaluator.ts +7 -0
  68. package/src/cognition/faculties/working.memory.ts +16 -21
  69. package/src/cognition/identity.entity.ts +205 -0
  70. package/src/cognition/index.ts +7 -0
  71. package/src/cognition/instruction.handler.ts +1 -1
  72. package/src/cognition/memory/vector.adapter.ts +12 -3
  73. package/src/cognition/memory/vector.embedder.ts +45 -4
  74. package/src/cognition/percept.entity.ts +122 -0
  75. package/src/cognition/persona.prior.ts +6 -0
  76. package/src/cognition/sense.boundary.ts +176 -0
  77. package/src/cognition/senses/audition.engine/engine.ts +492 -53
  78. package/src/cognition/senses/base.sense.engine.ts +105 -7
  79. package/src/cognition/senses/index.ts +83 -13
  80. package/src/cognition/senses/provenance.ts +128 -0
  81. package/src/cognition/senses/somatosensation.engine.ts +117 -9
  82. package/src/cognition/social.identity.ts +296 -0
  83. package/src/cognition/utilities/token.tracker.ts +94 -10
  84. package/src/core/orchestrator.ts +51 -0
  85. package/src/index.ts +39 -5
  86. package/src/llm/gate.ts +48 -0
  87. package/src/llm/index.ts +127 -33
  88. package/src/llm/routing.ts +6 -0
  89. package/src/llm/summarizer.ts +1 -1
  90. package/src/llm/wire.contracts.ts +57 -0
  91. package/src/pma/index.ts +68 -54
  92. package/src/stem/assembly.audit.ts +1 -0
  93. package/src/stem/guards/identity.coherence.ts +1 -1
  94. package/src/stem/index.ts +171 -23
  95. package/src/stem/mind.ts +198 -57
  96. package/src/stem/policy/arbiter.ts +10 -0
  97. package/src/stem/profiles/built-in.ts +7 -0
  98. package/src/{profiles → stem/profiles}/companion.ts +1 -1
  99. package/src/{profiles → stem/profiles}/company-brain.ts +1 -1
  100. package/src/{profiles → stem/profiles}/customer-service.ts +1 -1
  101. package/src/{profiles → stem/profiles}/game-npc.ts +1 -1
  102. package/src/{profiles → stem/profiles}/index.ts +1 -1
  103. package/src/{profiles → stem/profiles}/smart-home.ts +1 -1
  104. package/src/stem/tracts/effector/escalation.lifecycle.ts +239 -0
  105. package/src/stem/tracts/effector/policy.enforcement.ts +261 -0
  106. package/src/stem/tracts/effector/types.ts +110 -0
  107. package/src/stem/tracts/effector.controller.ts +112 -401
  108. package/src/stem/tracts/outbox.controller.ts +30 -17
  109. package/src/stem/tracts/outbox.writer.ts +40 -2
  110. package/src/stem/tracts/sensory.controller.ts +6 -6
  111. package/src/stem/tracts/session.logger.ts +6 -1
  112. package/src/stem/tracts/transport/types.ts +20 -1
  113. package/src/stem/tracts/transport.controller.ts +33 -9
  114. package/src/surface/channels/discord.ts +609 -0
  115. package/src/{channels → surface/channels}/roster.ts +1 -1
  116. package/src/surface/channels/types.ts +136 -0
  117. package/src/{channels → surface/channels}/whatsapp.ts +22 -10
  118. package/src/{cli.ts → surface/cli.ts} +14 -9
  119. package/src/{host → surface/host}/boot.ts +3 -3
  120. package/src/{host → surface/host}/utterances.ts +2 -2
  121. package/src/{mcp → surface/mcp}/effectors.ts +19 -6
  122. package/src/{mcp → surface/mcp}/server.ts +19 -5
  123. package/src/{sdk → surface/sdk}/will.ts +194 -33
  124. package/src/{serve → surface/serve}/server.ts +11 -4
  125. package/src/types.ts +24 -3
  126. package/dist/channels/discord.d.ts +0 -69
  127. package/dist/channels/discord.js +0 -193
  128. package/dist/channels/discord.js.map +0 -1
  129. package/dist/channels/whatsapp.js.map +0 -1
  130. package/dist/cli.js.map +0 -1
  131. package/dist/mcp/effectors.js.map +0 -1
  132. package/src/channels/discord.ts +0 -214
  133. package/src/channels/types.ts +0 -46
  134. package/src/cognition/faculties/executive.engine/messages.ts +0 -102
  135. package/src/extensions/livestream.ext.ts +0 -570
  136. package/src/extensions/time.ext.ts +0 -339
  137. package/src/profiles/built-in.ts +0 -7
  138. package/src/runners/coherence.runner.ts +0 -49
  139. package/src/runners/outreach.runner.ts +0 -155
  140. package/src/runners/social.runner.ts +0 -179
  141. package/src/runners/thin-shim.runner.ts +0 -205
  142. /package/dist/{cli.d.ts → surface/cli.d.ts} +0 -0
@@ -2,6 +2,8 @@
2
2
  // src/cognition/faculties/executive.engine/context.ts
3
3
  // ─────────────────────────────────────────────────────────────
4
4
 
5
+ import { recentActionRecords } from '#faculties/executive.engine/action.record'
6
+ import { AFFECT_STATE_ID } from '#faculties/affective.blender'
5
7
  import type { ReadonlySimulationState } from '#core/types'
6
8
  import type { GoalManager } from '#faculties/goal.manager'
7
9
  import type { WorkingMemory } from '#faculties/working.memory'
@@ -9,6 +11,13 @@ import type { ExecutiveContext } from '#faculties/executive.engine/types'
9
11
  import type { EpisodicConsolidator } from '#faculties/episodic.consolidator'
10
12
  import type { SemanticIntegrator } from '#faculties/semantic.engine/integrator'
11
13
  import { readEffectiveParams, summarizePersonaPrior } from '#cognition/persona.prior'
14
+ import { readIdentityName } from '#cognition/identity.entity'
15
+ import { readSpokenTurns } from '#agency/conversation.aim'
16
+ import { nameOf as referentName } from '#cognition/social.identity'
17
+
18
+ /** How many of the mind's own recent utterances it is shown. Enough to notice a
19
+ * repetition, few enough not to crowd out what is happening now. */
20
+ const SPOKEN_TURNS_SHOWN = 6
12
21
 
13
22
  export interface ContextDependencies {
14
23
  workingMemory: WorkingMemory | null
@@ -32,8 +41,10 @@ export async function buildExecutiveContext(
32
41
  // Identity — read directly from the identity-self entity.
33
42
  const identityEntity = state.entities.get('identity-self')
34
43
  // name is the canonical persona name from WillConfig.name (e.g. "Aria", "Guard-1").
35
- // Falls back to 'Will' for snapshots created before this field was added.
36
- const identityName = (identityEntity?.metadata?.name as string) ?? 'Will'
44
+ // '' when unknown NEVER a default. This read used to end in `?? 'Will'`, which
45
+ // is how the container's name reached a tenant's own prompt. See
46
+ // cognition/identity.entity for what that cost.
47
+ const identityName = readIdentityName( state )
37
48
  const identityPrompt = (identityEntity?.metadata?.prompt as string) ?? 'I am a self-aware mind.'
38
49
  const identityValues = (identityEntity?.metadata?.values as string[]) ?? []
39
50
  const identityTraits = (identityEntity?.metadata?.traits as Record<string, number>) ?? {}
@@ -44,7 +55,7 @@ export async function buildExecutiveContext(
44
55
 
45
56
  // Working memory — getItems() returns WMItem[] sorted by activation descending.
46
57
  // Filter types that are already rendered elsewhere in the prompt:
47
- // conversation.exchange → shown in Recent Action Outcomes
58
+ // conversation.exchange → shown in What Became Of What I Did
48
59
  // goal → shown in Active Goals
49
60
  const WM_FILTER_TYPES = new Set([ 'conversation.exchange', 'goal' ])
50
61
  const wmItems = ( deps.workingMemory?.getItems() ?? [] )
@@ -52,7 +63,12 @@ export async function buildExecutiveContext(
52
63
  const workingMemory = wmItems.map( item => ({
53
64
  type: item.type,
54
65
  summary: extractSummary( item.content ),
55
- activation: item.activation
66
+ activation: item.activation,
67
+ // Storing the evidence in memory and then rendering only the label would
68
+ // lose it just as completely, one step later. A percept entity is swept
69
+ // after 2 ticks and the executive fires on its own schedule, so memory is
70
+ // often where the mind meets an observation at all.
71
+ ...( itemData( item.content ) !== undefined ? { data: itemData( item.content ) } : {} ),
56
72
  }))
57
73
 
58
74
  // Episodic memory — semantic query for relevant memories based on current goals
@@ -247,33 +263,46 @@ export async function buildExecutiveContext(
247
263
  impulsivity: execParams.impulsivity ?? 0.3,
248
264
  } : undefined
249
265
 
250
- // Recent action outcomesscan decision.record entities that have been processed
251
- // (actionStatus is set) and return the last 5 most recent, newest first.
252
- // This closes the Act → Confirm → Perceive loop: the executive can see what it
253
- // tried, whether it landed, and whether an external dispatch went unanswered.
254
- const recentActions: Array<{
255
- type: string; status: 'completed' | 'failed' | 'awaiting_host' | 'timed_out'
256
- tick: number; outcome: string; planId?: string
257
- }> = []
258
-
259
- for( const entity of state.entities.values() ){
260
- if( entity.type !== 'decision.record') continue
261
- const actionStatus = entity.metadata?.actionStatus as string | undefined
262
- if( !actionStatus ) continue
263
- if( !( [ 'completed', 'failed', 'awaiting_host', 'timed_out' ] as string[] ).includes( actionStatus ) ) continue
264
-
265
- recentActions.push({
266
- type: ( entity.metadata?.actionType as string ) ?? 'unknown',
267
- status: actionStatus as 'completed' | 'failed' | 'awaiting_host' | 'timed_out',
268
- tick: ( entity.metadata?.executionTick as number ) ?? ( entity.metadata?.dispatchedAt as number ) ?? 0,
269
- outcome: String( entity.metadata?.outcome ?? '').slice( 0, 120 ),
270
- planId: entity.metadata?.planId as string | undefined,
271
- })
266
+ // What became of what I did this is what closes the Act → Confirm → Perceive
267
+ // loop the prompt's `## What Became Of What I Did` section was written for.
268
+ //
269
+ // It used to scan `decision.record` for an `actionStatus`, a field READ here
270
+ // and written nowhere in the engine. The section therefore rendered zero times
271
+ // across every prompt a live COO ever received, while `## What I've Said
272
+ // Lately` rendered in all of them — the mind could see what it had said and
273
+ // never what it had done. See `action.record.ts` for what that cost.
274
+ const recentActionsCapped = recentActionRecords( state.entities as never )
275
+
276
+ // Current best name for a person, from the known-entity roster.
277
+ const nameOf = ( keid: string ): string | undefined => {
278
+ for( const e of state.entities.values() ){
279
+ if( e.type !== 'known-entity') continue
280
+ const m = e.metadata ?? {}
281
+ if( m['keid'] !== keid ) continue
282
+ const n = m['name']
283
+ return typeof n === 'string' && n.trim() ? n : undefined
284
+ }
285
+ return undefined
272
286
  }
273
287
 
274
- // Sort newest-first, cap at 5
275
- recentActions.sort( ( a, b ) => b.tick - a.tick )
276
- const recentActionsCapped = recentActions.slice( 0, 5 )
288
+ // What the mind has said to people lately, and who answered. Newest first,
289
+ // capped — this is a reminder, not a transcript; the conversation itself lives
290
+ // in memory and in "## In Conversation Now".
291
+ const spokenTurns: ExecutiveContext['spokenTurns'] = readSpokenTurns( state.entities )
292
+ .filter( t => !t.isAck )
293
+ .reverse()
294
+ .slice( 0, SPOKEN_TURNS_SHOWN )
295
+ .map( t => ({
296
+ // Roster first, the record's stored name second. A name is learned over
297
+ // time, so records written before the mind knew it keep the raw id — and
298
+ // the same person rendered as both `FKEM` and `discord:15255…` in one list,
299
+ // which reads as two people. The roster holds the current best name.
300
+ target: nameOf( t.targetEntityId ) ?? t.targetEntityName ?? t.targetEntityId,
301
+ preview: t.preview,
302
+ age: Math.max( 0, state.tick - t.tick ),
303
+ answered: t.answeredAt !== undefined,
304
+ ...( t.answeredWith ? { answeredWith: t.answeredWith } : {} ),
305
+ }) )
277
306
 
278
307
  // Active/known plans — read persisted `plan` entities so the executive has
279
308
  // execution awareness: which plans exist per goal, their status + step
@@ -313,7 +342,11 @@ export async function buildExecutiveContext(
313
342
  sleepPressure: state.metrics.get('sleep.pressure') ?? 0,
314
343
  stressLoad: state.metrics.get('stress.load') ?? 0,
315
344
  circadianPhase: state.metrics.get('circadian.phase') ?? 0,
316
- timeOfDay: state.metrics.get('time.of_day') ?? 12,
345
+ // `circadian.time_of_day`, not `time.of_day`. The oscillator has always
346
+ // written the first and this has always read the second, so the fallback
347
+ // fired on EVERY tick a Will has ever run: the prompt said `Time: 12.0h`
348
+ // — noon, permanently — beside a phase label that disagreed with it.
349
+ timeOfDay: state.metrics.get('circadian.time_of_day') ?? 12,
317
350
  // Tonic threat representation — survives event habituation (guardrail).
318
351
  threatLevel: state.metrics.get('threat.level') ?? 0
319
352
  },
@@ -328,6 +361,7 @@ export async function buildExecutiveContext(
328
361
  beliefs,
329
362
  beliefsOmitted,
330
363
  recentActions: recentActionsCapped,
364
+ spokenTurns,
331
365
  behavioralDisposition,
332
366
  selfTuning,
333
367
  knownEntities: extractKnownEntities( state ),
@@ -436,6 +470,25 @@ export function extractKnownEntities( state: ReadonlySimulationState ): Executiv
436
470
  if( typeof m.name === 'string') a.name = m.name
437
471
  if( m.kind === 'thing' || m.kind === 'sentient') a.kind = m.kind as 'thing' | 'sentient'
438
472
  if( typeof m.reliability === 'number') a.reliability = m.reliability as number
473
+
474
+ // The routes, so choosing where to say something is a decision the mind
475
+ // makes rather than a fallback the plumbing makes for it.
476
+ if( Array.isArray( m.handles ) )
477
+ a.handles = ( m.handles as Array<{ keid?: string; kind?: string; lastAnsweredTick?: number }> )
478
+ .filter( h => typeof h?.keid === 'string')
479
+ .map( h => ({
480
+ keid: h.keid!,
481
+ kind: h.kind ?? 'unknown',
482
+ ...( typeof h.lastAnsweredTick === 'number'
483
+ ? { answeredAgo: Math.max( 0, state.tick - h.lastAnsweredTick ) } : {} ),
484
+ }) )
485
+
486
+ // An identity the mind has not settled. Carried as NAMES where it knows
487
+ // them, because a raw keid in a prompt is noise it cannot act on.
488
+ if( Array.isArray( m.suspectedSameAs ) )
489
+ a.mayBeSameAs = ( m.suspectedSameAs as string[] )
490
+ .map( k => referentName( state.entities, k ) )
491
+ .filter( ( n ): n is string => !!n )
439
492
  a._recency = Math.max( a._recency, ( m.lastSeenTick as number ) ?? 0 )
440
493
  }
441
494
  else if( e.type === 'attachment.bond'){
@@ -473,17 +526,11 @@ function buildSemanticQuery(
473
526
  const dominantEmotion = valence > 0.3 ? 'positive' : valence < -0.3 ? 'negative' : 'neutral'
474
527
  if( dominantEmotion !== 'neutral') parts.push(`Feeling ${dominantEmotion}`)
475
528
 
476
- // Active conversation entities pulls memories about current interlocutors
477
- const senderNames = new Set<string>()
478
- for( const entity of state.entities.values() ){
479
- if( entity.type !== 'communication') continue
480
- const msgTick = ( entity.metadata?.tick as number ) ?? 0
481
- if( state.tick - msgTick > 30 ) continue
482
- if( entity.metadata?.processedByExecutive ) continue
483
- const name = entity.metadata?.agentName as string | undefined
484
- if( name && name !== 'unknown') senderNames.add( name )
485
- }
486
- if( senderNames.size > 0 ) parts.push(`Talking with: ${[ ...senderNames ].join(', ')}`)
529
+ // A "Talking with: …" hint used to be built here from `communication` entities.
530
+ // Nothing has ever written that type (#114), so the clause never fired. Removed
531
+ // rather than repointed: the inbound entity that now exists (`conversation.received`)
532
+ // is consumed within one tick, so it is not a dependable source for a recall hint —
533
+ // restoring this wants a durable interlocutor signal, which is its own decision.
487
534
 
488
535
  // Recent percepts (top 3 by salience)
489
536
  const percepts = extractPercepts( state ).slice( 0, 3 )
@@ -569,6 +616,13 @@ function mapEpisodeToMemory( ep: {
569
616
  }
570
617
  }
571
618
 
619
+ /** A working-memory item's host payload, when it carries one. */
620
+ function itemData( content: unknown ): unknown {
621
+ if( content && typeof content === 'object')
622
+ return ( content as Record<string, unknown> )['data']
623
+ return undefined
624
+ }
625
+
572
626
  function extractSummary( content: unknown ): string {
573
627
  if( typeof content === 'string')
574
628
  return content.slice( 0, 120 )
@@ -584,8 +638,8 @@ function extractSummary( content: unknown ): string {
584
638
  return String( content ?? '').slice( 0, 120 )
585
639
  }
586
640
 
587
- function extractPercepts( state: ReadonlySimulationState ): Array<{ category: string; summary: string; salience: number }> {
588
- const percepts: Array<{ category: string; summary: string; salience: number }> = []
641
+ function extractPercepts( state: ReadonlySimulationState ): Array<{ category: string; summary: string; salience: number; data?: unknown }> {
642
+ const percepts: Array<{ category: string; summary: string; salience: number; data?: unknown }> = []
589
643
 
590
644
  for( const entity of state.entities.values() ){
591
645
  if( entity.type !== 'percept' && entity.type !== 'percept.social') continue
@@ -598,6 +652,10 @@ function extractPercepts( state: ReadonlySimulationState ): Array<{ category: st
598
652
  percepts.push({
599
653
  category: (entity.metadata?.category as string) ?? 'general',
600
654
  summary,
655
+ // What the host actually sent, beside the label the engine wrote. A mind
656
+ // reasoning only from labels is reasoning from somebody else's summary of
657
+ // the evidence.
658
+ ...( entity.metadata?.data !== undefined ? { data: entity.metadata.data } : {} ),
601
659
  salience: (entity.metadata?.salience as number) ?? 0
602
660
  })
603
661
  }
@@ -618,12 +676,14 @@ function extractAffect( state: ReadonlySimulationState ): ExecutiveContext['affe
618
676
  const arousal = state.metrics.get('affect.arousal') ?? 0.5
619
677
  const dominance = state.metrics.get('affect.dominance') ?? 0.5
620
678
 
621
- // Non-numeric affect data — read from the affective-state entity.
622
- // AffectiveBlender writes this entity each tick with dominantEmotion and blends.
679
+ // Non-numeric affect data — read from the entity AffectiveBlender writes each
680
+ // tick. The id comes from the writer rather than being spelled again here: this
681
+ // read used to look for 'affective-state', which nothing has ever written, so
682
+ // both values silently took their fallbacks in every prompt ever rendered.
623
683
  let dominantEmotion = 'neutral'
624
684
  let blends: string[] = []
625
685
 
626
- const affectEntity = state.entities.get('affective-state')
686
+ const affectEntity = state.entities.get( AFFECT_STATE_ID )
627
687
  if( affectEntity ){
628
688
  dominantEmotion = (affectEntity.metadata?.dominantEmotion as string) ?? 'neutral'
629
689
  blends = (affectEntity.metadata?.blends as string[]) ?? []
@@ -49,7 +49,7 @@ export async function proposeCandidates( params: ProposeParams ): Promise<Ideati
49
49
  try {
50
50
  const result = await params.director.call(
51
51
  params.systemPrompt, params.ideationUserMessage, params.tick, params.proposeTemperature,
52
- params.meta ?? { category: 'executive', attribute: 'master', function: 'ideation' }
52
+ params.meta ?? { category: 'executive', attribute: 'master', process: 'ideation', function: '-' }
53
53
  )
54
54
  const candidates = parseIdeation( result.text ).candidates
55
55
  return candidates.length > 0 ? candidates : undefined