Help us shape the future of Go! Take the 2026 Go Developer Survey

workagents

package
v0.7.0 Latest Latest
Warning

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

Go to latest
Published: Oct 19, 2026 License: AGPL-3.0 Imports: 24 Imported by: 0

README

Native agent workflows

Register workagents.New(admin.CompleteWorkAgent) in kernel BootOrder after admin. The module publishes the authenticated /agents and /workspace screens, scoped /api/v1/workagents operations, system health checks, and workagents.run jobs. It uses native auth, CSRF, audit, SQLite and the persistent job scheduler. No browser session is required for scheduled execution.

The owner permissions migration grants workagents.read and workagents.run to native customer/editor/author/contributor roles. Every query still checks ownership; these grants do not expose other users' profiles or runs. Management is separate and is not granted by this migration. API keys additionally need matching scopes. Register reloads the auth role cache after this module's migrations so the permissions work immediately on first boot.

Supported execution registry

  • text: a text-only AI turn through the encrypted native provider registry. Connection and model may be blank to use the site's configured defaults. No shell, external tools, publishing or arbitrary HTTP actions are executed.
  • github_stars: public GitHub repository statistics. Input is {"repository":"owner/repo"}. Only a fixed, read-only GitHub API endpoint is contacted; no private repository credential is accepted or returned.
  • github_starred: public repositories starred by a GitHub user. Input is {"username":"octocat"}. Returns repository ID, name, canonical link and starred_at, deduplicated by repository ID across at most three 100-item pages. truncated=true explicitly signals the 300-item ceiling. Requests use the star media type, accept no token/URL, reject redirects and never follow upstream pagination links. Each run persists a bounded snapshot; completed job replays do not refetch or create duplicate artifacts.
  • content_draft: creates a sanitized native draft with the owner's author ID, provided that owner has content.create. Input is {"type":"post","title":"Title","body":"Content","locale":"en"}. Types are limited to post and page; locale is ar or en. It cannot publish, replace existing content, delete records or choose another author. A stable per-run slug avoids duplicate drafts if a process restarts.

unsupported_tools blocks execution even for an enabled profile. Configuration readability is displayed separately from profile enablement and does not assert upstream reachability. Provider failures persist a safe error code, never a successful empty artifact. Logs/audit omit credentials and request content.

Scheduling and import

Workflow intervals range from 60 seconds to one year; the queue checks due workflows every 30 seconds. Due-run insertion, job enqueue and advancement of next_run_at commit together. Disabled workflows, inactive owners, disabled agents and unsupported tools are excluded. API idempotency keys are scoped to the owner; a changed request with the same key returns a conflict.

Source IDs have unique indexes in the agents, workflows, runs, artifacts and approvals tables. Import source ownership through an explicit account mapping. Historical runs/artifacts/approvals must have historical=1 and no new job records. Imported workflows should remain disabled until an operator maps their requested action to the native execution registry. Imported source_config.organization and organization graphs expose blocked_reason=workflow_graph_unsupported. Activation returns HTTP 409; the scheduler skips legacy enabled graphs and already-queued graph jobs fail before any provider call. This is a compatibility guard, not a multi-step executor. Map steps, output contracts and fresh human approval before enabling. Historical approvals are read-only; importing them does not authorize a fresh action.

System health warns about unsupported imported tools, paused source workflows and failed native executions. Raw source provider credentials/configuration must remain encrypted and must not be copied into profile prompts, inputs, artifacts or API-visible descriptions.

Verification

go test -race ./internal/workagents exercises real SQLite, the job queue, provider HTTP boundary, full kernel boot/catalog/API registration, owner isolation, escaped HTML, schedule deduplication, disabled/history protection, bounded GitHub requests, and permission-checked sanitized draft creation.

Explicit linear flows with fresh approval

POST /api/v1/workagents/linear-flows starts a manual, operator-owned plan:

{
  "name": "Reviewed article",
  "input": "Verified source material",
  "request_key": "review-2026-01",
  "draft_title": "Reviewed article",
  "draft_locale": "ar",
  "steps": [
    {"kind": "agent", "agent_id": "native-writer-id"},
    {"kind": "approval"},
    {"kind": "draft", "agent_id": "native-draft-agent-id"}
  ]
}

Read /linear-flows/{id} for status, result, step and result_hash. At awaiting_approval, the same owning operator submits to /linear-flows/{id}/decision with approve, exact step and result_hash. A stale/replayed decision returns409; rejection stops execution. Historical approvals are never read. Management permission is checked on start/decision and again while advancing. The cron runs every30seconds with persistent jobs; closing the browser does not stop the flow. An unchanged request_key returns the same flow; changed input/plan returns409. Each stage has a stable queue key so a repeated tick cannot duplicate output.

Plans support2–12 steps: text agents, an optional initial public GitHub agent, approval gates, and an optional terminal content_draft agent immediately after approval. Every agent belongs to the operator. Output is bounded32KiB between stages. Drafts are sanitized and never published. This v1 is a strict linear manual runner, not the imported graph executor: conditions, branching, retries, audio generation, scheduled source triggers and automatic source-ID mapping are unsupported. Unknown JSON fields are rejected. Existing imported graphs remain disabled until an operator explicitly maps and verifies equivalent contracts; removing source conditions merely to activate a plan is invalid.

Documentation

Overview

Package workagents runs owner-scoped text agents through GoRun's job queue.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Agent

type Agent struct {
	ID                 string   `json:"id"`
	OwnerID            string   `json:"owner_id"`
	SourceID           string   `json:"source_id"`
	Name               string   `json:"name"`
	Description        string   `json:"description"`
	SystemPrompt       string   `json:"system_prompt"`
	ConnectionID       string   `json:"connection_id"`
	Model              string   `json:"model"`
	Enabled            bool     `json:"enabled"`
	UnsupportedTools   []string `json:"unsupported_tools"`
	ProviderConfigured bool     `json:"provider_configured"`
	ExecutionKind      string   `json:"execution_kind"`
}

type Completion

type Completion func(context.Context, *kernel.Deps, string, string, string, string) (string, error)

Completion is supplied by the native provider adapter; secrets never enter this module's database or HTTP responses.

type LinearDecision

type LinearDecision struct {
	Approve    bool   `json:"approve"`
	Step       int    `json:"step"`
	ResultHash string `json:"result_hash"`
}

type LinearFlow

type LinearFlow struct {
	ID           string     `json:"id"`
	OwnerID      string     `json:"owner_id"`
	Plan         LinearPlan `json:"plan"`
	Step         int        `json:"step"`
	Status       string     `json:"status"`
	Result       string     `json:"result"`
	ResultHash   string     `json:"result_hash"`
	ErrorCode    string     `json:"error_code"`
	ApprovedStep int        `json:"approved_step"`
}

type LinearPlan

type LinearPlan struct {
	Name        string       `json:"name"`
	Input       string       `json:"input"`
	RequestKey  string       `json:"request_key"`
	Steps       []LinearStep `json:"steps"`
	DraftTitle  string       `json:"draft_title,omitempty"`
	DraftLocale string       `json:"draft_locale,omitempty"`
}

LinearPlan deliberately does not accept imported graphs or conditions. An operator must map them explicitly without silently losing source semantics.

type LinearStep

type LinearStep struct {
	Kind    string `json:"kind"` // agent, approval, draft
	AgentID string `json:"agent_id,omitempty"`
}

type Module

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

func New

func New(complete Completion) *Module

func (*Module) Catalogs

func (*Module) Catalogs() fs.FS

func (*Module) Migrations

func (*Module) Migrations() fs.FS

func (*Module) Name

func (*Module) Name() string

func (*Module) Register

func (m *Module) Register(d *kernel.Deps) error

type Run

type Run struct {
	ID         string `json:"id"`
	AgentID    string `json:"agent_id"`
	WorkflowID string `json:"workflow_id"`
	Status     string `json:"status"`
	ErrorCode  string `json:"error_code"`
	Input      string `json:"input"`
	Result     string `json:"result"`
	CreatedAt  string `json:"created_at"`
	FinishedAt string `json:"finished_at"`
	Historical bool   `json:"historical"`
}

type Workflow

type Workflow struct {
	ID              string `json:"id"`
	AgentID         string `json:"agent_id"`
	Name            string `json:"name"`
	Input           string `json:"input"`
	Enabled         bool   `json:"enabled"`
	IntervalSeconds int    `json:"interval_seconds"`
	NextRunAt       string `json:"next_run_at"`
	BlockedReason   string `json:"blocked_reason,omitempty"`
}

Jump to

Keyboard shortcuts

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