Skip to content

feat: template variables for Loop/Filter nodes, settings validation, secrets fix#195

Merged
chrisli30 merged 12 commits into
mainfrom
staging
Mar 19, 2026
Merged

feat: template variables for Loop/Filter nodes, settings validation, secrets fix#195
chrisli30 merged 12 commits into
mainfrom
staging

Conversation

@chrisli30

@chrisli30 chrisli30 commented Mar 13, 2026

Copy link
Copy Markdown
Member

Summary

  • fix: enforce inputVariables.settings validation in createWorkflow
  • fix: pass workflowId when cleaning up secrets
  • feat: support template variables in Loop/Filter inputVariable — rename proto field input_node_nameinput_variable, resolve via Goja JS VM (e.g., {{settings.address_list}})
  • feat: add iterationTimeout to LoopNode.Config — per-iteration timeout in seconds, required by server
  • fix: accept both graphqlQuery and graphqlDataQuery as loop runner type
  • chore: replace fake contract addresses with real USDC Sepolia in tests
  • chore: use LoopRunnerType enums in test templates

Validates that inputVariables.settings contains required `name` and
`runner` fields in toRequest(), matching the server-side validation
that was already in place. This catches misconfigured requests at the
SDK level before they reach the aggregator.
In toRequest(), extract contract addresses from event trigger
queries that have decimals method calls and merge them into
settings.tokens. This ensures the aggregator provides
tokenMetadata to context-memory for correct decimal formatting.
@chrisli30 chrisli30 changed the title staging fix: enforce inputVariables.settings validation in createWorkflo Mar 13, 2026
@chrisli30 chrisli30 changed the title fix: enforce inputVariables.settings validation in createWorkflo fix: enforce inputVariables.settings validation in createWorkflow Mar 13, 2026
Client should explicitly declare settings.tokens rather than having
the SDK silently extract them from trigger config. This keeps the
data flow transparent and predictable.
will-dz added 2 commits March 18, 2026 12:02
cleanupSecrets now passes workflowId/orgId from the list response when
deleting secrets. Added regression test for issue #772 verifying that
workflow-scoped secrets can be deleted without passing workflowId.
- Rename proto field input_node_name → input_variable (Loop + Filter)
- Add iteration_timeout field to LoopNode.Config (seconds, required)
- Update loop.ts and filter.ts models to use new proto fields
- Update all tests to use {{variable}} template syntax
- Replace fake contract addresses with real USDC Sepolia in tests
- Use LoopRunnerType enums in test templates
@chrisli30 chrisli30 requested a review from Copilot March 19, 2026 08:29

Copilot AI left a comment

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.

Pull request overview

This PR updates the SDK and test suite to align with new workflow/node input semantics by enforcing inputVariables.settings validation during workflow submission and migrating Loop/Filter nodes from inputNodeName to templated inputVariable (plus adding per-iteration timeout for loops).

Changes:

  • Enforce client-side validation that inputVariables.settings exists and includes non-empty name and runner before creating the gRPC CreateTask request.
  • Migrate Loop/Filter node configs to inputVariable template syntax and add iterationTimeout to Loop node config + protobuf/codegen.
  • Improve secret cleanup behavior in tests and add a regression test for deleting workflow-scoped secrets without providing workflowId.

Reviewed changes

Copilot reviewed 12 out of 13 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
tests/utils/utils.ts Updates secret cleanup to delete secrets directly (passing scope options when available).
tests/utils/templates/loopNode.ts Updates Loop node templates to use inputVariable, iterationTimeout, and enum runner types.
tests/nodes/loopNode.test.ts Migrates Loop node tests to inputVariable + iterationTimeout, updates expectations and timings.
tests/nodes/filterNode.test.ts Migrates Filter node tests to inputVariable.
tests/core/secret.test.ts Adds regression coverage for workflow-scoped secret deletion without workflowId.
packages/sdk-js/src/models/workflow.ts Adds validation for required inputVariables.settings fields before serialization.
packages/sdk-js/src/models/node/loop.ts Writes inputVariable and iterationTimeout into Loop protobuf config.
packages/sdk-js/src/models/node/filter.ts Writes inputVariable into Filter protobuf config.
grpc_codegen/avs_pb.js Updates generated JS for renamed fields and new loop iteration timeout.
grpc_codegen/avs_pb.d.ts Updates generated TS declarations for renamed fields and new loop iteration timeout.
grpc_codegen/avs.proto Renames Filter/Loop input field to input_variable and adds iteration_timeout.
.claude/settings.json Adds Claude tool permission configuration.
.claude/commands/create-pr-review.md Updates internal PR-review automation instructions.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

Comment on lines +235 to 238
const inputVarsMap = request.getInputVariablesMap();
for (const [key, value] of Object.entries(this.inputVariables)) {
inputVarsMap.set(key, convertJSValueToProtobuf(value));
}
iterKey: "index",
runner: {
type: "graphqlQuery",
type: LoopRunnerType.GraphQLQuery,
config.setExecutionMode(executionMode);

// Set per-iteration timeout (seconds, required by server)
config.setIterationTimeout(data.iterationTimeout);
@chrisli30 chrisli30 changed the title fix: enforce inputVariables.settings validation in createWorkflow feat: template variables for Loop/Filter nodes, settings validation, secrets fix Mar 19, 2026
will-dz added 2 commits March 19, 2026 02:00
Releases:
  @avaprotocol/sdk-js@2.14.0

[skip ci]
@chrisli30 chrisli30 merged commit ae191bd into main Mar 19, 2026
3 checks passed
@chrisli30 chrisli30 requested a review from Copilot March 20, 2026 03:18

Copilot AI left a comment

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.

Pull request overview

Updates the SDK/proto and tests to support template-variable addressing for Loop/Filter node inputs, add per-iteration timeouts for Loop nodes, and tighten workflow/settings + secret cleanup behavior.

Changes:

  • Replace input_node_name with input_variable for Loop/Filter nodes (template variable resolution) and update SDK + tests accordingly.
  • Add iteration_timeout to LoopNode.Config and thread it through proto codegen + SDK + tests.
  • Enforce inputVariables.settings validation in Workflow.toRequest() and improve secrets cleanup + add regression coverage for workflow-scoped secret deletion.

Reviewed changes

Copilot reviewed 21 out of 22 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
tests/workflows/createWorkflow.test.ts Formatting tweaks to assertions/calls.
tests/utils/utils.ts Update secrets cleanup to pass workflow/org scope when deleting secrets.
tests/utils/templates/loopNode.ts Update Loop node templates to use inputVariable, iterationTimeout, and LoopRunnerType enums.
tests/triggers/manual.test.ts Formatting + minor cleanup (remove unused import).
tests/templates/telegram-alert-on-transfer.test.ts Minor whitespace/comment change inside the template node source section.
tests/nodes/loopNode.test.ts Migrate tests to inputVariable + add iterationTimeout; update addresses and timeouts.
tests/nodes/filterNode.test.ts Migrate tests to inputVariable for Filter node config.
tests/core/secret.test.ts Add regression test for deleting workflow-scoped secret without workflowId.
packages/sdk-js/src/models/workflow.ts Add inputVariables.settings validation before building CreateTask request.
packages/sdk-js/src/models/trigger/event.ts Formatting (commas) and remove unused import.
packages/sdk-js/src/models/node/loop.ts Switch Loop config to inputVariable, set iterationTimeout, accept both graphqlQuery and graphqlDataQuery.
packages/sdk-js/src/models/node/interface.ts Import/format cleanup and minor utility signature formatting.
packages/sdk-js/src/models/node/filter.ts Switch Filter config to inputVariable.
packages/sdk-js/src/models/edge.ts Remove unused import.
packages/sdk-js/src/index.ts Formatting-only adjustments (commas/params).
packages/sdk-js/package.json Bump SDK version to 2.14.0.
packages/sdk-js/CHANGELOG.md Add 2.14.0 changelog entry.
grpc_codegen/avs_pb.js Update generated JS for renamed fields + new Loop iteration timeout field.
grpc_codegen/avs_pb.d.ts Update generated TS types for renamed fields + new Loop iteration timeout field.
grpc_codegen/avs.proto Rename Loop/Filter input field to input_variable; add iteration_timeout; update a few comments.
.claude/settings.json Add Claude permissions config.
.claude/commands/create-pr-review.md Update internal PR review automation instructions.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +139 to +141
// reject the request if it is 0 or missing. No default is applied here —
// the caller must explicitly provide iterationTimeout in their node config.
config.setIterationTimeout(data.iterationTimeout);

Copilot AI Mar 20, 2026

Copy link

Choose a reason for hiding this comment

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

config.setIterationTimeout(data.iterationTimeout) will throw at runtime if iterationTimeout is omitted (e.g., JS callers) and also allows sending 0, which the comment says the server rejects. Add explicit validation here (e.g., ensure it’s a positive integer) and/or apply a default (like 30) before calling the protobuf setter so SDK behavior is predictable and doesn’t crash.

Suggested change
// reject the request if it is 0 or missing. No default is applied here —
// the caller must explicitly provide iterationTimeout in their node config.
config.setIterationTimeout(data.iterationTimeout);
// reject the request if it is 0 or missing.
//
// To avoid runtime errors when iterationTimeout is omitted (e.g., from JS callers)
// and to ensure we never send 0, validate the value and apply a default.
let iterationTimeout = data.iterationTimeout;
if (
!Number.isInteger(iterationTimeout) ||
iterationTimeout <= 0
) {
// Fallback default in seconds for predictable SDK behavior.
iterationTimeout = 30;
}
config.setIterationTimeout(iterationTimeout);

Copilot uses AI. Check for mistakes.
Comment thread grpc_codegen/avs.proto
// Note: ContractWrite operations always run sequentially regardless of this setting
ExecutionMode execution_mode = 4;
// Per-iteration timeout in seconds. If an iteration does not complete within
// this duration, it is marked as failed. Default: 30 seconds.

Copilot AI Mar 20, 2026

Copy link

Choose a reason for hiding this comment

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

The proto comment says iteration_timeout has a default of 30 seconds, but the SDK implementation/comment (LoopNode.toRequest) states the server rejects when this field is 0 or missing and that no default is applied. Please reconcile these so the contract is unambiguous (either document that it’s required/no default, or update server/SDK to truly default to 30).

Suggested change
// this duration, it is marked as failed. Default: 30 seconds.
// this duration, it is marked as failed.
// This field is required and must be a positive value; the server rejects
// requests where this field is missing or set to 0. No default is applied.

Copilot uses AI. Check for mistakes.
lang: Lang.JavaScript,

// eslint-disable-next-line max-len

Copilot AI Mar 20, 2026

Copy link

Choose a reason for hiding this comment

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

There’s trailing whitespace on this otherwise blank line, which creates unnecessary diff noise. Consider removing the extra spaces (or restoring a meaningful comment) to keep the template source block clean.

Suggested change

Copilot uses AI. Check for mistakes.
Sign up for free to 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.

4 participants