Skip to content

feat(api): Add unwrap query param to /wait#2535

Merged
topher-lo merged 4 commits intomainfrom
feat/webhook-wait-unwrap
Apr 20, 2026
Merged

feat(api): Add unwrap query param to /wait#2535
topher-lo merged 4 commits intomainfrom
feat/webhook-wait-unwrap

Conversation

@topher-lo
Copy link
Copy Markdown
Contributor

@topher-lo topher-lo commented Apr 16, 2026

Summary by cubic

Add unwrap to POST /webhooks/{workflow_id}/{secret}/wait so workflows-as-APIs can return the raw result when it fits inline; externalized results return 413 with a download envelope in detail. OpenAPI keeps 200 typed as the envelope (WaitResultOutput), with 413 as a typed overflow response.

  • New Features

    • POST /wait?unwrap=true: returns the workflow’s return value directly; inline only.
    • For externalized results with unwrap=true: respond 413 Payload Too Large and include the download_* envelope in detail.
    • OpenAPI/SDK: 200 is WaitResultOutput; 413 is WaitResultUnwrapOverflowResponse. publicIncomingWebhookWait supports unwrap.
    • Docs expanded for /wait, envelope kinds, externalization, and query params (incl. vendor=okta). Tests cover unwrap for inline, external file, collection, and OpenAPI invariants.
  • Migration

    • Generated client publicIncomingWebhookWait accepts unwrap; 200 stays WaitResultOutput, and 413 is WaitResultUnwrapOverflowResponse.
    • If you need the envelope, omit unwrap and handle { kind: "value" | "download_file" | "download_export", ... }.
    • With unwrap=true, expect:
      • Inline results: raw JSON body.
      • Externalized results: HTTP 413 with the download envelope under detail.

Written for commit 6a69958. Summary will update on new commits.

Lets workflows-as-APIs return the result directly as the response body.
Inline results are returned raw via JSONResponse; externalized results
respond 413 with the download envelope in detail so callers can still
fetch the data. Webhook docs now cover every query param and add a
dedicated /wait section explaining the kind envelope and the
externalization rationale.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
@topher-lo topher-lo added the api Improvements or additions to the backend API label Apr 16, 2026
@topher-lo topher-lo temporarily deployed to internal-registry-ci April 16, 2026 18:28 — with GitHub Actions Inactive
@topher-lo topher-lo temporarily deployed to internal-registry-ci April 16, 2026 18:29 — with GitHub Actions Inactive
@mintlify
Copy link
Copy Markdown
Contributor

mintlify Bot commented Apr 16, 2026

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated (UTC)
tracecat 🟢 Ready View Preview Apr 16, 2026, 6:31 PM

💡 Tip: Enable Workflows to automatically generate PRs for you.

Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 6 files

Confidence score: 5/5

  • Automated review surfaced no issues in the provided summaries.
  • No files require special attention.

@zeropath-ai
Copy link
Copy Markdown

zeropath-ai Bot commented Apr 16, 2026

No security or compliance issues detected. Reviewed everything up to 6a69958.

Security Overview
Detected Code Changes

| Change Type | Relevant files

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 448e626fc9

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread tracecat/webhooks/router.py Outdated
@topher-lo topher-lo requested a review from daryllimyt April 16, 2026 18:55
Setting response_model=None dropped the typed 200 schema from OpenAPI,
regressing generated SDK types to `unknown`. Restore response_model to
WaitResultOutput; JSONResponse returns for unwrap=true still bypass
serialization at runtime, so the envelope-mode contract stays typed
for SDK consumers.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
@topher-lo topher-lo temporarily deployed to internal-registry-ci April 16, 2026 18:58 — with GitHub Actions Inactive
@topher-lo topher-lo temporarily deployed to internal-registry-ci April 16, 2026 18:58 — with GitHub Actions Inactive
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 2ceb6f548c

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread tracecat/webhooks/router.py Outdated
Comment on lines +431 to +433
raise HTTPException(
status_code=status.HTTP_413_REQUEST_ENTITY_TOO_LARGE,
detail=envelope,
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Declare 413 response schema for unwrap overflow

When unwrap=true and the result was externalized, the handler raises HTTP 413 with a structured download envelope in detail, but that response is not declared in the route metadata. As a result, OpenAPI/SDK output omits this documented control-flow path, so clients cannot type or reliably handle detail.kind without ad-hoc parsing.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 4 files (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="tracecat/webhooks/router.py">

<violation number="1" location="tracecat/webhooks/router.py:388">
P2: `response_model=WaitResultOutput` is too narrow for `/wait` because `unwrap=true` returns raw JSON on 200. This produces an incorrect OpenAPI contract/client type for successful unwrapped responses.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Comment thread tracecat/webhooks/router.py Outdated
@topher-lo topher-lo temporarily deployed to internal-registry-ci April 17, 2026 09:16 — with GitHub Actions Inactive
@topher-lo topher-lo temporarily deployed to internal-registry-ci April 17, 2026 09:16 — with GitHub Actions Inactive
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 5da8f9b9d9

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread tracecat/webhooks/router.py Outdated
@router.post("/wait")
@router.post(
"/wait",
response_model=WaitResultOutput | WaitResultUnwrappedOutput,
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Keep /wait default response schema discriminated

Defining response_model as WaitResultOutput | WaitResultUnwrappedOutput makes the OpenAPI 200 schema include a catch-all object branch (dict[str, Any]), so generated clients can no longer rely on the {kind, ...} discriminator even when unwrap is omitted (the default behavior that still returns the envelope). This is a contract regression for existing typed consumers of /wait because kind-based handling is no longer type-safe. Fresh evidence: the generated client now unions WaitResultUnwrappedOutput into PublicIncomingWebhookWaitResponse, and that unwrapped type includes { [key: string]: unknown }, which subsumes the envelope shape.

Useful? React with 👍 / 👎.

@topher-lo topher-lo temporarily deployed to internal-registry-ci April 20, 2026 14:52 — with GitHub Actions Inactive
@topher-lo topher-lo temporarily deployed to internal-registry-ci April 20, 2026 14:53 — with GitHub Actions Inactive
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 5 files (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="tests/unit/test_webhook_execution_path.py">

<violation number="1" location="tests/unit/test_webhook_execution_path.py:1066">
P3: The 200 schema assertion is too strict for a union `response_model`; FastAPI emits an `anyOf` for the member schemas, not a single `WaitResultOutput` ref.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

success_schema = responses["200"]["content"]["application/json"]["schema"]
overflow_schema = responses["413"]["content"]["application/json"]["schema"]

assert success_schema == {"$ref": "#/components/schemas/WaitResultOutput"}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P3: The 200 schema assertion is too strict for a union response_model; FastAPI emits an anyOf for the member schemas, not a single WaitResultOutput ref.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At tests/unit/test_webhook_execution_path.py, line 1066:

<comment>The 200 schema assertion is too strict for a union `response_model`; FastAPI emits an `anyOf` for the member schemas, not a single `WaitResultOutput` ref.</comment>

<file context>
@@ -1051,6 +1052,22 @@ async def test_wait_webhook_unwrap_returns_413_for_collection_object(self):
+        success_schema = responses["200"]["content"]["application/json"]["schema"]
+        overflow_schema = responses["413"]["content"]["application/json"]["schema"]
+
+        assert success_schema == {"$ref": "#/components/schemas/WaitResultOutput"}
+        assert overflow_schema == {
+            "$ref": "#/components/schemas/WaitResultUnwrapOverflowResponse"
</file context>

@topher-lo topher-lo merged commit 28ffce3 into main Apr 20, 2026
21 checks passed
@topher-lo topher-lo deleted the feat/webhook-wait-unwrap branch April 20, 2026 15:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

api Improvements or additions to the backend API

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants