Skip to content

add self service agent to workbench - #4381

Open
chrisakinrinade wants to merge 4 commits into
masterfrom
prod-5138-self-serve-agent
Open

chrisakinrinade wants to merge 4 commits into
masterfrom
prod-5138-self-serve-agent

Conversation

@chrisakinrinade

Copy link
Copy Markdown

Workbench jobs can now provision infrastructure through existing Plural catalogs and PR automations instead of routing every request to the coding agent. When a task maps cleanly to a golden path, the self-service subagent finds the right automation, inspects it, and opens the PR directly.

Test Plan

Test environment: https://console.your-env.onplural.sh/

Checklist

  • I have added a meaningful title and summary to convey the impact of this PR to a user.
  • If required, I have updated the Plural documentation accordingly.
  • I have added tests to cover my changes.
  • I have deployed the agent to a test environment and verified that it works as expected (required only when changing agent code).

Plural Flow: console

@linear

linear Bot commented Sep 21, 2026

Copy link
Copy Markdown

PROD-5138

@soffi-ai

soffi-ai Bot commented Sep 21, 2026

Copy link
Copy Markdown
Soffi AI Summary

This PR introduces a self-service subagent to the AI workbench, enabling it to fulfill infrastructure requests through existing Plural catalogs and PR automations rather than always delegating to a coding agent. When a user's task maps to a known "golden path" (e.g., provisioning a database or deploying a service via a catalog template), the new subagent discovers the right PR automation, inspects its configuration, and opens the PR directly — without requiring custom code generation.

Why this was done: Many common infrastructure requests are already covered by pre-defined PR automations and catalog items. Routing all such requests through the coding agent is slower and more expensive (in LLM tokens/cost) than invoking the established self-service workflow directly. This subagent adds a structured shortcut for those cases.

Key changes:

  • Three new Elixir AI tool modules implement the self-service capabilities: catalog_search (finds relevant catalog entries), get_pr_automation (retrieves automation configuration), and invoke_pr_automation (executes the automation to open a PR).
  • A new SelfService subagent orchestrates these tools under its own LLM prompt (priv/prompts/workbench/self_service.md.eex).
  • The workbench schema, GraphQL API, and job activity/skill enums are extended with a SELF_SERVICE type and a selfService boolean capability flag.
  • The workbench creation/editing UI gains a toggle to enable the self-service subagent capability.
  • Tool JSON schemas, tests (unit + GraphQL mutation), and generated GraphQL types are all updated to match.

Changes

Self-service subagent for workbench

  • Adds the self-service subagent and its three underlying tools (catalog_search, get_pr_automation, invoke_pr_automation), the orchestrating subagent module, LLM prompt, tool JSON schemas, GraphQL schema/API extensions (selfService flag, SELF_SERVICE enum values), UI toggle in the workbench form, and full test coverage. (a935a7a)
  • Minor syntax fixes to the catalog_search Elixir module introduced in the preceding commit. (653afb2)
  • Merge from origin/master to bring the feature branch up to date with upstream changes before finalizing the self-service subagent work. (93be15e)

Updated: 2026-09-21 18:55 UTC

Deploy in Soffi

end

def implement(%__MODULE__{query: query}) do
case Tool.actor() do

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ai will screw this up a lot, but this should ideally be a with comprehension

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just changed it to a with using tagged failure cases

end

defp fallback_search(query, user) do
catalogs =

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be have two things:

  1. Be a stream so the list is set up lazily
  2. Have it factored in a single pipeline, can use Enum.concat into Jason.encode

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just made the fallback search more functional. for the streams, do you mean lazy load from the db or just when combining lists?

…e-agent

Co-authored-by: Cursor <cursoragent@cursor.com>

# Conflicts:
#	js/console/src/generated/graphql.ts
#	js/console/src/generated/persisted-queries/client.json
#	lib/console/ai/workbench/engine.ex
#	test/console/ai/workbench/environment_test.exs
@chrisakinrinade chrisakinrinade added the enhancement New feature or request label Sep 21, 2026
@chrisakinrinade
chrisakinrinade marked this pull request as ready for review September 21, 2026 19:53
@chrisakinrinade
chrisakinrinade requested a review from a team as a code owner September 21, 2026 19:53
@greptile-apps

greptile-apps Bot commented Sep 21, 2026

Copy link
Copy Markdown
Contributor

RetriggerConfidence Score: 4/5

This PR is not safe to merge until model-driven PR creation is routed through an explicit user-approval boundary.

Findings

  1. P1 Approval Is Bypassed

Summary

This PR adds an optional self-service workbench subagent that discovers catalog-backed PR automations, inspects their configuration, and creates a pull request linked to the current workbench job.

  • Adds catalog search, automation inspection, and invocation tools plus their model schemas and prompt.
  • Adds self-service capability configuration across persistence, GraphQL, generated client contracts, and the workbench form.
  • Integrates the new subagent with the workbench engine, skills, activities, and environment.
  • Adds backend tests for discovery, access checks, invocation, subagent execution, and configuration persistence.
  • The direct invocation currently bypasses the established user-approval boundary for external side effects.

Reviews (1) · Last reviewed commit: "fix test failures"

Comment thread lib/console/ai/tools/workbench/self_service/invoke_pr_automation.ex
Catalog.search(query)
|> Catalog.for_user(user)
|> Repo.all()
|> Enum.map(&%{catalog: Map.take(&1, [:id, :name, :description, :category])})

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ultimately not a huge deal here, but Enum.map materializes a new list (alongside really all enum mod functions). For something that could be large enumerations, Stream equivalents is lazy and more memory efficient

alias Console.Deployments.{Git, Policies}
alias Console.Schema.{Catalog, PrAutomation}

embedded_schema do

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

all queries in this function should have a limit (maybe 100)

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

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants