← Back to Patterns

Intent modes

Availablehumanosintermediate

# Intent modes

HUMΛN separates what the user said this turn from what they want built. Companion chat returns a per-turn classification (question | context | intent). The Intent-to-Capability pipeline (POST /v1/intent) turns durable goals into resolution plans, scaffolds, and provisioning.

Overview

  • question — user wants an answer; render text + citations.
  • context — user is sharing session context; acknowledge only.
  • intent — user wants something done; surface intent_action when present, or loop clarifying turns.
  • Mis-parsing an intent turn as a question is how you get confident wrong answers instead of governed action.

    Per-turn classification (Companion clients)

    Every Companion response that participates in governed action includes classification. Branch before you render:

    type TurnClassification = 'question' | 'context' | 'intent';

    interface CompanionTurn { classification: TurnClassification; text: string; citations?: Array<{ uri: string; title: string }>; intent_action?: { tool_id: string; params: Record; autonomy: 'observe' | 'propose' | 'auto'; requires_approval: boolean; reversible: boolean; human_readable: string; consequence: string; provenance_scope: string; } | null; }

    function handleTurn(turn: CompanionTurn) { switch (turn.classification) { case 'question': // Render answer + citations only return { mode: 'answer', body: turn.text, citations: turn.citations ?? [] };

    case 'context': // Acknowledge — context is persisted server-side return { mode: 'ack', body: turn.text };

    case 'intent': if (!turn.intent_action) { // Fuzzy intent — clarifying question; send next user message back through Companion return { mode: 'clarify', body: turn.text }; } // Clear intent — show approval card; call human.call only after explicit approval return { mode: 'propose', body: turn.text, approval: { title: turn.intent_action.human_readable, detail: turn.intent_action.consequence, requiresApproval: turn.intent_action.requires_approval, toolId: turn.intent_action.tool_id, params: turn.intent_action.params, }, }; } }

    Fourth Law: when requires_approval: true, wait for human respond — do not upgrade autonomy client-side.

    Intent-to-Capability API (/v1/intent)

    For durable “build this” flows (not just the current chat turn), use IntentClient from @human/sdk:

    >
    SDK:

    Multimodal ingest

    Same brief pipeline for voice or pasted docs:

    await client.intent.transcribe({
      transcript: 'Keep invoice reconciliation moving every Monday morning',
      source_surface: 'companion',
    });

    await client.intent.extract({ document_text: 'Refund policy: auto-approve under $500 with finance review above', source_surface: 'workflow_designer', });

    await client.intent.ingest({ text: 'Automate refund approvals under $500', document_text: policyPdfText, source_surface: 'agent_builder', });

    Shipped surfaces

    SurfacePurpose
    Companion turn classificationPer-message UX branching (question \context \intent)
    client.intent.*Intent brief lifecycle — build, shape, compile, provision, lineage
    POST /v1/intentCreate brief from natural language
    POST /v1/intent/:id/compileCapability-first resolution paths
    POST /v1/intent/:id/provisionStart provisioning from selected path
    GET /v1/intent/:id/lineageAudit chain for brief → execution
    Implementation: packages/sdk/src/intent.ts, apps/api/src/routes/intent/.

    Use cases

  • Embedded Companion widget — parse classification before auto-running tools; show approval cards for intent_action.
  • Builder / CLIintent.buildcompilescaffold for repeatable scaffolding.
  • Control Plane activityclient.intent.adminIntentActivity() for org-scoped brief lists.
  • Clarifying loops — tolerate 2–3 fuzzy intent turns; session is durable.
  • Security considerations

    DO

    Branch on classification before invoking tools

    Respect requires_approval and server-set autonomy on intent_action

    Use intent lineage for audit when provisioning agents or bundles

    DON'T

    Treat intent_action as optional decoration on intent turns

    Auto-execute because autonomy returned auto without checking reversible

    Re-use a spent approval_id on human.call

    See also

  • SPA-aware Companion surface context
  • Human-in-the-Loop
  • Public reference: /ai/articles/companion-intent-modes
  • Community: Intent routing architecture