Skip to main content

Prompt Assembly

Not one giant string. Every system prompt is assembled in discrete layers — each with a clear source, defined scope, and explicit separation of concerns.

Layer architecture

Lower layers are always present. Upper layers are selected at runtime by the OpenAI text runtime.

Always present in every prompt

5
Contextruntime

Recent conversation history, current user message, and any active crisis signals injected from runtime state.

state.historystate.historyruntime stateRecent conversation turnsThe last N turns of the conversation, injected as a message history block. Length is bounded to stay within context limits.state.messagestate.messageruntime stateCurrent user messageThe user's most recent message — appended as the final human turn so the model responds to exactly what was just said.state.crisisstate.crisisruntime stateActive crisis assessmentWhen a risk signal is present: the crisis level (0–3), confidence score, reason string, and pattern flags. Injected into context so the model can reference why crisis mode is active.
4
Tasktask-specific

The exact instruction for this runtime task — what to write, what format to use, what constraints apply. Includes response_guidance for turn-specific shaping.

builders.pyspecialists/therapeutic_prompts.pypythonTask prompt builderGenerates task instructions in code — the final prompt section that tells the model exactly what to produce for this runtime branch (reply, classification, orientation question, etc.).support_tasksupport_reply_task (builders.py)pythonTask instruction for support repliesTells the model to write the next conversational message: keep it short, stay warm, end with an open question if it feels natural. No unsolicited advice.crisis_taskcrisis_reply_task (builders.py)pythonTask instruction for crisis repliesTells the model to write a grounded, caring response that surfaces crisis resources clearly and keeps the door open for the user to continue.
3
Approachoptional overlay

A therapeutic lens selected by the TherapeuticAgent as therapeutic_approach: MI, CBT, ACT, DBT skills, grief support, IPT, or PFA.

pfa.mdtherapeutic_approaches/pfa.md + dbt_skills.mdmarkdownPsychological First Aid (+ DBT skills)Baseline for acute distress: calm presence, practical immediate next steps, emotional stabilisation. DBT skills bundled in. Avoids turning support into diagnosis or intensive therapy when someone is in crisis.cbt.mdtherapeutic_approaches/cbt.mdmarkdownCBT self-help overlayStructured self-help for thought-checking, pattern identification, behaviour activation, and problem-solving. Avoids clinical phrasing and does not force reframes before the user is ready.grief_support.mdtherapeutic_approaches/grief_support.mdmarkdownGrief support overlayMakes room for grief without rushing it. Validates mixed emotions, avoids silver linings, treats grief as non-pathological. Does not push the user toward resolution on any timeline.act.mdtherapeutic_approaches/act.mdmarkdownACT defusion and values overlayAcceptance and Commitment Therapy techniques: cognitive defusion, values clarification, willingness over control. Helps users relate differently to difficult thoughts rather than trying to eliminate them.
2
Responseruntime-selected

The response style selected by the runtime and specialist agent. Shapes the goal and tone of the turn — supportive, reflective, clarifying, psychoeducation, technique, guided_exercise, closing, safety_check, or crisis_response.

response_styles/support.mdresponse_styles/support.mdmarkdownDefault supportive response styleActive when no crisis or safety check is needed. Validates before suggesting, reflects the user's emotional state, offers one helpful next step. Replies stay concise and grounded.crisis_response.mdresponse_styles/crisis_response.mdmarkdownCrisis response styleActivates when a risk signal is confirmed. Prioritises immediate safety, avoids clinical distance, encourages offline human support and emergency services where appropriate.sources.pyspecialists/therapeutic_prompt_sources.pypythonPrompt source selectorPython code that chooses response-style knowledge and therapeutic-approach overlays before builders assemble the final system prompt.
1
Corealways present

The permanent foundation: who OpenCouch is, what it will and won't do, and the hard safety and privacy boundaries that no response style can override.

core_identity.mdcore_identity.mdmarkdownAssistant role, voice, and scopeDefines OpenCouch as a calm, direct, humane mental health support assistant: what it does, what it is not, how it sounds, and the non-negotiable stance that no response style or therapeutic approach can override.policy/boundaries.mdpolicy/boundaries.mdmarkdownHard behavioural constraintsMust not diagnose, claim therapeutic authority, give medication or legal advice, express false certainty about a user's internal state, or encourage dependency. Limits are stated clearly and alternatives surfaced.policy/privacy.mdpolicy/privacy.mdmarkdownData minimisation rulesUsers share sensitive mental health information. Only necessary context is injected into prompts. Memory is minimal and reviewable. Principle of least necessary context applies at every step.
Core — immutable
Response — runtime-selected
Approach — optional
Task — runtime-built
Context — runtime state

How the layers combine

LayerQuestion it answersSourcePer turn?
CoreWho is this system? What are the hard rules?core_identity.md, policy/boundaries.md, policy/privacy.md (collected as CORE_SOURCES in prompts/__init__.py)Never changes
Response styleWhat response shape is this turn?response_styles/*.md — support, reflection, psychoeducation, guided_exercise, closing, crisis_response, safety_checkSelected by agent-owned skill/tool context
Therapeutic approachWhat therapeutic framework overlay?Seven selectable approaches under therapeutic_approaches/ — motivational_interviewing, cbt (loads cbt.md + cbt_arc.md), act, dbt_skills, grief_support, interpersonal_therapy, pfaPer turn, selected by runtime state and skill context
InstructionsHow should it respond on this turn specifically?agent/specialists/therapeutic_response/prompt_instructions.py, agent/specialists/guided_exercise.py, and agent/guardrails/prompts.pyPer response style
Working memoryWhat does it know about the user?Semantic + episodic entries from the load-memory stageRe-retrieved each turn
Procedural rulesWhat style rules apply?Rules from ProceduralProfile, injected as suffixLoaded each turn
Two kinds of injected context

Working memory shapes the agent's awareness — "Previously noted: user has a sister named Sarah." Procedural rules shape its behavior — "this user prefers shorter responses." Rules are always applied regardless of the proactive recall toggle.

The crisis branch composes a tighter prompt: CORE_SOURCES + response_styles/crisis_response.md (and policy/crisis.md for the classifier prompt) + recent history. Memory layers are skipped on crisis turns by design.

The safety_check response style is used when the crisis classifier returns level 1 (ambiguous distress, needs_clarification) — a one-question safety probe inside the therapeutic branch rather than a full crisis response.


Why layers

PropertyHow layers enforce it
Safety policy can't be overwrittenCore layer (including policy/boundaries.md + policy/privacy.md) is always first; no style/approach can weaken it
Response knowledge is reviewableEach response style's knowledge is a standalone .md in agent/prompts/sources/response_styles/
Procedural rules can't be overriddenInjected last as system prompt suffix; safety-conflict rules ("skip the safety check") are dropped by the procedural extractor
Each layer has a clear owneragent/prompts/sources/ for content, agent/specialists/ for agent-owned assembly, and agent/guardrails/ for crisis prompt assembly

Implementation

FileWhat it does
agent/prompts/__init__.pyCORE_SOURCES tuple, load_prompt_source(), compose_sources(), format_recent_history(), plus crisis prompt builder re-exports
agent/guardrails/prompts.pyCrisis classifier + crisis response prompt builders
agent/specialists/therapeutic_response/prompt_sources.py_knowledge_for_response_style() and response-style / approach source selection
agent/specialists/therapeutic_response/prompt_instructions.pyPer-response-style instruction blocks
agent/specialists/therapeutic_response/prompts.pyTherapeutic-agent system/task prompt builders
agent/specialists/guided_exercise.pyGuided-exercise specialist instructions and system prompt builder
agent/prompts/sources/core_identity.mdAssistant role, product stance, voice, tone, pacing, directness, and core boundaries
agent/prompts/sources/policy/Safety + privacy + crisis policy (3 files)
agent/prompts/sources/response_styles/One file per response style (7 files)
agent/prompts/sources/therapeutic_approaches/8 knowledge files across 7 selectable approaches (CBT loads both cbt.md and cbt_arc.md), dynamically loaded per turn
agent/prompts/sources/session_stages.mdStage-aware response guidance (not yet wired into the runtime)
agent/prompts/sources/cross_session_continuity.mdFirst-turn catch-up framing
agent/runtime/memory_context.pyPopulates working_memory and procedural_profile.procedural_rules

Compatibility matrix

Which response styles pair with which therapeutic approaches, and which combinations the dispatcher can actually pick.

ResponseWhat it doesMICBTACTDBTGriefIPTPFA
supportiveDefault support lane — validate, reflect, and respond based on venting, strengths, or gentle guidance.
reflectiveExplore a named recurring pattern carefully without over-analyzing.
clarifyingAsk for the minimum context needed before choosing a deeper response.
psychoeducationExplain one likely mind-body process in simple, non-diagnostic language.
techniqueStructured therapeutic work without launching a named multi-turn exercise.
guided_exerciseState-tracked practice such as grounding, breathing, thought work, values, or emotion regulation.
closingWind down, reflect the useful part, and avoid opening a large new thread.
safety_checkAmbiguous risk signal — ask one direct safety clarification.
crisis_responseConfirmed risk — prioritize immediate safety and surface resources.

This is the intended routing surface, not a hard static registry. The therapeutic response agent selects a response skill throughload_therapeutic_response_skill; prompt source loading lives in agent/specialists/therapeutic_prompt_sources.py. Hover a column to highlight it.


Live assembly

Real (trimmed) excerpts generated from backend prompt dumps. Pick a scenario, hit play, and watch which layers light up as the animation walks past each section header. The "skipped" rows show which layers a given scenario deliberately omits (e.g., the crisis path drops the procedural-rules and recall-toggle blocks by design).

The default therapeutic turn — soul + identity + boundaries + privacy + supportive response style + MI overlay + recall hint.

Core identity
Response knowledge
Approach
Response instructions
Procedural rulesskipped
Memory recall hint
Task & history

Layers light up as the typing animation walks past each section header in the prompt.

supportive_mi.txtresponse_style=supportive · approach=motivational_interviewing
loading prompt dump…