Skip to content

fix(agiloft): align the integration with the documented ewws REST interface - #6556

Merged
waleedlatif1 merged 2 commits into
stagingfrom
validate/agiloft-api
Aug 11, 2026
Merged

fix(agiloft): align the integration with the documented ewws REST interface#6556
waleedlatif1 merged 2 commits into
stagingfrom
validate/agiloft-api

Conversation

@waleedlatif1

Copy link
Copy Markdown
Collaborator

Summary

  • Moved every Agiloft operation onto the EW* endpoint family and the documented EWREST_key='value'; response format. The CRUD tools were on /ewws/REST/{kb}/{table}/{id} with JSON bodies, guessing the response via data.result ?? data / id ?? ID — Agiloft documents that path as a URL convention only (no method table, no example, no response shape) and no known client uses it.
  • EWDelete now sends the deleteRule the docs require, defaulting to ERROR_IF_DEPENDANTS so a delete fails rather than cascading. It was previously sent with no rule at all.
  • EWRemoveAttachment uses GET — it does not accept DELETE.
  • EWSearch accepts the documented search saved-search label, making saved searches reachable for the first time; query is now optional with at least one of the two required.
  • Search query help taught AND/OR; Agiloft uses && and ||.
  • Added run_action_button (POST /ewws/async/EWActionButton) for approval and send-for-signature steps.
  • Dropped saved_search. EWSavedSearch has no doc page, so neither its URL nor its response could be verified — it could only ever return a silently empty list.
  • Added force on unlock, corrected lock status to LOCKED/NO_LOCK, filtered read fields locally since $fields is undocumented, and stopped reporting a fabricated page size of 25.

Type of Change

  • Bug fix

Testing

40 unit tests covering the EWREST parser (every fixture quoted verbatim from Agiloft's docs), the URL builders, and the create/remove-attachment routes. Reverted each fix once and confirmed the assertions go red. type-check, lint, integration-catalog:check, tool-metadata:check and check:api-validation all pass.

No live Agiloft instance was available, so this is validated against the published docs rather than exercised end to end. Two things worth a reviewer's eye: login credentials still travel in the EWLogin query string (documented that way, but the docs note they may go in the body), and EWTable / EWAsyncStatus remain uncovered because their doc pages 404 in the archive.

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)

@vercel

vercelBot commented Aug 11, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

ProjectDeploymentActionsUpdated (UTC)
docsReadyReadyPreviewAug 11, 2026 8:24pm

Request Review

@cursor

cursorBot commented Aug 11, 2026

Copy link
Copy Markdown

PR Summary

Medium Risk
Broad rewrite of how Agiloft CRUD/search calls are formed and parsed, so existing workflows may see different request shapes, delete behavior, and retired saved-search listing. Covered by unit tests against documented fixtures, but not live end-to-end.

Overview
Rewrites the Agiloft integration onto the documented EW* endpoints and EWREST_key='value'; response format, replacing the previous undocumented /ewws/REST JSON CRUD path.

Core protocol fixes

  • Adds an ewrest parser and rewires create/read/update/delete/search/select/choice-line handlers to parse EWREST bodies, treat plain-text HTTP 200 refusals as failures, and send field data as query-string pairs (with a URL length guard).
  • Corrects HTTP verbs (EWDelete/EWUpdate → POST, EWRemoveAttachment → GET) and requires a deleteRule on delete (default ERROR_IF_DEPENDANTS).

Feature changes

  • Adds Run Action Button (EWActionButton) for approval / send-for-signature style steps.
  • Search now accepts a saved-search label via search (query optional; at least one required) and documents &&/|| syntax.
  • Retires Saved Search listing (kept registered with a migration error so old blocks still resolve).
  • Adds force-unlock, filters read fields locally, and clarifies lock status as LOCKED/NO_LOCK.

Reviewed by Cursor Bugbot for commit 697568a. Configure here.

@greptile-apps

greptile-appsBot commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

The PR aligns the Agiloft integration with its documented EW endpoint and response conventions while preserving compatibility for persisted saved-search blocks.

  • Migrates CRUD, search, selection, locking, attachment, and choice-list operations to documented EW request and parsing behavior.
  • Adds saved-search filtering through EWSearch and introduces asynchronous action-button execution.
  • Retains the retired saved-search tool as a compatibility entry that returns actionable migration guidance.
  • Adds focused coverage for EWREST parsing, URL construction, protocol verbs, and refusal handling.

Confidence Score: 5/5

The PR appears safe to merge.

No blocking failure remains.

Important Files Changed

FilenameOverview
apps/sim/tools/agiloft/ewrest.tsAdds centralized parsing and normalization for documented EWREST assignment responses.
apps/sim/app/api/tools/agiloft/search_records/route.tsMigrates search handling to EWREST parsing and now rejects assignment-free refusal responses.
apps/sim/app/api/tools/agiloft/select_records/route.tsMigrates selection responses to EWREST record-ID parsing and rejects assignment-free refusals.
apps/sim/tools/agiloft/saved_search.tsPreserves persisted saved-search tool resolution through an intentional retirement response containing migration guidance.
apps/sim/app/api/tools/agiloft/run_action_button/route.tsIntroduces the documented asynchronous action-button operation and normalizes its callback response.
apps/sim/tools/agiloft/utils.tsUpdates Agiloft EW endpoint builders and request parameter encoding across integration operations.
apps/sim/blocks/blocks/agiloft.tsUpdates the Agiloft operation catalog, inputs, and compatibility access for persisted workflows.

Sequence Diagram

sequenceDiagram
participant W as Workflow
participant T as Agiloft Tool
participant R as Sim API Route
participant A as Agiloft EW Endpoint
W->>T: Execute configured operation
T->>R: Validated tool request
R->>A: EW request with encoded parameters
A-->>R: EWREST assignments or refusal text
R->>R: Parse and validate response shape
alt Valid EWREST result
R-->>T: success with normalized output
T-->>W: operation result
else Refusal or malformed response
R-->>T: failure with Agiloft response
T-->>W: failed workflow step
end
Loading

Reviews (2): Last reviewed commit: "fix(agiloft): fail loudly on non-EWREST ..." | Re-trigger Greptile

Comment threadapps/sim/app/api/tools/agiloft/search_records/route.ts Outdated
Comment threadapps/sim/tools/registry.ts
Comment threadapps/sim/tools/agiloft/utils.ts
Comment threadapps/sim/app/api/tools/agiloft/search_records/route.ts
…erface
The CRUD tools targeted /ewws/REST/{kb}/{table}/{id} with JSON bodies and
guessed at the response by probing `data.result ?? data` and `id ?? ID`.
Agiloft documents that path as a URL convention only -- no method table, no
example call, and no response shape -- and no known client uses it. The EW*
operation family is specified end to end, including exact response bodies, so
every operation now goes through it and parses the documented
`EWREST_key='value';` assignment format.
- EWCreate/EWRead/EWUpdate/EWDelete/EWSearch/EWSelect/EWGetChoiceLineId are
form-encoded and parsed via a shared EWREST parser; the /.json suffix is kept
only on EWAttachInfo, the one operation with a published JSON sample
- EWDelete now sends the deleteRule the docs require, defaulting to
ERROR_IF_DEPENDANTS so a delete fails rather than cascading
- EWRemoveAttachment uses GET; it does not accept DELETE
- EWSearch accepts the documented `search` saved-search label, so saved
searches are reachable for the first time
- Search query help taught AND/OR; Agiloft uses && and ||
- Add run_action_button (POST /ewws/async/EWActionButton) for approvals and
send-for-signature steps
- Drop saved_search: EWSavedSearch has no doc page, so neither its URL nor its
response could be verified and it could only ever return an empty list
- Add force on unlock, filter read fields locally since $fields is
undocumented, correct lock status to LOCKED/NO_LOCK, and stop reporting a
fabricated page size of 25
…ool resolvable
- EWSearch and EWSelect report an empty result set as `EWREST_id_length = '0';`,
so a body with no assignments at all is a refusal Agiloft returned with HTTP
200, not an empty result. Both routes now surface it as an error instead of a
successful empty list.
- Re-register agiloft_saved_search as a retired tool. Removing it outright left
workflows saved with operation='saved_search' deriving a tool id the registry
no longer provided, which throws "Tool not found" at execution. It now fails
through directExecution with a message pointing at the Search Records
operation's Saved Search field, without issuing an undocumented request. It
stays out of the operation dropdown so it cannot be chosen for new blocks.
- Guard EWCreate and EWUpdate against oversized record data. Those operations
carry field values in the query string, so a large payload hits the request
line limit; the tool now explains that rather than surfacing an opaque 414.
@waleedlatif1

Copy link
Copy Markdown
CollaboratorAuthor

@greptile

@waleedlatif1

Copy link
Copy Markdown
CollaboratorAuthor

@cursor review

@cursorcursorBot left a comment

Copy link
Copy Markdown

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 697568a. Configure here.

@waleedlatif1
waleedlatif1 merged commit 81e04a8 into stagingAug 11, 2026
22 of 23 checks passed
@waleedlatif1
waleedlatif1 deleted the validate/agiloft-api branch August 11, 2026 20:27
Sign up for freeto 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.

1 participant

@waleedlatif1