Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
97 changes: 95 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,48 @@ on:
branches: [main]
pull_request:
branches: [main]
workflow_dispatch:
inputs:
ref:
description: Immutable release commit to verify (full 40-character SHA)
required: true
type: string
retain-artifacts:
description: Retain the tarballs tested by the complete CI matrix
default: true
type: boolean
workflow_call:
inputs:
ref:
description: Immutable release commit to verify
required: true
type: string
retain-artifacts:
default: false
type: boolean
outputs:
manifest-sha256:
description: Hash of the retained manifest verified after the entire CI matrix
value: ${{ jobs.release-artifacts.outputs.manifest-sha256 }}

permissions:
contents: read

jobs:
validate-ref:
runs-on: ubuntu-latest
steps:
- name: Require an immutable commit when a ref is supplied
env:
REQUESTED_REF: ${{ inputs.ref }}
run: |
if [[ -n "$REQUESTED_REF" && ! "$REQUESTED_REF" =~ ^[a-f0-9]{40}$ ]]; then
echo "The requested ref must be a full 40-character commit SHA."
exit 1
fi

lint-and-test:
needs: validate-ref
runs-on: ubuntu-latest
strategy:
matrix:
Expand Down Expand Up @@ -48,6 +87,14 @@ jobs:

steps:
- uses: actions/checkout@v4
with:
ref: ${{ inputs.ref || github.sha }}

- name: Confirm the requested source commit
if: inputs.ref != ''
env:
REQUESTED_REF: ${{ inputs.ref }}
run: test "$(git rev-parse HEAD)" = "$REQUESTED_REF"

- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4
Expand Down Expand Up @@ -76,16 +123,29 @@ jobs:
run: npx biome ci .

- name: Verify release metadata
run: node --test scripts/release-lock.test.mjs scripts/cjs-declarations.test.mjs
run: node --test scripts/release-lock.test.mjs scripts/cjs-declarations.test.mjs scripts/release-artifacts.test.mjs

- name: Run tests, including Redis delivery and MongoDB crash recovery
run: npx vitest run
run: npx vitest run --maxWorkers=2
env:
AGENTIUM_REDIS_TEST: "1"
AGENTIUM_DURABLE_MONGO_TEST: "1"
AGENTIUM_COST_POSTGRES_TEST_URL: "postgresql://agentium_test:agentium_test@127.0.0.1:55473/agentium_test"

- name: Retain final release tarballs
if: inputs.retain-artifacts && matrix.node-version == 24
run: node scripts/release-artifacts.mjs pack --directory "$RUNNER_TEMP/agentium-release" --ref "$RELEASE_REF"
env:
RELEASE_REF: ${{ inputs.ref }}

- name: Verify retained release package consumers and CLI scaffolds
if: inputs.retain-artifacts && matrix.node-version == 24
run: npm run test:package
env:
AGENTIUM_RELEASE_ARTIFACT_DIR: ${{ runner.temp }}/agentium-release

- name: Verify packed package consumers and CLI scaffolds
if: '!inputs.retain-artifacts || matrix.node-version != 24'
run: npm run test:package

- name: Install pinned optional sandbox SDK fixture dependencies
Expand All @@ -106,3 +166,36 @@ jobs:
- name: Verify host OpenTelemetry SDK and independent OTLP decoding
if: matrix.node-version == 24
run: AGENTIUM_OTEL_SDK_FIXTURE="$RUNNER_TEMP/agentium-otel-fixture" AGENTIUM_OTEL_PROTO_PYTHON="$RUNNER_TEMP/agentium-otel-proto-fixture/bin/python" npx vitest run packages/observability/src/__tests__/otel-sdk.integration.test.ts

- name: Retain verified release artifacts
if: inputs.retain-artifacts && matrix.node-version == 24
uses: actions/upload-artifact@v4
with:
name: agentium-release-${{ inputs.ref }}-${{ github.run_attempt }}
path: |
${{ runner.temp }}/agentium-release/manifest.json
${{ runner.temp }}/agentium-release/*.tgz
if-no-files-found: error

release-artifacts:
if: inputs.retain-artifacts
needs: lint-and-test
runs-on: ubuntu-latest
outputs:
manifest-sha256: ${{ steps.verify.outputs.manifest_sha256 }}
steps:
- uses: actions/checkout@v4
with:
ref: ${{ inputs.ref }}
- uses: actions/setup-node@v4
with:
node-version: 24
- uses: actions/download-artifact@v4
with:
name: agentium-release-${{ inputs.ref }}-${{ github.run_attempt }}
path: ${{ runner.temp }}/agentium-release
- name: Bind retained artifacts to the complete CI matrix
id: verify
run: node scripts/release-artifacts.mjs verify --directory "$RUNNER_TEMP/agentium-release" --ref "$RELEASE_REF"
env:
RELEASE_REF: ${{ inputs.ref }}
147 changes: 57 additions & 90 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,118 +4,85 @@ on:
push:
tags:
- "v*"
# Allow manually re-firing this workflow (e.g. when GitHub silently
# drops the tag-push trigger, as happened for v2.2.0). The input is
# the tag name to publish — must already exist on the repo.
workflow_dispatch:
inputs:
tag:
description: 'Tag to publish (e.g. v2.2.1). Tag must already exist on the repo.'
description: Existing release tag to publish or resume (e.g. v4.9.0)
required: true
type: string

permissions:
contents: read

concurrency:
group: npm-release-${{ github.event.inputs.tag || github.ref_name }}
cancel-in-progress: false

jobs:
preflight:
runs-on: ubuntu-latest
outputs:
sha: ${{ steps.release.outputs.sha }}
version: ${{ steps.release.outputs.version }}
tag: ${{ steps.release.outputs.tag }}
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.event.inputs.tag || github.ref }}
fetch-depth: 0
- uses: actions/setup-node@v4
with:
node-version: 24
- name: Resolve release tag and validate every workspace version
id: release
run: node scripts/release-artifacts.mjs preflight --tag "$RELEASE_TAG"
env:
RELEASE_TAG: ${{ github.event.inputs.tag || github.ref_name }}

verify:
needs: preflight
uses: ./.github/workflows/ci.yml
with:
ref: ${{ needs.preflight.outputs.sha }}
retain-artifacts: true

publish:
needs: [preflight, verify]
runs-on: ubuntu-latest
environment: Prod
permissions:
contents: write

steps:
- uses: actions/checkout@v4
with:
# When triggered manually via workflow_dispatch, check out the
# supplied tag. On the normal tag-push trigger, GitHub already
# checks out the tag's SHA, so `ref` is empty / ignored.
ref: ${{ github.event.inputs.tag || github.ref }}

- name: Use Node.js 24
uses: actions/setup-node@v4
ref: ${{ needs.preflight.outputs.sha }}
- uses: actions/setup-node@v4
with:
node-version: 24
registry-url: https://registry.npmjs.org
cache: npm

- name: Install dependencies
run: npm ci --legacy-peer-deps --include=optional

- name: Verify installed native bindings and lock consistency
run: |
node -e "require('@rolldown/binding-linux-x64-gnu'); console.log('Linux native bindings loaded')"
git diff --exit-code -- package-lock.json

- name: Build packages
run: npm run build

- name: Verify tests and packed public API
run: |
npm run lint
node --test scripts/release-lock.test.mjs scripts/cjs-declarations.test.mjs
npm test
npm run test:package

- name: Publish @agentium/core
run: npm publish --workspace=packages/core --access public
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

- name: Publish @agentium/harness
run: npm publish --workspace=packages/harness --access public
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

- name: Publish @agentium/transport
run: npm publish --workspace=packages/transport --access public
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

- name: Publish @agentium/queue
run: npm publish --workspace=packages/queue --access public
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

- name: Publish @agentium/browser
run: npm publish --workspace=packages/browser --access public
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

- name: Publish @agentium/admin
run: npm publish --workspace=packages/admin --access public
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

- name: Publish @agentium/edge
run: npm publish --workspace=packages/edge --access public
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

- name: Publish @agentium/observability
run: npm publish --workspace=packages/observability --access public
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

- name: Publish @agentium/eval
run: npm publish --workspace=packages/eval --access public
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

- name: Publish @agentium/cli
run: npm publish --workspace=packages/cli --access public
- uses: actions/download-artifact@v4
with:
name: agentium-release-${{ needs.preflight.outputs.sha }}-${{ github.run_attempt }}
path: ${{ runner.temp }}/agentium-release
- name: Verify and reconcile publication of the exact retained tarballs
run: node scripts/release-artifacts.mjs publish --directory "$RUNNER_TEMP/agentium-release" --ref "$RELEASE_REF" --version "$RELEASE_VERSION" --manifest-sha256 "$MANIFEST_SHA256"
env:
RELEASE_REF: ${{ needs.preflight.outputs.sha }}
RELEASE_VERSION: ${{ needs.preflight.outputs.version }}
MANIFEST_SHA256: ${{ needs.verify.outputs.manifest-sha256 }}
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

- name: Extract version from tag
id: version
run: |
TAG="${{ github.event.inputs.tag || github.ref_name }}"
echo "TAG=$TAG" >> $GITHUB_OUTPUT
echo "VERSION=${TAG#v}" >> $GITHUB_OUTPUT

- name: Create GitHub Release
- name: Retain publication outcomes for safe manual resume
if: always()
uses: actions/upload-artifact@v4
with:
name: agentium-publication-${{ needs.preflight.outputs.sha }}-${{ github.run_attempt }}
path: ${{ runner.temp }}/agentium-release/outcomes.json
if-no-files-found: warn
- name: Create GitHub Release after every package is verified
uses: softprops/action-gh-release@v2
with:
name: Agentium v${{ steps.version.outputs.VERSION }}
tag_name: ${{ steps.version.outputs.TAG }}
name: Agentium v${{ needs.preflight.outputs.version }}
tag_name: ${{ needs.preflight.outputs.tag }}
generate_release_notes: true
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
1 change: 0 additions & 1 deletion .npmrc.bak

This file was deleted.

29 changes: 29 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,34 @@
# Changelog

## [4.9.0] - Release preparation

This entry describes the integrated release candidate after 4.8.3. Package publication and production or live-model validation are separate release gates.

### Added
- Workflow dependency graphs with incremental readiness, explicit control/data edges, structured-clone input isolation, stable topological joins, strict conflict detection, scoped execution paths, and bounded repeat episodes. Ordinary Workflow checkpoints remain completed top-level boundaries.
- Opt-in `ExecutionGraphRuntime` in `@agentium/harness`: versioned host executable catalogs, JSON DAG proposals, fenced node/model attempts, retained outputs, Agent decision replay, repeat decisions, and effect intent/receipt reconciliation over the existing durable task store.
- Shared root execution admission across nested graphs, repeats, Agent tools and planning, with FIFO cancellation/deadline handling and monotonic concurrency, expansion, dispatch-attempt and revision limits retained across recovery.
- Optional tool-free model DAG planning with bounded validation/corrections and NDJSON revision frames. Only unclaimed pending topology can change; committed fragments never gain execution authority until they form a complete validated plan.
- Host-owned bounded evidence recall, incremental archival task summaries, source provenance, scope attestation and current-view validation. Recall, summaries and persistent memory remain optional.
- `verifiedCompletionPolicy()` with a host `CompletionVerifier`, current evidence and bounded `pass`/`fail`/`unknown` decisions; `createHarnessEvalTarget()` connects the actual harness to `@agentium/eval` through the optional testing entrypoint.
- Explicit `tuple-v1` storage key encodings and borrowed scoped-wrapper ownership; `rememberWithResult()` and truthful owned-memory drain results.

### Fixed
- Await session commit/release, retain unknown-write evidence without blind retry, preserve incremental log high-water and propagate cancellation through owned work.
- Preserve provider/reflection/handoff terminal metadata, prevent incomplete cache reuse and double stream usage, and observe all settled members of canceled parallel tool batches.
- Reject busy/closing/closed Agent admission, wait for owned memory/accounting settlement, and keep failed cleanup retryable without reopening execution.
- Join only produced Workflow patches, propagate canceled children, expose ordinary step failures, and avoid duplicate controlled effect-budget admission.
- Validate versioned checkpoint continuation against workflow identity, callable definition version, ordered step names, restored state and absolute cursors.
- Keep failed evaluation graders distinct from task results, with valid-grade denominators and retained generated output.

### Compatibility and limits
- Custom `HarnessExecutionServices` implementations/test doubles must add required `observeToolSettlements`, `budget`, `archivedHistory`, `retrieveHistory` and `finishModel`; custom `RunHandle` wrappers must add `budget`. Normal runtime-provided services already implement them.
- Synchronous `CostTracker` budget helpers reject after canonical accounting is used even when usage is complete. Use asynchronous accounting/budget queries.
- Existing Agent, Workflow and HarnessRuntime use remains available. Durable graph recovery is opt-in, requires stateless JSON-compatible bindings with host-attested versions, and rejects unsupported mutable/dynamic continuation before dispatch.
- In-memory task stores advertise `durable: false`; use a verified persistent adapter and `requireDurable: true` for crash recovery. Generic `workflowDriver` still advertises non-durable execution.
- Budgets/deadlines do not replenish on recovery. Cancellation is cooperative; fencing cannot retract accepted remote work. Unknown effects require destination reconciliation/idempotency or an explicit recovery-required outcome. Exactly-once external execution and remote rollback are not guaranteed.
- See [dependability](packages/harness/DEPENDABILITY.md), [recoverable execution graphs](packages/harness/EXECUTION-GRAPHS.md), and the [Workflow contract](packages/core/src/workflow/README.md) for supported behavior and host responsibilities.

## [4.8.3] - 2026-10-12

### Added
Expand Down
13 changes: 13 additions & 0 deletions CONTEXT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Agentium execution

## Language

**Logical model call**: One host-requested model operation, which may cause several provider requests through retries or fallback.

**Provider attempt**: One observable submission to a provider SDK. Its physical request count is opaque when that SDK owns retries.

**Finishing capacity**: A portion of a run's total model-call and token allowance protected for explicitly designated tool-free finishing work. It does not authorize completion.

**Canonical conversation**: The immutable conversation records, whether held resident or referenced in the host archive.

**Resident history**: The conversation records currently retained for local replay. A model request can receive a separate projection of these records.
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ Agentium is a TypeScript-native agent orchestration framework with zero dependen

> Install from npm: [`@agentium/core`](https://www.npmjs.com/package/@agentium/core) · full docs at [docs.agentium.in](https://docs.agentium.in)

This checkout prepares **4.9.0** after 4.8.3. The local version and verification results do not establish npm publication. Build matching packages from this checkout to test the candidate; see the [changelog](CHANGELOG.md) for its release scope.

## Features

- **Model-agnostic** — swap between OpenAI, Anthropic, Google Gemini, Ollama, or any OpenAI-compatible API with one line
Expand All @@ -20,7 +22,9 @@ Agentium is a TypeScript-native agent orchestration framework with zero dependen
- **Sessions & Memory** — session history, standing MEMORY.md notes, long-term summaries, vector learnings
- **Knowledge Base** — vector + BM25 hybrid search with reciprocal rank fusion
- **Teams** — multi-agent coordination with coordinate, route, broadcast, and collaborate modes
- **Workflows** — deterministic step execution with typed state, conditions, parallel steps, retry policies
- **Workflows** — typed state, dependency graphs, stable joins, conditions, parallel steps and bounded repeats. [Checkpoint continuation](packages/core/src/workflow/README.md) validates completed boundaries and definition versions.
- **Recoverable execution graphs** — opt-in [versioned host catalogs and JSON plans](packages/harness/EXECUTION-GRAPHS.md), fenced node recovery, shared root limits, bounded model planning and streamed pending revisions. Hosts own persistent stores, executable versions and external-effect reconciliation.
- **Evidence and completion** — optional [scoped recall, archival task summaries and current-evidence verification](packages/harness/DEPENDABILITY.md), using host-owned memory adapters and the existing Agent loop.
- **Toolkit Catalog** — 30+ built-in toolkits from `@agentium/core/toolkits`, with dynamic credential management via Admin API
- **Edge & IoT** — Raspberry Pi support with GPIO, I2C sensors, camera, BLE, Ollama local LLM
- **Transport** — Express REST + SSE streaming + Socket.IO real-time + Voice gateway
Expand Down
Loading
Loading