GeezerVison is showing github.com — feat(textract): migrate to AWS SDK, add AnalyzeExpense and AnalyzeID by waleedlatif1 · Pull Request #5456 · simstudioai/sim
Conversation
Summary
- Replace the hand-rolled AWS SigV4 signer in the Textract parse route with the official
@aws-sdk/client-textract package, matching how sibling AWS integrations (Secrets Manager, S3, STS) already call AWS
- Add an Analyze Expense operation (structured invoice/receipt extraction: vendor, totals, line items) via
AnalyzeExpense (sync) / StartExpenseAnalysis+GetExpenseAnalysis (async, S3)
- Add an Analyze Identity Document operation (
AnalyzeID) for driver's licenses/passports, with an optional back-of-ID page
- These fill a real gap: the block's own templates/skills already advertised invoice extraction and ID verification, but no tool backed them
- Add an
operation dropdown to the textract_v2 block; defaults to the existing Analyze Document behavior so already-saved workflows are unaffected
- Removed 3 dead/unreferenced interfaces from
tools/textract/types.ts
Type of Change
Testing
- Added unit tests for tool body/response construction (all 3 tools) and for the AWS-response-to-output mapping functions in each route (29 tests total)
bun run type-check, bun run lint, and bun run check:api-validation all pass
Checklist
- Code follows project style guidelines
- Self-reviewed my changes
- Tests added/updated and passing
- No new warnings introduced
- I confirm that I have read and agree to the terms outlined in the Contributor License Agreement (CLA)
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
greptile-apps[bot] reacted with thumbs up emoji
- Replace hand-rolled AWS SigV4 signing with @aws-sdk/client-textract, matching sibling AWS integrations (secrets_manager, s3, sts)
- Add Analyze Expense operation (invoice/receipt structured extraction) via AnalyzeExpense/StartExpenseAnalysis+GetExpenseAnalysis
- Add Analyze Identity Document operation (AnalyzeID) with optional back-of-ID page
- Add an operation selector to the textract_v2 block; defaults to the existing Analyze Document behavior for backward compatibility
- Add tests for tool body/response mapping and route-level AWS response normalization
vercel
Bot
commented
Jul 7, 2026
•
edited
Loading
Uh oh!
There was an error while loading. Please reload this page.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
1 Skipped Deployment
| Project |
Deployment |
Actions |
Updated (UTC) |
| docs |
Skipped |
|
Jul 7, 2026 2:07am |

|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
cursor
Bot
commented
Jul 7, 2026
•
edited
Loading
Uh oh!
There was an error while loading. Please reload this page.
PR Summary
Medium Risk
Touches document ingestion (SSRF controls, file access) and accepts user-supplied AWS keys; Analyze ID adds PII handling, and the parse-route migration is a large behavioral swap though covered by tests.
Overview
Migrates Textract from hand-rolled SigV4 HTTP calls to @aws-sdk/client-textract, with shared helpers for document resolution (uploads, pinned URL fetch, S3 URI validation), async job polling, and SDK error mapping—including the multi-page PDF hint where async mode exists.
Adds two API surfaces and tools: Analyze Expense (sync AnalyzeExpense / async StartExpenseAnalysis + paginated GetExpenseAnalysis) and Analyze ID (sync AnalyzeID, optional back page), each returning camelCase-normalized payloads.
Extends textract_v2 with an Operation dropdown (defaults to existing analyze-document), routes to textract_parser_v2, textract_analyze_expense, or textract_analyze_id, operation-specific outputs, and back-of-ID inputs for ID verification. Zod contracts and the tool registry are updated; API route count baseline moves to 906.
Reviewed by Cursor Bugbot for commit 55cb4eb. Configure here.
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
greptile-apps
Bot
commented
Jul 7, 2026
•
edited
Loading
Uh oh!
There was an error while loading. Please reload this page.
Greptile Summary
This PR replaces the hand-rolled AWS SigV4 signing implementation in the Textract parse route with @aws-sdk/client-textract, and adds two new operations — AnalyzeExpense (sync + async) and AnalyzeID (sync only) — behind a new operation dropdown in the textract_v2 block. The SDK migration is clean and removes ~240 lines of bespoke signing/polling code by extracting shared logic into a new shared.ts module.
- Shared utilities (
resolveDocumentInput, pollTextractJob, mapTextractSdkError, parseS3Uri) are extracted into shared.ts, reducing duplication across the three route handlers, and all security guards (SSRF validation, path-traversal checks, S3 bucket name validation) are preserved in the new shared module.
- A function-typed
condition (documentFieldCondition) ensures the front-document upload fields remain visible for analyze_id regardless of any stale processingMode value left over from a prior operation, addressing the previously reported UI bug.
- 29 unit tests are added covering route-level normalization functions, tool
body builders, shared utilities (parseS3Uri, mapTextractSdkError, pollTextractJob), and response deserialization for all three operations.
Confidence Score: 5/5
Safe to merge — the SDK migration is a drop-in replacement for the hand-rolled SigV4 signer, all security guards are preserved in the new shared module, and the new operations follow the same patterns as the existing route.
The migration removes substantial bespoke code in favor of the official SDK and factors shared logic into a well-tested module. The documentFieldCondition function correctly handles the stale-processingMode scenario for analyze_id that was flagged in the previous review cycle. All three routes validate inputs at the contract layer and the route layer, SSRF and path-traversal guards are carried over intact, and 29 tests cover the key normalization and utility functions.
No files require special attention.
Important Files Changed
| Filename |
Overview |
| apps/sim/app/api/tools/textract/shared.ts |
New shared module extracting resolveDocumentInput, pollTextractJob, mapTextractSdkError, parseS3Uri, and TextractRouteError; all security guards from the original parse route are preserved, error statuses are correctly typed, and the module is well-tested. |
| apps/sim/blocks/blocks/textract.ts |
Adds operation dropdown with three choices and the documentFieldCondition helper that dynamically returns an operation-based condition for analyze_id; tool selector and param-builder updated correctly for all three operations. |
| apps/sim/app/api/tools/textract/parse/route.ts |
SDK migration drops ~220 lines; delegates document resolution, job polling, and error mapping to shared.ts; behavior is functionally equivalent to the pre-migration implementation. |
| apps/sim/app/api/tools/textract/analyze-expense/route.ts |
New route implementing AnalyzeExpense (sync) and StartExpenseAnalysis/GetExpenseAnalysis (async); normalizeExpenseDocuments maps the AWS SDK shape to a clean camelCase output; pagination handled correctly via pollTextractJob. |
| apps/sim/app/api/tools/textract/analyze-id/route.ts |
New synchronous-only route implementing AnalyzeID; correctly passes both front and optional back document pages via DocumentPages; mapTextractSdkError called with hasAsyncMode:false for appropriate error messages. |
| apps/sim/lib/api/contracts/tools/media/document-parse.ts |
Adds textractAnalyzeExpenseBodySchema and textractAnalyzeIdBodySchema with proper superRefine cross-field validation; new contracts follow the established pattern. |
| apps/sim/tools/textract/analyze-expense.ts |
New tool config; params visibility correctly uses user-only for credentials and hidden for file inputs; body builder handles sync and async paths consistently. |
| apps/sim/tools/textract/analyze-id.ts |
New tool config for textract_analyze_id; supports optional back-of-ID document; body builder validates that at least a front document is provided before sending. |
| apps/sim/tools/textract/types.ts |
Removes three dead interfaces and adds proper input/output types for the two new operations. |
Reviews (6): Last reviewed commit: "chore(textract): drop redundant inline c..." | Re-trigger Greptile
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
- textract_analyze_expense/textract_analyze_id now fall back to filePath/filePathBack when the document input is a URL string rather than an uploaded file object, so advanced "File reference" URL inputs actually reach the API (Cursor Bugbot)
- mapTextractSdkError defaults to 500 (not 400) when the AWS SDK error has no HTTP status, since that implies a server-side/network failure rather than a bad request (Greptile)
greptile-apps[bot] reacted with thumbs up emoji
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
- Front-document fields (fileUpload/fileReference) are shared across all 3 operations; gate them with a values-aware condition so switching to Analyze Identity Document keeps them visible even if a stale processingMode='async' is left over from a previous operation
- S3 URI field now also requires operation !== 'analyze_id', since that operation never supports S3 input
greptile-apps[bot] reacted with thumbs up emoji
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
pollTextractJob's merge callbacks spread only the latest page, dropping
any field (DocumentMetadata, model version) the first page had but a
follow-up NextToken page omits. Merge accumulated first so later pages
only override fields they actually return.
greptile-apps[bot] reacted with thumbs up emoji
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
…ch failures
fetchDocumentBytes hardcoded 400 for any non-OK response from a document
URL, masking transient 5xx failures from the document host as client
errors and blocking tool-execution retries. Use the actual response
status instead.
greptile-apps[bot] reacted with thumbs up emoji
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
cursor[bot] reacted with thumbs up emoji
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit dd92247. Configure here.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
greptile-apps[bot] reacted with thumbs up emoji
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
cursor[bot] reacted with thumbs up emoji
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit 55cb4eb. Configure here.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
This branch was previously deployed
1 inactive
deployment
Uh oh!
There was an error while loading. Please reload this page.
Assignees
No one assigned
Milestone
No milestone
Development
Successfully merging this pull request may close these issues.
Uh oh!
There was an error while loading. Please reload this page.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
|