Commit Graph

6005 Commits

Author SHA1 Message Date
Viren Baraiya ba0afb3a11 feat(files): enforce workflow-scoped transfers (#1355) 2026-07-20 00:04:58 -07:00
Viren Baraiya 3ea601884d Enhances A2A/AgentSpan execution (#1356) 2026-07-20 00:04:20 -07:00
Shailesh Padave 92d1aec166 feat(a2a): backward compat with A2A v0.2 clients (tasks/send, /rpc alias) (#1341) 2026-07-19 11:09:08 -07:00
Kowser c08d60c8a4 fix(scheduler): return 404 from GET /schedules/{name} when the schedule does not exist (#1357)
Co-authored-by: Kowser <kowser.orkes@gmail.com>
2026-07-19 09:56:18 -07:00
Viren Baraiya 86b58855d5 fixes (#1354) 2026-07-17 22:12:52 -07:00
Naomi Most c8e63df574 feat(rest): add task signal endpoints (#1205)
* feat(rest): add task signal endpoints

Adds the task signal endpoints the Go SDK / CLI already call but OSS never
implemented (conductor-oss/conductor#1197):

  POST /api/tasks/{workflowId}/{status}/signal        (async)
  POST /api/tasks/{workflowId}/{status}/signal/sync   (sync, returns SignalResponse)

Before this, the SDK's SignalAsync hit POST /tasks/{wfId}/{status}/signal, which
had no matching route, so Spring fell through to the all-variable update route
/{workflowId}/{taskRefName}/{status} and tried to coerce the literal "signal"
into TaskResult.Status -> MethodArgumentTypeMismatchException. Adding the literal
/signal segment makes that pattern more specific, so it now wins; a MockMvc
routing test (with PathPatternParser, mirroring production) locks this in.

"Signal" finds the first non-terminal WAIT task in the workflow (descending into
running sub-workflows) and applies the given status + output to it, via the new
TaskService.signalTask. The sync variant then waits for the workflow to settle
into its next blocking/terminal state and renders a SignalResponse per the
returnStrategy, reusing the same poll-to-response logic as executeWorkflow --
extracted into WorkflowSignalResponder so both controllers share it.

Tests: TaskServiceTest (signalTask found / not-found), TaskResourceTest (async,
sync, not-found, route resolution). Full conductor-rest suite green.

* fix(signal): add signalTimeout field and E2E Groovy integration tests

Two issues raised in PR #1205 review:

1. `SignalResponse` was missing the `signalTimeout` boolean that Orkes sets
   when the sync-signal poll times out. Without it a timed-out response looks
   identical to a successful one. Added `signalTimeout` to `SignalResponse`
   (absorbed by `WorkflowRun` and `TaskRun` via inheritance), propagated it
   through `NotificationResult.toResponse()`, and set it to `true` in
   `WorkflowSignalResponder`'s timeout fallback path.

2. Added `SignalTaskSpec` to the test-harness — a Spring Boot integration test
   backed by a real Redis testcontainer that exercises `TaskService.signalTask()`
   without any mocking: direct-WAIT-task signal, signal-with-no-blocker,
   signal-on-nonexistent-workflow, and sub-workflow descent.

* test(signal): remove mocked signal tests — covered by SignalTaskSpec E2E

* fix(test): SignalTaskSpec — expect NotFoundException for missing workflow

ExecutionDAOFacade.getWorkflow() throws NotFoundException for unknown IDs
(does not return null). The test was asserting null — corrected to thrown().

The e2e WorkflowRerunTests failure in the same CI run is pre-existing and
unrelated to signal changes (it was already failing on the prior commit).

* test(e2e): HTTP-level signal endpoint tests (async + sync)

* fix: spotless formatting violations in SignalTaskTest
2026-07-17 16:29:17 -07:00
Dale Brady f490ced7e4 Merge pull request #1348 from conductor-oss/fix/ui-next-bughunt
fix(ui-next): batch of UI bug fixes (status humanize, counters, queue wait, ref-name trim, diff editor, name validation)
v3.32.0-rc.13
2026-07-17 16:47:32 -04:00
Dale Brady aba51de8db Merge branch 'main' into fix/ui-next-bughunt 2026-07-17 16:33:01 -04:00
bradyyie 131c16f656 fix(ui-next): reject workflow names with slash or percent
Workflow names containing '/' or '%' were accepted by the name validator
but could never be reopened: the name is carried as a path segment
(/workflowDef/{name} and GET /metadata/workflow/{name}), and the
percent-encoded %2F / %25 is rejected by the server's path handling (400),
leaving the definition saved but unreachable with only a broken editor
shell.

Drop '%' from WORKFLOW_NAME_REGEX ('/' was already excluded) so both
unreachable characters fail client-side validation at edit time with the
standard name-error message, instead of persisting an unopenable
definition.

Fixes orkes-io/conductor-ui#4241
2026-07-17 16:27:11 -04:00
bradyyie 619cabdc42 fix(ui-next): prevent 'TextModel got disposed' from the diff editor
When a confirm-save flow closes (e.g. after the backend rejects a task-def
save), the diff editor unmounts and Monaco disposes its text models while
the DiffEditorWidget still references them, throwing an uncaught
'TextModel got disposed before DiffEditorWidget model got reset'.

Set keepCurrentOriginalModel/keepCurrentModifiedModel on the shared
DiffEditor so the models are not disposed on unmount. Applies to every
confirm-save diff view (task def, workflow def, event handler, scheduler).

Fixes orkes-io/conductor-ui#4250
2026-07-17 16:23:48 -04:00
bradyyie f41ff1ed7b fix(ui-next): trim reference names when detecting duplicate task refs
A leading or trailing space in a task reference name bypassed the
duplicate-name check: the graph compared raw node ids, so " wait_ref"
and "wait_ref" were treated as distinct and Save proceeded, persisting a
ref name that looks identical in the field but silently breaks
${ref.output} references and JOINs.

Compare reference names trimmed of surrounding whitespace so
whitespace-only variants are detected as duplicates.

Fixes orkes-io/conductor-ui#4248
2026-07-17 16:22:14 -04:00
bradyyie 7009e8a2e7 fix(ui-next): singularize result counters ('1 result')
Result counters were hard-coded to '${n} results', so a table or search
with exactly one row read '1 results'. Add a pluralizeResults() helper
that singularizes the noun, use it in createTableTitle (shared by the
Environment Variables, Workflow/Task Definition, and Task List tables)
and in the Workflow/Task/Agent search headers and Add-task sidebar.

Fixes orkes-io/conductor-ui#4246
2026-07-17 16:20:32 -04:00
bradyyie 5efa4c77a6 fix(ui-next): format task Summary 'Queue wait time' with a unit, clamp negatives
Queue wait time (startTime - scheduledTime) was passed through raw, so it
rendered as a unitless signed integer and could show a negative value
(e.g. -6) from sub-millisecond clock skew, directly under the properly
formatted Duration row.

Clamp to >= 0 and render via durationRenderer so it reads consistently
with Duration (e.g. '0ms'). Also guard on _isFinite so an explicit 0 is
still shown.

Fixes orkes-io/conductor-ui#4245
2026-07-17 16:17:57 -04:00
bradyyie 7d8e30535b fix(ui-next): humanize multi-word status enums
Multi-word task/workflow statuses rendered as raw enums with only the
first letter capitalized and the underscore kept (e.g. 'In_progress',
'Timed_out') because the status badges lowercased the value then applied
lodash capitalize, which neither replaces underscores nor title-cases
each word.

Add a humanizeStatus() helper that splits on underscores and title-cases
each word, and use it in StatusBadge, WorkflowStatusBadge, and
StatusTagChip. Single-word statuses are unchanged.

Fixes orkes-io/conductor-ui#4240
2026-07-17 16:15:37 -04:00
Andrew Lai (AJ) f4e5d5bdd3 Various bug fixes (#1343)
* https://github.com/orkes-io/conductor-ui/issues/4234

* https://github.com/orkes-io/conductor-ui/issues/4235

* https://github.com/orkes-io/conductor-ui/issues/4236

* https://github.com/orkes-io/conductor-ui/issues/4239

* https://github.com/orkes-io/conductor-ui/issues/4292

* https://github.com/orkes-io/conductor-ui/issues/4243

* https://github.com/orkes-io/conductor-ui/issues/4233

* Change notFound type to be final like noAccess
2026-07-17 13:13:46 -07:00
Viren Baraiya 80156f58ff Task cancel contract (#1342) v3.32.0-rc.12 2026-07-17 12:27:07 -07:00
Naomi Most 4abc877d6d fix(ui-next): Don't run playwright in Build UI CI (#1346) 2026-07-17 12:10:20 -07:00
Dale Brady 8fc4df0470 Merge pull request #1338 from conductor-oss/agent_task
Support for agent task and other UI fixes
v3.32.0-rc.11
2026-07-17 11:44:13 -04:00
bradyyie 57903d3282 ci: add update-snapshots workflow (comment /update-snapshots or manual dispatch) to regenerate ui-next baselines
On a PR comment of exactly "/update-snapshots" (once on default branch)
or via manual workflow_dispatch against any branch, regenerates the
Playwright reference snapshots in the same pinned image the e2e-mocked
check uses (docker-compose.snapshots.yml) and commits them back to the
branch. The workflow_dispatch path is the fallback while this file has
not yet merged to main (issue_comment workflows only run from default).
2026-07-17 10:40:38 -04:00
bradyyie 6958bc9d68 test(e2e): widen WorkflowRestartTests restart-await windows to de-flake
The post-restart state-transition assertions used tight atMost(5s)/(10s)
awaitility windows that flake under CI load (expected SCHEDULED but was
IN_PROGRESS; sub-workflow id still null). Widen the sub-workflow-id waits
to 20s and the terminal/restart-state waits to 15s, and add a poll
interval to the block that lacked one. Behavior-preserving.
2026-07-17 10:39:20 -04:00
bradyyie 11d57beb9f test(e2e): gate LLM-dependent AgentTaskTests behind OPENAI_API_KEY
The five AgentTaskTests that assert a successful LLM completion
(helloWorld, longRunning, agentClientStartsWaitsResponds,
twoAgentConversation, concurrentCalls) ran unconditionally against a CI
server with no LLM integration configured, so agents returned blank /
FAILED. Mirror LLMChatCompleteTests by gating them behind OPENAI_API_KEY
so they skip in a keyless CI and run when a key is present. Also:
- fix the model default case (openai -> OpenAI) so it resolves against a
  case-sensitively-registered integration when a key is supplied;
- relax the longRunning callback upper bound 8s -> 10s (CI-load flake).
The seven negative-path tests (FAILED/CANCELED/TIMED_OUT/NotFound) are
left ungated - they need no successful LLM and already pass.
2026-07-17 10:39:20 -04:00
bradyyie b1de6ce1a5 test(ui-next): drop /private/tmp debug screenshots (ENOENT on Linux CI)
The two page.screenshot({path:"/private/tmp/..."}) calls in the agent
metadata spec are debug dumps to a macOS-only path; on the Linux CI
runner /private/tmp does not exist, so the test throws ENOENT after its
real assertions have already passed. Remove them.
2026-07-17 10:39:20 -04:00
Viren Baraiya a49990eb85 more fixes 2026-07-17 01:26:40 -07:00
Viren Baraiya c85fa0fb4f support for agent task and other UI fixes 2026-07-17 00:24:44 -07:00
Dale Brady 1f97ea072c Merge pull request #1329 from conductor-oss/fix/agent-execution-terminal-failed-status
fix(ui-next): agent execution renders terminal-failed tasks as running
2026-07-16 18:49:59 -04:00
bradyyie 07a2c5c4ef fix(ui-next): agent execution shows terminal-failed tasks as running
The AgentExecution status mappers only special-cased the literal "FAILED"
task status. Conductor emits several terminal-failure statuses
(FAILED_WITH_TERMINAL_ERROR, TIMED_OUT, CANCELED); these fell through the
mapTaskStatus/taskSuccess default to RUNNING/undefined, so a failed agent
LLM task rendered a perpetual "running" chip + spinner while the
workflow itself was already FAILED.

- mapTaskStatus: map all terminal-failure statuses to FAILED, restrict
  RUNNING to genuinely-active statuses (IN_PROGRESS/SCHEDULED/PENDING),
  and default unknown statuses to FAILED so no unmapped status can
  render a perpetual spinner again.
- taskSuccess: same terminal-vs-active classification; only active
  statuses return undefined (spinner), everything else terminal.
- Extract isFailedTaskStatus() and use it at the three remaining
  status === "FAILED" tool/iteration sites.
- Add agentExecutionUtils unit tests covering every status.

Fixes orkes-io/conductor-ui#4260
2026-07-16 18:31:40 -04:00
Viren Baraiya c2439b7e6b fixes (#1306) v3.31.2 v3.32.0-rc.10 2026-07-16 08:43:09 -07:00
Viren Baraiya 0110401072 Resolve #1286: Support conductor agents in the AGENT tasks (#1288) v3.32.0-rc.9 2026-07-15 15:50:17 -07:00
Andrew Lai (AJ) 2cd84cb2fa LLM Task in workflow definition with both topP and temperature errors for claude and should be null if not defined (#1290)
LLM Task in workflow definition with both topP and temperature errors for claude and should be null if not defined

* Check clearEmptyNumberAsNull first
v3.32.0-rc.8
2026-07-14 21:38:14 -07:00
adonthi-fws 4ca9d812ab prometheus metrics for http webhook publishers (#1149)
* prometheus metrics for http webhook publisheres

* code review requested changes

* style: apply spotless formatting to TaskStatusPublisher

* test coverage for webhook publish metrics

* style: apply spotless formatting to TaskStatusPublisherTest

---------

Co-authored-by: Naomi Most <naomi.most@orkes.io>
2026-07-14 18:01:26 -07:00
Viren Baraiya 986fd89968 show worker polls (#1287)
* Fix worker poll UI
* Show CLI in code dialog
* Fix UX for code dialog
2026-07-14 00:15:29 -07:00
Andrew Lai (AJ) 2cbf7ce393 Revert the Scheduler Executions schedule-name dropdown back to using the list as the backend has not been updated yet (#1285) 2026-07-13 14:45:31 -07:00
Andrew Lai (AJ) 23c1b55fe5 Migrate scheduler to search API and self-contained clone dialog (#1276) v3.32.0-rc.7 2026-07-13 13:22:17 -07:00
Andrew Lai (AJ) 347247d1d3 https://orkes.atlassian.net/browse/CCOR-13224 Show total attempt account in the task card (#1282) 2026-07-13 13:15:39 -07:00
Viren Baraiya 694be9ee4d Fix/add condition (#1283)
* Register AgentEventListener only when agentspan.embedded=true

* Revert unit-test sharding/--parallel in CI (slower and unstable on shared runners)
2026-07-13 12:38:49 -07:00
Viren Baraiya 182d0d966b Add Agentspan and Agentic Workflows to Conductor 2026-07-13 11:55:29 -07:00
Viren Baraiya 978c47a9f0 Move SecretsDAO to org.conductoross package and simplify agentspan integration
Relocates SecretsDAO out of the legacy com.netflix.conductor.dao package,
adapts SkillMetadataDAO implementations accordingly, and removes the
AgentSpan embedded environment post-processor, principal filter, and
env-backed credential store in favor of a simpler configuration wired
directly through application.properties (agentspan.embedded).
2026-07-12 22:53:15 -07:00
Viren Baraiya e3b117514a Update LLMHelper.java 2026-07-11 22:30:23 -07:00
Nicholas Cole 813bea2bc2 Merge pull request #1259 from conductor-oss/feature/fix_lock_contention_wait_issue
fix(sweeper): re-queue on lock miss to eliminate multi-minute workflow pauses
2026-07-10 11:02:00 -07:00
nicholascole 28891001f5 revert(sweeper): drop unneeded WorkflowSweeper lock-miss re-queue
The decide(String) re-queue on a lock miss is sufficient to fix the
multi-minute JOIN-boundary pause: the existing due-based sweeper picks
up the short-backoff entry once the lock frees, and decide() invoked
from the sweeper is reentrant (sweep() already holds the lock) so it
never hits the lock-miss branch anyway. The re-queue only ever fires
from the completion-event callers (updateTask, AsyncSystemTaskExecutor)
- exactly the path that was losing the wake-up.

Verified end-to-end: DynamicForkJoinLockContentionSpec passes with the
decide() fix and WorkflowSweeper reverted to its pre-PR form.

Revert WorkflowSweeper.java and WorkflowSweeperTest.java to main; update
the design doc accordingly.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-10 10:14:24 -07:00
nicholascole 6732028154 Merge branch 'main' into feature/fix_lock_contention_wait_issue 2026-07-10 09:51:41 -07:00
nicholascole 28b09728e6 Push up design 2026-07-10 09:46:57 -07:00
nicholascole 42775d4fb7 Push up design 2026-07-10 09:28:42 -07:00
nicholascole bb5c3da2a1 fix(executor): re-queue on lock miss in decide() to eliminate multi-minute pause
Moves the fix to the correct layer per review feedback (thanks @manan164).

The lost wake-up is decide() returning null on a workflow-lock miss: the
completion-event callers (updateTask, AsyncSystemTaskExecutor) ignore that
null, so the next task is never scheduled and the workflow parks on its
decider-queue entry — which a polled task postpones out to
responseTimeoutSeconds (e.g. 600s), the observed pause. The previous
sweeper-only change could not help this: the sweeper's sweep() runs only when
the decider entry is popped, and that entry isn't due for responseTimeoutSeconds.

- WorkflowExecutorOps.decide(String): on a lock miss, re-queue the workflow to
  DECIDER_QUEUE with a lockTimeToTry/2 backoff (contention-scale, not the
  lockLeaseTime scale used for orphaned locks) before returning null. This is
  the primary fix and benefits every caller (completion events + sweeper).
- WorkflowSweeper.sweep(): keep the top-level lock-miss re-queue as a backstop
  but at the same short backoff; drop the redundant decide()==null re-queue
  (decide() now owns it); remove the lockLeaseTime-based helper.

Tests:
- TestWorkflowExecutor.testDecideReQueuesWorkflowOnLockMiss: decide() lock miss
  pushes to DECIDER_QUEUE with the short backoff and returns null (fails against
  the old bare return).
- DynamicForkJoinLockContentionSpec: rewritten as a true reproduction — drive a
  real dynamic fork/join to the JOIN boundary, hold the workflow lock from a
  foreign thread, run the JOIN (post-completion decide misses the lock), then
  release the lock and assert the workflow recovers on its own within seconds via
  the real background sweeper (no manual sweep, no manufactured queue state).
  Fails (times out) without the decide() fix; the no-contention control passes in
  both. Verified: with the fix reverted, both the unit test and this spec fail.
- Scrubbed customer identifiers from tests; dropped the three legacy
  (deprecated, off-by-default) TestWorkflowSweeper cases.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-10 09:15:12 -07:00
Viren Baraiya 21d1ff9f5a ignore getExecutionMetadataIfHasData when serializing to JSON 2026-07-10 08:43:31 -07:00
Viren Baraiya 1ba351c544 Merge branch 'main' into feature/fix_lock_contention_wait_issue 2026-07-09 21:09:09 -07:00
Miguel Prieto 411a800f2f Secrets & environment: workflow references (${workflow.secrets/env}) + task-declared runtimeMetadata (#1251)
Env-backed secrets & environment + task-declared runtimeMetadata (#1251)                                                                                                                        
                                                                                                                                                                                              
- Resolve ${workflow.secrets.X} / ${workflow.env.X} from CONDUCTOR_SECRET_* / CONDUCTOR_ENV_* env vars (secrets deferred, never persisted).                                                     
- Inject task-declared secret/env values onto polled tasks via TaskDef.runtimeMetadata (wire-only).                                                                                             
- Read-only GET /api/environment and /api/secrets. Part of #1152.
v3.32.0-rc.5
2026-07-10 00:48:23 -03:00
Aarish Alam 1370f450ca feat: add LiteLLM as AI gateway provider (#1249) 2026-07-09 20:24:19 -07:00
ling-senpeng13 06c44ee4ff fix(ai): attach user media for Cohere (vision) requests (#1246) 2026-07-09 20:23:20 -07:00
ling-senpeng13 c19c1fdbc2 fix(ai): migrate HuggingFace to OpenAI-compatible router (chat + multimodal) (#1245) 2026-07-09 20:22:09 -07:00