Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,20 @@ an entry here.

### 2

- §7.1 — embedded persona commands (summon, release, one-off query,
list, check) are ordinary intents: expressed as locale intent/entity
resources and matched with the standard intent machinery
(OVOS-INTENT-2), no bespoke matching layer.
- §8.5 — the out-of-band query always answers: on an unsupported
`persona_id` the plugin replies on `ovos.persona.answer` with the
`error` field set and `response` omitted, never silently dropping
the request; `response` and `error` are mutually exclusive.
- §6 — dismissal mechanics per session class: default sessions need an
explicit clear (empty-string `persona_id`, a release intent, or a
committed `Match.updated_session` without the field); named-session
clients dismiss by removing the field from the state they carry.
- §3 — `persona_id` character-set constraint relaxed to a RECOMMENDED
ASCII letters/digits/`_`/`-` convention.
- Initial draft. Defines persona as a scoped match+handler layer with
its own pipeline position, `persona_id` session field, summon and
dismiss bus messages, match contract (MAY return `None` for pass-
Expand Down
47 changes: 32 additions & 15 deletions persona.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,17 +116,17 @@ provides content and dialog transformers that shape it.
## 3. The `persona_id` session field

This specification claims one optional session field per the
OVOS-SESSION-1 §2.1 registry mechanism.
OVOS-SESSION-1 §2.2 registry mechanism.

| Field | Wire type | Owner |
|-------|-----------|-------|
| `persona_id` | string | §3 (this specification) |

`persona_id` is an opaque string identifying which persona identity
is active for the current session. The value space is
deployment-defined. This specification places no constraint on the
string beyond the opaque-string rules of OVOS-SESSION-1 §2.2 (no `:`,
no whitespace).
deployment-defined. This specification places no hard constraint on
the string; values composed of ASCII letters, digits, `_`, and `-`
are **RECOMMENDED**.

`persona_id` is a **single value** — exactly one persona identity may
be active per session at a time. Composition of multiple personas
Expand Down Expand Up @@ -234,11 +234,17 @@ session by:
- a **pipeline plugin** via handler-side session mutation;
- a **session sync** (`ovos.session.sync`) from any component.

Per OVOS-SESSION-1 §4, omitting `persona_id` from a message does
not clear it — the field is carried forward unchanged. A client
that wants to dismiss a persona must send an explicit clear (empty
string or absent field with intent to remove) via session sync or
a summoning plugin that handles the release intent.
Omission does not dismiss, but the mechanics differ by session
class. For the **default session**, the orchestrator's merge
semantics (OVOS-SESSION-2 §5.1) preserve the stored value when an
inbound Message omits `persona_id`; dismissal therefore requires an
**explicit clear** — an empty-string `persona_id` (equivalent to
absent, §3) sent via `ovos.session.sync`, a summoning plugin that
handles the release intent, or a committed `Match.updated_session`
snapshot without the field. For a **named session**, the client's
copy is authoritative (OVOS-SESSION-2 §2.5): the client dismisses
by removing `persona_id` from the session state it carries on
subsequent Messages.

When dismiss is detected, any in-progress generation for the session
**SHOULD** cease. The persona's per-session state (conversation
Expand Down Expand Up @@ -271,6 +277,14 @@ order:
handles one-off queries, or self-releases when no persona is yet
active.

The embedded persona commands are **ordinary intents**: the
plugin SHOULD express summon, release, one-off query, list, and
check as intent and entity resources in its own `/locale` tree
and match them with the same intent machinery any other intent
uses (OVOS-INTENT-2). Persona commands earn no bespoke matching
layer — a persona plugin is distinguished by route 2's
catch-all, not by how it recognises its own commands.

2. **Active-persona catch-all.** If no embedded command was
detected, the plugin checks `session.persona_id`:
- If `session.persona_id` is absent or empty → return `None`
Expand Down Expand Up @@ -340,7 +354,7 @@ A persona plugin **MAY** mutate session state via

- set or clear `session.persona_id` as part of a summon or release
match (§7.1 route 1);
- modify any other session field it owns per the OVOS-SESSION-1 §2.1
- modify any other session field it owns per the OVOS-SESSION-1 §2.2
registry mechanism.

One-off query matches (the `ask` command) do **not** mutate
Expand Down Expand Up @@ -401,7 +415,7 @@ OVOS-SESSION-2 §2.4. History too large to project into session-resident
fields is held in plugin-internal storage with best-effort resumption.

A persona plugin **SHOULD** project summary state into a
session-resident field registered per OVOS-SESSION-1 §2.1 — so that
session-resident field registered per OVOS-SESSION-1 §2.2 — so that
resumption across orchestrator restarts or multi-orchestrator
deployments retains basic continuity even when full history is held
internally.
Expand Down Expand Up @@ -431,15 +445,18 @@ Session context for history continuity is read from
The plugin generates a response for the specified `persona_id` using
the `reply()` derivation (OVOS-MSG-1 §5) to route back to the caller.
If `persona_id` is not supported by this plugin, the plugin **MUST**
respond with `None` rather than silently drop the request.
still reply on `ovos.persona.answer` — echoing `persona_id` and
`utterance`, omitting `response`, and setting the `error` field —
rather than silently drop the request.

The response payload:

| Field | Type | Required | Meaning |
|-------|------|----------|---------|
| `persona_id` | string | yes | The persona that answered. |
| `utterance` | string | yes | Echo of the query. |
| `response` | string | yes | The generated response text. |
| `response` | string | on success | The generated response text. Omitted when `error` is present. |
| `error` | string | on failure | Short reason the query could not be answered (e.g. `"unsupported persona_id"`). Omitted on success. |

This interface is **not** part of the utterance lifecycle — it
bypasses the pipeline, the dispatch mechanism, and the
Expand Down Expand Up @@ -694,7 +711,7 @@ listing the intent names it dispatches on.
- respond to `ovos.persona.list` with its supported `persona_id`
values (§8.7);
- project summary state into a session-resident field registered per
OVOS-SESSION-1 §2.1 for resumption safety (§8.4).
OVOS-SESSION-1 §2.2 for resumption safety (§8.4).

### A persona pipeline plugin **SHOULD**:

Expand Down Expand Up @@ -738,7 +755,7 @@ listing the intent names it dispatches on.
derivations used for all bus communication.
- *Session Carrier Wire Shape Specification* (OVOS-SESSION-1) — the
session field registry and the omission rule; the persona spec
claims the `persona_id` field via §2.1.
claims the `persona_id` field via §2.2.
- *Session Lifecycle and State Ownership Specification*
(OVOS-SESSION-2) — the SHOULD-project / MAY-internal state
pathways and the mutation boundaries.
Expand Down