Skip to content

feat(agents): scaffold Condukt-backed agentic workflow infrastructure#30

Merged
pepicrft merged 5 commits into
mainfrom
docs/agents-documentation-guidance
Jun 12, 2026
Merged

feat(agents): scaffold Condukt-backed agentic workflow infrastructure#30
pepicrft merged 5 commits into
mainfrom
docs/agents-documentation-guidance

Conversation

@pepicrft

Copy link
Copy Markdown
Contributor

Motivation

I want Hive to be the place where Tuist's agentic meadow workflows live, and right now there's no agent infrastructure here at all. Atlas already runs a production Condukt setup that we like, so this PR stands up the equivalent scaffolding in Hive so adding an agent becomes a single-file change rather than a multi-day plumbing exercise.

While I was at it, I added a small AGENTS.md convention that documentation should describe behavior from the operator's perspective and not leak internal module names or refactoring artifacts. That bullet is the original reason this branch existed; the Condukt scaffolding grew from a follow-up question in the same session.

What's in the PR

Condukt scaffolding (feat(agents))

  • :condukt 1.7.0 from tuist/condukt, pinned the same way Atlas pins it.
  • HIVE_LLM_API_KEY / HIVE_LLM_MODEL / HIVE_LLM_BASE_URL read into :hive, :llm in config/runtime.exs. When the API key is unset, the LLM stays unconfigured and the rest of Hive boots normally, so self-hosters who do not want agentic features can deploy without an LLM.
  • Hive.Agents exposes config/0, enabled?/0, and client_opts/0. Hive.Agents.Sessions is the single call site wrapping Condukt.run/3 and Condukt.Operation.run/4 and merging in the LLM options, so individual agents stay free of LLM plumbing and so a future audit-trail layer has one place to hook in. Hive.Agents.StyleGuide.prose_rules/0 carries the cross-cutting style rules every agent appends to its system_prompt/0.
  • Hive.TestSupport.Agents.NoopAgent + NoopRuntime mirror Atlas's pattern: a minimal use Condukt module backed by a runtime that returns {:ok, "handled: " <> prompt}, useful for code that needs a real agent module without an LLM round-trip. Mimic.copy(Condukt, type_check: true) is added in test/test_helper.exs so async tests can stub at the framework boundary.
  • AGENTS.md gets a Tech Stack mention, a Layout pointer to lib/hive/agents/ plus the lib/hive/<domain>/agents/<name>_agent.ex convention, and a new ## Agents section with the env vars and a five-step "Adding an agent" walkthrough.

Documentation guidance (docs(agents))

A new bullet in the Conventions section saying docs should describe behavior and outcomes from the user's perspective, not internal module names, function signatures, code paths, or refactoring artifacts.

Approach and trade-offs considered

I weighed a couple of options before settling on this shape:

  • Full Atlas parity vs. minimum viable scaffolding. Atlas's setup includes DB-backed Session/Event Ecto schemas, a TelemetryHandler that streams Condukt's telemetry into those rows, a Sessions LiveView for the audit UI, and a Helm overlay (agent-sandboxes.yaml) that provisions a separate Kubernetes namespace for sandboxed pods. Porting all of that now would mean writing migrations, schemas, UI, and infra for a system with zero agents to feed it. I chose to defer those layers to the PR that lands the first concrete agent, where we will know what we actually need to record. Hive.Agents.Sessions is structured so audit hooks slot in without changing any agent's call site.
  • HIVE_ prefix vs. raw LLM_*. Atlas uses LLM_API_KEY / LLM_MODEL / LLM_BASE_URL. Hive's existing env-var convention is to namespace everything (HIVE_GOOGLE_CLIENT_ID, HIVE_OIDC_ISSUER, HIVE_S3_BUCKET, etc.) so I went with HIVE_LLM_* for consistency with the rest of runtime.exs.
  • Building a ReqLLM.Model struct vs. passing the model string through. Atlas's Runner constructs a ReqLLM.Model and pattern-matches on the provider so unsupported providers raise at config time. Condukt accepts a raw "provider:model_id" string and forwards it to ReqLLM, so I pass the string directly and let ReqLLM handle the parsing. We can revisit if we ever need provider-level guardrails.
  • Single Hive.Agents module vs. Hive.LLMs + Hive.LLMs.Runner split. Atlas splits LLM config and runtime helpers across two modules because it has dozens of agents and multiple invocation sites. Hive has none, so I folded both into Hive.Agents and kept the surface small. If it gets unwieldy we can split later.

Verification

  • mix deps.get resolved the new tree (Condukt plus the transitives it pulls).
  • mix compile --warnings-as-errors clean in :dev and :test. The remaining warnings come from timex and puid (transitive deps) and are pre-existing.
  • mix format run on every touched file.
  • Manual audit of the diff against Atlas's setup (lib/atlas/llms.ex, lib/atlas/llms/runner.ex, lib/atlas/agents/sessions.ex, lib/atlas/agents/style_guide.ex, test/support/agents/, test/test_helper.exs) to make sure the public shapes line up.
  • No tests added in this PR because the modules are thin delegations with no branching logic and no agent exists yet to exercise them end to end. The first agent PR will land tests that cover both the agent and the wrapper.

Follow-ups

  • First concrete agent (probably triage or summarization in the forage section) which will also drive the audit-DB schema and LiveView.
  • Update README.md once at least one agent is operator-visible (env vars users need to set, what the feature does); per the new convention bullet, that doc lands in the same PR as the feature.

pepicrft and others added 2 commits June 12, 2026 17:51
Add an AGENTS.md convention that documentation should describe behavior
from the operator/end-user perspective and not leak internal module
names, function signatures, or refactoring artifacts. Internals stay in
code and AGENTS.md; user-facing surfaces (README.md) describe outcomes.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Mirror the setup that powers Atlas's AI features so adding an agent in
Hive is a single-file change:

- Pull in :condukt 1.7.0 from tuist/condukt.
- Read HIVE_LLM_API_KEY / HIVE_LLM_MODEL / HIVE_LLM_BASE_URL into
  `:hive, :llm` in config/runtime.exs. When the key is unset the LLM
  stays unconfigured and the rest of Hive boots normally, so self-hosters
  who don't want agentic features can deploy without an LLM.
- Add `Hive.Agents` (config/0, enabled?/0, client_opts/0),
  `Hive.Agents.Sessions` (single call site wrapping `Condukt.run/3` and
  `Condukt.Operation.run/4` and merging in the LLM options), and
  `Hive.Agents.StyleGuide` (cross-cutting prose rules that every agent
  appends to its `system_prompt/0`).
- Provide `Hive.TestSupport.Agents.NoopAgent` + NoopRuntime so tests that
  don't need a real LLM round-trip can still exercise a `use Condukt`
  module, and Mimic-copy Condukt in test_helper.exs so stubs work across
  async tests without `Application.put_env`.
- Document the env vars and the "Adding an agent" walkthrough in
  AGENTS.md, and surface Condukt in Tech Stack and Layout so the docs
  describe the new directory layout.

DB-backed session/event audit, the audit LiveView, and any sandbox Helm
overlay are deferred until the first concrete agent lands, so this PR
ships the minimum surface to unblock that work without dead code.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@pepicrft pepicrft requested a review from a team as a code owner June 12, 2026 15:53
@pepicrft pepicrft requested review from esnunes and fortmarek and removed request for a team June 12, 2026 15:53
pepicrft and others added 3 commits June 12, 2026 18:03
Mirror Atlas's production LLM setup so the agentic scaffolding in this PR
is actually reachable on hive.tuist.dev:

- Add HIVE_LLM_MODEL (openai:accounts/fireworks/models/kimi-k2p5) and
  HIVE_LLM_BASE_URL (https://api.fireworks.ai/inference/v1) to the env
  block. Same provider, model, and endpoint as Atlas so we share rate
  limits and capacity planning, and so anyone reading both charts sees
  one consistent picture.
- Bind HIVE_LLM_API_KEY to the 1Password item hive-llm-api-key/credential
  via External Secrets. The 1Password item itself is created out-of-band;
  this PR only wires up the chart side.

Self-hosters who don't load values-production.yaml are unaffected: the
chart's generic defaults leave HIVE_LLM_API_KEY unset, and Hive.Agents
returns {:error, :llm_not_configured} until they set it themselves.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Add a Self-hosting > Agents page sibling to Authentication that covers
HIVE_LLM_API_KEY / HIVE_LLM_MODEL / HIVE_LLM_BASE_URL, what happens when
the API key is unset, and provider-shaped examples for Anthropic, OpenAI,
and OpenAI-compatible gateways such as Fireworks. This is the destination
self-hosters will look for once they hear Hive has agentic features, and
keeps Deployment focused on Helm plumbing rather than feature toggles.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Note in the Agents page that ReqLLM's catalog is sourced from
  models.dev so operators know where to look up valid
  `provider:model_id` values for HIVE_LLM_MODEL.
- Drop the Authentication bullet from "Why Hive". It describes a
  configuration detail (OIDC delegation), not a product capability
  that belongs in a "what Hive is" overview alongside Specs and Forage.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown

Blick review didn't run

The blick review step failed before producing a manifest, so there's no review to post on this PR. This usually means the agent (opencode) couldn't start — common causes are an expired or suspended model API key, a missing secret, or the workflow timing out.

See the workflow run for details: https://github.com/tuist/hive/actions/runs/27428396515

Commit: 8d54dca41c92eb61fb963cc01ddf4615cc4953a8

@pepicrft pepicrft merged commit 8cd0c37 into main Jun 12, 2026
10 checks passed
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.

2 participants