Skip to content
Merged
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
19 changes: 19 additions & 0 deletions cueapi/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -2966,13 +2966,25 @@ def subscriptions() -> None:
help="Delivery mechanism: pull (poll via `cueapi events list`) or webhook (server POSTs).")
@click.option("--webhook-url", "webhook_url", default=None,
help="Required for delivery-target=webhook; HTTPS only.")
@click.option("--inline-body", "inline_body", is_flag=True, default=False,
help=(
"Opt into body embedding on emitted events (hosted PR #791, "
"Item 1). When set, the source message body is embedded in "
"event payloads as `payload.body` — eliminates the extra "
"GET /v1/messages/{id} round-trip on the consumer side. "
"Bodies > 32KB are NOT embedded; the payload instead carries "
"`payload.body_omitted = \"size_too_large\"` + "
"`payload.body_size_bytes = N` so consumers fall back to the "
"fetch. Default unset = server default (False)."
))
@click.pass_context
def subscriptions_create(
ctx: click.Context,
ref: str,
event_type: str,
delivery_target: str,
webhook_url: Optional[str],
inline_body: bool,
) -> None:
"""Create a subscription for an agent.

Expand All @@ -2987,6 +2999,13 @@ def subscriptions_create(
body: dict = {"event_type": event_type, "delivery_target": delivery_target}
if webhook_url:
body["webhook_url"] = webhook_url
# is_flag means click defaults to False when unset; only send the
# field when explicitly opted in (matches SDK convention — keeps the
# wire format identical to pre-#791 callers for the common no-embed
# case). Sending False when the user explicitly opted out would also
# work but adds payload noise; the server default handles it.
if inline_body:
body["inline_body"] = True
try:
with CueAPIClient(api_key=ctx.obj.get("api_key"), profile=ctx.obj.get("profile")) as client:
resp = client.post(f"/agents/{ref}/subscriptions", json=body)
Expand Down
71 changes: 71 additions & 0 deletions tests/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -3643,3 +3643,74 @@ def test_bulk_delete_rejects_more_than_100_ids_pre_request():
# exit code shape is implementation-detail (echo_error may raise
# SystemExit). What matters is the cap message appears.
assert "100" in result.output


# --- subscriptions --inline-body (hosted PR #791 / Item 1 parity) ---


def test_subscriptions_create_inline_body_flag_default_omits_field(monkeypatch):
"""Default (no --inline-body flag) MUST NOT send inline_body on the wire.
Preserves pre-#791 caller compatibility — server default of False applies."""
holder: dict = {}
_patch_client(
monkeypatch,
holder,
responses={
("POST", "/agents/agt_x/subscriptions"): lambda: _FakeResp(
201,
{
"id": "sub_uuid",
"event_type": "message.received",
"delivery_target": "pull",
"inline_body": False,
},
)
},
)
result = runner.invoke(
main,
["subscriptions", "create", "agt_x",
"--event-type", "message.received",
"--delivery-target", "pull"],
)
assert result.exit_code == 0, result.output
body = holder["client"].calls[-1][2]
assert "inline_body" not in body


def test_subscriptions_create_inline_body_flag_opts_in(monkeypatch):
"""--inline-body opts into body-embedding on emitted events."""
holder: dict = {}
_patch_client(
monkeypatch,
holder,
responses={
("POST", "/agents/agt_x/subscriptions"): lambda: _FakeResp(
201,
{
"id": "sub_uuid",
"event_type": "message.received",
"delivery_target": "pull",
"inline_body": True,
},
)
},
)
result = runner.invoke(
main,
["subscriptions", "create", "agt_x",
"--event-type", "message.received",
"--delivery-target", "pull",
"--inline-body"],
)
assert result.exit_code == 0, result.output
body = holder["client"].calls[-1][2]
assert body["inline_body"] is True


def test_subscriptions_create_help_lists_inline_body():
result = runner.invoke(main, ["subscriptions", "create", "--help"])
assert result.exit_code == 0
assert "--inline-body" in result.output
# Mention the 32KB cap so users discover it via --help
assert "32KB" in result.output or "body_omitted" in result.output