Skip to content

Commit 09c77eb

Browse files
refactor(agents): route workflow agents through Hub sessions
1 parent deeb8de commit 09c77eb

57 files changed

Lines changed: 86 additions & 4210 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎README.md‎

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -388,15 +388,10 @@ allow-list ignores everyone. `mode=anyone` still refuses a message with no
388388
From. Additional workflow filters AND with the address rule. Sender admission
389389
is separate from receiving-address configuration and outbound senders.
390390

391-
An `agent` action queues a prompt for a Dapier worker — a machine running
392-
`dapier worker`, which picks the task up and runs a headless Claude Code
393-
process there, reporting the terminal result through the authenticated API.
394-
Tasks stay queued until a worker is running; the console's **Workers** tab
395-
and `dapier workers list` show which workers are active. An agent action can
396-
sit on an email, a webhook, a schedule, or a poll.
397-
The host needs a dedicated Dapier token, not AWS credentials or Aplexer; see
398-
[headless worker setup](docs/headless-worker.md). Webhooks are managed with
399-
`dapier webhooks`. A sample of what a flow receives is `dapier workflows sample`.
391+
The `hub_session` action creates a Hub intake and requests a Hub-managed
392+
headless session. Use it for workflow-triggered coding work; Dapier does not
393+
run coding agents on host workers. Webhooks are managed with `dapier webhooks`.
394+
A sample of what a flow receives is `dapier workflows sample`.
400395

401396
A receiving address is a workflow trigger, for example:
402397

@@ -417,7 +412,7 @@ trigger:
417412
418413
Action types and their keys match the workflow catalog (`webhook`, `slack`,
419414
`telegram_send`, `email_send`, `dataops`, `dropbox_upload`, `dropbox_delete`,
420-
`render_html_to_pdf`, `code`). Text fields accept `{field}` templates from the
415+
`render_html_to_pdf`, `code`, `hub_session`). Text fields accept `{field}` templates from the
421416
triggering event; `{trigger.field}` reaches the same data (plus envelope
422417
scalars like `trigger.connector` and `trigger.occurred_at`), and
423418
`{steps.<action_id>.output.<path>}` / `{steps.<action_id>.status}` reference an

‎dapier_cli/cli/ops.py‎

Lines changed: 2 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
"""Single-command operator nouns: overview, usage, quota, errors, agent-tasks, workers, worker, catalog."""
1+
"""Single-command operator nouns: overview, usage, quota, errors, catalog."""
22

33
import sys
44

55
from .. import commands
66

7-
GROUPS = ("costs", "overview", "usage", "quota", "errors", "agent-tasks", "workers", "worker", "catalog",
7+
GROUPS = ("costs", "overview", "usage", "quota", "errors", "catalog",
88
"store-check",)
99

1010

@@ -29,40 +29,6 @@ def register(sub):
2929
errors_sub = errors_p.add_subparsers(dest="command")
3030
errors_sub.add_parser("send-digest",
3131
help="Render and email the error digest now (operator)")
32-
agent_tasks_p = sub.add_parser(
33-
"agent-tasks", help="Host jobs the agent action enqueued (run by `dapier worker`)")
34-
agent_tasks_sub = agent_tasks_p.add_subparsers(dest="command", required=True)
35-
agent_tasks_list = agent_tasks_sub.add_parser("list", help="List host agent tasks, newest first")
36-
agent_tasks_list.add_argument("--limit", default=None,
37-
help="How many to show (default 50, max 200)")
38-
agent_tasks_list.add_argument("--status", default=None,
39-
help="Only rows with this status: queued, running, succeeded, failed, timed_out, interrupted")
40-
agent_tasks_list.add_argument("--owner",
41-
help="Only this person's tasks (alias or email, for example orin)")
42-
agent_tasks_list.add_argument("--as", dest="as_id",
43-
help="Only tasks for this subject id")
44-
agent_tasks_list.add_argument("--assignee",
45-
help="Only tasks assigned to this subject id")
46-
agent_tasks_show = agent_tasks_sub.add_parser("show", help="Show one agent task and its recorded logs")
47-
agent_tasks_show.add_argument("task_id")
48-
workers_p = sub.add_parser(
49-
"workers", help="Host workers (`dapier worker` processes) that run agent tasks")
50-
workers_sub = workers_p.add_subparsers(dest="command", required=True)
51-
workers_sub.add_parser("list", help="List host workers, most recently seen first")
52-
worker_p = sub.add_parser(
53-
"worker",
54-
help="Run headless host jobs over HTTPS until interrupted.")
55-
worker_p.add_argument("--token-file", default=None,
56-
help="Owner-only Dapier host-worker token file")
57-
worker_p.add_argument("--workspace-root", default=None,
58-
help="Host job root directory (default ~/dapier-ws)")
59-
worker_p.add_argument("--max-runtime", type=int, default=3600,
60-
help="Maximum seconds per headless job")
61-
worker_p.add_argument("--capability", action="append", default=[],
62-
help="Advertise a capability, e.g. browser (repeatable)")
63-
worker_p.add_argument("--engine", choices=("claude", "codex"), default="claude",
64-
help="Agent engine available on this worker")
65-
worker_p.add_argument("--once", action="store_true", help="Poll once and exit")
6632
catalog_p = sub.add_parser("catalog", help="Show the action and trigger catalog (GET /api/catalog)")
6733
catalog_p.add_argument("--json", action="store_true", help="Print the raw catalog JSON")
6834
store_check_p = sub.add_parser(
@@ -89,22 +55,6 @@ def run(args, api_url, debug, child=None):
8955
if getattr(args, "command", None) == "send-digest":
9056
return commands.errors_send_digest(api_url, debug)
9157
return commands.errors_summary(api_url, debug, days=args.days)
92-
if args.group == "agent-tasks":
93-
if args.command == "show":
94-
return commands.agent_tasks_show(api_url, args.task_id, debug)
95-
return commands.agent_tasks_list(api_url, debug,
96-
limit=getattr(args, "limit", None),
97-
status=getattr(args, "status", None),
98-
owner=getattr(args, "owner", None),
99-
as_id=getattr(args, "as_id", None),
100-
assignee=getattr(args, "assignee", None))
101-
if args.group == "workers":
102-
return commands.workers_list(api_url, debug)
103-
if args.group == "worker":
104-
return commands.worker_run(api_url, token_file=args.token_file,
105-
workspace_root=args.workspace_root,
106-
max_runtime=args.max_runtime, once=args.once,
107-
capabilities=args.capability, engine=args.engine)
10858
if args.group == "catalog":
10959
return commands.catalog_show(api_url, debug, as_json=args.json)
11060
if args.group == "store-check":

‎dapier_cli/commands/__init__.py‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525
from .storage import *
2626
from .oauth_clients import *
2727
from .emails import *
28-
from .tasks import *
2928
from .typefully import *
3029
from .slack import *
3130
from .gdocs import *

‎dapier_cli/commands/tasks.py‎

Lines changed: 0 additions & 85 deletions
This file was deleted.

‎dapier_cli/commands/tokens.py‎

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,7 @@ def tokens_create(api_url, name, agent, debug=False, output=None):
3737
{"token_id": name, "agent": agent}, debug=debug)
3838
print(f"Created API token {data.get('token_id')} "
3939
f"(subject {data.get('subject')}, agent {data.get('agent')}).")
40-
if agent != "host-worker":
41-
print(f"Grant it access with `dapier grants save` using subject {data.get('subject')}.")
40+
print(f"Grant it access with `dapier grants save` using subject {data.get('subject')}.")
4241
if output:
4342
path = Path(output).expanduser()
4443
path.parent.mkdir(mode=0o700, parents=True, exist_ok=True)

‎designer/src/catalog.ts‎

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -129,20 +129,6 @@ export const logicOperators = [
129129

130130
/** Mirrors the run_* dispatch in src/dapier/engine/__init__.py. */
131131
export const actionCatalog: ActionEntry[] = [
132-
{
133-
type: "agent",
134-
label: "Agent",
135-
icon: Bot,
136-
description: "Queue a prompt for a Dapier worker — a machine running `dapier worker`, listed on the console's Workers page. The worker runs the prompt as a headless Claude session in its workspace; the step returns as soon as the task is queued. With no worker running, tasks stay queued until one starts. The trigger's stored attachments (an email's files) are staged into the workspace under attachments/ and the run is told where they landed; set Pass trigger attachments to off to skip them.",
137-
fields: [
138-
{ key: "prompt", label: "Prompt", type: "textarea", required: true, placeholder: "{subject}\n\n{text}" },
139-
{ key: "workspace", label: "Workspace", required: true, placeholder: "/home/alexey/git/dapier" },
140-
{ key: "engine", label: "Engine", placeholder: "claude" },
141-
{ key: "requires", label: "Required capabilities", placeholder: "browser" },
142-
{ key: "tag_prefix", label: "Tag prefix", placeholder: "agent" },
143-
{ key: "attachments", label: "Pass trigger attachments", type: "select", options: ["default", "off"], default: "default" }
144-
]
145-
},
146132
{
147133
type: "hub_session",
148134
label: "Hub session",

0 commit comments

Comments
 (0)