100 Commits
Author SHA1 Message Date
zeekay 5c38bcef83 Run the flow image as uid 1000
The data on flow.hanzo.ai is 1000-owned; a system uid cannot open it.

Claude-Session: https://claude.ai/code/session_011i2AG9nwpiKUCVxAdDzYuU
2026-09-29 18:43:43 -07:00
zeekay 8670ff6033 Document flow's API under /v1
Claude-Session: https://claude.ai/code/session_011i2AG9nwpiKUCVxAdDzYuU
2026-09-29 18:34:39 -07:00
zeekay db35659c45 Point flow's tests and scripts at /v1
Claude-Session: https://claude.ai/code/session_011i2AG9nwpiKUCVxAdDzYuU
2026-09-29 18:34:34 -07:00
zeekay 8c119882bc Call flow's API at /v1 from every client
The frontend drops its v2 base and getURL's version switch; lfx,
the SDK, template validation and the OpenAPI token URL name /v1.

Claude-Session: https://claude.ai/code/session_011i2AG9nwpiKUCVxAdDzYuU
2026-09-29 18:34:20 -07:00
zeekay 5421a384b5 Fold the v2 API into /v1 and 404 /api
The upstream v2 routers mount under /v1 without collisions. flowweb
answers /api with 404 instead of the SPA shell, and a CI test fails
on any first-party /api/ or /v2/ path in src/.

Claude-Session: https://claude.ai/code/session_011i2AG9nwpiKUCVxAdDzYuU
2026-09-29 18:34:03 -07:00
zeekayandHanzo Dev fe92c6d5f4 Go 1.27.1, and the code it can say more simply
security / semgrep (push) Successful in 42s
Hanzo CI/CD / cicd (push) Failing after 50m21s
CI/CD / cicd (push) Failing after 50m21s
Modules declare go 1.27.1 and the build images follow. go fix had nothing to
change in core.

Co-authored-by: Hanzo Dev <[email protected]>
2026-09-16 19:14:46 -07:00
zeekayandHanzo Dev ce1ab25132 Watch the path the workflows now live at
Co-authored-by: Hanzo Dev <[email protected]>
2026-09-08 19:38:43 -07:00
zeekayandHanzo Dev c8de10a4ba Move the workflows to .github/workflows
The forge reads .github/workflows natively and github.com reads nothing else,
so one directory serves both planes instead of two conventions that disagree
about which one is live. The reusable in hanzoai/ci already lives there, so a
caller naming that path now resolves to a file that exists.

Co-authored-by: Hanzo Dev <[email protected]>
2026-09-08 18:55:46 -07:00
zeekay 8861702ac2 Reconcile main with the canonical GitHub history 2026-08-28 11:49:29 -07:00
zeekay 8fd0d79ead feat(docs): self-host Zen instead of Geist from Google 2026-08-23 15:04:14 -07:00
zeekayandHanzo Dev 4f11077b6c Let the security scan install, then say why each finding is not one
The lane never scanned anything. `pip --break-system-packages` cannot
install semgrep on the runner image: semgrep wants PyJWT, the image has
PyJWT 2.7.0 from its distro, a distro package carries no RECORD, so pip
cannot uninstall what it needs to replace and stops. The flag grants
permission to touch that environment; it does not make the uninstall
possible. uv gives semgrep its own environment and shims the binary onto
PATH — the same fix the insights lane took, so both read alike now.

With the install working the scan reports four, and all four are the
code being careful rather than careless. Each carries the reason at the
line, because a bare suppression is indistinguishable from someone
silencing a real one:

  alembic/env.py     the advisory-lock key is an int on both branches —
                     a sha256 digest reduced mod 2**63-1, or a literal
  auth/iam.py        decoded unverified only to read `iss` and pick a
                     validator; a token claiming our issuer then goes to
                     validate(), which checks the signature and raises
  auth/service.py    reads a claim without authenticating it, safe while
                     nothing authorises on the result — today only this
                     module's tests call it
  arxiv.py           imports the Element TYPE for annotations; parsing is
                     defusedxml.fromstring, two lines below

Placement matters and cost a round trip: the directive has to sit on the
line the rule anchors to, which for the jwt call is the `options=` line
carrying verify_signature, not the line opening the call.

Co-authored-by: Hanzo Dev <[email protected]>
2026-08-22 22:01:32 -07:00
zeekay 26cf6eef79 point at the copy that owns the tag
Every branch here is reachable from `hanzoai/flow` — 13 refs, not one commit it lacks — and this copy has no push mirror, so anything committed here reached nothing.
2026-08-21 16:25:06 +00:00
zeekay f9bc6e2727 stop declaring an image this copy does not own
Every branch here is reachable from `hanzoai/flow` — 13 refs, not one commit it lacks — and this copy has no push mirror, so anything committed here reached nothing.

hanzoai/flow keeps ghcr.io/hanzoai/flow.
2026-08-21 16:25:03 +00:00
zeekay e1fd5767db stop declaring an image this copy does not own
Every branch here is reachable from `hanzoai/flow` — 13 refs, not one commit it lacks — and this copy has no push mirror, so anything committed here reached nothing.

hanzoai/flow keeps ghcr.io/hanzoai/flow.
2026-08-21 16:25:01 +00:00
zeekay 4c4caf6f69 stop declaring an image this copy does not own
Every branch here is reachable from `hanzoai/flow` — 13 refs, not one commit it lacks — and this copy has no push mirror, so anything committed here reached nothing.

hanzoai/flow keeps ghcr.io/hanzoai/flow.
2026-08-21 16:24:59 +00:00
zeekay 6ad9b945ea static analysis runs again; the GitHub-only scanners do not
The forge reads the first WORKFLOW_DIRS entry that exists. .hanzo/workflows has
existed here since the image lane landed, so all 43 workflow files under
.github/workflows ran nowhere. Nothing went red, because the checks that would
go red were the ones not running: the forge listed 2 workflows for this repo
against 45 files on disk. This repo has had no test gate of any kind since
actions-runner-controller was decommissioned.

security.yml replaces the two dead scanners rather than restoring them:

  - codeql.yml ended in github/codeql-action/analyze under `security-events:
    write`, which names an upload to GitHub's code-scanning store. There is no
    such store here, and a scanner whose findings have nowhere to go is not a
    scanner. Semgrep covers the same two languages CodeQL was configured for.
  - mend.yml ran the Mend unified agent against WS_APIKEY / WS_USERKEY. That is
    a commercial subscription this org does not hold. Dependency and licence
    scanning is GONE, not replaced — semgrep reads code, not a dependency graph,
    and claiming otherwise would be the more expensive mistake.

Measured before it was written: 98 rules over 3558 git-tracked files in 20s.

The other 42 files are upstream's CI and cannot run here: PR labelers, autofix
bots that push to pull requests, IBM Globalization Pipeline, Codeflash, macOS
and Windows release trains, PyPI publishes for packages this fork does not own,
and a `ci_success` gate that passes only when upstream's flow-nightly was
published to PyPI that same day. They are deleted rather than moved — a dead
file cannot accumulate where there is no directory.

Still ungated and needing their own change: mypy, which lint-py.yml ran and
which nothing ever called even upstream, and `ruff check`, which the tree fails
1204 times against its own declared config.
2026-08-13 21:10:55 -07:00
zeekayandHanzo Dev 48990a63bd Point every Discord invite at the current Hanzo server (discord.gg/CJCyAsm9Vr)
Co-authored-by: Hanzo Dev <[email protected]>
2026-08-04 21:47:02 -07:00
zeekayandHanzo Dev a46ef3a325 publish through the shared sitedeploy action
The enqueue -> upload -> complete calls were transcribed into this file and
twelve others before hanzoai/ci carried them. Four steps collapse to one
`uses:`, so the plane's contract is written once and a fix lands everywhere
rather than in whichever repo someone remembered to edit.

It also self-provisions. sitedeploy POSTs /v1/projects idempotently before the
enqueue, so a slug that has never deployed no longer 404s on its first run --
which is every site in this fleet except hanzo-ai, hips and hanzo-app.

Build steps are untouched, verified byte-identical against the previous
revision; only the Sites-plane plumbing moved.

Co-authored-by: Hanzo Dev <[email protected]>
2026-08-04 19:46:35 -07:00
zeekayandHanzo Dev 5f360f4132 ci: publish the storybook through our own Sites plane; delete three foreign ones
Three site deploys in this repo published to planes that are not ours.

deploy-storybook.yml handed src/frontend/storybook-static to
actions/deploy-pages. It is a real static site, so it moves:
.hanzo/workflows/storybook.yml builds the export, POSTs
/v1/projects/flow-storybook/deploy, syncs the bytes straight to the S3 prefix
cloud names in the 202, then flips the deployment live — and marks it error if
the run dies after enqueueing, so cloud never records a deployment as "queued"
forever. Modelled on hanzoai/hips. It runs on hanzo-build-linux-amd64, a label
the forge runners actually advertise; a label nothing answers does not fail, it
queues silently until the 24h timeout.

This is a SEPARATE file from .hanzo/workflows/deploy.yml on purpose. That one
builds and pushes ghcr.io/hanzoai/flow — the App the operator runs. An App is a
container the cluster executes, a Site is bytes S3 serves; folding a docs
publish into an image build would couple it to a deployable release.

deploy_gh-pages.yml pushed docs/ to a gh-pages branch via
peaceiris/actions-gh-pages, and deploy-docs-draft.yml published per-PR docs
previews to an AWS S3 bucket behind CloudFront on upstream's account
(DOCS_AWS_ACCESS_KEY_ID, DOCS_DRAFT_CLOUD_FRONT_DISTRIBUTION_ID). Both are gone
with no native replacement, because this repo is not where these docs live:
hanzoai/docs carries them at apps/flow, and standing a second site up here would
be a second source of truth for one set of pages. docs/static/CNAME
(docs.flow.org) and docs/static/.nojekyll go with them — Pages artifacts that
mean nothing to S3.

The docs tree also shipped three third-party trackers: a Google gtag
(G-SLQFLQ3KPT), the consent-mode + TrustArc scripts feeding it, and a Segment
plugin reading SEGMENT_PUBLIC_WRITE_KEY. All removed, along with
@docusaurus/plugin-google-tag-manager, @mendable/search and
docs/src/plugins/segment. Telemetry goes to our own bus or nowhere.

Analytics on the storybook is the ONE hosted tag (cloud apps/analytics/tag.go)
posting to POST /v1/event. Its key is read from the project this run deploys, so
pk- rotation is one server-side change rather than five repo edits, and no key
means no tag: a keyless beacon is accepted 200 into $public, a tenant this org
cannot read.

Every other workflow stays. They are release, image-build, lint and test lanes,
not deploy planes.

Co-authored-by: Hanzo Dev <[email protected]>
2026-08-04 18:25:55 -07:00
zeekayandHanzo Dev c67f7d26e6 fix: repair the import-stripped API layer — core routes NameError'd at request time
An unused-import sweep ran against the wrong tree and deleted LOAD-BEARING
imports across the API layer, so main answered 500 NameError on first touch:
settings could not even construct (os, logger, copy2, AGENTIC_VARIABLES,
sanitize_database_url), create_app crashed on DeploymentGuardError, flows
CRUD lost its _new/_read/_patch/_update/_upsert helpers, projects lost its
deployment guards and MCP helpers, monitor lost the message crud, run lost
allow_custom_components (never lifted flat onto Settings) and builds lost the
Flow join. tracing/native.py additionally lost the resolved-spans collection
loop, so every trace flush hit an undefined name.

Repaired mechanically (every fix is an import restored to the module that
defines the name, plus the two Settings fields main.py reads: root_path,
allow_custom_components) and proven live: create -> list -> get -> patch ->
run (ChatInput->ChatOutput graph executes and echoes) -> monitor builds ->
delete, all 2xx against a fresh sqlite deployment. ruff --select F821 is
clean on every touched file.

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-30 22:26:13 -07:00
zeekayandHanzo Dev 1ce238f12f build: migrate tsconfig to TypeScript 7 (native compiler)
TypeScript 7 is the native Go compiler and removes `baseUrl` and
`moduleResolution: node|node10`. Both appear here, so `tsc` from TS7
refuses the config outright (TS5102 / TS5108) and cannot typecheck.

`paths` targets resolve relative to `baseUrl` when it is set and relative
to the tsconfig file otherwise. Every `baseUrl` folded here already
pointed at the config's own directory, so dropping it moves nothing and
the targets are left byte-identical. Where a baseUrl pointed elsewhere,
each affected target was rewritten as join(baseUrl, target).

`moduleResolution` was chosen from the declared `module`: commonjs ->
node16, esnext/preserve -> bundler. Configs whose `module` is unset or
exotic were left alone rather than guessed at.

The result is accepted by BOTH toolchains, so nothing has to upgrade
TypeScript in lockstep. Verified on hanzo/chat packages/api: tsc 5.9
779 -> 778 errors (no regression), and tsc 7.0.2 now runs the project
in 2s where it previously refused the config.

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-27 17:09:54 -07:00
zeekayandHanzo Dev 759e007eb8 fix(docker): move the golang base with the go directive
core/go.mod was bumped to `go 1.26.5` while the goweb stage stayed on
golang:1.23-bookworm. The golang images pin GOTOOLCHAIN=local, so the base can
never fetch a newer toolchain to satisfy the directive:

    go: go.mod requires go >= 1.26.5 (running go 1.23.12; GOTOOLCHAIN=local)

The build dies in 0.086s. A release build that fails in under a second did not
fail to compile — it failed to acquire a toolchain.

This is the fourth instance of the same shape (search-fts5 golang:1.23 vs go
1.26.4, world node:20 vs pnpm@11, search rust:1.89 vs 1.91.1), so I swept the
whole repo: node:20-slim, python:3.12.12-slim-trixie and now golang:1.26 all
satisfy what the tree declares.

Worth noting the frontend is now clean — this build got all the way through
vite to a Go stage, which the asset and identifier fixes are what unblocked.

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-27 13:48:07 -07:00
zeekayandHanzo Dev 4d035332a7 chore(go): bump go directive to 1.26.5
Set the go directive to 1.26.5 for 1 module(s) and ran go mod tidy.
Build and tests pass at 1.26.5.

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-27 13:37:50 -07:00
zeekayandHanzo Dev 2988cb5ec1 fix(frontend): resolve the last logo import; drop a second orphan
playground-modal.tsx carried the same import/usage split as the other eight
files — it imported FlowLogoColor from ../../assets/FlowLogoColor.svg and
rendered <HanzoFlowLogoColor>. The previous commit made the identifiers agree,
which is what finally let rollup reach the import and report that the FILE has
never existed either.

Collapsed onto FlowLogo, the asset that does exist. FlowLogoColor was a colour
variant of a monochrome mark used in an 18x18 slot, so one asset under one name
is both correct for the brand and one fewer thing to keep in sync. Also removed
the stale commented-out import above it, which pointed at a third spelling
(FlowLogocolor.svg) that never existed.

Removed pages/MainPage/pages/enchanced-beam-effect.tsx: imports BorderBeam from
../../../components/ui/border-beams, which is not in the repo, and nothing
imports it. Same shape as importButtonComponent.

Note both orphans were UNREACHABLE, so rollup never resolved them and neither
was blocking the build — that is cleanup, not the fix. Widened the sweep from
alias-only to alias + relative specifiers, which is what caught FlowLogoColor:
2778 -> 5495 checked, now 0 unresolved.

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-27 13:36:36 -07:00
zeekayandHanzo Dev 810c78bb93 fix(frontend): commit the HanzoFlowLogo -> FlowLogo rename itself
The previous commit renamed the asset FILES but shipped none of the 13 source
edits that point at them: git mv and git rm stage themselves, plain edits do
not, and that commit named no paths. So the tree kept importing
@/assets/HanzoFlowLogo.svg?react from an asset that is now FlowLogo.svg, and
rollup failed on exactly the import the rename was meant to remove.

It did move: modules transformed went 3401 -> 6441, so the earlier asset and
module renames were real. This is the remaining 8 files.

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-27 13:27:25 -07:00
zeekayandHanzo Dev ddf8cddac0 fix(frontend): make every asset and module import resolve again
The rebrand sed rewrote import PATHS and IDENTIFIERS but never the files they
name, in three distinct ways. Rollup reports one unresolved import per build,
so these surface one at a time, each looking like a fresh unrelated breakage:

1. Assets renamed in code only. Restored the files to the names the code
   already asks for:
     langflow_assistant.svg    -> flow_assistant.svg     (6 importers)
     langflow-icon-smooth.svg  -> FlowLogo.svg           (9 importers)
     MCPLangflow.png           -> MCPFlow.png            (1 importer)
   No file referenced the old names, so these are pure renames.

2. ONE logo, TWO invented names. The same asset was rewritten to both
   FlowLogo.svg and HanzoFlowLogo.svg, so neither existed. Worse, the rename
   landed on imports and usages independently — LoginPage imported FlowLogo
   and rendered <HanzoFlowLogo>, an identifier bound to nothing. Collapsed to
   FlowLogo everywhere (13 occurrences, 8 files); import and usage now agree.

3. Modules renamed in importers only:
     custom-langflow-counts.tsx -> custom-flow-counts.tsx
     langflow-counts.tsx        -> flow-counts.tsx

Also removed modals/fileManagerModal/components/importButtonComponent/. It
imports @/components/ui/morphing-menu, which has never existed in this repo,
and it is orphaned: its only reference is inside a JSX comment and nothing
imports it. Every one of its three onClick handlers is an empty body with a
"// Handle X click" comment, so it is unfinished scaffolding, not a feature.
Writing MorphingMenu to satisfy it would ship a menu where every item does
nothing.

Verified by resolving all 2777 '@/' specifiers against the tree: 0 unresolved,
0 stale references to the renamed files.

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-27 13:19:20 -07:00
zeekayandHanzo Dev 59609dfbe4 fix(frontend): repair identifier broken by the rebrand sed
vite.config.mts declares envHanzoFlow on line 22 but every USE of it reads
`envHanzo Flow` — the rebrand replaced Langflow with "Hanzo Flow" and the
space landed inside the identifier. esbuild rejects the config before Vite
starts, so the whole frontend stage dies with
`Expected ")" but found "Flow"`.

Usages now match the existing declaration. Swept the tree: this was the only
file the sed corrupted.

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-27 12:53:10 -07:00
zeekay fdd1497f04 fix(docker): copy the src/sdk workspace manifest uv resolves against
With the phantom base uv.lock removed the build reached uv sync and failed:

  error: Failed to determine installation plan
    Caused by: Distribution not found at: file:///app/src/sdk

[tool.uv.workspace] lists four members — src/backend/base, ., src/lfx and
src/sdk — and the Dockerfile copied manifests for the first three only. uv needs
every member's pyproject.toml present when it resolves, even though the packages
themselves are installed later with --no-install-project.
2026-07-27 12:26:51 -07:00
zeekay 4cde123db4 fix(docker): drop the COPY of a uv.lock that does not exist
The build failed with

  failed to calculate checksum of ref ...: "/src/backend/base/uv.lock": not found

A uv workspace has exactly ONE lockfile, at the root, which line 54 already
copies. Members do not carry their own, and src/backend/base contains only
README.md, flow/ and pyproject.toml. The comment asserting the base member
required its own lock was wrong.

Verified against [tool.uv.workspace] members = [src/backend/base, ., src/lfx,
src/sdk] and the actual repo tree, rather than repointing the path at
src/lfx/uv.lock, which would have fed the wrong member's lock to the build.
2026-07-27 12:16:55 -07:00
zeekay 16ff3f471e ci: drop the Gitea mirror-sync nudge
Superseded: the Hanzo GitHub App pushes a webhook, so the forge tracks GitHub
without a per-repo workflow. This file called git.hanzo.ai/api/v1/.../mirror-sync
— a Gitea API for a system we no longer drive — and would sit inert in every repo.

One mechanism, in one place, instead of ~350 copies of a cron.
2026-07-27 10:31:15 -07:00
zeekayandHanzo Dev f6d8f3378c ci: trigger native pipeline after ARC decommission
Empty commit to exercise the rewritten .hanzo/workflows/deploy.yml on
git.hanzo.ai. workflow_dispatch is accepted (HTTP 204) but creates no run on
this forge — every run is ev=push — so a real push is the only reliable
trigger. The previous failures were push events that predated the rewrite
reaching the mirror.

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-27 08:48:43 -07:00
zeekay 40e42b5722 ci: build an image that can actually be built
The previous pipeline called buildctl-daemonless.sh, absent from the job image
(catthehacker/ubuntu:act-24.04 per GIT_RUNNER_LABELS) — exit 127 — and read
secrets.GIT_CLONE_TOKEN, which exists on neither the repo nor the hanzoai org.
It had never produced an image.

Its kubectl step failed the same way and was futile regardless: cd.hanzo.ai
selfHeal restores the App CR from the reviewed pin in hanzoai/universe within
minutes, so the deploy step is removed rather than repaired.

This is now urgent rather than cosmetic: actions-runner-controller was
decommissioned 2026-07-27 and every GitHub workflow pinning an ARC pool was
removed, so this pipeline is the ONLY CI this repo has.

Replaced with the shape proven on hanzoai/playground and 14 siblings:
setup-buildx + login-action + build-push-action using GHCR_USER/GHCR_TOKEN/
GH_PAT, which DO exist as org secrets, plus an imagetools check because
build-push-action can exit 0 before the manifest resolves.
2026-07-27 08:31:34 -07:00
zeekay 5a0e6331b7 ci: nudge git.hanzo.ai to pull on push
git.hanzo.ai mirrors this repo by PULL on a ~10-minute interval, and arcd runs
CI/CD there — so every push waited out that interval before anything built.
This asks Gitea to pull HEAD immediately.

Latency only: the repo already mirrors via the App webhook, so a missing
HANZO_GIT_TOKEN or a failed curl is non-fatal and never fails the push.
Idempotent (mirror-sync just pulls HEAD) and concurrency-coalesced.
2026-07-27 08:16:25 -07:00
zeekay 50755fe27e fix(ci): target a runner pool that exists
These jobs asked for `hanzo-linux-amd64`. No runner advertises that label, so
they never ran — and crucially they did not FAIL either. A job requesting an
unadvertised label queues until the 24h timeout, which reads as "CI is slow"
rather than "CI is misconfigured", so this hid rather than surfaced.

Verified live against git.hanzo.ai /api/v1/admin/actions/runners rather than
inferred: the four ONLINE runners (git-runner-0..3) advertise exactly
ubuntu-latest, ubuntu-22.04, ubuntu-24.04 and hanzo-build-linux-amd64. The
three self-hosted hosts that carry other labels (spark gb10/cuda, dbc
m4max/metal, evo gfx1151/rocm) are all OFFLINE, and none of them advertises
a linux-amd64 pool anyway.

So there is exactly ONE usable pool today and this points at it.

Fleet-wide this was 27 jobs across 14 files in 8 repos. The one remaining
mention of the old label is a COMMENT in iam2/image.yml that documents this
very defect — deliberately left intact.
2026-07-26 01:52:12 -07:00
zeekayandHanzo Dev 6841a92fec feat(serverless): run a Flow graph as a Hanzo Function on Fission
compiler.py + runner.py + FUNCTIONS.md — take a Flow (graph) and execute it as a
Hanzo Function against the live Fission control plane.

Rebased onto upstream rather than merged: my local tree was 21 commits behind and
also carried a fix repointing four alembic migrations from `langflow.utils` to
`flow.utils`. That fix is obsolete — upstream deleted those four migration files
outright AND completed the rename (src/backend/base/langflow no longer exists,
630 files now under base/flow). Keeping my version would have resurrected four
deleted migrations. Only the genuinely new work is carried forward.

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-25 23:54:01 -07:00
zeekay 7328e3a0e4 ci: neutralize docker-publish → sync notice (native pipeline is .hanzo/workflows/deploy.yml) 2026-07-24 15:16:49 -07:00
zeekay 3b67f42c0a ci: native Hanzo deploy pipeline (act_runner + BuildKit → ghcr → operator) 2026-07-24 15:16:21 -07:00
zeekay 123aed19a4 build(flow): one image — flowweb front door over the Python backend
Multi-stage: build the Vite frontend, go:embed it into the CGO-free flowweb
binary, and run flowweb (:8080) as the container front door — it serves the
embedded UI + landing and reverse-proxies /api to the Python flow backend
(:7860, loopback). One image, one origin at flow.hanzo.ai; retires the split
flow-site landing + separate app host. EXPOSE 8080.
2026-07-17 22:44:40 -07:00
zeekay b0a85aec05 feat(flow): flowweb — native Go front door, embeds UI + landing, proxies API
One binary fronts flow.hanzo.ai instead of the split flow-site landing + a
separate app host + a disabled-ingress backend. flowweb go:embeds the built flow
UI (Vite frontend) plus a self-contained Hanzo Flow landing and serves it with
SPA fallback, while reverse-proxying /api, /health, /openapi.json, /docs, /logs
etc. to the flow backend (FLOW_BACKEND_URL, default 127.0.0.1:7860). One image,
one origin — hanzoai/world + hanzoai/cloud's embedded-SPA pattern.

At plain `go build` it ships the committed landing placeholder; the image build
overwrites core/cmd/flowweb/frontend/ with the real Vite bundle before `go build`.
Verified: go build clean, GET / serves the landing (200), /api/* proxies.
2026-07-17 22:41:34 -07:00
zeekay a5397cc135 feat(flow-ml): real hanzo-ml binding — GpuResident seam made concrete
MlDevice wraps hanzo_ml::Device (CPU/CUDA/Metal/…); MlTensor wraps
hanzo_ml::Tensor — already an Arc-backed device-resident handle, so it IS the
DeviceTensor abstraction concretely (zero-copy step-to-step). The same steps
run on CPU or GPU; only the Device ctor differs (MlDevice::cpu vs ::cuda).

flow-core stays std-only — hanzo-ml lives behind this crate so hanzo-desktop
embeds flow-core alone (tiny) or flow-ml (with compute) as needed. Verified on
CPU (no GPU): a real affine op runs through GpuResidentBackend, 1.0→2.0, result
resident on the injected device. 2/2, clippy clean. cuda/metal features forward
to hanzo-ml for on-GPU residence.
2026-07-16 19:21:15 -07:00
zeekay 9f740023f9 feat(core-rs): Durable backend — checkpoint/resume, the third Mode
Closes the Mode trio: InProcess, GpuResident, and now Durable each have a real
backend — no bare enum variant without an impl. The DurableBackend checkpoints
each step's outputs to a Store and skips steps that already completed, so a run
survives a crash, resumes where it stopped, and the same graph can be scheduled
or re-run in the cloud without repeating finished work. This is the engine side
of "build/test locally, save to cloud, re-run/schedule on GPU."

Store is a trait — hanzo cloud impls it over S3/Base, hanzo-desktop over local
disk. MemoryStore is the std-only reference impl (also useful for retrying a
failed graph in-process). Verified: resume does NOT re-execute a checkpointed
step. 3/3 durable + 3/3 gpu + 5/5 pipeline = 11/11, clippy clean.
2026-07-16 19:13:48 -07:00
zeekay d3abd556a3 feat(core-rs): GpuResident backend — the hanzo-ml / hanzo-engine seam
Step 2 of the Rust flow migration: the backend that pins tensors in device
memory across steps. DeviceTensor carries only an opaque handle (a hanzo-ml
tensor id), never the bytes, so it flows step-to-step zero-copy and never
round-trips through host memory. The GpuResidentBackend injects the active
Device into each step via a thread-local (current_device()); real GPU steps
downcast it to their concrete hanzo-ml device (as_any) to call typed kernels.

Core stays dependency-free — Device is a trait, hanzo-ml/hanzo-fusion plug in
behind it. Verified with a stub device: 3/3 gpu tests + 5/5 pipeline = 8/8,
clippy clean.
2026-07-16 19:11:38 -07:00
zeekay 074efd95c7 feat(core-rs): Rust flow-core engine — the embeddable native seed
The Rust twin of hanzoai/flow/core (Go): the ONE parametric step-DAG engine, now
native. Dependency-free (std only) so it drops into hanzo-desktop (local/private,
low memory) and the cloud unchanged — the SAME library builds/tests a flow locally
on BYO GPU and runs/schedules it in the cloud, surfaced via studio.hanzo.ai /
flow.hanzo.ai.

Contract (1:1 with the Go core, so they stay in lockstep):
- Value (Arc<dyn Value>, zero-copy hand-off — the point for GPU tensors), Port, Step
- Graph (add/wire/validate — port typecheck + acyclicity, deterministic Kahn topo)
- Mode (InProcess | GpuResident | Durable) + Backend — the locality/durability seam
  where hanzo-ml / hanzo-fusion on hanzo-engine plug in as the GpuResident backend
- Scheduler — the one topology walk, curried over (value-domain, Mode)

Verified: cargo build clean, cargo test 5/5 (domain-agnostic pipeline runs in order,
port type mismatch rejected at wire time, ANY_TYPE bypasses, cycle caught by
validate, Mode selects the backend), clippy clean.

This is step 1 of the Rust migration: the engine. Node-packs (mechanically porting
the Python flow/comfy nodes -> Rust steps on hanzo-ml/hanzo-fusion), the GpuResident
backend on hanzo-engine, and studio's canvas on this engine build on top.
2026-07-16 15:47:20 -07:00
zeekay e3af109d5b feat(multi-tenant): org_id on every resource + drop historic migrations (never live)
Flow was never live, so no migration ceremony / backward-compat: delete the 70
upstream Langflow migrations and tag every resource table with the IAM tenant.

- deleted flow/alembic/versions/*.py (schema is recreated fresh from the models)
- added org_id (str, indexed, nullable) to all 11 resource tables (flow, folder,
  file, variable, api_key, message, jobs, deployment, deployment_provider_account,
  flow_version, flow_version_deployment_attachment) — User already had it. This is
  the tenant-isolation column the IAM seam's current_org scopes queries on.

py_compile clean. NEXT: scope the 18 user_id query sites by current_org (the
enforcement), then a single fresh initial migration once base.py boots (blocked on
the concurrent session's settings merge).
2026-07-16 15:40:11 -07:00
zeekay 943040fbf7 feat(hanzo): native Hanzo AI model backend + rebrand-completion fixes
The directive: hanzoai/ai (api.hanzo.ai) as the AI backend for all. Adds a native
HanzoAI model component so flow routes generations through the Hanzo gateway (one
OpenAI-compatible backend fronting Zen/DeepSeek/GLM) instead of a raw provider SDK
— which is also what lets the provider-langchain zoo be dropped.

- components/hanzo/hanzo_ai.py — HanzoAIModelComponent (LCModelComponent). Points
  ChatOpenAI at HANZO_BASE_URL (default https://api.hanzo.ai/v1) with the HANZO_API_KEY
  and the Zen model tiers (zen5-pro default). json_mode, temperature, max_tokens.
- components/__init__.py — registered the "hanzo" category.

Also fixes two more rebrand-missed-a-file-rename bugs surfaced by finally getting
the env to resolve (they broke the whole model layer at import):
- renamed lfx/utils/langflow_utils.py -> flow_utils.py (the import was rebranded,
  the file wasn't) — unblocks every LCModelComponent.
- added the missing `from .schemas import DeploymentProviderKey` in the migrated
  deployment_provider_account model.

NOTE: full app-load can't be verified from here yet — a SEPARATE, pre-existing
breakage (the concurrent session's in-flight upstream settings-mixin merge, PR
#13141) leaves lfx/services/settings/base.py with a broken import block
(VARIABLES_TO_GET_FROM_ENVIRONMENT / Field / MAX_TEXT_LENGTH undefined). That's
theirs to reconcile; this component's own code is py_compile-clean and mirrors the
proven OpenAI component exactly.
2026-07-16 15:19:40 -07:00
zeekay 81ce604aee fix(deps): unblock the workspace resolution — align langchain to 1.x, drop dead providers
The fork's provider extras were pinned to a pre-1.0 langchain generation that
can't coexist with lfx's langchain-core 1.x, so `uv sync` (and CI) couldn't
resolve at all. Per the "route everything through hanzoai/ai" direction, the fix
is to align/drop rather than resurrect the provider zoo:
- langchain-openai >=1.1.12, langchain-anthropic >=1.0, pgvector >=0.4.2 (match lfx / cuga)
- dropped langchain-cohere (no core-1.x release exists; cohere is reached via the
  hanzoai/ai gateway, not a direct langchain integration)
- [tool.uv] environments pinned to linux (our deploy target; the macOS-only
  cuga/pgvector split is a separate dev-env concern)
- renamed the stale SDK module dir langflow_sdk -> flow_sdk (the rebrand renamed
  the pyproject refs + the pytest11 entry point but missed the directory, so the
  `flow` test plugin failed to import)

Verified: `uv sync` resolves + installs clean, and the IAM auth seam test now runs
in the REAL full-app env — 7/7 pass (previously only verifiable via direct module
load). This unblocks CI and all further flow work.
2026-07-16 15:07:37 -07:00
zeekay 170b34b09a fix(build): restore workspace package names flow-base/sdk -> hanzo-flow-base/sdk
The langflow->flow sweep had over-reached in the root pyproject: a langflow-base
missed by the package-name pass was then hit by the general langflow->flow sweep,
becoming 'flow-base' (and 'flow-sdk') in [tool.uv.sources] + the dependency specs,
while the actual member packages are hanzo-flow-base/hanzo-flow-sdk. That made
'uv sync' fail ('flow-base references a workspace ... but is not a workspace
member'). Restored the hanzo- prefix everywhere (protecting existing ones).
2026-07-16 14:38:34 -07:00
zeekay 59caea463a feat(auth): Hanzo IAM auth seam — flow trusts IAM (org/project/user), multi-tenant
Phase (a) of "flow uses only Hanzo IAM": flow stops minting identity and validates
a Hanzo IAM access token instead, mirroring the cloud's principal model so one IAM
login is the same session across console, studio, and flow.

- services/auth/iam.py — the self-contained seam. HanzoIAMValidator verifies an IAM
  JWT via the IAM JWKS (PyJWT PyJWKClient), pins RS256, enforces issuer (+audience),
  and extracts (org, project, user) into an IAMPrincipal. org falls back to the
  Casdoor `owner` claim. Sets current_org/current_project context vars — the hook the
  data layer scopes queries on (phase c). Enabled by FLOW_IAM_ISSUER (forward-only, no
  compat alias).
- service.py — _authenticate_with_iam wired at the top of _authenticate_with_token:
  an IAM token is validated + resolved to an org-scoped flow user (get-or-create,
  org_id carries the tenant) BEFORE any local decode. Critically, a token FOR our IAM
  issuer that fails verification RAISES — it never falls through to the weaker local
  SECRET_KEY path. Inert unless FLOW_IAM_ISSUER is set, so existing deploys are
  unaffected.

Verified: the security-critical validator logic was exercised directly (RSA keypair,
signed tokens) — 7/7 pass incl. bad-signature-never-falls-through, wrong-issuer->local
fallback, missing-org/expired rejected, tenant context vars set. iam_test.py runs the
same in CI (full-app deps). py_compile clean.

Follow-on: (b) org_id/project_id on the remaining 15 resource tables + Alembic
migration (User already has org_id); (c) scope the 24 user_id query sites by
current_org/current_project. Those need the running app + a migration, so they land
as the next verified phase.
2026-07-16 14:09:56 -07:00
zeekay a270a374f0 refactor(rebrand): unify hanzoflow -> hanzo-flow (pkg) / flow (module,cmd) / FLOW_ (env)
Cleaned the concurrent session's half-rebrand inconsistency (166 files):
- pip/pypi refs hanzoflow -> hanzo-flow (matches hanzo-flow-base/sdk)
- module paths/commands/devcontainer hanzoflow -> flow (the import name + CLI)
- env vars HANZOFLOW_ -> FLOW_ (was inconsistent with the LANGFLOW_->FLOW_ sweep)
- fixed a stale src/backend/base/hanzoflow/ path that didn't exist
- product display HanzoFlow -> 'Hanzo Flow' in docs; kept HanzoFlow only as a
  code identifier where a space is illegal

Canonical: pip install hanzo-flow / import flow / `flow` CLI. compileall clean.
2026-07-16 10:26:22 -07:00
zeekay 168078735f docs(license): restore upstream MIT attribution in NOTICE, drop redundant README credit
The rebrand sweep had corrupted NOTICE — it read 'Copyright (c) 2024 Hanzo Flow'
where MIT requires the ORIGINAL upstream notice. Restored the exact upstream line
(Copyright (c) 2024 Langflow, verified against langflow-ai/langflow LICENSE) plus
the full MIT permission text, so the legal requirement (retain the original
copyright + permission notice in the distribution) is satisfied in the file where
it belongs — NOTICE.

With NOTICE correct, the README 'Forked from' line is redundant courtesy, not a
legal requirement, and is removed per direction. Attribution lives where it's
actually needed (NOTICE), not the marketing README.
2026-07-16 10:23:19 -07:00
zeekay 94741a8363 refactor(rebrand): sweep the remaining langflow — env vars, identifiers, stragglers
Completes the rebrand per direction: LANGFLOW_/LANGFLOW -> FLOW_/FLOW (env vars,
headers), langflow_ -> flow_ (settings fields, local vars), camelCase identifiers
(LangflowClient/Logo/HTTPError, builtWithLangflow, getLangflowDesktop) -> Flow*,
and all remaining bare tokens. Fixed the identifier-space hazard (Langflow ->
'Hanzo Flow' is prose-only; in code it collapses to Flow so no identifier gains a
space). compileall of flow + lfx is clean.

Repo-wide langflow now = 4, all the protected MIT attribution to langflow-ai/
langflow in README (legally required; deliberately preserved).

Breaking (per no-backwards-compat / forward-perfection): the LANGFLOW_* env-var
prefix is now FLOW_* — deployments must update their env. CI's uv + frontend
build is the runtime gate.
2026-07-16 10:18:53 -07:00
zeekay d650dd60f0 refactor(rebrand): langflow->flow across docs, starter-project data, CI, tests
Docs corpus (Langflow->Hanzo Flow, upstream URLs langflow-ai/langflow->hanzoai/
flow, docs.langflow.org->docs.hanzo.ai), starter-project template help-URLs, CI
workflows, and test files. Remaining 'langflow' repo-wide is now dominated by
LANGFLOW_* env-var names + langflow_ settings fields — the config-boundary layer
deliberately preserved pending a coordinated FLOW_/HANZO_ alias-with-fallback
(renaming them blind breaks every deployment).
2026-07-16 10:00:51 -07:00
zeekay 2a4dc61353 refactor(rebrand): langflow->flow package names + product strings (app code)
Stage 2 of the rebrand, on top of the module migration:
- Workspace distribution names langflow-base/langflow-sdk -> hanzo-flow-base/
  hanzo-flow-sdk across all pyproject.toml (matches root hanzo-flow).
- App-code product strings: "Langflow" -> "Hanzo Flow", bare "langflow" -> "flow"
  across src/backend/base/flow + src/lfx/src (207 files) — MCP server names,
  docstrings, user-facing labels.

compileall of the flow package + lfx parses clean.

DELIBERATELY NOT swept (the delicate config-boundary layer — needs the running
app + a compat decision, not a blind sed):
- LANGFLOW_* env vars (LANGFLOW_DATABASE_URL, LANGFLOW_SERVER_URL,
  LANGFLOW_SSRF_PROTECTION_ENABLED, ...) — renaming breaks every deployment's
  config; needs a FLOW_/HANZO_ alias with fallback, coordinated with deploy env.
- pydantic settings fields that map to those env vars.
- internal identifiers (LangflowHTTPError, *_langflow_connections_binding) — safe
  to global-rename but want the uv suite green to confirm no reference is missed.
2026-07-16 10:00:50 -07:00
zeekay 88e4947893 refactor(rebrand): finish langflow->flow module rebrand — migrate unique code, repoint all imports
The concurrent rebrand left src/backend/base/langflow alive with 34 UNIQUE
unmigrated files (a flow_events service, the WatsonX-Orchestrate deployment
adapter, the flow_version_deployment_attachment DB model + tests) that flow/
never received, plus 152 files still importing `langflow` and 137 more with
`langflow.<mod>` string module paths (import_module/monkeypatch targets).

- Migrated all 34 unique files langflow/ -> flow/ at matching paths (dropped
  langflow/api/v1/__init__.py, superseded by flow/'s).
- Deleted the emptied src/backend/base/langflow package.
- Repointed every `from langflow`/`import langflow` (152 files) and every
  `langflow.<mod>` string path (137 files) to `flow`.

Verify: 0 `from/import langflow` and 0 `langflow.` module refs remain in *.py;
compileall of src/backend/base/flow + src/lfx/src parses clean. Runtime import
resolution + the uv test suite is the CI gate (the module tree is now internally
consistent: every moved model/service resolves under flow/).

Remaining (follow-on commits): runtime identifier strings (MCP server names),
the langflow-base/langflow-sdk distribution names, and the docs corpus.
2026-07-16 10:00:50 -07:00
zeekay 2a497d56d9 docs(readme): credit upstream fork langflow-ai/langflow 2026-07-16 09:18:41 -07:00
zeekay 30ed03549f feat(core): the flow step/port contract — ONE parametric step-DAG engine
The seam the whole platform composes on. A stdlib-only Go module (core/) that
holds zero domain knowledge and is what every node-pack and execution backend
plugs into. flow is curried over two parameters:

  Value type — what travels on an edge (Message / Tensor / connector I/O). The
               engine never inspects it; a Step interprets it per its domain.
  Mode       — execution locality/durability (InProcess | GPUResident | Durable),
               a PARAMETER not baked in: media flows keep latents pinned in VRAM
               and serialize nothing; automations checkpoint every step on the
               durable backend. Same scheduler, different Backend.

So every product is flow applied:
  studio      = Run(GPUResident, graph-of-Tensor-steps)   // comfy nodes
  automations = Run(Durable,     graph-of-ConnectorIO)     // triggers -> actions
  llmFlow     = Run(InProcess,   graph-of-Message-steps)   // langflow (lfx) nodes

Contract: Value (opaque, typed by PortType), Port/Step (typed in/out ports + Run),
Graph (Add/Wire/Validate — port typecheck + acyclicity), Mode + Backend (the
locality/durability seam), and Scheduler (the ONE topology walk, curried over
value-domain and Mode). Ships with the reference InProcess backend; GPUResident
(studio VRAM) and Durable (auto/tasks activities) register the same way.

Tests prove it: a domain-agnostic 2-step pipeline runs in order, port type
mismatch is rejected at wire time, AnyType bypasses, cycles are caught by
Validate, and Mode selects the backend over an identical scheduler walk.

Next: studio and langflow delete their private executors and become node-packs
on this scheduler; auto's tasks engine registers as the Durable backend.
2026-07-16 00:50:35 -07:00
zeekay 38c8231a68 chore: bump version to 1.8.2 (alembic boot fix) 2026-06-28 23:15:38 -07:00
zeekay e8a54941a7 fix(alembic): resolve duplicate revision id + finish langflow->flow rebrand in migrations
Two boot blockers prevented flow from starting (deploy parked at replicas:0):

1. Duplicate revision id: both the Hanzo-local add_org_id_to_user migration and
   the upstream convert_provider_key_and_deployment migration declared
   revision='a1b2c3d4e5f6'. Alembic cannot build a history graph with a duplicate
   id. Upstream legitimately owns a1b2c3d4e5f6 (chained to head d306e5c17c41), so
   the Hanzo migration is re-id'd to 9f2e7b14c0aa and re-parented onto the current
   head; its body is made idempotent (guards column/index) so re-runs are safe.

2. Incomplete rebrand: 4 upstream migrations imported 'from langflow.utils import
   migration' (+ langflow.services.auth.utils). The langflow shim is an empty
   namespace package, so these raised ModuleNotFoundError at alembic load time.
   Switched to 'from flow.*' (flow.utils.migration / flow.services.auth.utils both
   exist), matching every other migration in the tree.

Validated: alembic ScriptDirectory now loads a single clean head (9f2e7b14c0aa)
across the full 70-revision chain.
2026-06-28 23:12:56 -07:00
zeekay f5d2c6c057 chore: restore upstream attribution + NOTICE (OSS compliance) 2026-06-21 07:42:09 -07:00
zeekayandGitHub 44e58662a4 Merge pull request #17 from hanzoai/dependabot/github_actions/actions/download-artifact-8
build(deps):(deps): bump actions/download-artifact from 4 to 8
2026-06-04 01:32:25 -07:00
zeekayandGitHub d75ef799e8 Merge pull request #19 from hanzoai/dependabot/github_actions/mikepenz/action-junit-report-6
build(deps):(deps): bump mikepenz/action-junit-report from 5 to 6
2026-06-04 01:32:19 -07:00
zeekayandGitHub 3fa7f1d4a3 Merge pull request #15 from hanzoai/dependabot/github_actions/actions/checkout-6
build(deps):(deps): bump actions/checkout from 5 to 6
2026-06-03 13:16:27 -07:00
zeekayandGitHub 472e99a7d1 Merge pull request #16 from hanzoai/dependabot/github_actions/actions/upload-pages-artifact-4
build(deps):(deps): bump actions/upload-pages-artifact from 3 to 4
2026-06-03 13:16:23 -07:00
zeekay 488de4eb05 merge: upstream/main (sync, brand preserved)
# Conflicts:
#	.github/workflows/docs-update-openapi.yml
#	AGENTS.md
#	AGENTS.md~upstream_main
#	CLAUDE.md
#	CLAUDE.md~upstream_main
#	docker_example/docker-compose.yml
#	src/backend/base/flow/agentic/flows/TranslationFlow.json
#	src/backend/base/flow/agentic/flows/langflow_assistant.py
#	src/backend/base/flow/agentic/helpers/code_security.py
#	src/backend/base/flow/agentic/helpers/input_sanitization.py
#	src/backend/base/flow/agentic/helpers/streaming_retry.py
#	src/backend/base/flow/alembic/versions/8255e9fc18d9_add_name_to_deployment_provider_account.py
#	src/backend/base/flow/alembic/versions/a1b2c3d4e5f6_convert_provider_key_and_deployment_.py
#	src/backend/base/flow/alembic/versions/c0d2ce43b315_add_flow_version_deployment_attachment_.py
#	src/backend/base/flow/alembic/versions/d306e5c17c41_add_api_key_hash_column_to_apikey_table.py
#	src/backend/base/flow/alembic/versions/ef4b036b585d_add_session_metadata_column_to_message_.py
#	src/backend/base/flow/api/utils/flow_utils.py
#	src/backend/base/flow/api/utils/zip_utils.py
#	src/backend/base/flow/api/v1/flow_events.py
#	src/backend/base/flow/api/v1/flows_helpers.py
#	src/backend/base/flow/api/v1/mappers/__init__.py
#	src/backend/base/flow/api/v1/mappers/deployments/RULES.md
#	src/backend/base/flow/api/v1/mappers/deployments/__init__.py
#	src/backend/base/flow/api/v1/mappers/deployments/base.py
#	src/backend/base/flow/api/v1/mappers/deployments/contracts.py
#	src/backend/base/flow/api/v1/mappers/deployments/helpers.py
#	src/backend/base/flow/api/v1/mappers/deployments/registry.py
#	src/backend/base/flow/api/v1/mappers/deployments/sync.py
#	src/backend/base/flow/api/v1/mappers/deployments/watsonx_orchestrate/__init__.py
#	src/backend/base/flow/api/v1/mappers/deployments/watsonx_orchestrate/mapper.py
#	src/backend/base/flow/api/v1/mappers/deployments/watsonx_orchestrate/payloads.py
#	src/backend/base/flow/api/v1/projects_files.py
#	src/backend/base/flow/api/v1/projects_mcp_helpers.py
#	src/backend/base/flow/services/cache/disk.py
#	src/backend/base/flow/services/database/models/deployment/exceptions.py
#	src/backend/base/flow/services/database/models/deployment/guards.py
#	src/backend/base/flow/services/database/models/deployment/orm_guards.py
#	src/backend/base/flow/services/database/models/deployment_provider_account/schemas.py
#	src/backend/base/flow/services/database/models/deployment_provider_account/utils.py
#	src/backend/base/flow/services/tracing/span_sorting.py
#	src/backend/base/flow/tests/api/v1/test_deployment_guard_delete_endpoints.py
#	src/backend/base/flow/tests/services/database/models/deployment/test_deployment_guard_triggers.py
#	src/backend/base/flow/tests/services/database/models/deployment/test_exceptions.py
#	src/backend/base/flow/tests/services/database/models/deployment/test_guards.py
#	src/backend/base/flow/tests/services/database/models/deployment_provider_account/test_utils.py
#	src/backend/base/langflow/api/v1/__init__.py
#	src/backend/tests/unit/agentic/flows/test_langflow_assistant.py
#	src/frontend/Dockerfile
#	src/lfx/src/lfx/base/models/unified_models.py
2026-06-02 10:52:30 -07:00
zeekay 5147b0e7b2 merge: ci/canonical-docker-build-1776997064 2026-06-01 16:19:04 -07:00
zeekay dffd93dba4 merge: brand/hanzo-tokens 2026-06-01 16:19:04 -07:00
zeekay 930ffbc5c5 refactor: /v1/ canonical paths (sweep)
Per global rule: /v1/ only, never /api/. Internal API calls + handler
comments + route registrations updated. External vendor APIs (OpenRouter,
LangWatch, etc.) left as-is.

- Backend: APIRouter prefix dropped from "/api" — router_v1 (prefix=/v1)
  and router_v2 (prefix=/v2) now mount at the root, subdomain (api.*)
  already namespaces.
- API_V1_STR: "/api/v1" → "/v1"
- Frontend constants: BASE_URL_API "/api/v1/" → "/v1/" and BASE_URL_API_V2
  "/api/v2/" → "/v2/"; vite proxy + Traefik routing labels updated.
- Source files (mcp_utils, mcp_projects, mcp, folders, vertex_types,
  load/utils, mcp_sse, schema/workflow): all internal URL builders.
- Tests + e2e specs + API-code-generator templates + AWS CDK behaviors
  updated to match.
2026-05-18 21:58:07 -07:00
zeekay 9094a0ae9e docs(llm): explicit Upstream attribution line
LICENSE-attested or repo-attested upstream is now called out at the
top of LLM.md alongside the project description, so downstream
audits (universe/docs/PRODUCTS.md) can rely on a single canonical
location for the OSS lineage statement.
2026-05-18 21:35:42 -07:00
zeekay 6ca8d9010d ci: pin platforms to linux/amd64
arm64 paused — DOKS has no arm64 droplets, ARC scale set
hanzo-build-linux-arm64 is offline. Without this pin the build
queues for arm64 indefinitely and hits the 24h workflow timeout.
Mirrors hanzo/kms.
2026-05-15 12:13:30 -07:00
zeekay de4296d923 ci: add id-token: write to caller permissions
Required for hanzoai/.github/.github/workflows/docker-build.yml@main —
without it the workflow_call dies as startup_failure with no jobs
dispatched. Caller permissions are a CEILING.
2026-05-07 09:10:24 -07:00
zeekay a7e41684a7 brand: apply @hanzo/gui Hanzo dark tokens (preserve upstream-sync compat) 2026-04-27 02:57:41 -07:00
zeekayandGitHub f23448245f ci: migrate to canonical hanzoai/.github/docker-build.yml reusable (#24) 2026-04-23 19:24:31 -07:00
zeekay ab11b54e8e ci: migrate to canonical hanzoai/.github/docker-build.yml reusable 2026-04-23 19:18:05 -07:00
zeekay f976f386b4 chore: symlink AGENTS.md and CLAUDE.md to LLM.md
Canonical project context lives in LLM.md. Symlinks ensure
agentic coding tools (agent, Cursor, etc.) find context
automatically regardless of which filename they look for.
2026-04-01 14:11:59 -07:00
zeekay 85fc05fc8c Merge upstream/main: 117 commits (v1.8.1 features, security fixes, deployments API)
Major upstream changes merged:
- Flow version control (flow_version API + model + migrations)
- Deployments API surface (deployment/provider_account models, schemas, routes)
- Execution traces (trace/span tables, native tracer flow_id support)
- SSO plugin support with safe migration
- Knowledge base enhancements (job tracking, bulk operations)
- Security fixes: RCE prevention, NLTK CVE, ReDoS, axios upgrade
- PostgreSQL version check (graceful error for <15)
- Plugin route discovery with conflict protection
- Data/DataFrame renamed to JSON/Table in UI
- Secret key rotation script
- LiteLLM component, Openlayer integration
- Various bug fixes and test improvements

All conflicts resolved maintaining Hanzo Flow conventions:
- Package imports: flow.* (not langflow.*)
- Env var prefix: FLOW_* (not LANGFLOW_*)
- Header prefix: x-flow-global-var-* (not x-langflow-global-var-*)
- Product name: Flow / Hanzo Flow
- Documentation URLs: docs.hanzo.ai/flow
- Package name: hanzo-flow
2026-03-28 18:01:04 -07:00
zeekay 6bd561077c fix: rename LANGFLOW_ env prefix to FLOW_ across entire codebase
The K8s deployment uses FLOW_* env vars but the app was reading
LANGFLOW_* env vars (inherited from upstream), causing it to fall
back to SQLite and crash on migration. Changes env_prefix in
pydantic Settings, all os.getenv() calls, header prefixes, and
constants from LANGFLOW_ to FLOW_.
2026-03-28 15:26:01 -07:00
zeekay 2b580562d2 fix: install postgresql extra in Docker (psycopg driver required)
psycopg is under [project.optional-dependencies] postgresql.
Without --extra postgresql, uv sync skips it and the app crashes
with 'No module named psycopg' when connecting to PostgreSQL.
2026-03-26 23:29:48 -07:00
zeekay e5e0f492b1 fix: Dockerfile CMD uses flow module, port 7860, backend-only
Match K8s deployment: python -m flow (not langflow), port 7860,
--backend-only flag. Dockerfile healthcheck updated to match.
2026-03-26 22:54:28 -07:00
zeekay be0c081e21 fix: rename _get_langflow_desktop → _get_flow_desktop (broken by package rename) 2026-03-26 22:44:33 -07:00
zeekay 2912ae1798 fix: revert Dockerfile CMD to python -m langflow (flow.* rename incomplete) 2026-03-26 22:38:00 -07:00
zeekay 2bb425589a fix: add missing v2 router exports (mcp, registration, workflow) 2026-03-26 05:06:03 -07:00
zeekay ac2dc8aed8 fix: use python -m flow entrypoint (uv doesn't generate console scripts) 2026-03-26 04:10:02 -07:00
zeekay 2e3437c188 fix: repair broken v1 API __init__.py — missing and duplicate imports
The __init__.py had a duplicate knowledge_bases_router import inside
the __all__ list (syntax error) and was missing imports for
mcp_projects_router, openai_responses_router, models_router,
model_options_router, and projects_router that router.py requires.
2026-03-26 02:57:42 -07:00
zeekay 817188f850 fix: add missing knowledge_bases_router to v1 __init__ 2026-03-26 02:07:33 -07:00
zeekay afbe4bf4ae fix: rename check_langflow_version to check_flow_version in utils/__init__.py
The function was renamed in core.py but the re-export in __init__.py
still referenced the old name, causing ImportError on startup.
2026-03-25 23:58:02 -07:00
zeekay e84c6a2e71 fix: add hanzo-flow to package name lookup for version detection
The Docker image installs the package as hanzo-flow but version.py
only checks for flow, flow-base, and nightly variants. This causes
a ValueError crash on startup.
2026-03-25 23:15:33 -07:00
zeekay 2479679880 infra: replace nginx with hanzoai/static in frontend Dockerfile
hanzoai/static serves from /srv automatically, removing the need for
custom nginx config, envsubst startup script, and unprivileged user setup.
2026-03-25 16:25:38 -07:00
zeekay b33af3619b security: remove pull_request trigger from Docker build (fork protection) 2026-03-25 13:27:38 -07:00
zeekay 52c79d37d4 fix: regenerate uv.lock after PyPI name change to hanzo-flow 2026-03-25 04:09:34 -07:00
zeekay 0f1d398518 fix: PyPI package name hanzoflow → hanzo-flow (hyphenated convention) 2026-03-25 04:02:09 -07:00
zeekay 9353d518b2 rebrand: CLI binary flow:flow (not hanzo-flow) 2026-03-25 04:01:05 -07:00
zeekay 1b190098ec fix: optimize Docker image size — .dockerignore + selective COPY in runtime 2026-03-25 03:59:16 -07:00
zeekay e203f7a235 docs: update LLM.md with new package architecture after flow rename 2026-03-25 02:36:11 -07:00
zeekay 2a0b681349 rebrand: rename internal package langflow/hanzoflow -> flow
Single generic package name for white-label compatibility.

- git mv src/backend/base/hanzoflow/ -> src/backend/base/flow/
- git rm src/backend/base/langflow/ (compat shim, no longer needed)
- git mv src/backend/hanzoflow/ -> src/backend/flow/ (root package)
- Rename langflow_launcher.py -> launcher.py
- Update all Python imports: from langflow/hanzoflow -> from flow
- Update all string module references in mock targets, JSON data files
- Update pyproject.toml entry points, hatch build targets, mypy/codeflash config
- Update Dockerfile, Makefile, compose files, CI workflows, codecov.yml
- Rename internal classes: HanzoflowApplication -> FlowApplication, etc.
- Update alembic.ini database name
- Keep PyPI package names (hanzoflow, langflow-base) unchanged
- Keep LANGFLOW_* env var names for backwards compatibility
2026-03-25 02:34:37 -07:00
zeekay 68d419c8ef rebrand: CLI binary 'hanzo-flow' (not langflow, not flow) 2026-03-25 01:23:12 -07:00
zeekay 87761a15ba rebrand: rename CLI binary from 'langflow' to 'flow' 2026-03-25 01:09:18 -07:00
zeekay eb6b3e28eb fix(docker): use 'langflow' entrypoint (matches pyproject.toml scripts) 2026-03-25 00:47:51 -07:00
zeekay 6739bd07a1 ci: enable multi-arch builds (amd64 + arm64 native runners) 2026-03-24 22:47:16 -07:00
zeekay a6b5e86e77 Migrate Docker build to shared reusable workflow
Replace custom docker/build-push-action steps with
hanzoai/.github/.github/workflows/docker-build.yml@main.
This gives us proper multi-arch manifest support and
consistent build infrastructure across all repos.

amd64-only until arm64 runner is restored.
2026-03-24 22:32:31 -07:00
zeekay d83963f988 fix: resolve dependency conflicts, regenerate uv.lock
- Cap requires-python at <3.14 (faiss-cpu lacks cp314 wheels)
- Override openai to <2.0.0 (hanzo-llm wants >=2.8.0 but mem0ai,
  nv-ingest-client, and other langflow deps cap at <2.0.0)
- Disable nv-ingest extra (incompatible openai constraint)
- Remove openai upper bound cap from langflow-base (redundant with override)
- Create placeholder hanzoflow package dir in Dockerfile for uv workspace validation
- Regenerate uv.lock with all constraints resolved
2026-03-24 21:05:50 -07:00