Skip to content

feat(engine): host-owned Negotiation-T activation and taskless Propose support - #71

Merged
Zhoujie628 merged 4 commits into
project-openan:mainfrom
Zhoujie628:main
Sep 14, 2026
Merged

Zhoujie628 merged 4 commits into
project-openan:mainfrom
Zhoujie628:main

Conversation

@Zhoujie628

Copy link
Copy Markdown
Contributor

Closes #70

Changes

  1. 9e67772 feat(engine): make Negotiation-T activation host-owned — Negotiation-T is activated per send by the business (MessageContent.withExtension(...)); the engine mirrors the selection into message.extensions and the A2A-Extensions request header, validates the target AgentCard declares the extension, and fails fast on unsolicited negotiation instead of silently entering the auto-loop.

  2. ad4a5b4 feat(engine): support taskless Negotiation-T propose (pre-task negotiation) — a remote may propose before creating any task, on a bare message with no INPUT_REQUIRED status and no taskId. The engine previously recorded the proposal text as a successful step output, so onNegotiation never fired. advance() now enters the negotiation loop when a response carries no task state and its received messages carry Negotiation-T metadata; the exchange correlates by contextId + negotiation id and follow-up sends omit taskId. Task-anchored INPUT_REQUIRED behavior, round-regression checks, duplicate-observe polling and the exchange budget are unchanged; both carriers share one loop and the same activation rule. Invalid negotiation metadata on a bare message now fails explicitly instead of being silently treated as a normal result.

  3. a1d4e35 style: converge non-Eastcom drift with dev — engine sources, tests and the shared zh/en guides accumulated formatting/javadoc drift through parallel double-applied changes; aligned verbatim so main and dev differ only in the Eastcom platform integration.

Testing

  • workflow-engine: 232 tests green, including six new taskless-negotiation cases (propose entry with taskId-less follow-up, multi-round loop completing on a task-anchored result, loud failures without host activation or with missing context, duplicate-propose failure, bare messages without negotiation metadata remain normal responses).
  • samples: negotiation E2E suites green, including the order-platform simulator path; 329 tests green on main after the sync.

Docs

The negotiation contract sections in the zh/en API reference, design, callbacks, developer and integration guides now describe both carriers; the changelog has an Unreleased entry.

Negotiation-T was previously treated as an implicit capability: a target
agent could start negotiation from an incomplete task even when the
caller never selected it, and the engine drove the auto-loop either way.
Now the business activates Negotiation-T per send via the new
MessageContent.withExtension(...); the engine mirrors that selection
into message.extensions and the A2A-Extensions request header and
validates that the target AgentCard declares the extension before
dispatch. An unsolicited INPUT_REQUIRED negotiation (host did not
activate Negotiation-T) fails fast instead of silently entering the
loop. The sample agent executor requires the request header to have
activated Negotiation-T before serving a Propose.

Tests cover activation without negotiation metadata on the wire,
rejection of activation against an undeclared target, unactivated
incomplete tasks staying out of negotiation, E2E wire-level
A2A-Extensions evidence, and withExtension immutability.

Signed-off-by: Zhoujie628 <zhoujie628@users.noreply.github.com>
…ation)

A2A-T lets the remote propose before creating any task, so the Propose can
arrive on a bare message with no INPUT_REQUIRED status and no taskId. The
engine previously fell through to the normal-response path and recorded the
proposal text as a successful step output, so hosts never saw onNegotiation.

- advance() now enters the negotiation loop when a response carries no task
  state and its received messages carry Negotiation-T metadata. The exchange
  correlates by contextId and negotiation id, and follow-up sends omit
  taskId. Task-anchored INPUT_REQUIRED behavior is unchanged; both carriers
  share one loop with the same round-regression, duplicate-observation and
  exchange budget rules.
- The activation rule is unchanged: negotiation runs only when the host
  activated Negotiation-T on the original send (A2A-Extensions carries the
  Negotiation-T URI). A taskless propose without activation fails fast
  instead of entering the loop.
- Invalid negotiation metadata on a bare message (missing negotiationContext,
  non-PROPOSE performative, duplicate propose with no remote task to observe)
  now fails explicitly instead of being silently treated as a normal result.

Tests cover taskless propose entry with taskId-less follow-up, a multi-round
loop that completes on a task-anchored result, loud failures without host
activation or with missing context, explicit duplicate-propose failure, and
that bare messages without negotiation metadata remain normal responses. The
zh/en negotiation contract sections, the platform adaptation guide and the
integration checklist are updated for the taskless carrier.

Signed-off-by: Zhoujie628 <zhoujie628@users.noreply.github.com>
Engine sources, tests and the shared zh/en guides drifted between main and
dev through parallel double-applied changes: line wrapping differs across
transport, runtime, config, executor and registry files and across the
guides, and the HTTP client customization hook javadoc carries older
wording. None of it is functional. Align these files verbatim with dev so
future cross-branch cherry-picks apply without conflicts and the branches
differ only in the Eastcom platform integration (dev-only guides, the
Eastcom adapter changelog section and the Eastcom README scenario remain
dev-only).

Signed-off-by: Zhoujie628 <zhoujie628@users.noreply.github.com>
@Zhoujie628
Zhoujie628 requested a review from a team as a code owner September 14, 2026 14:32
Signed-off-by: Zhoujie628 <zhoujie628@users.noreply.github.com>
@Zhoujie628
Zhoujie628 merged commit 3597e28 into project-openan:main Sep 14, 2026
3 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.

feat(engine): host-owned Negotiation-T activation and taskless Propose support

1 participant