How do I keep a human in the loop?

Five tools write as you. Everything else is safe to let an agent run unattended.

Most of the surface is read-only: signals, lookups, searches, email verification. An agent can run those unattended all day, and the worst case is a wasted token.

Five tools are different. They act as your own logged-in account, and what they produce is visible to a real person with your name on it. Those are the ones worth a gate.

Which tools actually write

ToolWhat the recipient sees
send_linkedin_messageA DM from your LinkedIn account
send_linkedin_invitationA connection request, optionally with a note
create_reddit_commentA public comment under your username
create_reddit_postA public post in a subreddit
send_reddit_messageA Reddit Chat message from your account

Everything else (every get_*, list_*, search_*, signal_*, detect_signal, get_email) changes nothing outside our system. vote_reddit, follow_reddit_post, save_reddit_thing, and subscribe_reddit_subreddit do touch your account, but privately; they’re annoying to get wrong, not embarrassing.

A practical consequence: if you want a provably read-only agent, allowlist the tools rather than trusting the prompt. Both Eve and Google ADK support tool filters, and an allowlist that omits those five is a hard guarantee.

Draft, approve, then send

LinkedIn’s write API is gated to approved Marketing Developer Platform partners, so posts and comments are copy-paste only: there is no API path for an agent to publish them, whatever prompt you write. That constraint turns out to be the right default, and our skills lean into it:

  • Posts and comments: the linkedin-copywriter skill returns finished text for you to paste. You are the approval step, by construction.
  • DMs and invitations: these can send through the API, so the skill requires explicit approval first, and it distinguishes “ship it” or “send it” from “looks good”, because agreement isn’t authorization.
  • Reddit replies: the reddit-community-manager skill gates on the five-question reply test before drafting at all, and any comment touching your product must open with a disclosure line. Skipping is treated as the higher-value action.

The pattern generalizes: have the agent produce the artifact, show it, and require a distinct affirmative before the send tool is called. The draft is cheap; the send is not reversible.

Gating at the runtime

Prompt-level rules are guidance. If you want enforcement, put it in the runtime:

  • Eve ships a first-class approval policy per connection. Gate only the sends and let reads through, so the human isn’t prompted for every lookup:

    1const SENDS = ["send_linkedin_message", "send_linkedin_invitation",
    2 "create_reddit_comment", "create_reddit_post", "send_reddit_message"];
    3
    4approval: ({ toolName }) =>
    5 SENDS.some((n) => toolName.endsWith(n)) ? "user-approval" : "not-applicable",
  • Tool allowlists in Eve (tools.allow) and ADK (tool_filter) remove the capability entirely for agents that should never write.

  • Two-agent split. A research agent with read-only tools produces drafts; a separate, human-triggered run holds the send tools. Nothing to approve mid-run because the sending agent only runs when a person starts it.

Auditing what was sent

There’s no send log in our API, so audit at the source of truth:

  • list_linkedin_conversations shows recent threads on a connected account, the fastest way to answer “did we already message them?”
  • list_reddit_inbox covers DMs, comment replies, and mentions.
  • list_connected_linkedin_accounts / list_connected_reddit_accounts (both free) tell you which account would have sent anything, which matters when several teammates have pooled sessions in one workspace.

Related: Tracking engagement state covers keeping your own record so an agent doesn’t message the same person twice.