Skip to content

Commit fb01267

Browse files
vvillait88claude
andcommitted
feat(commerce): verification_agent_instructions accepts retry_step override (parity with node)
Mirror of node-commerce 1a0f8fe. retry_step REPLACES the canonical "Retry the original merchant request..." step instead of appending via extra_steps — eliminates the duplicate retry instruction when vendors need merchant-specific retry mechanics (e.g. martin-estate's order_id resume). extra_steps remains for genuinely additional steps that come AFTER retry. Tests cover both cases: retry_step replaces (no duplicate canonical retry), retry_step + extra_steps compose correctly. 485 → 487 tests pass. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 4431843 commit fb01267

2 files changed

Lines changed: 26 additions & 1 deletion

File tree

‎agentscore_commerce/identity/_denial.py‎

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@ def build_contact_support_next_steps(support_email: str, message: str | None = N
136136
def verification_agent_instructions(
137137
*,
138138
user_action: str | None = None,
139+
retry_step: str | None = None,
139140
extra_steps: list[str] | None = None,
140141
poll_interval_seconds: int = 5,
141142
timeout_seconds: int = 3600,
@@ -147,6 +148,12 @@ def verification_agent_instructions(
147148
Tells the agent how to present verify_url, poll for the operator_token, and retry the
148149
original request. Universal across every AgentScore-gated merchant — overrides let vendors
149150
add merchant-specific steps.
151+
152+
``retry_step`` REPLACES the generic "Retry the original merchant request..." step with a
153+
merchant-specific one (e.g. "Retry POST /purchase with X-Operator-Token AND include
154+
order_id..."). Use it when your retry instruction is a refinement of the canonical retry,
155+
not an additional step. ``extra_steps`` is for genuinely additional steps that come AFTER
156+
the retry (e.g. "After payment the same call returns 200").
150157
"""
151158
base_steps = [
152159
"Present the verify_url directly to the user — it is a complete, ready-to-open URL with the session "
@@ -158,7 +165,8 @@ def verification_agent_instructions(
158165
"and closes the tab. They do NOT need to copy or paste anything back to you.",
159166
'When your poll returns status "verified", extract operator_token from the response. This is a one-time '
160167
'value — save it immediately. Subsequent polls return status "consumed" without the token.',
161-
"Retry the original merchant request with header X-Operator-Token set to the operator_token value.",
168+
retry_step
169+
or "Retry the original merchant request with header X-Operator-Token set to the operator_token value.",
162170
]
163171
out: dict[str, Any] = {
164172
"action": "poll_for_credential",

‎tests/test_denial.py‎

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,3 +142,20 @@ def test_extra_steps_and_order_ttl_and_extras(self):
142142
assert inst["steps"][-1] == "Resume by including order_id in the retry body."
143143
assert "1 hour" in inst["order_ttl"]
144144
assert inst["vendor_field"] == "value"
145+
146+
def test_retry_step_replaces_canonical_step(self):
147+
custom = "Retry POST /purchase with X-Operator-Token AND include order_id from this response."
148+
inst = verification_agent_instructions(retry_step=custom)
149+
assert inst["steps"][4] == custom
150+
canonical = "Retry the original merchant request with header X-Operator-Token set to the operator_token value."
151+
assert canonical not in inst["steps"]
152+
153+
def test_retry_step_and_extra_steps_compose(self):
154+
inst = verification_agent_instructions(
155+
retry_step="Custom retry.",
156+
extra_steps=["Then do X.", "Then do Y."],
157+
)
158+
assert len(inst["steps"]) == 7
159+
assert inst["steps"][4] == "Custom retry."
160+
assert inst["steps"][5] == "Then do X."
161+
assert inst["steps"][6] == "Then do Y."

0 commit comments

Comments
 (0)