* fix: propagate CANCELED instead of FAILED from JOIN when a forked branch is canceled
* test: cover permissive fork join sub workflows terminated by the user in the test harness
---------
Co-authored-by: Naomi Most <naomi.most@orkes.io>
* - Add end to end integration tests
- Update playwright so it can get OPENAI_API_KEY from .env.local
* Bump coverage percentage to 90% to test CI before merging in additional tests
* Update workflow to use coverage report script
* Add tests and remove kitchen
* - Delete orphaned components
- Cleanup local coverage runs
* Make test less flaky
* Run integration tests in docker for consistent snapshots
* Show incompletion reasons
---------
Co-authored-by: Dale Brady <49766562+bradyyie@users.noreply.github.com>
- Extract shared buildContextInjectionTask/injectContextIntoUserMessage on
AgentCompiler and reuse across both compilers (3 duplicated sites); the
swarm loop now honors the configured context size limits instead of
hardcoded defaults, and the user-message rewrite uses a ListIterator
instead of index bookkeeping.
- Extract parentHandsOffOnToolOf predicate for the swarm turn-skip check.
- Join: move the agent output-shaping explanation onto prepareAgentOutput's
javadoc and return unmodifiable maps for the constructed shapes
(LinkedHashMap kept over Map.of — tool outputs may contain nulls; the
pass-through branch stays live to preserve default JOIN behavior).
agentspan:
- Only suppress an agent's post-tool-call turn when a parent on_tool_result
handoff actually watches a tool that agent owns, instead of suppressing it
for every sub-agent in the swarm whenever any handoff targets any tool.
Otherwise a sub-agent's own tool result was never summarized in words
because its loop ended before the LLM saw the output.
- Add a ctx_inject task to the resumed per-turn loop so a turn that does
keep looping (per the above fix) can see prior state/tool-results instead
of just the bare prompt, mirroring AgentCompiler's existing wiring.
ui-next:
- Guard AgentExecutionDiagram's response sublabel against undefined text so
a tool-call-only turn renders an empty sublabel instead of the literal
string "undefined".
- In agentExecutionUtils, render handoffs (explicit transfer, condition-based
via handoff_check, or HANDOFF-strategy routing) for real sub-agent turns,
which previously showed nothing between agents handing off work.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The End Time column on the executions and task search pages is marked
sortable, and the date-range picker emits `endTime>`/`endTime<` clauses.
`end_time` was never a column on workflow_index or task_index, so the
query builders snake_cased the field, failed to match it against
VALID_FIELDS, and dropped it -- from the ORDER BY via getSort() and from
the WHERE via Condition.isValid(). Sorting by End Time returned an
unordered page and lost the default `startTime:DESC`; filtering by an
End Time range silently returned unfiltered results.
Add end_time to both index tables on sqlite and postgres, index it,
populate it from the summary on write, and add it to the allow-list.
The millis-to-UTC conversion applied to filter values keys off the
`_time` suffix, so the date range needs no further change.
The column is NOT NULL defaulting to the epoch rather than nullable.
End time is absent until an execution is terminal, and SQLite sorts
NULL lowest while Postgres sorts it highest, so a nullable column would
put still-running executions at opposite ends of an endTime:DESC page
depending on the backend. getSort() emits a bare
`attribute + " " + order` with no room for a NULLS clause, so the
sentinel is what keeps the two engines agreeing: unfinished rows carry
the epoch and sort last on DESC, first on ASC, on both. This follows the
update_time sentinel already in V1 and V13.1.
end_time is added to the ON CONFLICT update clause as well as the
insert, since the row already exists by the time a workflow finishes.
Existing rows are back-filled from json_data, which already holds the
instant as an ISO-8601 string. Terminal executions are never re-indexed,
so without a back-fill every historical execution would sort as
unfinished forever.
Both back-fills are written to survive a malformed value rather than
abort. Sqlite's strftime() returns NULL on one and COALESCE keeps the
epoch. Postgres needs more care than V13.2 took: to_timestamp with a
fixed 'YYYY-MM-DD"T"HH24:MI:SS.MS' raises `invalid value "Z" for "MS"`
on an endTime with no milliseconds, and since applyDataMigrations
defaults to true that would abort the migration and stop the server
booting. V18.1 uses a ::timestamptz cast, which accepts any ISO-8601
form and reads the trailing Z as UTC, behind a regex guard so a
non-timestamp value skips the row instead of failing the statement.
Verified on a 3913-workflow / 45531-task sqlite database: all 3822
finished workflows match json_data exactly with 0 mismatches, the 91
unfinished rows keep the epoch, and `ORDER BY end_time DESC` plans as
`SCAN workflow_index USING INDEX workflow_index_end_time_idx`. On
postgres, V18 then V18.1 against seeded data converts values with and
without milliseconds and with offsets, and leaves empty, malformed and
absent endTimes at the epoch.
No UI change: only `workflowType` was ever remapped on the way out, so
`endTime` already reached the server unchanged.
* Create workflow to run enterprise integration tests against OSS branch changes on creation of pull request
* Add to documentation
* Use status context to get status of playwright tests
* Update OSS token
* Trigger CI pipeline
* Revert "Pin agent quickstarts to latest installable SDK releases (#1432)"
This reverts commit 955601f9f1.
* Remove redundant install
* Fix version to 6.0.0
- TODO should be variable
* Remove strict version
---------
Co-authored-by: Kowser <kowser.orkes@gmail.com>
Replaces window.location.href redirect with window.open() so Swagger UI opens
in a new tab rather than replacing the current window. Also calls navigate()
to leave the /api-reference route immediately, eliminating the stuck spinner
that appeared when the user hit browser back.
Fixes#1316
Keys read from environment variables (e.g. via export KEY=$(cat keyfile) or
.env parsers) can carry a trailing newline, producing a cryptic Java HTTP
client error: "Unexpected char 0x0a in Authorization value".
AgentspanAIModelProvider.getSystemEnv() now strips surrounding whitespace
from System.getenv() results. A new package-private readRawEnv() hook makes
the trimming testable without PowerMock; existing tests that override
getSystemEnv() are unaffected.
The direct System.getenv() call inside getModel() is also routed through
getSystemEnv() for consistency.