Skip to content

Add PersonaNode for OCEAN personality trait configuration - #17

Merged
jay-m-dev merged 5 commits into
EpistasisLab:mainfrom
aysmayyy:persona
Oct 21, 2026
Merged

jay-m-dev merged 5 commits into
EpistasisLab:mainfrom
aysmayyy:persona

Conversation

@aysmayyy

@aysmayyy aysmayyy commented Oct 6, 2026 •

Copy link
Copy Markdown
Contributor

Adds a PersonaNode for experimental manipulation of agent personality traits using the OCEAN framework.

Rebuilt on top of current main (bb61d45, includes #18-#20). The diff is additive; no existing exports, dialogs, or factor workflows are removed.

What's included

  1. PersonaNode: a connector node (like Skill) wired into a new Persona slot on Agent. Persona text is prepended to the agent's system prompt at runtime via _resolve_persona_configs in protocol_execution.py.

  2. Persona library with 15 entries: Baseline, 4 composite personas (Analyst, Explorer, Critic, Pushover) and 10 OCEAN poles (high/low Openness, Conscientiousness, Extraversion, Agreeableness, Neuroticism). Single source of truth in personaLibrary.ts. Baseline has an empty prompt so control cells get an unmodified system prompt.

  3. Three configuration modes in the node inspector: pick from library (multi-select, up to 5 personas combined per node), direct text, or .md file upload.

  4. Factor support: a Persona node can be turned into an experimental factor from its hover toolbar. Levels use the same library/text/file UI, each level can combine up to 5 personas, and level labels show the persona names (i.e. "High Neuroticism + Low Agreeableness") instead of level1/level2. The factor binds the node's whole config, consistent with model_config and dataset_config, so the baseline invariant holds and cells apply a plain persona_text string.

  5. Backend connector registration: persona is in _CONNECTOR_HANDLES, _NODE_TYPE_TO_HANDLE, _HANDLE_LABELS and the agent-only connector guard, so a persona edge is treated as configuration, not a pipeline input. The connector is deliberately uncapped, matching Skill: multiple personas concatenate in wiring order.

Changes since the last review

  • Frontend compiles; tsc, oxlint and vitest match main.
  • Persona factor levels resolve to their persona text before prompt composition, and the Baseline level no longer injects metadata text.
  • Persona connector is registered on both frontend and backend with 7 new backend tests covering uncapped wiring, edge classification, validation errors, disabled/empty skipping, and factor level application.
  • Fixed factor level persistence (level 1 was being overwritten by baseline reconciliation).
  • Removed the duplicated persona library and the type casts in metricFields.ts and mcpToolMetrics.ts.

@aysmayyy
aysmayyy force-pushed the persona branch 2 times, most recently from 8c986c5 to 43e7886 Compare October 14, 2026 00:49
@jay-m-dev
jay-m-dev self-requested a review October 20, 2026 18:26

@jay-m-dev jay-m-dev left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Found four issues that should be addressed before merging:

  1. Frontend compilation fails. The PR removes existing exports, props, and types while callers still depend on them, including LlmConfigLevelRow, ProtocolCanvasHandle.openConnectorFactor, NodeRunState.bypassed, and DatasetRowSchema.ready. The frontend CI check confirms these failures.
  2. Existing factor workflows regress. ProtocolCanvas.tsx removes connector-factor dialogs, actions, and test selectors unrelated to adding personas. Please preserve these existing workflows.
  3. Persona factors produce incorrect system prompts. Persona factor levels store structured objects, but _resolve_persona_config() returns those objects directly and _run_agent_node() interpolates them into the prompt. This also affects the included experiment: “None” produces metadata text instead of an empty persona, contaminating the baseline. Please resolve each level to its actual persona text before composing the prompt.
  4. Persona connector integration is incomplete. Both backend and frontend connector registries omit persona, so persona configuration edges are treated as main-pipeline inputs. The documented single-persona limit is also unenforced. Please register the connector consistently and enforce its cardinality in both frontend and backend validation.

- Add PersonaNode component with persona connector to agents
- Implement 15 OCEAN personality traits (baseline + 4 presets + 10 dimensions)
- Add PersonaLevelRow to FactorEditorDialog for persona_text factors
- Backend: persona texts prepend to agent system prompts via _resolve_persona_configs()
- Frontend: extract persona_label for proper cell labeling in results
- Add persona connector handle to AgentNode (top position)
- Store all 15 persona markdown files in personas/ directory
- Fix label extraction in factorLevels.ts and FactorEditorDialog makeDraft()
- Add PersonaNodeConfig type and persona connection validation
- Add state management for multiple persona selection
- Restore 'Add another' button with max 5 personas
- Join all selected persona labels with ' + ' separator
- Combine all selected persona prompts into single text
- Clicking toolbar icon now opens factor editor directly
- Added personaFactorNodeId state and dialog in ProtocolCanvas
- PersonaNode uses requestPersonaFactor instead of generic requestMakeFactor
- Added useEffect to sync persona selections when editing
- Fixes field picker UX and partial fix for selection persistence
Persona levels are config-shaped objects, but the factor was bound to
config.persona_text (a string). reconcileFactorBaselines enforces
level[0] == bound canvas value, so it overwrote level 1 with the node's
string after every edit; apply_factor_bindings would likewise have written
the level object into persona_text at runtime. Bind config instead, like
model_config/dataset_config, seed a real factor name and baseline level
from the node, and mirror level 1 back into the node on save.
…dedupe library

Addresses the remaining items from the PR EpistasisLab#17 review:

- Register "persona" in _CONNECTOR_HANDLES, _NODE_TYPE_TO_HANDLE,
  _HANDLE_LABELS and the agent-only connector guard. Without it a persona
  edge was classified as a main-pipeline edge, so the Persona node showed
  up as an upstream input of its agent. Persona is uncapped like Skill:
  several wired personas concatenate into one system-prompt prefix in
  wiring order. Covered by 7 new tests mirroring the Skill ones.
- Baseline persona now has an empty prompt. The executor skips empty
  persona_text, so a "Baseline" cell gets a clean, unmodified system
  prompt instead of metadata text contaminating the control condition.
- Move the persona library into personaLibrary.ts; the inspector and the
  factor level editor each had their own identical 15-entry copy.
- Declare persona_ids on PersonaNodeConfig and drop its index signature,
  which lets metricFields.ts/mcpToolMetrics.ts go back to main's cast-free
  versions.
@jay-m-dev
jay-m-dev merged commit 82a84bf into EpistasisLab:main Oct 21, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants