Skip to content

Contributing

angelatgithub edited this page Sep 19, 2026 · 1 revision

Contributing

Contributions are welcome — and inbound=outbound under GitHub's Terms of Service §D.6, under the repo's Apache-2.0 license. No CLA. The canonical document is CONTRIBUTING.md; this page is the working summary.

Development setup

Prerequisites: Python ≥ 3.10 with uv, Node.js ≥ 18 (CI runs 20) with pnpm 9.

Python — one uv workspace, one member per package:

git clone https://github.com/thyn-ai/algenta-integrations
cd algenta-integrations/python
uv sync --all-packages --all-extras   # --all-extras is required: pytest lives in the dev extras

Run one package's suite — one pytest process per package, never pytest . across packages (package-relative imports deliberately do not collect together):

uv run pytest langchain-algenta -v

TypeScript — two self-contained pnpm + Turborepo workspaces:

cd typescript/algenta-tools        # or typescript/n8n-nodes-algenta
pnpm install
pnpm turbo run build lint test
pnpm --filter algenta-tools test   # one package's tests

Lint/format: Ruff for Python (ruff.toml), tsc --noEmit for TypeScript, plus the repo's pre-commit hooks (pre-commit install).

The one rule that matters most

Every package may depend only on the published algenta-sdk (PyPI / npm) — and only if it genuinely imports it — and may talk only to the caller's own self-hosted engine over its public HTTP/MCP surface at runtime. The engine is closed source: never vendored, imported, or depended on, in any form — no path-, git-, or file-based dependencies, no Algenta-named artifact other than the published SDK.

This is enforced mechanically, not by convention: scripts/check-no-engine-dependency.py scans every manifest and every import/require statement on every PR, and scripts/test_check_no_engine_dependency.py proves the gate actually catches violations (a crafted relative-path dependency, among other cases). A PR that fails this check does not merge.

One more repository-wide rule: no hardcoded credentials, tokens, or hosted-cloud endpoints anywhere — every example and default resolves its endpoint from ALGENTA_BASE_URL (see Self-Hosted).

Testing expectations

Every behavior change ships with tests; CI runs the full suite on every PR (including forks, no secrets), so green locally must mean green in CI. Changes to a package's tool surface must preserve three properties every suite exercises:

  • Contract parity — exposed tools per profile match contracts/integration-tool-contract.json exactly (also gated repo-wide by scripts/check-parity.py and scripts/check-parity.ts).
  • Profile filtering — no execute-tier tool leaks into observe/govern; force/override_safety are never model-facing, in any profile.
  • Receipts and denials — execute_decision's typed receipt and synchronous named-gate denials keep their typed mapping.

Write tests the way the existing suites do: against a real stub server speaking real HTTP/MCP, never mocks of the package's own internals. End-to-end scenarios needing a live engine belong in the conformance suite, not in unit tests.

Adding a new integration

  1. Create the package under python/ (uv workspace member) or typescript/ (pnpm + turbo workspace), following an existing sibling's layout.
  2. Embed the contract boundary as a contract.py / contract.ts module — pure module-level constants, declared not computed, so check-parity can parse them statically.
  3. Implement the four profiles with observe as default, the two-layer force/override_safety scrub, and the synchronous receipt/named-gate denial mapping onto your framework's native failure idiom.
  4. Build a real stub-server test fixture (real MCP server, real socket) and the three test properties above.
  5. Keep it self-hosted-only and free of any engine dependency — the gate will check.

Conventional Commits (required) and auto-release

The repository releases automatically from commit messages — format is a hard requirement. After each merge to main, scripts/compute_release_bumps.py walks the commits that touched each package since its last tag and derives a per-package semver bump:

Commit message Version effect
feat: ... minor bump
fix: ... patch bump
BREAKING CHANGE: in body/footer, or ! after type/scope major bump
docs, chore, test, ci, refactor, perf, style, build no bump

Format: type(scope): summary, scope naming the package (feat(langchain-algenta): ...). Which package actually bumps is determined by the paths the commit touched — a repo-level-only commit bumps nothing. Squash-merged PRs work as long as the final squashed message follows the format.

Pull requests

Branch from main as feat/…, fix/…, or docs/…; keep the diff focused; fill in the PR template checklist. Changes to contracts/, the no-engine-dependency gate, or .github/ always get deliberate maintainer review per CODEOWNERS.

Clone this wiki locally