Skip to content

Add composite building-block examples - #1

Open
anthonyshafer wants to merge 3 commits into
subforkdev:mainfrom
anthonyshafer:add-composite-building-blocks
Open

anthonyshafer wants to merge 3 commits into
subforkdev:mainfrom
anthonyshafer:add-composite-building-blocks

Conversation

@anthonyshafer

Copy link
Copy Markdown

Summary

Adds seven small, generic graphs that are meant to be called from a parent graph as composites. Each is built only from released nodes, has a typed composite_interface and matching graph_inputs, and holds no credentials. Where a service needs auth, the parent builds the request headers from its own secrets and passes them in through a headers input.

Graph Path What it does
LLM Call graphs/pipes/http/llm-call Builds a chat request body, POSTs it to a caller-supplied URL, extracts the reply
Audit Log Write graphs/pipes/http/audit-log-write POSTs one audit record to a caller-supplied sink and reads back its id (externally visible write)
Job Run graphs/pipes/jobs/job-run Generic submit-and-poll for an HTTP job service
Approval Gate graphs/pipes/jobs/approval-gate Requests a human approval as a job and polls until approved, rejected, or expired
Render Job graphs/pipes/jobs/render-job Submit-and-poll, then rebuilds the file URL from the base URL and downloads the artifact
Fallback Match graphs/pipes/transforms/fallback-match Exact-key left join that returns a recorded fixture when the join is empty
Media Probe Normalize graphs/media/video/media-probe-normalize Probes one audio or video artifact and projects the facts into a stable shape

Each graph ships with <name>.subfork.json, <name>.notes.md, and <name>.thumbnail.jpg (also embedded in the envelope as a 480x320 JPEG). Notes cover the Notes Checklist (purpose and data flow, inputs and outputs, authentication, security guidance, side effects, limits, and validation status) except a Subfork version, which is not published. Each note records the check date (2026-11-05) and the node catalog size (75 node types) instead.

Index updates: graphs/README.md, graphs/pipes/README.md, graphs/media/README.md, graphs/media/video/README.md. A new graphs/pipes/jobs/ subfolder has its own README.md landing page.

Design notes

  • No secrets are referenced (requires.secrets is empty for all seven). Notes show how a parent builds headers from its own graph-scoped secret.
  • The job graphs describe the submit and poll behavior in prose in job-run.notes.md: request fields, response fields id, status, status_url, url, result, error, the statuses queued, running, completed, failed, cancelled, rejected, expired, an integer poll_after_seconds hint, and idempotency_key. They use the built-in HTTP Submit Job and HTTP Poll Job nodes and add no node types.
  • Graphs that write externally (Audit Log Write, Job Run, Approval Gate, Render Job) say so in the description and notes, document retry and duplication risk, and set external-write in requires.capabilities.
  • metadata.template.status is network-probe for LLM Call and Audit Log Write, media-worker-probe for Media Probe Normalize, and mock-only-probe for Job Run, Approval Gate, Render Job, and Fallback Match. The three job graphs ship as mock-only because they have not been run against a live job service.
  • Tags use the existing vocabulary (pipes, http, ai, operations, automation, rendering, transforms, media, video).
  • Thumbnails are simple diagram cards generated locally with the graph title and main node chain. They were not exported from the app. The Job Run, Approval Gate, and Render Job cards say "main steps shown" because the helper nodes (headers, endpoint, and the like) are left out of the drawing.
  • No reference service or server code is included. This PR is graphs, notes, and indexes only.

Known caveats

  • Approval Gate does not block by itself. The poll node lists rejected and expired as failure statuses, but whether a failed poll halts dependent nodes is unverified. The notes and the graph description say the service that performs the effect must confirm the approval itself (read the job at its status_url and require status completed) before acting.
  • Credential-bearing URL inputs (url, sink_url, base_url) receive the headers, including any bearer token. The notes tell authors to pass a literal URL from the parent and never feed it from untrusted data, and to use a low-privilege token. Happy to rework these to pin an origin through a variable if reviewers prefer.
  • The poll node follows the status_url the service returns, with the same headers. Whether it enforces a same-host rule is unverified, so the notes advise pointing the graphs only at a service the author controls.
  • Media Probe Normalize needs a media-worker worker. Its default mapping is a guess at the probe key layout and needs one run to confirm.
  • Fallback Match: whether the fallback node returns the fixture for an empty join is unconfirmed. Two fixture runs used a left join with records in left, so the join was never empty and the fixture was not used. The notes say how to check with an empty left list.

Verification

Run from the repository root on this branch:

  • python3 scripts/validate_examples.py exits 0: "Validated 69 Subfork example graphs." (62 existing plus 7 new.)
  • python3 scripts/validate_examples.py --node-catalog-url https://subfork.com/api/v1/nodes exits 0: "Checked node types against the target catalog (75 available types)."
  • python3 -m unittest discover -s scripts -p 'test_validate*.py' runs 6 tests, OK.
  • mkpages build . --output .mkpages (mkpages 0.4.1) builds 105 pages with the seven new notes pages and the pipes/jobs landing page present. The PNG social card is Linux-only, so the SVG fallback was used on macOS.
  • A case-insensitive scan of the added lines found no local paths, credentials, or account-specific identifiers.
  • All seven graphs, as committed in this PR, passed Subfork's POST /graphs/validate (server-side validation) on 2026-11-05. A deliberately broken definition (unknown node type) was rejected with HTTP 422, so the check is not a no-op.
  • LLM Call and Audit Log Write were each imported into a Subfork account and executed once on 2026-11-05, and both runs completed. LLM Call posted to the httpbin.org echo endpoint and Audit Log Write posted to jsonplaceholder.typicode.com. Fallback Match was executed twice with fixture inputs and no network, and both runs completed. The published definitions of these three graphs match the files here apart from server-added empty defaults. The test runs bound fixture values, and the LLM Call run set reply_path to read the echoed prompt instead of the default choices.0.message.content.

All seven graphs use only node versions 1.0.0.

Not verified

  • Job Run, Approval Gate, and Render Job are mock-only. They passed the repository validator, the node-catalog check, and server-side validation, but have not been run against a live job service: no job submission, no approval request, no file download.
  • Media Probe Normalize was not executed. It needs an artifact input and a media-worker worker.
  • The LLM Call and Audit Log Write runs used public test endpoints, not a real model provider, audit sink, or production data, so they do not confirm behavior against those services. The LLM Call run did not exercise the default reply path.
  • Fallback Match: neither run produced an empty join, so the fixture fallback itself has not been exercised.
  • Subfork version: no platform version could be found. These paths return 404 JSON: /api/v1/version, /api/v1/health, /api/v1/status, /api/version, /api/v1/openapi.json, /api/openapi.json, /api/v1/docs, and /api/docs. /api/health returns only {"status":"ok"}, and the site root HTML shell does not state a version. Each note records the check date and node catalog size instead: the catalog served 75 node types on 2026-11-05, and every node used here is version 1.0.0.
  • Behaviors listed as unverified in the notes: whether the job graphs' standalone placeholders keep their JSON type, whether a poll that reaches a failure status raises a node error or returns the status, the longest wall time a single run can wait, and the 250,000,000 byte response cap in Render Job. Placeholders nested inside array and object template values resolved correctly in the LLM Call run.

Questions for maintainers

  • Is graphs/pipes/jobs/ an acceptable new subfolder, or would you prefer these under existing folders?
  • Are composite-ready examples with typed interfaces welcome in the pipes and media categories as proposed?
  • The split is easy if you prefer smaller PRs: the three job graphs and the jobs folder can go separately from the other four.

…te, render job, audit log write, fallback match, media probe)
Set metadata.template.status to mock-only-probe for job-run, approval-gate,
and render-job, and note in each notes file that the graph was validated by
the repository validator and the Subfork server-side validate endpoint but has
not been run against a live job service.
Replace the not-executed text in the LLM Call, Audit Log Write, and Fallback
Match notes with the actual run record (date, endpoint, result, what was and
was not exercised). Add the server-side validation result and the node
catalog size to all seven notes, and drop the duplicated trailing line from
the three job notes. Mark Media Probe Normalize as media-worker-probe to
match the repository convention. Label the Job Run, Approval Gate, and
Render Job cards as showing the main steps only and regenerate the embedded
and sidecar thumbnails.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant