agentflow

package module
v0.5.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 25, 2026 License: Apache-2.0 Imports: 60 Imported by: 0

README

agentflow-go

Go Reference License Release

English | 简体中文

agentflow-go 是面向 Go 后端工程师 的可嵌入 Agent 运行时库:用 Go 代码(pkg/buildercore.Scenario)定义 Agent、Tool、Skill 与工作流,在自有服务中显式接线 LLM Gateway、Memory、RunState 与 Human-in-the-loop,然后调用 Framework.Run——无需 Python 运行时,也无需把业务托管到外部 Agent 平台

适合谁: 已有 Go 后端、要在进程内或自管 Worker 中落地 Agent/工作流,并重视类型安全、可测试性、审批治理与生产可观测的团队。

功能强项

编排与运行时
  • 三种编排模式autonomous(ReAct 工具循环)、fixed_workflow(确定性 DAG)、hybrid(工作流阶段 + 自主阶段)
  • 图表达能力:subgraph 嵌套、map 动态 fan-out、parallel_grouploop、条件边;Builder 提供 MapOverRouteIfParallelGroup 等 DSL
  • Skill 语义:prompt 片段 + tool 白名单/策略 + 可内联 workflow 子图,编译期展开为命名空间节点
  • 多 Agent:supervisor + sub_agents 虚拟 delegation tool;可选 planning pass(自主执行前 JSON 计划)
  • AI 自动构图(ComposeGraph):一句话任务 → agentic composer 带构图工具循环 + 增量校验反馈,产出可校验 DAG;catalog 模式只编排已注册零件,scenario 模式可增量新建 Agent/Skill(拒绝覆盖已有 ID);默认 ephemeral 执行,不改写 live 场景(用法见 compose-graph.md,机制见 orchestration-flow.md 第十一节,示例 examples/go/compose-graph
生产治理
  • 工具治理:Agent 白名单、审批拒绝、每 run rate cap、分类 LLM/Tool 重试、工具结果大小限制
  • Human-in-the-loop:自主暂停、workflow human_gate 节点、HMAC Token、ResumeAndContinue 续跑
  • 企业能力:Identity 上下文、API Key / JWT middleware、RBAC、AuditSink 审计事件
  • 持久化与时间旅行:File / PostgreSQL / Redis RunState;S3 兼容 Blob;CAS 快照、Checkpoint 历史链、从任意 step/checkpoint 恢复或分叉
AgentFlow Studio(内置 Web 调试台)

挂载 NewObservabilityHTTPHandler 即可在 /observability/ 获得可视化面板(默认中文)。新一代 Studio 是 AI-first 构图工作台(React + React Flow SPA,go:embed 内嵌,单二进制分发;未构建前端时回退旧版内联 UI):

视图 能力
画布 AI 构图栏(一句话 → catalog/scenario 两种模式生成图,上图即为可编辑草稿)、零件箱拖入、React Flow 画布编辑、节点 Inspector、Undo/Redo、校验 / YAML / Go codegen / 保存、试跑面板(SSE 节点实时高亮 + HITL 批准)
运行 runs 列表轮询、Trace 树(span 嵌套)、step 输出、checkpoint 时间轴(查看快照 / 从版本恢复 / 分叉)、thread lineage
对比 双 run step 级 diff(仅 A / 仅 B / 输出不一致高亮)

前端工程在 web/studio/(Vite + React + TS + Tailwind),make studio-ui 构建并嵌入;HTTP API 新增 POST /api/studio/composeGET /api/studio/parts(生产侧镜像为 /v1/studio/compose/v1/studio/parts)。

示例:go run ./examples/go/http-worker/main.gohttp://127.0.0.1:7060/observability/。详见 observability-dashboard.mdstudio-roadmap.md

可观测与部署
  • 指标与追踪:Prometheus recorder、OpenTelemetry tracer、事件级 parent_span_id 传播
  • HTTP 生产套件httpx.NewProductionHTTPHandler、异步 Job Worker(run / event / resume.continue
  • Memory Tier:Postgres warm + file/S3 cold tier、迁移事件、可选 RAG 摘要协同
  • 参考部署Compose 栈Helm chart
开发者体验
  • Builder-first(v0.2+):场景即 Go 代码,ValidateScenario + make validate-builder 可进 CI;Studio 仍支持 YAML 导入/导出互操作
  • 显式 Hexagonal 接线:Gateway、ToolExecutor、RunState、EventSink 由宿主控制,单测与 mock 友好
  • 与 LangGraph 的差异:Go 原生嵌入、Scenario 可校验、企业可读 tool 契约;借鉴编排概念但不做 Python 全量 parity(见 competitive-analysis-langgraph.md

快速开始

go get github.com/aijustin/agentflow-go
go run ./examples/go/minimal/main.go
go run ./examples/go/builder/main.go
make validate-builder
make test

产品方向:docs/product-direction.md · Builder 参考:docs/builder-reference.md

发布前建议运行 GOTOOLCHAIN=auto make release-check。见 docs/release-checklist.mddocs/api-stability.md

集成指南:docs/library-integration.md · HTML 手册:docs/manual.html · 与 LangGraph 对比:docs/competitive-analysis-langgraph.md

集成路径

目标 入口
首选:Go DSL 构造场景 docs/builder-reference.md · examples/go/builder/main.go
嵌入现有 Go 服务 docs/library-integration.md
进程内最小运行 examples/go/minimal/main.go
Postgres / 文件持久化 examples/go/postgres/main.go
HTTP + 异步 Worker examples/go/http-worker/main.go
HITL 暂停与恢复 examples/go/hitl-resume/main.go
事件触发 examples/go/event-trigger/main.go
测试与示例接线 pkg/testutil

库 API(根包):ValidateWiringNewFramework.Run / ComposeGraphNewFrameworkJobHandlerScenarioJSONSchemaVersion;HTTP 构造器在 pkg/httpx(如 NewProductionHTTPHandlerNewObservabilityHTTPHandler);适配器在 pkg/adapters(如 NewPrometheusRecorderNewOpenTelemetryTracer、RunState/Blob/EventStore);Builder 栈入口见 builder.go(如 MinimalAutonomous)。

示例路径对照表

可运行 Go 示例(examples/go/
目录 说明 运行命令
builder Go DSL 构造场景并进程内 Run(推荐起点 go run ./examples/go/builder/main.go
minimal 最小嵌入:buildertestutil.WiringOptionsNewRun go run ./examples/go/minimal/main.go
compose-graph AI ComposeGraph(catalog / scenario 模式) go run ./examples/go/compose-graph
postgres Postgres / 文件 RunState 持久化 go run ./examples/go/postgres/main.go
http-worker 挂载 httpx.NewProductionHTTPHandler + 异步 Worker + Studio go run ./examples/go/http-worker/main.go
hitl-resume HITL 暂停与 ResumeAndContinue go run ./examples/go/hitl-resume/main.go
event-trigger scenario.triggers 事件驱动 Run go run ./examples/go/event-trigger/main.go
tier-memory 进程内 tier 记忆最小示例 go run ./examples/go/tier-memory/main.go
tier-worker Postgres warm/cold tier + memory.reconcile 异步 Worker examples/deploy/
validate 校验 builder catalog 或 legacy YAML go run ./examples/go/validate -kind builder all

生产环境请用 WithLLMGateway / WithToolExecutor 替代 testutil.WiringOptions;测试接线见 pkg/testutil

Builder catalog 对照

完整 Catalog ID 与 builder.* 函数对照见 docs/builder-reference.md。共享 stack 实现在 examples/go/scenario/scenario.go

校验全部 catalog stack:

go run ./examples/go/validate -kind builder all
make validate-builder

环境要求

  • Go 1.25.12+
  • macOS/Linux shell
  • 构建 Studio SPA:Node.js 24 LTS + pnpm 10(普通 Go 构建无需 Node.js)
作为框架在其他 Go 项目中使用

添加依赖:

go get github.com/aijustin/agentflow-go

引入根门面包:

package main

import (
    "context"
    "fmt"
    "log"

    agentflow "github.com/aijustin/agentflow-go"
    "github.com/aijustin/agentflow-go/pkg/builder"
)

func main() {
    scenario := builder.MinimalAutonomous("assistant")
    fw, err := agentflow.New(scenario, agentflow.WithLLMGateway(myLLMGateway))
    if err != nil {
        log.Fatal(err)
    }

    result, err := fw.Run(context.Background(), agentflow.RunRequest{
        RunID:  "run-1",
        Agent:  "assistant",
        Prompt: "hello",
    })
    if err != nil {
        log.Fatal(err)
    }

    fmt.Println(result.Output)
}

如需接入自定义 LLM、Memory、RunState、EventSink 或 HumanGate,可使用 Option API:

scenario := builder.MinimalAutonomous("assistant")
fw, err := agentflow.New(
    scenario,
    agentflow.WithLLMGateway(myLLMGateway),
    agentflow.WithToolExecutor("repo_search", myToolExecutor),
    agentflow.WithMemoryRepository("session", myMemoryRepo),
    agentflow.WithRunStateRepository(myRunStateRepo),
    agentflow.WithEventSink(myEventSink),
)

常见 LLM Provider 的构造函数已从根包暴露:

gateway := adapters.NewOpenAICompatibleGateway([]llm.Profile{{
  Name:      "default",
  Provider:  "openai-compatible",
  Model:     "qwen/qwen3.6-35b-a3b",
  Endpoint:  "http://127.0.0.1:1234/v1",
  APIKeyEnv: "AGENT_REALMODEL_API_KEY",
}}, nil)

scenario := builder.MinimalAutonomous("assistant")
fw, err := agentflow.New(scenario, agentflow.WithLLMGateway(gateway))

如果需要同时接 OpenAI-compatible 聊天与 Embedding,可使用 NewOpenAICompatibleProvider,并显式声明 profile 能力:

provider := adapters.NewOpenAICompatibleProvider([]llm.Profile{
  {Name: "chat", Provider: "openai-compatible", Model: "qwen/qwen3.6-35b-a3b", Endpoint: "http://127.0.0.1:1234/v1"},
  {Name: "embed", Provider: "openai-compatible", Model: "text-embedding-3-small", Endpoint: "http://127.0.0.1:1234/v1", Capabilities: []llm.Capability{llm.CapEmbed}},
}, nil)

混合 Provider 场景可使用 NewLLMProviderRouter 按 profile 路由 chat/tool/structured/stream 和 embedding 调用。能力会显式检查:Provider 不支持的能力会清晰失败,不会被静默模拟。

openaiProvider := adapters.NewOpenAICompatibleProvider(openaiProfiles, nil)
anthropicGateway := adapters.NewAnthropicGateway(anthropicProfiles, nil)

provider := adapters.NewLLMProviderRouter(map[string]llm.Gateway{
  "chat":  anthropicGateway,
  "embed": openaiProvider,
})

结构化输出:在 agents.<name>.output_schema 中配置 JSON Schema,并调用 RunStructured。LLM Gateway 需要实现 llm.StructuredOutputter

result, err := fw.RunStructured(ctx, agentflow.RunRequest{
    RunID:  "run-json",
    Agent:  "assistant",
    Prompt: "return JSON",
})
fmt.Println(string(result.StructuredOutput))

流式输出:使用实现了 llm.Streamer 的 Gateway:

chunks, err := fw.Stream(ctx, agentflow.RunRequest{
    RunID:  "run-stream",
    Agent:  "assistant",
    Prompt: "stream the answer",
})
if err != nil {
    log.Fatal(err)
}
for chunk := range chunks {
    if chunk.Error != "" {
        log.Fatal(chunk.Error)
    }
    fmt.Print(chunk.Content)
}

当 Agent 配置了工具,并且 LLM Gateway 支持 CapToolCall 时,Runtime 会执行自主工具调用循环:向 LLM 发送工具规格,校验返回的工具调用是否在 Agent 白名单中,执行审批策略和每次运行的 rate_cap,按 retry_limit/max_retries 对分类后的临时 LLM/工具错误做指数退避重试(write/external/dangerous 工具默认不自动重试),执行注册的 ToolExecutor,将受限后的工具结果回填给 LLM,直到 LLM 返回最终答案或达到 max_steps

Stream 也支持带工具的 Agent:跑与 Run 相同的受治理 tool loop,并在循环中按序发出 kind=tool_call / tool_result(或 tool_denied)进度 chunk,最终答案仍以终端 Done chunk 交付(进度不写入最终持久化输出)。每轮模型调用当前仍为阻塞 ChatWithTools(非 provider 级 tool_call token 流)。若 Agent 配置了 before_final_answer HITL checkpoint,Stream 会直接拒绝(请改用 Run / RunStructured);工具级 approval: pause 仍可通过流结束时的 Paused chunk 暴露。固定工作流若含 agent 节点,RunStructured / Stream 会拒绝,以免 agent 被完整执行后再二次跑自主/结构化阶段。

配置 orchestration.planning.enabled: true 后,Runtime 会在自主工具循环前先执行规划 pass。规划默认使用当前执行 Agent,也可以通过 orchestration.planning.agent 指定专门规划 Agent;生成的简短 JSON 计划会注入后续执行上下文。设置 orchestration.planning.execute: true 可在 tool loop 中跟踪 plan step 完成状态(见 builder.MultiExpertResearch())。

固定工作流支持 toolagentskillhuman_gatetransformparallel_grouploop 节点。condition 可使用 exists(...)missing(...)eq(...)ne(...) 读取 steps.<node_id> 路径,transform 节点可用 set/copy 从前序步骤构造结构化输出。

当 Agent 绑定 memory 时,Runtime 会在上下文准备前读取 conversation/session 记忆并注入 LLM 上下文,执行后追加用户输入、助手回复和工具观察结果。根门面会自动为 in_memory 类型创建内存仓库,除非调用方显式传入自定义仓库。session / long_term 作用域必须显式配置 namespace(否则 Validate/New 失败),避免默认落到 scenario:agent 导致跨调用方串会话。

启用内置 HMAC Token 的 HITL Gate:

scenario := builder.MinimalHumanInLoop("assistant")
fw, err := agentflow.New(scenario,
    agentflow.WithHITLTokenSecret([]byte("strong-secret-16bytes"), nil),
)
if err != nil {
    log.Fatal(err)
}

result, err := fw.Run(ctx, agentflow.RunRequest{RunID: "run-1", Prompt: "needs approval"})
if err != nil {
    log.Fatal(err)
}

if result.Token != "" {
    err = fw.Resume(ctx, result.Token, core.DecisionApprove, nil)
}

需要进程重启后仍能恢复运行时,可使用文件持久化适配器:

runs, _ := adapters.NewFileRunStateRepository("./data/runs")
blobs, _ := adapters.NewFileBlobStore("./data/blobs")
memoryRepo, _ := adapters.NewFileMemoryRepository("./data/memory")

scenario := builder.MinimalAutonomous("assistant")
fw, err := agentflow.New(scenario, agentflow.WithRunStateRepository(runs),
    agentflow.WithBlobStore(blobs),
    agentflow.WithMemoryRepository("session", memoryRepo),
)

生产环境需要 PostgreSQL RunState 时,可在应用侧注册 database/sql driver,并把初始化后的连接池传给根门面构造器:

db, err := sql.Open("pgx", os.Getenv("AGENTFLOW_POSTGRES_DSN"))
if err != nil {
  log.Fatal(err)
}
runs, err := adapters.NewPostgresRunStateRepository(db)
if err != nil {
  log.Fatal(err)
}

scenario := builder.MinimalAutonomous("assistant")
fw, err := agentflow.New(scenario, agentflow.WithRunStateRepository(runs),
)

表结构契约和运维注意事项见 docs/persistence/postgres-runstate.md

如果希望使用 Redis 存储低延迟 CAS RunState,也可以使用 Redis RunState 适配器:

runs, err := adapters.NewRedisRunStateRepository(adapters.RedisRunStateRepositoryConfig{
  Addr:      os.Getenv("AGENTFLOW_REDIS_ADDR"),
  Password:  os.Getenv("AGENTFLOW_REDIS_PASSWORD"),
  KeyPrefix: "agentflow:runstate:",
})
if err != nil {
  log.Fatal(err)
}

存储语义和运维注意事项见 docs/persistence/redis-runstate.md

生产环境异步执行可使用队列和 Worker。PostgreSQL 队列适配器基于 database/sql,不强制绑定具体驱动:

queue, err := adapters.NewPostgresJobQueue(db)
if err != nil {
  log.Fatal(err)
}

runHandler, err := agentflow.NewFrameworkJobHandler(agentflow.FrameworkRunJobHandlerConfig{Framework: fw})
if err != nil {
  log.Fatal(err)
}

worker, err := async.NewWorker(queue, runHandler, async.WorkerConfig{
  WorkerID:      "worker-1",
  Concurrency:   4,
  LeaseTTL:      time.Minute,
  RenewInterval: 30 * time.Second,
  JobTimeout:    5 * time.Minute,
})

httpx.NewProductionHTTPHandler 会挂载 /healthz/readyz、异步 run/event/resume job API;当配置 Framework 时还会挂载同步 /v1/events/v1/hitl/resume。构造器默认要求 AuthMiddleware + Policy;仅 loopback 本地开发可显式设置 InsecureAllowNoAuth。更多说明见 docs/async-runtime.mddocs/persistence/postgres-queue.md

MCP Server 可以通过适配器变成普通受治理工具,无需改变 runtime core:

mcpClient, err := adapters.NewMCPHTTPClient("http://127.0.0.1:3333/mcp", nil)
if err != nil {
  log.Fatal(err)
}
searchTool, err := adapters.NewMCPToolExecutor(mcpClient, "search")
if err != nil {
  log.Fatal(err)
}
fw, err := agentflow.New(builder.MinimalMCPTool("assistant"),
  agentflow.WithToolExecutor("docs.search", searchTool),
)

适配模型和安全注意事项见 docs/mcp-tools.md

重型或租户隔离的工具不需要在框架启动时全部构造。可以先在 scenario.tools 声明 manifest,然后通过 WithToolResolver 在运行时完成 allowlist、审批、RBAC、治理策略和 rate cap 检查后,再按需解析真正的 executor:

resolver := adapters.ToolResolverFunc(func(ctx context.Context, tool core.Tool) (core.ToolExecutor, error) {
  switch tool.Type {
  case "builtin.sql":
    return newTenantSQLTool(ctx, tool.Metadata)
  case "mcp.tool":
    return newTenantMCPTool(ctx, tool.Metadata)
  default:
    return nil, fmt.Errorf("unsupported tool type %q", tool.Type)
  }
})

scenario := builder.MinimalAutonomous("assistant")
fw, err := agentflow.New(scenario, agentflow.WithToolResolver(resolver),
)

WithToolExecutor 仍适合轻量或常驻工具,并且优先级高于 resolver。resolver 解析出的 executor 会按场景工具名缓存在 framework 生命周期内。Skill 不负责初始化工具;它只在场景构建阶段展开 prompt 片段、策略覆盖和 workflow 片段,真实 executor 绑定由 resolver 在调用时完成。

读取内部 API 可注册受限 HTTP Tool Executor:

httpTool, err := adapters.NewHTTPToolExecutor(adapters.HTTPToolConfig{
  AllowedHosts: []string{"https://status.example.internal"},
})
if err != nil {
  log.Fatal(err)
}
fw, err := agentflow.New(builder.MinimalHTTPTool("assistant"),
  agentflow.WithToolExecutor("http.status", httpTool),
)

该执行器必须配置 host allowlist,默认只允许 GET/HEAD。详见 docs/tools-http.md

读取本地 runbook 或已检出的文档,可注册受限文件系统读取 Tool Executor:

filesystemTool, err := adapters.NewFilesystemToolExecutor(adapters.FilesystemToolConfig{
  AllowedRoots: []string{"/srv/agentflow/runbooks"},
})
if err != nil {
  log.Fatal(err)
}
fw, err := agentflow.New(builder.MinimalFilesystemTool("assistant"),
  agentflow.WithToolExecutor("fs.read", filesystemTool),
)

该执行器必须配置 root allowlist,会拒绝路径逃逸和符号链接逃逸,并限制文件大小。详见 docs/tools-filesystem.md

需要读取业务库、工单库或报表库时,可注册受限 SQL 查询 Tool Executor,并使用命名 allowlist 查询:

sqlTool, err := adapters.NewSQLToolExecutor(adapters.SQLToolConfig{
  DB: db,
  AllowedQueries: map[string]string{
    "tickets.open": "SELECT id, title, status FROM tickets WHERE status = $1",
  },
  MaxRows: 20,
})
if err != nil {
  log.Fatal(err)
}
fw, err := agentflow.New(builder.MinimalSQLTool("assistant"),
  agentflow.WithToolExecutor("sql.query", sqlTool),
)

该执行器默认只执行命名 SELECT 查询,拒绝多语句 SQL,带超时并限制返回行数。详见 docs/tools-sql.md

SQL 工具可接入任意 database/sql 驱动,包括 PostgreSQL、MySQL 和 ClickHouse。宿主应用自行导入具体驱动并传入已打开的 *sql.DB;agentflow-go 不强制引入数据库驱动依赖。

代码审查流水线可注册只读 Git 工具:

gitTool, err := adapters.NewGitToolExecutor(adapters.GitToolConfig{
  AllowedRoots: []string{"/workspace/repos"},
})
fw, err := agentflow.New(builder.CodeReviewPipeline(),
  agentflow.WithToolExecutor("git", gitTool),
)

详见 docs/tools-git.md。须通过 WithToolExecutor(或 WithToolResolver)显式注册 executor。

客服工单场景可注册 ticket 工具并注入 store:

store := adapters.NewMemoryTicketStore(map[string]adapters.Ticket{
  "T-9": {ID: "T-9", Title: "Login issue", Status: "open"},
})
ticketTool, err := adapters.NewTicketToolExecutor(adapters.TicketToolConfig{Store: store})
fw, err := agentflow.New(builder.MinimalTicketHandling("support"),
  agentflow.WithToolExecutor("ticket", ticketTool),
)

详见 docs/tools-ticket.md

RAG 场景可组合 Embedder、VectorStore 和 Retriever Tool:

store, err := adapters.NewPostgresVectorStore(adapters.PostgresVectorStoreConfig{DB: db})
if err != nil {
  log.Fatal(err)
}
retriever, err := adapters.NewRetrieverTool(adapters.RetrieverToolConfig{
  Embedder:     provider,
  Store:        store,
  Profile:      "embed",
  Namespace:    "tenant-a/docs",
  DefaultLimit: 5,
})
if err != nil {
  log.Fatal(err)
}
fw, err := agentflow.New(builder.MinimalRAG("assistant"),
  agentflow.WithLLMGateway(provider),
  agentflow.WithToolExecutor("knowledge.retrieve", retriever),
)

公共契约和 pgvector 表结构见 docs/knowledge-rag.mddocs/persistence/pgvector.md

使用 migrations/postgres 中的 SQL,由宿主应用自己的 migration 工具建表后再接入 Postgres 适配器。见 docs/persistence/postgres-runstate.mddocs/persistence/postgres-queue.md

大输出需要进入 S3-compatible 对象存储时,可单独配置 BlobStore:

blobs, err := adapters.NewS3BlobStore(adapters.S3BlobStoreConfig{
  Endpoint:        os.Getenv("AGENTFLOW_S3_ENDPOINT"),
  Bucket:          os.Getenv("AGENTFLOW_S3_BUCKET"),
  Region:          os.Getenv("AGENTFLOW_S3_REGION"),
  Prefix:          "agentflow/outputs",
  AccessKeyID:     os.Getenv("AGENTFLOW_S3_ACCESS_KEY_ID"),
  SecretAccessKey: os.Getenv("AGENTFLOW_S3_SECRET_ACCESS_KEY"),
})
if err != nil {
  log.Fatal(err)
}

scenario := builder.MinimalAutonomous("assistant")
fw, err := agentflow.New(scenario, agentflow.WithBlobStore(blobs),
)

对象路径和安全注意事项见 docs/persistence/s3-blobstore.md

企业级可观测和治理能力保持可选且低依赖:

scenario := builder.MinimalAutonomous("assistant")
fw, err := agentflow.New(scenario, agentflow.WithEventSink(adapters.NewSlogEventSink(logger)),
  agentflow.WithAuditSink(adapters.NewSlogAuditSink(logger)),
  agentflow.WithToolGovernancePolicy(governance.ChainToolPolicies(
    governance.NewToolBudgetPolicy(8),
    governance.NewMaxSideEffectPolicy(core.SideEffectRead),
  )),
  agentflow.WithOutputRedactor(governance.NewJSONFieldRedactor("secret", "token")),
)

治理策略会在工具执行前生效,输出脱敏会在运行时 step output 持久化前执行。

AgentFlow 也内置了运行时可观测面板,用于查看实时会话、编排时序和事件详情。PostgreSQL 事件仓库默认自动创建表和索引,开启面板只需要接入事件 sink 并挂载 HTTP handler:

eventStore, err := adapters.NewPostgresEventStore(ctx, adapters.PostgresEventStoreConfig{DB: db})
if err != nil {
  log.Fatal(err)
}
eventHub := adapters.NewEventHub()

scenario := builder.MinimalAutonomous("assistant")
fw, err := agentflow.New(scenario, agentflow.WithEventSink(adapters.NewEventFanoutSink(
    adapters.NewEventStoreSink(eventStore, eventHub),
    adapters.NewSlogEventSink(logger),
  )),
)

dashboard, err := httpx.NewObservabilityHTTPHandler(httpx.ObservabilityHTTPHandlerConfig{
  Store:               eventStore,
  Hub:                 eventHub,
  InsecureAllowNoAuth: true, // 仅限本地开发;生产必须配置 AuthMiddleware
})
mux.Handle("/observability/", http.StripPrefix("/observability", dashboard))

数据库配置、自动建表、接口列表和安全建议见 docs/observability-dashboard.md

底层扩展接口位于:

  • github.com/aijustin/agentflow-go/pkg/core
  • github.com/aijustin/agentflow-go/pkg/llm
  • github.com/aijustin/agentflow-go/pkg/contextwindow
  • github.com/aijustin/agentflow-go/pkg/async
  • github.com/aijustin/agentflow-go/pkg/audit
  • github.com/aijustin/agentflow-go/pkg/governance
  • github.com/aijustin/agentflow-go/pkg/identity
  • github.com/aijustin/agentflow-go/pkg/knowledge
  • github.com/aijustin/agentflow-go/pkg/mcp
  • github.com/aijustin/agentflow-go/pkg/memory
  • github.com/aijustin/agentflow-go/pkg/runstate
  • github.com/aijustin/agentflow-go/pkg/security

内置工具适配器说明见 docs/tools-http.mddocs/tools-filesystem.mddocs/tools-sql.mddocs/tools-git.mddocs/tools-ticket.mddocs/mcp-tools.mddocs/knowledge-rag.md

安装依赖
go mod download
校验示例场景
go run ./examples/go/validate -kind builder all
make validate-builder
可运行示例
示例 说明
examples/go/minimal 进程内 Run + 测试接线
examples/go/postgres 文件或 Postgres RunState
examples/go/http-worker 生产 HTTP Handler + 异步 Worker
examples/go/hitl-resume HITL 暂停与 ResumeAndContinue
examples/go/event-trigger HandleEvent 与 triggers

将示例中的 testutil.WiringOptions 替换为显式的 WithLLMGateway / WithToolExecutor 即可用于生产。

排障见 docs/troubleshooting.md

HTTP 集成

在自有服务中挂载库提供的 Handler,例如:

go run ./examples/go/http-worker/main.go

默认监听 127.0.0.1:7060(可通过 AGENT_HTTP_ADDR 覆盖);Studio 面板:http://127.0.0.1:7060/observability/

生产环境 HITL 续跑使用 httpx.NewProductionHTTPHandlerhttpx.NewHumanHTTPHandlerPOST /v1/hitl/resume。设置 "continue": true 会调用 ResumeAndContinue

curl -X POST http://localhost:7060/v1/hitl/resume \
  -H 'Content-Type: application/json' \
  -d '{
    "token": "'"$TOKEN"'",
    "decision": "approve",
    "continue": true
  }'

Webhook 事件在配置 Framework 时使用 POST /v1/events。详见 docs/async-runtime.md

网络传递的 Token 使用 HMAC 签名。生产环境必须设置强密钥,并使用持久化 RunState 仓库。

YAML 场景格式(Studio 互操作)

新场景请用 pkg/builder 在 Go 中定义。YAML 仅用于 Studio 导入/导出 与字段对照,不再提供 LoadScenarioFile / NewFromFile 等公共加载 API。

示例栈(Go builder,非 YAML 文件):

Builder 说明
builder.MinimalAutonomous("assistant") 自主工具循环基线
builder.MinimalFixedWorkflowReview("reviewer") 图工作流 + 条件 + HITL
builder.CodeReviewPipeline() Git 工具 + parallel_group
builder.MultiExpertResearch() Hybrid + planning

默认 CI catalog(CoreCatalog,autonomous):make validate-builder;全量 19 条:go run ./examples/go/validate -kind builder full

库 API

大多数应用只需要引入根门面:

import agentflow "github.com/aijustin/agentflow-go"

公共包:

作用
root package 框架门面:校验、运行、恢复、事件处理、Studio 互操作与扩展注入。
pkg/adapters 具体适配器构造器(run-state/blob/memory 存储、job 队列、LLM providers、knowledge、MCP、工具执行器、分层记忆、observability),不依赖根包。
pkg/httpx HTTP 适配器构造器(checkpoint、retention、studio、webhook/HITL、async jobs、生产组合、observability dashboard)与 knowledge/MCP 接线。
pkg/async 异步执行所需的 Job Queue、Lease、Handler 和 Worker 契约。
pkg/eventrouter 外部事件类型与 scenario.triggers 到 RunRequest 的路由。
pkg/audit 合规记录所需的 Audit Event 模型和 Sink 契约。
pkg/coordination 用于 Worker 和工作流协调的分布式租约契约。
pkg/core Agent、Tool、Skill、Scenario、Workflow、HumanGate、Event 类型。
pkg/llm 提供商无关的 LLM 能力接口和请求/响应类型。
pkg/contextwindow 上下文窗口策略管理、token 估算、裁剪和压缩统计。
pkg/identity Principal、角色、租户/工作区/项目作用域和 context helpers。
pkg/memory Memory Namespace 和 Repository 契约。
pkg/runstate RunSnapshot、CAS Repository 端口、Blob 引用和 Token 签名。
pkg/security API Key 认证器、授权 action/resource 和 RBAC policy 契约。

创建并保存运行快照:

repo := runstateinmem.NewRepository()
snapshot := runstate.RunSnapshot{
    RunID:        "run-1",
    ScenarioName: "demo",
    Status:       runstate.RunStatusRunning,
}
if err := repo.Save(context.Background(), &snapshot, 0); err != nil {
    log.Fatal(err)
}

签发并验证 HITL Token:

signer, err := runstate.NewTokenSigner([]byte("replace-with-at-least-16-bytes"))
if err != nil {
    log.Fatal(err)
}
token, err := signer.Sign(runstate.TokenPayload{RunID: "run-1", Version: 1})
if err != nil {
    log.Fatal(err)
}
payload, err := signer.Verify(token)
if err != nil {
    log.Fatal(err)
}
fmt.Println(payload.RunID)

获取 Redis 分布式租约,用于 Worker 协调:

locker, err := agentflow.NewRedisLocker(agentflow.RedisLockerConfig{
  Addr:      os.Getenv("AGENTFLOW_REDIS_ADDR"),
  Password:  os.Getenv("AGENTFLOW_REDIS_PASSWORD"),
  KeyPrefix: "agentflow:",
})
if err != nil {
  log.Fatal(err)
}
lease, acquired, err := locker.Acquire(ctx, "run:123", "worker:alpha", 30*time.Second)
if err != nil {
  log.Fatal(err)
}
if acquired {
  defer func() { _ = locker.Release(ctx, lease) }()
}

租约语义和运维注意事项见 docs/persistence/redis-locker.md

通过 async worker foundation 执行异步任务:

queue := adapters.NewInMemoryJobQueue()
worker, err := async.NewWorker(
  queue,
  async.HandlerFunc(func(ctx context.Context, job async.Job) error {
    return nil
  }),
  async.WorkerConfig{WorkerID: "worker-1", Concurrency: 4},
)
if err != nil {
  log.Fatal(err)
}

队列状态、Worker 行为和后续生产化切片见 docs/async-runtime.md

暴露异步 run/event/resume job endpoints:

queue := adapters.NewInMemoryJobQueue()
handler, err := httpx.NewAsyncRunHTTPHandler(httpx.AsyncRunHTTPHandlerConfig{
  Queue:  queue,
  Policy: security.NewDefaultRolePolicy(),
  Audit:  auditSink,
})
if err != nil {
  log.Fatal(err)
}
http.Handle("/v1/", middleware(handler))

生产 Handler 可同时挂载可选的同步 event/HITL 路由:

api, err := httpx.NewProductionHTTPHandler(httpx.ProductionHTTPHandlerConfig{
  Queue:     queue,
  Framework: fw,
  AuthMiddleware: authMiddleware,
  Policy:    security.NewDefaultRolePolicy(),
  Audit:     auditSink,
  Version:   agentflow.Version,
})

完整路由矩阵见 docs/async-runtime.md/v1/runs/v1/jobs/events/v1/jobs/hitl/resume/v1/events/v1/hitl/resume)。

使用 API Key 保护 HTTP handler,并把企业 Principal 注入 request context:

auth, err := agentflow.NewStaticAPIKeyAuthenticator(map[string]identity.Principal{
  os.Getenv("AGENTFLOW_SERVICE_API_KEY"): {
    ID:    "svc-agent-runner",
    Type:  identity.PrincipalService,
    Scope: identity.Scope{TenantID: "tenant-1"},
    Roles: []identity.Role{identity.RoleService},
  },
})
if err != nil {
  log.Fatal(err)
}
middleware, err := agentflow.NewAPIKeyMiddleware(agentflow.APIKeyMiddlewareConfig{Authenticator: auth})
if err != nil {
  log.Fatal(err)
}
handler := middleware(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  principal, _ := identity.RequirePrincipal(r.Context())
  _ = principal
}))

生产 OIDC/OAuth2 网关可使用 OIDC Discovery/JWKS 自动刷新来校验 JWT:

auth, err := agentflow.NewOIDCJWTAuthenticator(agentflow.OIDCJWTAuthenticatorConfig{
  Issuer:          "https://issuer.example.com",
  Audience:        "agentflow-api",
  DiscoveryURL:    "https://issuer.example.com/.well-known/openid-configuration",
  RefreshInterval: 5 * time.Minute,
})
if err != nil {
  log.Fatal(err)
}
middleware, err := agentflow.NewJWTMiddleware(agentflow.JWTMiddlewareConfig{Authenticator: auth})

为 HTTP handler 添加授权检查:

authz, err := agentflow.NewAuthorizationMiddleware(agentflow.AuthorizationMiddlewareConfig{
  Policy:   security.NewDefaultRolePolicy(),
  Action:   security.ActionRunSubmit,
  Resource: security.Resource{Type: "run"},
  Audit:    auditSink,
})
if err != nil {
  log.Fatal(err)
}
handler = middleware(authz(handler))

使用 runtime 工具授权和审计记录运行框架:

fw, err := agentflow.New(
  scenario,
  agentflow.WithSecurityPolicy(security.NewDefaultRolePolicy()),
  agentflow.WithAuditSink(auditSink),
)
ctx := identity.WithPrincipal(context.Background(), identity.Principal{
  ID:    "svc-agent-runner",
  Type:  identity.PrincipalService,
  Scope: identity.Scope{TenantID: "tenant-1"},
  Roles: []identity.Role{identity.RoleService},
})
result, err := fw.Run(ctx, agentflow.RunRequest{RunID: "run-1", Agent: "assistant", Prompt: "hello"})

将审计事件写入 append-only JSONL 文件:

auditSink, err := adapters.NewFileAuditSink("./data/audit/events.jsonl")
if err != nil {
  log.Fatal(err)
}
err = auditSink.Record(ctx, audit.Event{
  Type:    audit.EventRunSubmitted,
  RunID:   "run-1",
  Outcome: "accepted",
})

架构

项目采用 DDD 风格分层和 Hexagonal Ports/Adapters:

examples/
  go/          # 可复制的集成 main(minimal、validate、builder、http-worker 等)
  deploy/      # 参考 Compose 栈(Postgres、Redis、MinIO)
pkg/
  core/
  builder/     # Go DSL 构造 core.Scenario
  catalog/     # Tool/Skill manifest 加载与校验
  llm/
  contextwindow/
  memory/
  runstate/
internal/
  application/
    runtime/
    orchestration/
    scenario/
  adapter/
    config/yaml/
    human/cli/
    human/http/
    llm/openai/
    llm/anthropic/
    llm/local/
    llm/mock/
    memory/inmem/
    runstate/inmem/
    blob/inmem/

设计边界:

  • Skill = prompt fragments + tool whitelist/policy + 可内联的 workflow 子图
  • Tool = 带 Schema 的执行单元
  • Agent = 拥有 LLM 和 Memory 绑定的实体
  • RunStateRepository 与 Memory 分离,专门处理可恢复的运行快照。
  • 上下文治理按 LLM Profile 生效:不同 Agent/Tool 可以路由到具有不同窗口、输出、thinking 和压缩策略的 LLM Profile。
  • 自主执行支持可选 planning pass、LLM 工具调用循环、工具白名单、审批拒绝、每次运行 rate cap、分类重试、受限工具结果回填和生命周期事件。
  • 结构化输出使用 Agent 级 output_schema 和 Provider 的 StructuredOutputter;普通流式输出使用 Streamer;带工具 Agent 的 Stream 在受治理工具循环中发出增量 tool_call/tool_result(或 tool_denied)chunk,并以终端 Done chunk 交付最终答案(并持久化)。before_final_answer 与带 agent 节点的 fixed_workflow 不被 Stream/RunStructured 支持。
  • Memory 绑定已接入 Runtime 读写,用于 conversation/session 历史。
  • 固定工作流按图依赖和边执行,支持有限并行、parallel_group/loop 节点、条件跳过、重试、transform/agent/human-gate 节点和 CAS 安全输出保存。
  • Workflow human-gate 节点会持久化 CurrentNodeID/PendingGate,审批后可继续执行下游图;ResumeAndContinue 还支持自主、工作流和工具审批暂停路径的续跑。
  • 外部事件通过 scenario.triggers 映射到 Framework.HandleEvent、Webhook HTTP(NewWebhookHTTPHandler)、同步 /v1/events 和异步 event job。
  • sub_agents 会在自主执行中作为虚拟 delegation tool 暴露给 supervisor Agent。
  • Skill prompt fragments、Agent policy、Tool policy 和 workflow segments 会在场景构建阶段展开为命名空间化的 workflow 节点。
  • Tool 的声明面和执行面已经分离:scenario.tools 向 LLM 和校验器暴露 manifest,WithToolExecutor 提前注册轻量 executor,WithToolResolver 则在允许的调用真正进入执行阶段时按需绑定重型或租户隔离 executor。
  • 文件 / PostgreSQL / Redis RunState、S3-compatible BlobStore、Memory 适配器通过 pkg/adapters 构造;Redis 分布式租约(NewRedisLocker)仍在根包;异步队列与 Worker 契约支持 runeventresume.continueNewFrameworkJobHandler),HTTP 路由由 httpx.NewAsyncRunHTTPHandler / httpx.NewProductionHTTPHandler 提供;当输出超过 step_output_threshold 时会外置到 BlobStore。
  • 企业 identity context、API Key middleware、静态和 OIDC/JWKS JWT middleware、授权 middleware、RBAC policy 契约和 runtime tool authorization 可通过 pkg/identitypkg/security、根包 NewStaticAPIKeyAuthenticator / NewOIDCJWTAuthenticator / NewAPIKeyMiddleware / NewJWTMiddleware / NewAuthorizationMiddlewareWithSecurityPolicy 使用。
  • Audit event 契约与 sink 可通过 pkg/auditadapters.NewNoopAuditSink / NewInMemoryAuditSink / NewFileAuditSink,以及 WithAuditSink 使用。
  • 运行时可观测面板、事件仓库、实时 EventHub 和 PostgreSQL 自动建表可通过 adapters.NewPostgresEventStoreNewInMemoryEventStoreNewEventStoreSinkNewEventHubhttpx.NewObservabilityHTTPHandler 使用;Studio SPA 另提供 ComposeGraph / parts API。
  • 企业认证/租户和可观测/治理设计见 docs/security-auth-tenancy.mddocs/observability-governance.mddocs/observability-dashboard.md
  • 内存适配器是并发安全的,并按 run/session 命名空间隔离。

测试

默认单元测试:

make test

集成测试:

make test-integration

真实本地模型流程测试:

export AGENT_REALMODEL_BASE_URL="http://127.0.0.1:1234/v1"
export AGENT_REALMODEL_MODEL="qwen/qwen3.6-35b-a3b"
export AGENT_REALMODEL_API_KEY="..."
make test-realmodel

并发内存适配器 Race 测试:

make test-race

静态检查和漏洞扫描:

make vet
make lint
make security

直接运行:

CGO_ENABLED=0 go test -ldflags="-w" ./...
CGO_ENABLED=0 go test -ldflags="-w" -tags=integration ./...
CGO_ENABLED=0 go test -ldflags="-w" -tags=realmodel -run TestRealModel -v .
go test -race ./internal/adapter/memory/inmem ./internal/adapter/runstate/inmem ./internal/adapter/blob/inmem

在较旧的 Darwin 本地工具链 + CGO_ENABLED=0 环境中,-ldflags="-w" 可规避本地 dyld 测试二进制问题。

当前状态

当前发布:v0.5.0 — 完成 Memory/RunState/Outbox 多租户隔离、生产 HTTP 默认失败关闭、全编排模式 Tool Schema 强校验、稳定工具幂等键,以及 React 19 / Router 8 Studio 安全升级。完整变更与迁移说明见 CHANGELOG.md

核心模块已可用:

  • 场景构造pkg/builderCoreCatalog + legacy ExampleCatalog)、ValidateScenario、Studio YAML 互操作、ComposeGraph;三模式立场见 docs/orchestration-modes.md
  • 运行时:autonomous / fixed_workflow / hybrid、subgraph / map / loop / parallel、planning pass、Skill 展开
  • 治理:工具白名单与审批、HITL、Identity/RBAC/Audit、timeout 与分类重试
  • 持久化:File / Postgres / Redis RunState、S3 Blob、Checkpoint 历史、Memory Tier
  • 集成httpx Production HTTP、异步 Worker、Webhook/事件触发、Prometheus + OTel(pkg/adapters
  • Studio:AI-first SPA(ComposeBar + 零件箱 + 试跑)、运行追踪 / checkpoint 时间旅行、双 run 对比

后续方向(非阻塞):Tool/Skill catalog 版本化 manifest、托管环境集成测试矩阵扩展、http-worker 示例接 TraceExploreURL。产品边界见 product-direction.md(不做 agent_loop 图节点、不做 LangGraph Store 全量 parity)。

贡献

参见 CONTRIBUTING.md

License

本项目使用 Apache License 2.0

Documentation

Overview

Package agentflow provides a small public facade for embedding the scenario-driven agent runtime in other Go projects.

Applications that need low-level extension points can import pkg/core, pkg/llm, pkg/memory, and pkg/runstate directly. Applications that only need to load a YAML scenario and run it should use this package.

Root package layout:

  • core runtime: framework.go and the framework_*.go family (run, resume, checkpoints, streaming, workflow/hybrid orchestration, async job handler, event emit helpers)
  • lifecycle and options: lifecycle.go, builder.go, security.go
  • wiring validation: wiring.go (ValidateWiring and the New-time wiring checks; scenario knowledge/MCP wiring constructors live in pkg/httpx because they return []agentflow.Option)
  • retention: retention.go (purge policies, orphan blob GC)
  • run lease: lease.go
  • metadata: meta.go (version, JSON schema, JSON helpers)

Convenience constructors that used to live here moved in v0.3:

  • pkg/adapters: concrete adapter constructors (run-state/blob/memory stores, job queues, LLM providers, catalog manifests, knowledge, MCP, tool executors, tiered memory, observability sinks/stores). It never imports this root package.
  • pkg/httpx: HTTP adapter constructors (checkpoint, retention, studio, webhook/human-gate, async jobs, production composition, observability dashboard) and the knowledge/MCP wiring options.
  • pkg/testutil: the mock LLM gateway and test wiring helpers.

Index

Examples

Constants

View Source
const (
	TrustModeDefault   = appexec.TrustModeDefault
	TrustModeFullTrust = appexec.TrustModeFullTrust
)
View Source
const (
	EventFilterProductUI  = core.EventFilterProductUI
	EventFilterDiagnostic = core.EventFilterDiagnostic
)

Event filter presets for StreamRun / EventStore.ListEvents read-side views.

View Source
const SchemaVersion = "2020-12"

SchemaVersion is the JSON Schema draft used by ScenarioJSONSchema.

View Source
const Version = "0.5.0"

Version is the library release version exposed to embedders.

Variables

View Source
var (
	ErrRunAlreadyCompleted = appexec.ErrRunAlreadyCompleted
	ErrRunInProgress       = appexec.ErrRunInProgress
	ErrRunPaused           = appexec.ErrRunPaused
	ErrRunFailed           = appexec.ErrRunFailed
	ErrRunCancelled        = appexec.ErrRunCancelled
	// ErrResumeInProgress reports that another caller is already resuming or
	// continuing this run in this process. A concurrent ResumeAndContinue /
	// ResumeRunByID / ContinueRun on the same run fails fast with it instead
	// of racing the pause token and surfacing an ambiguous ErrTokenSuperseded.
	ErrResumeInProgress = runstate.ErrResumeInProgress
)

Classified run-state errors, re-exported from the runtime so callers of every orchestration mode's entry points can branch on them with errors.Is.

AdaptiveRAG builds the adaptive-rag workflow example stack.

View Source
var AdaptiveRAGWorkflow = scenariobuilder.AdaptiveRAGWorkflow

AdaptiveRAGWorkflow builds the adaptive RAG workflow graph.

CodeReviewPipeline builds the code review workflow example stack.

View Source
var CodeReviewPipelineWorkflow = scenariobuilder.CodeReviewPipelineWorkflow

CodeReviewPipelineWorkflow builds the code review workflow graph.

ContextGovernance builds the context governance example stack.

CorrectiveRAG builds the corrective-rag workflow example stack.

View Source
var CorrectiveRAGWorkflow = scenariobuilder.CorrectiveRAGWorkflow

CorrectiveRAGWorkflow builds the corrective RAG workflow graph.

View Source
var DeclarativeInterruptWorkflow = scenariobuilder.DeclarativeInterruptWorkflow

DeclarativeInterruptWorkflow builds the prepare → interrupt → continue graph.

View Source
var ErrFenceRequired = runstate.ErrFenceRequired

ErrFenceRequired reports that a leased run save requires a run-state repository implementing runstate.FencedRepository.

View Source
var ErrRunLeaseLost = coordination.ErrRunLeaseLost

ErrRunLeaseLost reports that this worker no longer holds the run lease (renewal returned not-held or failed) and must stop executing before another worker reaps or takes over the run. It aliases the coordination package's sentinel so the runtime engine classifies the same error the facade returns.

View Source
var ErrStaleFence = runstate.ErrStaleFence

ErrStaleFence reports that a fenced snapshot save presented a fencing token below the highest token already recorded for the run: this worker's run lease was superseded by a newer holder and its writes are rejected. It is handled exactly like ErrRunLeaseLost — the worker stops executing immediately and settles the run through the lease-lost path, never retrying the save. It aliases the runstate package's sentinel so facade and engine classify the same error.

View Source
var FixedWorkflowReviewWorkflow = scenariobuilder.FixedWorkflowReviewWorkflow

FixedWorkflowReviewWorkflow builds the inspect → review workflow graph.

HybridResearch builds the hybrid research example stack.

View Source
var HybridResearchWorkflow = scenariobuilder.HybridResearchWorkflow

HybridResearchWorkflow builds the hybrid research workflow graph.

MapItemField sets the per-item field name for map branches.

MapNodeInput builds map node input JSON from a list field and branches.

MapOnError sets the map node error policy branch.

MinimalAutonomous builds the common mock/session/tool autonomous stack.

View Source
var MinimalDeclarativeInterrupt = scenariobuilder.MinimalDeclarativeInterrupt

MinimalDeclarativeInterrupt builds the declarative interrupt demo stack.

View Source
var MinimalFilesystemTool = scenariobuilder.MinimalFilesystemTool

MinimalFilesystemTool builds the filesystem tool example stack.

View Source
var MinimalFixedWorkflowReview = scenariobuilder.MinimalFixedWorkflowReview

MinimalFixedWorkflowReview builds the fixed workflow review example stack.

MinimalHTTPTool builds the http tool example stack.

MinimalHumanInLoop builds the human-in-loop demo stack.

MinimalMCPTool builds the MCP tool example stack.

MinimalRAG builds the rag-knowledge example stack.

MinimalSQLTool builds the sql tool example stack.

View Source
var MinimalTicketHandling = scenariobuilder.MinimalTicketHandling

MinimalTicketHandling builds the ticket-handling example stack.

View Source
var MultiExpertResearch = scenariobuilder.MultiExpertResearch

MultiExpertResearch builds the multi-expert hybrid example stack.

View Source
var MultiExpertResearchWorkflow = scenariobuilder.MultiExpertResearchWorkflow

MultiExpertResearchWorkflow builds the parallel expert workflow graph.

NewMinimal starts a scenario with the standard mock/session stack. Register tools, then call MinimalAgent or configure agents manually.

View Source
var NewScenarioBuilder = scenariobuilder.New

NewScenarioBuilder creates a scenario builder. Prefer pkg/builder when importing only the builder package without the root facade.

View Source
var NewWorkflowBuilder = scenariobuilder.NewWorkflow

NewWorkflowBuilder creates a workflow builder.

SelfRAG builds the self-rag workflow example stack.

SelfRAGWorkflow builds the self RAG workflow graph.

View Source
var TierMemoryAutonomous = scenariobuilder.TierMemoryAutonomous

TierMemoryAutonomous builds the tier-memory example stack.

View Source
var WorkflowEnhancements = scenariobuilder.WorkflowEnhancements

WorkflowEnhancements builds the workflow enhancements example stack.

View Source
var WorkflowEnhancementsWorkflow = scenariobuilder.WorkflowEnhancementsWorkflow

WorkflowEnhancementsWorkflow builds the workflow enhancements graph.

Functions

func NewAPIKeyMiddleware

func NewAPIKeyMiddleware(config APIKeyMiddlewareConfig) (func(http.Handler) http.Handler, error)

func NewAuthorizationMiddleware

func NewAuthorizationMiddleware(config AuthorizationMiddlewareConfig) (func(http.Handler) http.Handler, error)

func NewFrameworkJobHandler added in v0.1.2

func NewFrameworkJobHandler(config FrameworkRunJobHandlerConfig) (async.Handler, error)

func NewInMemoryLocker added in v0.3.0

func NewInMemoryLocker() coordination.Locker

NewInMemoryLocker creates an in-process lease manager for tests and single-process deployments.

func NewJWTMiddleware

func NewJWTMiddleware(config JWTMiddlewareConfig) (func(http.Handler) http.Handler, error)

func NewOIDCJWTAuthenticator

func NewOIDCJWTAuthenticator(config OIDCJWTAuthenticatorConfig) (security.BearerAuthenticator, error)

NewOIDCJWTAuthenticator creates a bearer authenticator that discovers and refreshes RSA verification keys from OIDC Discovery/JWKS endpoints.

func NewStaticAPIKeyAuthenticator

func NewStaticAPIKeyAuthenticator(keys map[string]identity.Principal) (security.APIKeyAuthenticator, error)

func ScenarioJSONSchema added in v0.1.4

func ScenarioJSONSchema() []byte

ScenarioJSONSchema returns a copy of the AgentFlow scenario JSON Schema.

func StreamDetached added in v0.3.0

func StreamDetached(ctx context.Context) context.Context

StreamDetached marks ctx so a run started by Framework.Stream keeps executing to a terminal state in the background when the caller's context is cancelled (client disconnect), instead of being marked Cancelled. It is the context-level equivalent of the WithStreamDetached StreamRun option for callers of the lower-level Stream API. An explicit run Cancel and a lost run lease still abort the run.

func ValidateScenario

func ValidateScenario(scenario core.Scenario) error

ValidateScenario validates a scenario built programmatically.

func ValidateWiring added in v0.1.4

func ValidateWiring(scenario core.Scenario, opts ...Option) error

ValidateWiring checks that a scenario's declared dependencies are covered by the provided options before constructing a Framework.

func ValidateWiringWithOptions added in v0.1.4

func ValidateWiringWithOptions(scenario core.Scenario, wiring WiringOptions, opts ...Option) error

ValidateWiringWithOptions validates wiring using explicit wiring rules.

Types

type APIKeyMiddlewareConfig

type APIKeyMiddlewareConfig struct {
	Authenticator security.APIKeyAuthenticator
	HeaderName    string
}

type AuthorizationMiddlewareConfig

type AuthorizationMiddlewareConfig struct {
	Policy       security.Policy
	Action       security.Action
	Resource     security.Resource
	ResourceFunc func(*http.Request) security.Resource
	Audit        audit.Sink
}

type CodegenResult added in v0.2.0

type CodegenResult struct {
	Language string `json:"language"`
	Code     string `json:"code"`
}

CodegenResult contains generated builder code for a Studio graph.

type ComposeGraphRequest added in v0.4.0

type ComposeGraphRequest struct {
	// Prompt is the one-sentence task the composed graph should accomplish.
	Prompt string `json:"prompt"`
	// Mode selects catalog (default) or scenario composition.
	Mode ComposeMode `json:"mode,omitempty"`
	// ComposerLLM names the LLM profile the composer agent uses; empty
	// resolves to the scenario's "default" profile or the first profile.
	ComposerLLM string `json:"composer_llm,omitempty"`
	// MaxSteps caps the composer tool loop. Default 15.
	MaxSteps int `json:"max_steps,omitempty"`
	// Run executes the composed graph after validation when true. Runs are
	// ephemeral: the live framework scenario is never replaced.
	Run bool `json:"run,omitempty"`
	// RunRequest is passed through to the run when Run is true (run_id,
	// prompt, context, trust mode).
	RunRequest RunRequest `json:"run_request,omitempty"`
}

ComposeGraphRequest drives one AI graph-composition call.

type ComposeGraphResult added in v0.4.0

type ComposeGraphResult struct {
	Mode ComposeMode `json:"mode"`
	// Graph is the exported topology of the composed (merged) scenario.
	Graph graph.ScenarioGraph `json:"graph"`
	// Scenario is the merged temporary scenario. It is never installed as
	// the live scenario; persist explicitly via SaveStudioGraph or YAML
	// codegen if desired.
	Scenario *core.Scenario `json:"scenario,omitempty"`
	Valid    bool           `json:"valid"`
	Error    string         `json:"error,omitempty"`
	// Run holds the ephemeral run outcome when Run was requested and the
	// composed graph validated.
	Run *RunResult `json:"run,omitempty"`
}

ComposeGraphResult reports the outcome of one composition call.

type ComposeMode added in v0.4.0

type ComposeMode string

ComposeMode selects what the AI composer may generate.

const (
	// ComposeModeCatalog (default) lets the composer orchestrate only parts
	// already registered in the base scenario (agents, tools, skills,
	// subgraphs): it produces topology, nothing else.
	ComposeModeCatalog ComposeMode = "catalog"
	// ComposeModeScenario additionally lets the composer create new agents
	// and prompt skills, merged as an additive patch. Overwriting existing
	// part IDs is rejected, and new tools are never executable unless the
	// host bound an executor/resolver for them.
	ComposeModeScenario ComposeMode = "scenario"
)

type EventFilterPreset added in v0.3.0

type EventFilterPreset = core.EventFilterPreset

EventFilterPreset is a named read-side event view (product_ui | diagnostic).

type EventRouter added in v0.1.2

type EventRouter = eventrouter.Router

EventRouter maps external events to run requests for a scenario.

func NewEventRouter added in v0.1.2

func NewEventRouter(scenario core.Scenario) *EventRouter

NewEventRouter creates a router from scenario trigger definitions.

type ForkRunResult added in v0.2.0

type ForkRunResult struct {
	RunID           string `json:"run_id"`
	ParentRunID     string `json:"parent_run_id"`
	ThreadID        string `json:"thread_id"`
	ForkFromVersion int64  `json:"fork_from_version,omitempty"`
}

type Framework

type Framework struct {
	// contains filtered or unexported fields
}

Framework is an embeddable runtime wrapper for one scenario.

func New

func New(scenario core.Scenario, opts ...Option) (*Framework, error)

New creates a Framework for a validated scenario. By default it wires in-memory run-state and blob stores and a no-op event sink. Production applications should provide persistent repositories through options.

Example
package main

import (
	"context"
	"encoding/json"

	agentflow "github.com/aijustin/agentflow-go"
	"github.com/aijustin/agentflow-go/pkg/builder"
	"github.com/aijustin/agentflow-go/pkg/core"
)

func testAutonomousScenario() core.Scenario {
	return builder.MinimalAutonomous("assistant", builder.MinimalScenarioName("autonomous-echo"))
}

type noopTool struct{}

func (noopTool) Execute(context.Context, core.ToolCall) (core.ToolResult, error) {
	return core.ToolResult{}, nil
}

func main() {
	fw, err := agentflow.New(testAutonomousScenario(), agentflow.WithToolExecutor("echo", noopTool{}))
	if err != nil {
		panic(err)
	}
	result, err := fw.Run(context.Background(), agentflow.RunRequest{
		RunID:  "example-run",
		Prompt: "hello",
	})
	if err != nil {
		panic(err)
	}
	out, _ := json.Marshal(result.Status)
	println(string(out))
}

func (*Framework) BlobStore

func (f *Framework) BlobStore() runstate.BlobStore

BlobStore returns the blob store backing large step outputs.

func (*Framework) Catalog added in v0.1.4

func (f *Framework) Catalog() catalog.Catalog

func (*Framework) Close added in v0.1.4

func (f *Framework) Close(ctx context.Context) error

Close releases resources registered through WithCloser or WithDatabase.

func (*Framework) CompareRuns added in v0.2.0

func (f *Framework) CompareRuns(ctx context.Context, runA, runB string) (studio.RunCompareResult, error)

func (*Framework) ComposeGraph added in v0.4.0

ComposeGraph is a thin Framework delegate — prefer Framework.Studio().

func (*Framework) ContinueRun added in v0.3.0

func (f *Framework) ContinueRun(ctx context.Context, runID string) (*RunResult, error)

ContinueRun retries the continue of a run that is stuck in Running with unconsumed checkpoint metadata. That state arises when the human gate was approved (gate.Resume flipped the run back to Running) but the subsequent continue failed, or the worker crashed between the two; without this entry point the run would sit in Running forever with no public way forward.

The call is idempotent and safe to retry:

  • a run that already reached Completed returns its persisted RunResult;
  • a Running run with pending checkpoint metadata re-enters the internal continue-after-checkpoint path (workflow/hybrid runs resume from their persisted step outputs);
  • anything else (Paused, Failed, Cancelled, or Running with no checkpoint metadata) returns a classified error naming the actual state, since the right entry point for those is ResumeAndContinue, RetryFailedRun, or none at all.

A concurrent ContinueRun/ResumeAndContinue on the same run fails fast with ErrResumeInProgress.

func (*Framework) ExportScenarioGraph added in v0.2.0

func (f *Framework) ExportScenarioGraph() ScenarioGraph

ExportScenarioGraph exports the framework scenario as a nested graph.

func (*Framework) ForkRun added in v0.2.0

func (f *Framework) ForkRun(ctx context.Context, parentRunID string, version int64) (ForkRunResult, error)

func (*Framework) GenerateStudioBuilderCode added in v0.2.0

func (f *Framework) GenerateStudioBuilderCode(ctx context.Context, edited graph.ScenarioGraph) (CodegenResult, error)

func (*Framework) GenerateStudioBuilderCodeWithScenario added in v0.4.5

func (f *Framework) GenerateStudioBuilderCodeWithScenario(ctx context.Context, edited graph.ScenarioGraph, draft *core.Scenario) (CodegenResult, error)

func (*Framework) GenerateStudioScenarioYAML added in v0.2.0

func (f *Framework) GenerateStudioScenarioYAML(ctx context.Context, edited graph.ScenarioGraph) (CodegenResult, error)

func (*Framework) GenerateStudioScenarioYAMLWithScenario added in v0.4.5

func (f *Framework) GenerateStudioScenarioYAMLWithScenario(ctx context.Context, edited graph.ScenarioGraph, draft *core.Scenario) (CodegenResult, error)

func (*Framework) GetRunCheckpoint added in v0.2.0

func (f *Framework) GetRunCheckpoint(ctx context.Context, runID string, version int64) (runstate.RunSnapshot, error)

GetRunCheckpoint loads one historical snapshot revision for a run.

func (*Framework) HandleEvent added in v0.1.2

func (f *Framework) HandleEvent(ctx context.Context, event IncomingEvent) (RunResult, error)

HandleEvent resolves an incoming event and executes the scenario. The event type is carried into the run as its trigger kind ("event:<type>") so lifecycle events and metrics attribute the run to the external trigger that started it.

func (*Framework) ImportStudioScenarioYAML added in v0.2.0

func (f *Framework) ImportStudioScenarioYAML(ctx context.Context, yamlData []byte, layout graph.ScenarioGraph) (ImportStudioResult, error)

func (*Framework) Interject added in v0.3.0

func (f *Framework) Interject(runID, text string) error

Interject queues a mid-turn user message for an in-flight run. The autonomous tool loop drains it at the next safe point (before the next LLM call).

func (*Framework) ListRunCheckpoints added in v0.2.0

func (f *Framework) ListRunCheckpoints(ctx context.Context, runID string, limit int) (ListRunCheckpointsResult, error)

ListRunCheckpoints returns append-only snapshot revisions recorded for a run.

func (*Framework) ListRunSteps added in v0.2.0

func (f *Framework) ListRunSteps(ctx context.Context, runID string) (ListRunStepsResult, error)

ListRunSteps returns persisted step outputs and the current snapshot version.

func (*Framework) ListRunThread added in v0.2.0

func (f *Framework) ListRunThread(ctx context.Context, runID string) ([]ThreadRunSummary, error)

func (*Framework) MarkAbandonedRuns added in v0.3.0

func (f *Framework) MarkAbandonedRuns(ctx context.Context) ([]string, error)

MarkAbandonedRuns scans this scenario's Running runs and marks as Failed (run_error_message="worker lost") every lease-managed run whose lease is no longer held: its worker crashed or was partitioned away, so nothing will ever move the run out of Running. It returns the IDs of the runs it marked. Requires WithRunLease.

Only runs stamped with a lease owner (run_lease_owner variable, written when the run executes under WithRunLease) are eligible: a Running run without the marker belongs to a worker that does not use lease coordination, and probing its lease would always succeed and reap live work. Tenant scope: when ctx carries a tenant-scoped principal, only that tenant's runs are scanned and reaped; runs belonging to other tenants are never touched even if the repository's List filtering is lax. Without a tenant principal this is an admin operation across all tenants.

func (*Framework) PurgeExpired added in v0.1.4

func (f *Framework) PurgeExpired(ctx context.Context, maxAge time.Duration) (int, error)

PurgeExpired deletes terminal run snapshots whose UpdatedAt is before now-maxAge. Snapshots without UpdatedAt are skipped.

func (*Framework) PurgeOrphanBlobs added in v0.1.4

func (f *Framework) PurgeOrphanBlobs(ctx context.Context) (int, error)

PurgeOrphanBlobs deletes blob objects that are no longer referenced by any run snapshot for the current scenario (and tenant, when a principal is present).

func (*Framework) PurgeRuns added in v0.1.4

func (f *Framework) PurgeRuns(ctx context.Context, filter runstate.ListFilter, opts ...PurgeRunsOption) (int, error)

PurgeRuns deletes run snapshots matching the filter. Non-terminal runs (Running, Paused) are skipped unless WithPurgeForce is given. Each deleted run's checkpoint history is deleted alongside when a history store is configured, so time-travel data does not outlive its run.

func (*Framework) PurgeWithPolicy added in v0.1.4

func (f *Framework) PurgeWithPolicy(ctx context.Context, policy RetentionPolicy) (int, error)

PurgeWithPolicy deletes run snapshots using a retention policy.

func (*Framework) ResolveEvent added in v0.1.2

func (f *Framework) ResolveEvent(event IncomingEvent) (RunRequest, error)

ResolveEvent resolves an incoming event without executing it.

func (*Framework) Resume

func (f *Framework) Resume(ctx context.Context, token string, decision core.Decision, amendment json.RawMessage) error

Resume approves or rejects a paused run via the human gate without continuing execution. An approved run becomes Running with its checkpoint metadata still attached and no execution driver behind it; call ContinueRun (or ResumeAndContinue) to carry it to a terminal state. Such a run is never reaped by MarkAbandonedRuns, which only touches runs stamped with a lease owner, so the recovery window is unbounded.

func (*Framework) ResumeAndContinue added in v0.1.2

func (f *Framework) ResumeAndContinue(ctx context.Context, token string, decision core.Decision, amendment json.RawMessage) (RunResult, error)

ResumeAndContinue resumes a paused run and continues execution until the next pause point or completion.

The call is idempotent: resuming a run that already reached Completed returns the persisted RunResult instead of a token error. A concurrent resume of the same run (with or without run leases) fails fast with ErrResumeInProgress rather than racing the pause token into an ambiguous ErrTokenSuperseded.

When run leases are enabled, the lease is acquired before gate.Resume so the run is never left Running without a holder. Callers that only approve via Resume / ResumeRunByID(..., false) can carry the run to a terminal state later with ContinueRun.

func (*Framework) ResumeFromCheckpoint added in v0.2.0

func (f *Framework) ResumeFromCheckpoint(ctx context.Context, runID string, version int64) (RunResult, error)

ResumeFromCheckpoint restores a historical snapshot revision and reruns the workflow forward from that restored state.

func (*Framework) ResumeFromStep added in v0.2.0

func (f *Framework) ResumeFromStep(ctx context.Context, runID, nodeID string) (RunResult, error)

ResumeFromStep rewinds a workflow run to the given node, truncating that node and all downstream step outputs, then reruns from that point forward.

func (*Framework) ResumeRunByID added in v0.2.0

func (f *Framework) ResumeRunByID(ctx context.Context, runID string, decision core.Decision, amendment json.RawMessage, continueExecution bool) (RunResult, error)

ResumeRunByID resumes a paused run by signing a HITL token from the current snapshot. When continueExecution is true, execution continues until completion or the next pause.

The call is idempotent for a run that already reached Completed: it returns the persisted RunResult instead of a "not paused" error.

SECURITY: knowing the run ID alone is sufficient to mint a fresh resume token here — this is an indefinite resume capability that is NOT bounded by the HITL token TTL (the TTL only constrains tokens issued at pause time). Any HTTP surface exposing this method must authorize callers, e.g. via WithResumeAuthorizationHook; the built-in observability/studio and checkpoint write endpoints already default-deny without a configured policy.

func (*Framework) RetryFailedRun added in v0.3.0

func (f *Framework) RetryFailedRun(ctx context.Context, runID string) (RunResult, error)

RetryFailedRun moves a Failed run back to Running and re-executes it from its persisted progress: workflow nodes that already produced step outputs are skipped, a hybrid run whose workflow phase already finished re-enters the autonomous phase directly (workflow step outputs are re-hydrated into the request context), and an autonomous run with unconsumed checkpoint metadata (e.g. a lease-lost failure that left a tool-approval checkpoint behind) continues from that checkpoint. An autonomous run without pending checkpoint metadata resumes from the last persisted iteration boundary (StepOutputs["auto:iter:<n>"], written after every completed LLM+tools iteration): completed iterations are not re-sent to the LLM. Side effects of the one iteration that crashed before its boundary was persisted may replay - at-least-once at iteration granularity; side-effecting tools should deduplicate on the run-scoped idempotency key. A failed run with neither checkpoint metadata nor iteration progress has nothing resumable and returns an explicit error instead of silently re-running from scratch.

func (*Framework) Run

func (f *Framework) Run(ctx context.Context, req RunRequest) (RunResult, error)

Run executes the framework scenario.

func (*Framework) RunStateRepository

func (f *Framework) RunStateRepository() runstate.Repository

RunStateRepository returns the repository backing run-state snapshots.

func (*Framework) RunStructured

func (f *Framework) RunStructured(ctx context.Context, req RunRequest) (RunResult, error)

RunStructured executes an agent using its configured output_schema and a gateway that implements llm.StructuredOutputter.

func (*Framework) RunStudioGraph added in v0.2.0

func (f *Framework) RunStudioGraph(ctx context.Context, edited graph.ScenarioGraph, req RunRequest) (RunResult, error)

func (*Framework) RunStudioGraphWithScenario added in v0.4.4

func (f *Framework) RunStudioGraphWithScenario(ctx context.Context, edited graph.ScenarioGraph, draft *core.Scenario, req RunRequest) (RunResult, error)

func (*Framework) SaveStudioGraph added in v0.2.0

func (f *Framework) SaveStudioGraph(ctx context.Context, edited graph.ScenarioGraph, path string) (SaveStudioResult, error)

func (*Framework) SaveStudioGraphWithScenario added in v0.4.4

func (f *Framework) SaveStudioGraphWithScenario(ctx context.Context, edited graph.ScenarioGraph, draft *core.Scenario, path string) (SaveStudioResult, error)

func (*Framework) Scenario

func (f *Framework) Scenario() core.Scenario

Scenario returns the scenario used by this framework.

func (*Framework) Stream

func (f *Framework) Stream(ctx context.Context, req RunRequest) (<-chan llm.ChatChunk, error)

Stream executes an agent using a gateway that implements llm.Streamer. Callers must drain the returned channel to completion or cancel ctx; otherwise the engine goroutine (and any run lease renewer) may remain blocked indefinitely.

func (*Framework) StreamRun added in v0.3.0

func (f *Framework) StreamRun(ctx context.Context, req RunRequest, opts ...StreamRunOption) (<-chan StreamFrame, error)

StreamRun executes a run and merges LLM token chunks with runtime events into a single frame channel. Existing Stream remains unchanged.

Events are teed via a context-scoped sink for the duration of the stream so callers do not need an EventHub. Done is emitted only after the token stream closes and pending teed events have been flushed into the frame channel.

Use WithStreamEventFilterPreset to project events for product_ui vs diagnostic views. Default is diagnostic (full stream).

func (*Framework) Studio added in v0.3.0

func (f *Framework) Studio() Studio

Studio returns the development-time Studio API bound to this framework.

func (*Framework) StudioParts added in v0.4.0

func (f *Framework) StudioParts() StudioParts

StudioParts is a thin Framework delegate — prefer Framework.Studio().

func (*Framework) ValidateStudioGraph added in v0.2.0

func (f *Framework) ValidateStudioGraph(ctx context.Context, edited graph.ScenarioGraph) (ValidateStudioResult, error)

func (*Framework) ValidateStudioGraphWithScenario added in v0.4.5

func (f *Framework) ValidateStudioGraphWithScenario(ctx context.Context, edited graph.ScenarioGraph, draft *core.Scenario) (ValidateStudioResult, error)

type FrameworkRunJobHandlerConfig

type FrameworkRunJobHandlerConfig struct {
	Framework *Framework
}

type GraphEdge added in v0.2.0

type GraphEdge = graph.GraphEdge

GraphEdge connects two GraphNodes.

type GraphNode added in v0.2.0

type GraphNode = graph.GraphNode

GraphNode is a workflow node in a GraphView.

type GraphView added in v0.2.0

type GraphView = graph.GraphView

GraphView describes one workflow DAG for visualization.

type ImportStudioResult added in v0.2.0

type ImportStudioResult struct {
	ScenarioName string              `json:"scenario_name"`
	Graph        graph.ScenarioGraph `json:"graph"`
}

ImportStudioResult describes a YAML import into an editable Studio graph.

type IncomingEvent added in v0.1.2

type IncomingEvent = eventrouter.Event

IncomingEvent is an external trigger delivered through webhooks or CLI.

type JWTAlgorithm

type JWTAlgorithm string
const (
	JWTAlgorithmHS256 JWTAlgorithm = "HS256"
	JWTAlgorithmRS256 JWTAlgorithm = "RS256"
)

type JWTAuthenticatorConfig

type JWTAuthenticatorConfig struct {
	Issuer         string
	Audience       string
	Keys           []JWTKey
	Now            func() time.Time
	Leeway         time.Duration
	PrincipalType  identity.PrincipalType
	TenantClaim    string
	WorkspaceClaim string
	ProjectClaim   string
	RolesClaim     string
}

type JWTKey

type JWTKey struct {
	ID              string
	Algorithm       JWTAlgorithm
	HMACSecret      []byte
	RSAPublicKeyPEM []byte
}

type JWTMiddlewareConfig

type JWTMiddlewareConfig struct {
	Authenticator security.BearerAuthenticator
}

type ListRunCheckpointsResult added in v0.2.0

type ListRunCheckpointsResult struct {
	RunID       string                       `json:"run_id"`
	Checkpoints []runstate.CheckpointSummary `json:"checkpoints"`
}

ListRunCheckpointsResult summarizes append-only snapshot revisions for a run.

type ListRunStepsResult added in v0.2.0

type ListRunStepsResult struct {
	RunID         string             `json:"run_id"`
	Version       int64              `json:"version"`
	Status        runstate.RunStatus `json:"status"`
	CurrentNodeID string             `json:"current_node_id,omitempty"`
	PendingHITL   *PendingHITLInfo   `json:"pending_hitl,omitempty"`
	Steps         []RunStep          `json:"steps"`
}

ListRunStepsResult summarizes checkpointed workflow steps for a run.

type MapBranch added in v0.2.0

type MapBranch = scenariobuilder.MapBranch

MapBranch configures a map node fan-out branch.

type OIDCJWTAuthenticatorConfig

type OIDCJWTAuthenticatorConfig struct {
	Issuer          string
	Audience        string
	DiscoveryURL    string
	JWKSURL         string
	HTTPClient      *http.Client
	RefreshInterval time.Duration
	Now             func() time.Time
	Leeway          time.Duration
	PrincipalType   identity.PrincipalType
	TenantClaim     string
	WorkspaceClaim  string
	ProjectClaim    string
	RolesClaim      string
}

type Option

type Option func(*options) error

Option customizes Framework construction.

func WithApprovalStore added in v0.3.0

func WithApprovalStore(store toolorch.ApprovalStore) Option

WithApprovalStore wires a session/run-scoped approval decision cache.

func WithAuditSink

func WithAuditSink(sink audit.Sink) Option

WithAuditSink wires an audit sink used for compliance-oriented events.

func WithBlobStore

func WithBlobStore(store runstate.BlobStore) Option

WithBlobStore wires storage for large step outputs.

func WithCheckpointHistory added in v0.2.0

func WithCheckpointHistory(history runstate.CheckpointHistory) Option

WithCheckpointHistory wires append-only run snapshot history for time-travel.

func WithCloser added in v0.1.4

func WithCloser(fn func(context.Context) error) Option

WithCloser registers a function invoked by Framework.Close in LIFO order.

func WithCognitiveMemory added in v0.1.9

func WithCognitiveMemory(name string, repo memory.CognitiveMemory) Option

WithCognitiveMemory wires a cognitive memory backend by scenario memory name.

func WithDatabase added in v0.1.4

func WithDatabase(db *sql.DB) Option

WithDatabase registers a database handle for automatic close on Framework.Close.

func WithDeferredTools added in v0.4.2

func WithDeferredTools(enabled bool) Option

WithDeferredTools controls whether a wired tool catalog defers non-pinned tool schemas until load_tool_schemas is called. Default true when a catalog is attached.

func WithEventSink

func WithEventSink(sink core.EventSink) Option

WithEventSink wires observability event output.

func WithEventStore added in v0.3.1

func WithEventStore(store observability.EventStore) Option

WithEventStore wires the durable runtime event store so the framework can cascade retention deletions to event history (see PurgeRuns/PurgeExpired) and deliver outbox-parked events (see WithOutboxRelay). The store is typically the same one wrapped by the EventStoreSink passed to WithEventSink; the sink chain itself stays opaque to the framework.

func WithHITLTokenRotation added in v0.3.0

func WithHITLTokenRotation(primary, secondary []byte, tokenWriter io.Writer) Option

WithHITLTokenRotation wires the built-in human gate with a rotating key pair: new resume tokens are signed with primary, while tokens signed by either primary or secondary still verify. Deploy with (new, old), wait for in-flight tokens to drain, then switch back to WithHITLTokenSecret(new) — no token is invalidated mid-rotation. Both secrets must be at least runstate.MinTokenSecretLength bytes.

func WithHITLTokenSecret

func WithHITLTokenSecret(secret []byte, tokenWriter io.Writer) Option

WithHITLTokenSecret wires the built-in HMAC-token human gate using the same RunStateRepository as the framework. tokenWriter can be nil. The secret must be at least runstate.MinTokenSecretLength bytes.

func WithHITLTokenTTL

func WithHITLTokenTTL(ttl time.Duration) Option

WithHITLTokenTTL sets the lifetime for tokens emitted by WithHITLTokenSecret. Without this option tokens expire after 24 hours; pass 0 explicitly to issue tokens that never expire.

func WithHumanGate

func WithHumanGate(gate core.HumanGate) Option

WithHumanGate wires a custom human-in-the-loop gate.

func WithInterjectDrainPolicy added in v0.3.0

func WithInterjectDrainPolicy(policy interjection.DrainPolicy) Option

WithInterjectDrainPolicy controls when Framework.Interject messages enter the autonomous tool loop (Codex-style steer drain alignment).

func WithJobQueue added in v0.1.9

func WithJobQueue(queue async.Queue) Option

WithJobQueue wires an async queue used to enqueue memory.reconcile jobs after tier writes.

func WithLLMGateway

func WithLLMGateway(gateway llm.Gateway) Option

WithLLMGateway wires a provider-neutral LLM gateway.

func WithLLMPayloadCapture added in v0.3.1

func WithLLMPayloadCapture(capture bool) Option

WithLLMPayloadCapture controls whether LLMCalled events include message and prompt plaintext. It is disabled by default: payloads carry only message count, per-message content lengths, and a truncated content hash, so user input - which may contain PII - is not persisted to the event store. Enable it only for debugging (Studio debug drawers show LLM 入参 only when capture is on); captured plaintext still passes through the output redactor configured with WithOutputRedactor before it is emitted.

func WithLogger added in v0.1.1

func WithLogger(logger log.Logger) Option

WithLogger wires a structured logger that receives warning and error messages from the runtime. If not provided, messages are silently discarded.

func WithMemoryRepository

func WithMemoryRepository(name string, repo memory.Repository) Option

WithMemoryRepository wires a memory backend by scenario memory name.

func WithOutboxRelay added in v0.3.1

func WithOutboxRelay(interval time.Duration) Option

WithOutboxRelay starts a background loop (same GoSafe + closers pattern as the run reaper) that drains the run-state repository's event outbox: unpublished rows are delivered to the durable event store wired with WithEventStore and marked published, at-least-once — delivery failures leave the row unpublished for the next sweep, and redelivery is deduplicated by the event store's UNIQUE (run_id, sequence) constraint. The relay stops on Framework.Close.

Pair it with the outbox-capable event sink (adapters.NewPostgresOutboxEventSink) in the WithEventSink fanout: that sink parks events in the outbox whenever the durable append fails, and the relay closes the gap. Multiple nodes may relay concurrently against the same database; marking is a conditional update (WHERE published_at IS NULL) and duplicate delivery collapses on the sequence constraint.

interval defaults to 2s when non-positive. New returns an error unless the event store implements observability.SequencedEventStore and the run-state repository implements runstate.OutboxRepository — today that means the PostgreSQL runstate repository; combining Redis runstate with a PostgreSQL outbox is not supported because the outbox must share the snapshots' database.

func WithOutputRedactor

func WithOutputRedactor(redactor governance.OutputRedactor) Option

WithOutputRedactor wires an output redactor that scrubs sensitive fields from step outputs before they are persisted or returned to callers.

func WithRecorder added in v0.1.1

func WithRecorder(recorder observability.Recorder) Option

WithRecorder wires a metrics recorder. If not provided, metrics are discarded via observability.NoopRecorder.

func WithRequireLLM added in v0.1.4

func WithRequireLLM() Option

WithRequireLLM makes New fail when no LLM gateway is wired.

func WithResumeAuthorizationHook added in v0.3.0

func WithResumeAuthorizationHook(hook ResumeAuthorizationHook) Option

WithResumeAuthorizationHook installs the authorization hook consulted by ResumeRunByID before it signs a new resume token. Without a hook the library keeps its historical behavior (any caller that knows the run ID may resume), so every HTTP exposure of ResumeRunByID must be authorized out-of-band — see the warning on ResumeRunByID.

func WithRunLease added in v0.3.0

func WithRunLease(locker coordination.Locker, owner string, ttl time.Duration) Option

WithRunLease enables distributed run-lease coordination: every Run, RunStructured, ResumeAndContinue, and RetryFailedRun holds (and renews) a lease on the run for as long as it executes. A run left in Running whose lease has expired belonged to a crashed or partitioned worker and can be reaped with MarkAbandonedRuns; pair it with WithRunReaper on multi-node deployments so reaping happens automatically.

The lease's fencing token travels with execution: when the run-state repository implements runstate.FencedRepository, every snapshot save is validated against the run's fence high-water mark, so a zombie writer whose lease was superseded fails with ErrStaleFence instead of clobbering the new owner's state. Framework construction fails with ErrFenceRequired when the configured run-state repository cannot fence; leased execution never falls back to an unprotected plain save.

owner identifies this worker in lease ownership; when empty, a random worker ID is generated. ttl defaults to 30s when non-positive.

func WithRunReaper added in v0.3.1

func WithRunReaper(interval, gracePeriod time.Duration) Option

WithRunReaper starts a background loop that periodically calls MarkAbandonedRuns, failing Running runs whose worker crashed or was partitioned away (their run lease is no longer held). It requires WithRunLease; New returns an error otherwise.

The sweep is lease-probe based and idempotent, so any number of nodes may run it concurrently against shared storage — a run is reaped exactly once no matter how many reapers race it. Multi-node deployments are strongly encouraged to enable it on every worker: without it, a crashed worker leaves its runs in Running forever.

interval defaults to 1m when zero. gracePeriod overrides how long a Running run must go without snapshot updates before it becomes reapable; it defaults to the run-lease TTL, which covers the Resume and gate→lease windows. The reaper stops on Framework.Close.

func WithRunStateRepository

func WithRunStateRepository(repo runstate.Repository) Option

WithRunStateRepository wires run-state persistence used for pause/resume.

func WithSecurityPolicy

func WithSecurityPolicy(policy security.Policy) Option

WithSecurityPolicy wires an authorization policy used by runtime execution.

func WithTierColdSummarizer added in v0.2.0

func WithTierColdSummarizer(name string, summarizer tier.ContentSummarizer) Option

WithTierColdSummarizer wires an LLM summarizer for cold-tier archive on a memory name.

func WithTierColdSummaryIndexer added in v0.2.0

func WithTierColdSummaryIndexer(name string, indexer tier.ColdSummaryIndexer) Option

WithTierColdSummaryIndexer wires a vector indexer for cold-tier summary recall on a memory name.

func WithTierMemory added in v0.1.9

func WithTierMemory(name string, manager tier.Manager) Option

WithTierMemory wires a tier manager by scenario memory name.

func WithTierStore added in v0.1.9

func WithTierStore(name string, store tier.Store, policy tier.Policy) Option

WithTierStore wires a tier store and the policy used to build its default manager. The supplied policy overrides the policy derived from the scenario memory tier settings for this memory name.

func WithToolApprovalEvaluator added in v0.3.0

func WithToolApprovalEvaluator(evaluator core.ToolApprovalEvaluator) Option

WithToolApprovalEvaluator wires dynamic tool approval evaluation beyond static scenario Tool.Approval policies.

func WithToolCatalog added in v0.4.2

func WithToolCatalog(catalog toolcatalog.Catalog) Option

WithToolCatalog attaches a deferred tool catalog to the engine. When set, the LLM initially sees only catalog meta-tools (search_tools, load_tool_schemas) plus pinned or non-MCP builtin tools on the agent.

func WithToolExecutor

func WithToolExecutor(name string, executor core.ToolExecutor) Option

WithToolExecutor registers an executable tool implementation by scenario tool name. Agent tool policies still come from the scenario YAML.

func WithToolGovernancePolicy

func WithToolGovernancePolicy(policy governance.ToolPolicy) Option

WithToolGovernancePolicy wires a per-invocation tool governance policy. The policy is evaluated before every tool execution and can deny calls based on side-effect level, call budget, or custom logic.

func WithToolOrchestrator added in v0.3.0

func WithToolOrchestrator(orch toolorch.ToolOrchestrator) Option

WithToolOrchestrator wires approval-cache / post-attempt orchestration. OS sandbox escalate remains host-owned via AttemptResult.

func WithToolOutputTransform added in v0.3.0

func WithToolOutputTransform(tool string, fn contextwindow.ToolOutputTransform) Option

WithToolOutputTransform registers a per-tool reshaper applied before LLM and memory persistence when ToolResultMaxTokens / ToolOutputMaxBytes apply.

func WithToolResolver

func WithToolResolver(resolver core.ToolResolver) Option

WithToolResolver wires a resolver that creates or retrieves tool executors only when a declared tool is invoked. Explicit WithToolExecutor registrations take precedence over the resolver.

func WithToolResolverCacheLimit added in v0.4.5

func WithToolResolverCacheLimit(limit int) Option

WithToolResolverCacheLimit bounds principal-scoped lazy executor caching. The default is 1024 entries; zero disables caching.

func WithTracer added in v0.1.1

func WithTracer(tracer observability.Tracer) Option

WithTracer wires a distributed-tracing provider. If not provided, tracing is a no-op via observability.NoopTracer.

func WithTurnStopHook added in v0.3.0

func WithTurnStopHook(hook core.TurnStopHook) Option

WithTurnStopHook registers a host callback that may veto turn completion and inject a continuation prompt (Codex stop-hooks style).

type PendingHITLInfo added in v0.2.0

type PendingHITLInfo struct {
	NodeID    string `json:"node_id,omitempty"`
	Interrupt bool   `json:"interrupt,omitempty"`
}

PendingHITLInfo describes a paused run awaiting HITL approval.

type Plan

type Plan struct {
	Scenario core.Scenario
	LLMs     map[string]llm.Profile
	Memory   map[string]memory.Namespace
}

Plan is a resolved scenario plan that library users can inspect before creating a Framework.

func BuildPlan

func BuildPlan(scenario core.Scenario) (Plan, error)

BuildPlan validates and resolves public LLM and memory metadata from a scenario. It does not create provider clients or start execution.

type PurgeRunsOption added in v0.3.0

type PurgeRunsOption func(*purgeRunsOptions)

PurgeRunsOption customizes PurgeRuns.

func WithPurgeForce added in v0.3.0

func WithPurgeForce() PurgeRunsOption

WithPurgeForce lets PurgeRuns delete runs in any status, including Running and Paused. Without it, non-terminal runs are skipped so a retention sweep can never delete a run that is still executing or awaiting a human.

type RedisLocker added in v0.3.1

type RedisLocker interface {
	coordination.Locker
	Close() error
}

RedisLocker is a coordination.Locker with a Close method releasing the underlying connection pool. Lockers built from a caller-provided go-redis client do not close that client on Close.

func NewRedisLocker

func NewRedisLocker(config RedisLockerConfig) (RedisLocker, error)

NewRedisLocker creates a Redis-backed lease manager for distributed worker and workflow coordination. Every Acquire mints a monotonically increasing fencing token (Lease.Token); Renew and Release compare the full "{owner}:{token}" lock value, so a stale handle from a superseded holder — including a different process configured with the same owner name — is rejected. The returned locker owns a pooled go-redis client; close it with Close when done.

func NewRedisLockerFromClient added in v0.3.1

func NewRedisLockerFromClient(client *redis.Client, keyPrefix string) (RedisLocker, error)

NewRedisLockerFromClient wraps an existing pooled go-redis client so several subsystems (run lease, device registry, command routing) can share one connection pool. The client stays owned by the caller and is not closed by the locker.

type RedisLockerConfig

type RedisLockerConfig struct {
	Addr         string
	Password     string
	DB           int
	KeyPrefix    string
	DialTimeout  time.Duration
	ReadTimeout  time.Duration
	WriteTimeout time.Duration
}

type ResumeAuthorizationHook added in v0.3.0

type ResumeAuthorizationHook func(ctx context.Context, runID string) error

ResumeAuthorizationHook authorizes a ResumeRunByID call before the framework mints a fresh HITL token for runID. A nil error allows the resume; any non-nil error aborts it and is returned to the caller.

type RetentionPolicy added in v0.1.4

type RetentionPolicy struct {
	MaxAge       time.Duration
	Status       runstate.RunStatus
	ScenarioName string
	Limit        int
}

RetentionPolicy controls run-state cleanup.

type RunRequest

type RunRequest = appexec.RunRequest

RunRequest is the input passed to Framework.Run.

type RunResult

type RunResult = appexec.RunResult

RunResult is the result returned from Framework.Run.

type RunStep added in v0.2.0

type RunStep struct {
	NodeID string                 `json:"node_id"`
	Output runstate.StepOutputRef `json:"output"`
}

RunStep describes one persisted workflow step output.

type SaveStudioResult added in v0.2.0

type SaveStudioResult struct {
	Path         string              `json:"path"`
	ScenarioName string              `json:"scenario_name"`
	Graph        graph.ScenarioGraph `json:"graph,omitempty"`
}

SaveStudioResult describes a persisted Studio graph write.

type ScenarioBuilder added in v0.1.10

type ScenarioBuilder = scenariobuilder.ScenarioBuilder

ScenarioBuilder constructs scenarios with a fluent Go API. See pkg/builder for the full surface.

type ScenarioGraph added in v0.2.0

type ScenarioGraph = graph.ScenarioGraph

ScenarioGraph is a Studio-friendly orchestration topology view.

type StreamFrame added in v0.3.0

type StreamFrame struct {
	Kind   StreamFrameKind
	Chunk  *llm.ChatChunk // for token
	Event  *core.Event    // for event
	Err    error
	Result *RunResult // for done
	// EventsLost carries the cumulative number of teed events dropped so far
	// when Kind is StreamFrameEventsLost.
	EventsLost int64
}

StreamFrame is a unified token/event/terminal frame for StreamRun.

type StreamFrameKind added in v0.3.0

type StreamFrameKind string

StreamFrameKind discriminates unified StreamRun frames.

const (
	StreamFrameToken StreamFrameKind = "token"
	StreamFrameEvent StreamFrameKind = "event"
	StreamFrameDone  StreamFrameKind = "done"
	StreamFrameError StreamFrameKind = "error"
	// StreamFrameEventsLost marks that teed events were dropped because the
	// frame consumer fell behind; EventsLost carries the cumulative count.
	// Token frames are never dropped, so the stream stays authoritative for
	// the answer itself.
	StreamFrameEventsLost StreamFrameKind = "events_lost"
)

type StreamRunOption added in v0.3.0

type StreamRunOption func(*streamRunOptions)

StreamRunOption configures StreamRun read-side behavior.

func WithStreamDetached added in v0.3.0

func WithStreamDetached() StreamRunOption

WithStreamDetached detaches execution from the caller's context: when the caller's ctx is cancelled (e.g. the SSE client disconnects), the run is NOT marked Cancelled but keeps executing in the background until it reaches a terminal state and persists its result normally. The frame channel closes when the caller goes away; the terminal state is observable afterwards via the run-state repository. An explicit Framework-level cancellation of the run (Cancel API) and a lost run lease still abort it.

func WithStreamEventFilterPreset added in v0.3.0

func WithStreamEventFilterPreset(preset EventFilterPreset) StreamRunOption

WithStreamEventFilterPreset selects the event view for StreamFrameEvent frames. EventStore / WithEventSink still receive the full stream. Empty defaults to diagnostic (all events, including MemoryRead and ContextPrepared).

type Studio added in v0.3.0

type Studio struct {
	// contains filtered or unexported fields
}

Studio groups development-time graph editing and run inspection APIs. Prefer Framework.Studio() for new call sites; existing Framework methods remain as thin delegates for compatibility.

func (Studio) CompareRuns added in v0.3.0

func (s Studio) CompareRuns(ctx context.Context, runA, runB string) (studio.RunCompareResult, error)

CompareRuns diffs step outputs between two persisted runs.

func (Studio) ComposeGraph added in v0.4.0

func (s Studio) ComposeGraph(ctx context.Context, req ComposeGraphRequest) (ComposeGraphResult, error)

ComposeGraph generates a validated scenario graph for a natural-language task using an agentic composer: an internal agent builds the draft through compose_* tools with incremental validation feedback, the result is merged onto a deep copy of the live scenario, fully validated, and optionally executed ephemerally. The live framework state is never mutated.

func (Studio) ForkRun added in v0.3.0

func (s Studio) ForkRun(ctx context.Context, parentRunID string, version int64) (ForkRunResult, error)

ForkRun copies a run snapshot into a new run ID without modifying the parent run.

func (Studio) GenerateStudioBuilderCode added in v0.3.0

func (s Studio) GenerateStudioBuilderCode(ctx context.Context, edited graph.ScenarioGraph) (CodegenResult, error)

GenerateStudioBuilderCode renders builder Go code for an edited Studio graph.

func (Studio) GenerateStudioBuilderCodeWithScenario added in v0.4.5

func (s Studio) GenerateStudioBuilderCodeWithScenario(_ context.Context, edited graph.ScenarioGraph, draft *core.Scenario) (CodegenResult, error)

GenerateStudioBuilderCodeWithScenario renders builder code including an optional additive scenario-mode composition draft.

func (Studio) GenerateStudioScenarioYAML added in v0.3.0

func (s Studio) GenerateStudioScenarioYAML(ctx context.Context, edited graph.ScenarioGraph) (CodegenResult, error)

GenerateStudioScenarioYAML renders legacy scenario YAML for an edited Studio graph.

func (Studio) GenerateStudioScenarioYAMLWithScenario added in v0.4.5

func (s Studio) GenerateStudioScenarioYAMLWithScenario(_ context.Context, edited graph.ScenarioGraph, draft *core.Scenario) (CodegenResult, error)

GenerateStudioScenarioYAMLWithScenario renders YAML including an optional additive scenario-mode composition draft.

func (Studio) ImportStudioScenarioYAML added in v0.3.0

func (s Studio) ImportStudioScenarioYAML(_ context.Context, yamlData []byte, layout graph.ScenarioGraph) (ImportStudioResult, error)

ImportStudioScenarioYAML parses legacy scenario YAML and returns an editable graph. When layout is non-empty, node positions from layout are merged onto the imported graph.

func (Studio) ListRunThread added in v0.3.0

func (s Studio) ListRunThread(ctx context.Context, runID string) ([]ThreadRunSummary, error)

ListRunThread returns runs in the same fork/thread group as the given run.

func (Studio) Parts added in v0.4.0

func (s Studio) Parts() StudioParts

Parts lists the composable parts of the live scenario.

func (Studio) RunStudioGraph added in v0.3.0

func (s Studio) RunStudioGraph(ctx context.Context, edited graph.ScenarioGraph, req RunRequest) (RunResult, error)

RunStudioGraph validates an edited graph and executes it as a new run.

func (Studio) RunStudioGraphWithScenario added in v0.4.4

func (s Studio) RunStudioGraphWithScenario(ctx context.Context, edited graph.ScenarioGraph, draft *core.Scenario, req RunRequest) (RunResult, error)

RunStudioGraphWithScenario executes a graph with an optional additive scenario-mode compose draft without mutating the live Framework.

func (Studio) SaveStudioGraph added in v0.3.0

func (s Studio) SaveStudioGraph(ctx context.Context, edited graph.ScenarioGraph, path string) (SaveStudioResult, error)

SaveStudioGraph validates an edited graph, writes legacy YAML to path, and atomically replaces the live scenario and engine so subsequent runs use the saved definition (not a half-updated Framework / stale Engine pair).

func (Studio) SaveStudioGraphWithScenario added in v0.4.4

func (s Studio) SaveStudioGraphWithScenario(ctx context.Context, edited graph.ScenarioGraph, draft *core.Scenario, path string) (SaveStudioResult, error)

SaveStudioGraphWithScenario persists a graph together with the additive agents/skills returned by scenario-mode ComposeGraph. Existing live parts are immutable; a stale or tampered draft that changes them is rejected.

func (Studio) ValidateStudioGraph added in v0.3.0

func (s Studio) ValidateStudioGraph(ctx context.Context, edited graph.ScenarioGraph) (ValidateStudioResult, error)

ValidateStudioGraph validates an edited Studio graph against the framework scenario.

func (Studio) ValidateStudioGraphWithScenario added in v0.4.5

func (s Studio) ValidateStudioGraphWithScenario(_ context.Context, edited graph.ScenarioGraph, draft *core.Scenario) (ValidateStudioResult, error)

ValidateStudioGraphWithScenario validates a graph together with the additive agents/skills returned by scenario-mode composition.

type StudioPart added in v0.4.0

type StudioPart struct {
	Name        string `json:"name"`
	Description string `json:"description,omitempty"`
}

StudioPart describes one composable part of the live scenario.

type StudioParts added in v0.4.0

type StudioParts struct {
	Agents    []StudioPart `json:"agents"`
	Tools     []StudioPart `json:"tools"`
	Skills    []StudioPart `json:"skills"`
	Subgraphs []StudioPart `json:"subgraphs"`
}

StudioParts groups the live scenario's composable parts by kind, sorted by name. It backs the Studio parts palette and AI composition catalog.

type ThreadRunSummary added in v0.2.0

type ThreadRunSummary struct {
	RunID           string             `json:"run_id"`
	ParentRunID     string             `json:"parent_run_id,omitempty"`
	ForkFromVersion int64              `json:"fork_from_version,omitempty"`
	ThreadID        string             `json:"thread_id"`
	Status          runstate.RunStatus `json:"status"`
	ScenarioName    string             `json:"scenario_name,omitempty"`
}

ThreadRunSummary describes one run in a fork/thread group.

type TrustMode added in v0.3.0

type TrustMode = appexec.TrustMode

TrustMode controls run-scoped tool approval overrides (e.g. full_trust).

type ValidateStudioResult added in v0.2.0

type ValidateStudioResult struct {
	Valid     bool   `json:"valid"`
	Error     string `json:"error,omitempty"`
	ErrorCode string `json:"error_code,omitempty"`
	Scenario  string `json:"scenario_name"`
}

ValidateStudioResult reports graph/scenario validation output for Studio.

type WiringOptions added in v0.1.4

type WiringOptions struct {
	RequireLLM                 bool
	AllowMockProviderWithoutGW bool
}

WiringOptions controls ValidateWiring and optional New-time checks.

type WorkflowBuilder added in v0.1.10

type WorkflowBuilder = scenariobuilder.WorkflowBuilder

WorkflowBuilder constructs workflow graphs with a fluent Go API.

Directories

Path Synopsis
examples
go/builder command
go/compose-graph command
Command compose-graph demonstrates AI graph composition (Studio.ComposeGraph) in both modes: catalog (orchestrate existing parts only) and scenario (compose new agents plus topology).
Command compose-graph demonstrates AI graph composition (Studio.ComposeGraph) in both modes: catalog (orchestrate existing parts only) and scenario (compose new agents plus topology).
go/hitl-resume command
go/http-worker command
go/minimal command
go/postgres command
go/scenario
Package scenario provides builder stacks shared by examples/go programs.
Package scenario provides builder stacks shared by examples/go programs.
go/tier-memory command
go/tier-worker command
tier-worker runs the tier-memory builder stack with Postgres warm tier, file or blob cold tier, and async memory.reconcile jobs via a shared job queue.
tier-worker runs the tier-memory builder stack with Postgres warm tier, file or blob cold tier, and async memory.reconcile jobs via a shared job queue.
go/validate command
internal
adapter/coordination/inmem
Package inmem provides an in-process coordination.Locker for tests and single-process deployments.
Package inmem provides an in-process coordination.Locker for tests and single-process deployments.
adapter/coordination/redis
Package redis provides a coordination.Locker backed by Redis with monotonically increasing fencing tokens.
Package redis provides a coordination.Locker backed by Redis with monotonically increasing fencing tokens.
fsatomic
Package fsatomic provides crash-safe atomic file writes shared by the file-backed adapters.
Package fsatomic provides crash-safe atomic file writes shared by the file-backed adapters.
toolinvoke
Package toolinvoke holds shared tool-invocation preflight checks used by both the autonomous runtime tool loop and the workflow NodeTool path so approval, input validation, side-effect retry, and security resource shape cannot drift between the two stacks.
Package toolinvoke holds shared tool-invocation preflight checks used by both the autonomous runtime tool loop and the workflow NodeTool path so approval, input validation, side-effect retry, and security resource shape cannot drift between the two stacks.
migrations
postgres
Package postgres applies and inspects the versioned PostgreSQL schema migrations embedded from this directory (the NNNN_*.up.sql files).
Package postgres applies and inspects the versioned PostgreSQL schema migrations embedded from this directory (the NNNN_*.up.sql files).
postgres/cmd/apply-migrations command
Command apply-migrations applies the embedded agentflow PostgreSQL schema migrations to the database named by AGENT_POSTGRES_DSN (or the first argument).
Command apply-migrations applies the embedded agentflow PostgreSQL schema migrations to the database named by AGENT_POSTGRES_DSN (or the first argument).
pkg
adapters
Package adapters collects the convenience constructors for the concrete adapters shipped with agentflow: run-state/blob/memory stores, job queues, LLM providers, catalog manifests, knowledge and MCP tooling, built-in tool executors, tiered memory, and observability sinks/stores.
Package adapters collects the convenience constructors for the concrete adapters shipped with agentflow: run-state/blob/memory stores, job queues, LLM providers, catalog manifests, knowledge and MCP tooling, built-in tool executors, tiered memory, and observability sinks/stores.
builder
Package builder is the **primary** way to construct core.Scenario values for agentflow-go.
Package builder is the **primary** way to construct core.Scenario values for agentflow-go.
httpx
Package httpx hosts the HTTP adapter constructors for the agentflow root facade (checkpoint, retention, studio, webhook/human-gate, async jobs, production composition, and the observability dashboard) plus the scenario wiring helpers whose signatures reference root-facade types such as agentflow.Framework and agentflow.Option.
Package httpx hosts the HTTP adapter constructors for the agentflow root facade (checkpoint, retention, studio, webhook/human-gate, async jobs, production composition, and the observability dashboard) plus the scenario wiring helpers whose signatures reference root-facade types such as agentflow.Framework and agentflow.Option.
interjection
Package interjection formats and buffers mid-turn user messages.
Package interjection formats and buffers mid-turn user messages.
llm
log
mcp
memory/tier
Package tier implements the tiered memory subsystem: tier-scoped record stores, a manager that remembers and recalls records across hot/warm/cold levels, and the policies that migrate records between them.
Package tier implements the tiered memory subsystem: tier-scoped record stores, a manager that remembers and recalls records across hot/warm/cold levels, and the policies that migrate records between them.
planmode
Package planmode provides a pure interactive plan-mode state machine.
Package planmode provides a pure interactive plan-mode state machine.
retry
Package retry provides the retry classification and backoff shared by the autonomous runtime and the workflow orchestrator, so both apply the same semantics: only errors that explicitly classify themselves as retryable are re-attempted, with exponential backoff and jitter between attempts.
Package retry provides the retry classification and backoff shared by the autonomous runtime and the workflow orchestrator, so both apply the same semantics: only errors that explicitly classify themselves as retryable are re-attempted, with exponential backoff and jitter between attempts.
security/ssrf
Package ssrf provides Server-Side Request Forgery guards for URL-fetching tools.
Package ssrf provides Server-Side Request Forgery guards for URL-fetching tools.
testutil
Package testutil provides helpers for testing applications built on agentflow.
Package testutil provides helpers for testing applications built on agentflow.
toolorch
Package toolorch provides Codex-inspired tool orchestration helpers for autonomous runs: sampling step freeze, approval cache, and deny breakers.
Package toolorch provides Codex-inspired tool orchestration helpers for autonomous runs: sampling step freeze, approval cache, and deny breakers.
toolschema
Package toolschema provides a lightweight, dependency-free validator for tool call inputs against a tool's declared JSON-Schema-like InputSchema.
Package toolschema provides a lightweight, dependency-free validator for tool call inputs against a tool's declared JSON-Schema-like InputSchema.
Package schemas embeds machine-readable configuration schemas for AgentFlow.
Package schemas embeds machine-readable configuration schemas for AgentFlow.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL