Ajustes conforme relatorio de testes 2026-08-27
This commit is contained in:
@@ -624,6 +624,74 @@ When semantic confirmation succeeds, the router records:
|
||||
|
||||
`AgentRuntime` reuses this routed decision instead of re-running the deterministic parser. The change is additive: existing explicit yes/no inputs continue through the deterministic path with no extra LLM call. Semantic generations are named `transaction.confirmation.semantic_classifier` for observability.
|
||||
|
||||
### `expected_input.semantic_classifier.unmatched_value` and `reprompt`
|
||||
|
||||
Paused workflows may accept literal replies and also classify free-text replies semantically. When `semantic_classifier` is enabled, an utterance that **cannot safely be mapped to any valid class** must not be forced into `SIM`, `NAO`, or `CONTINUAR`. For that case, the workflow may declare a classifier sentinel through `unmatched_value`.
|
||||
|
||||
Example:
|
||||
|
||||
```yaml
|
||||
expected_input:
|
||||
key: resposta_usuario
|
||||
allowed_values:
|
||||
- SIM
|
||||
- NAO
|
||||
- CONTINUAR
|
||||
normalize: upper_strip
|
||||
reprompt: >
|
||||
I did not understand. Did this explanation resolve your question?
|
||||
Please answer yes or no.
|
||||
|
||||
semantic_classifier:
|
||||
enabled: true
|
||||
include_relevant_context: true
|
||||
unmatched_value: OUTRO
|
||||
prompt: |
|
||||
Classify the customer's utterance into a valid option only when there is
|
||||
enough meaning to do so safely.
|
||||
|
||||
SIM: unambiguous understanding/acceptance.
|
||||
NAO: unambiguous negative answer.
|
||||
CONTINUAR: a meaningful utterance that complements or continues the request.
|
||||
OUTRO: incomprehensible, disconnected, or insufficient input for any valid class.
|
||||
|
||||
Return only SIM, NAO, CONTINUAR, or OUTRO.
|
||||
|
||||
option_actions:
|
||||
CONTINUAR:
|
||||
action: contextual_reentry
|
||||
```
|
||||
|
||||
The contract is:
|
||||
|
||||
```text
|
||||
SIM -> resume with SIM
|
||||
NAO -> resume with NAO
|
||||
CONTINUAR -> execute the configured option_action (for example contextual_reentry)
|
||||
OUTRO -> never resume with this value; return reprompt and keep the workflow paused
|
||||
```
|
||||
|
||||
Important rules:
|
||||
|
||||
- `unmatched_value` is a **classifier sentinel**, not a business response;
|
||||
- do not add the sentinel to `allowed_values`; `allowed_values` contains only values the workflow may consume;
|
||||
- `CONTINUAR` is valid only for a meaningful utterance that actually continues the topic; contextually meaningless input should return `unmatched_value` and trigger `reprompt`;
|
||||
- `reprompt` does not complete or restart the execution: the same workflow remains `PAUSED` and waits for another reply;
|
||||
- internal values such as `SIM`, `NAO`, `CONTINUAR`, and the sentinel must never leak as customer-facing output.
|
||||
|
||||
Behavioral example:
|
||||
|
||||
```text
|
||||
Pending prompt: "Did this explanation resolve your question?"
|
||||
|
||||
"sim" -> SIM
|
||||
"não resolveu" -> NAO
|
||||
"mas e a cobrança de R$ 14,99?" -> CONTINUAR -> contextual_reentry
|
||||
"ano" -> OUTRO -> reprompt
|
||||
```
|
||||
|
||||
This option is **opt-in per workflow**. Workflows that do not declare `semantic_classifier.unmatched_value` keep the previous contract, preventing a change in one flow from silently changing other workflows or agents.
|
||||
|
||||
### Durable interrupt compatibility in pause/resume
|
||||
|
||||
The runtime does not use `snapshot.next` alone to decide whether a workflow is paused. A truthy `next` may represent LangGraph helper work, including framework-generated synthetic nodes such as `__pause` and `__continue`.
|
||||
|
||||
@@ -95,6 +95,35 @@ A response created because of an input block is still agent output. Therefore it
|
||||
|
||||
This allows `DLEX_OUT`, `PINJ`, `TOXOUT`, Output Supervisor, and other policies to remove or sanitize information that should not be exposed.
|
||||
|
||||
## COER, `expected_input`, and `reprompt` in paused workflows
|
||||
|
||||
When an active `expected_input.semantic_classifier` exists, the framework may delegate semantic interpretation to the workflow contract instead of immediately treating an ambiguous input as a generic `COER` block. In this mode, the guardrail may be recorded as allowed/delegated, for example with mechanism `expected_input_semantic_classifier`.
|
||||
|
||||
The workflow remains responsible for distinguishing:
|
||||
|
||||
```text
|
||||
valid, meaningful reply -> valid class / option_action
|
||||
insufficient or meaningless -> unmatched_value -> reprompt
|
||||
```
|
||||
|
||||
Example:
|
||||
|
||||
```yaml
|
||||
expected_input:
|
||||
allowed_values: [SIM, NAO, CONTINUAR]
|
||||
reprompt: "I did not understand. Did this explanation resolve your question? Please answer yes or no."
|
||||
semantic_classifier:
|
||||
enabled: true
|
||||
unmatched_value: OUTRO
|
||||
option_actions:
|
||||
CONTINUAR:
|
||||
action: contextual_reentry
|
||||
```
|
||||
|
||||
Under this contract, `CONTINUAR` does not mean "anything other than SIM or NAO". It represents a **coherent, contextual** utterance that continues the topic. Input such as `ano`, which has insufficient meaning for the pending prompt, should return sentinel `OUTRO` and produce the `reprompt`, while keeping the same workflow paused.
|
||||
|
||||
`OUTRO` must not be added to `allowed_values` or sent to the runtime as a resume value. See [03 — Transactional Workflows and State](./03_transaction_workflows_and_state.md#expected_inputsemantic_classifierunmatched_value-and-reprompt) for the full contract.
|
||||
|
||||
## Relationship with `agent_graph.py`
|
||||
|
||||
This feature belongs to template orchestration because it defines precedence between graph nodes and blocked-turn state semantics.
|
||||
@@ -151,6 +180,8 @@ input_guardrails blocked
|
||||
Cover at least:
|
||||
|
||||
- `COER=false` asks for clarification instead of returning a generic security message;
|
||||
- with `expected_input.semantic_classifier.unmatched_value`, incoherent/insufficient input triggers `reprompt` and keeps the workflow `PAUSED`;
|
||||
- meaningful input outside literal SIM/NAO can still follow `CONTINUAR -> contextual_reentry` without being confused with incoherent input;
|
||||
- blocked branch does not retain previous-turn `mcp_results`/routing;
|
||||
- no transactional tool executes after an input block;
|
||||
- the public message passes through output guardrails;
|
||||
|
||||
@@ -21,6 +21,7 @@ If something is not working, use **Search by problem** below.
|
||||
| An answer that should fill a parameter is interpreted as a new intent | transactional precedence, parameter extraction | [Transactional Workflows](docs/developer/en/03_transaction_workflows_and_state.md) |
|
||||
| The transaction keeps asking for the same parameter | transaction state, extractor, schema | [Transactional Workflows](docs/developer/en/03_transaction_workflows_and_state.md) and [MCP/Tools](docs/developer/en/04_mcp_integration_tools_and_policies.md) |
|
||||
| “yes/no” confirmation does not continue the flow | confirmation state, transaction state | [Transactional Workflows](docs/developer/en/03_transaction_workflows_and_state.md) |
|
||||
| Invalid input during `expected_input` becomes `CONTINUAR` instead of asking for clarification | `semantic_classifier.unmatched_value`, `reprompt`, `contextual_reentry`, delegated COER | [Transactional Workflows](./03_transaction_workflows_and_state.md) and [Input Guardrail Feedback](./12_input_guardrail_feedback_and_blocked_turns.md) |
|
||||
| A completed transaction reappears | old checkpoint versus active transaction state | [Transactional Workflows](docs/developer/en/03_transaction_workflows_and_state.md) and [LTM/Checkpoint](docs/developer/en/08_long_term_memory_and_checkpoint.md) |
|
||||
| The system says it executed something, but there is no evidence | MCP result, `COMPLETED` state, transactional judges | [Transactional Workflows](docs/developer/en/03_transaction_workflows_and_state.md) and [Guardrails/Judges](docs/developer/en/06_guardrails_judges_and_transaction_evaluation.md) |
|
||||
| A tool does not appear or cannot be found | `tools.yaml`, MCP catalog, discovery | [MCP/Tools](docs/developer/en/04_mcp_integration_tools_and_policies.md) |
|
||||
@@ -68,7 +69,7 @@ If something is not working, use **Search by problem** below.
|
||||
|
||||
**What it is:** multi-turn transaction lifecycle, states, confirmation, pause/resume, and operational evidence.
|
||||
|
||||
**Use when:** there are loops, incorrect confirmations, incorrect resumes, or critical operations.
|
||||
**Use when:** there are loops, incorrect confirmations/resumes, unintended `CONTINUAR`/`contextual_reentry`, missing `reprompt`, or critical operations.
|
||||
|
||||
### [04 — MCP, Tools, Policies, and Parameter Extraction](docs/developer/en/04_mcp_integration_tools_and_policies.md)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user