agentleFS
go-steergo-steer/core-agent/SKILLS/library-embedding/SKILL.md

library-embedding

Skill9 starsChanged 43 days agoApache-2.0View on GitHub

Walk a Go developer through embedding core-agent in their own binary. Use when the user asks "how do I embed core-agent", "use core-agent as a library", "build my own agent on core-agent", "agent.New", "custom prompter", "custom tools", "custom provider", "HTTP-served agent", "integrate core-agent into [Go project]", or asks any question implying they want to use the Go API rather than the bundled CLI.

The file

We split this skill into the rules it gives an agent

5 rules. About 0 are common, 1 is distinctive, and 4 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈1

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 4

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    If the user just wants to customize core-agent's behavior for their project, the CLI + skills covers it without embedding.

    line 13
  2. Very specific:

    Use the documented agent.Option interface — not internal/private symbols

    line 31
  3. Distinctive:

    If the user is building anything beyond a one-shot CLI, push them toward durable sessions early:

    line 116
  4. Very specific:

    If the embedded agent is itself autonomous OR spawns subagents, use RunAutonomous + background.Manager:

    line 136
  5. Very specific:

    When showing extension points, ALWAYS include the interface contract being satisfied.

    line 170

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

When invoked:

  1. Confirm the use case. Embedding fits when:

    • You're building a domain-specific agent (web service, custom UI, IDE plugin)
    • You need extension points the CLI doesn't expose (custom prompter, custom tools, custom provider)
    • You're wrapping core-agent in a larger system (orchestrator, agent platform)

    If the user just wants to customize core-agent's behavior for their project, the CLI + skills covers it without embedding. Walk them to the cli-setup skill instead.

  2. Start with the minimal embed. Show the 20-line "hello world" — agent.New + Run + iterate events. Most embedding work builds on this base. Use references/minimal-embed.md.
  3. Identify the extension point they need. Most embedding use cases come down to one of:

    • Custom Prompter — different approval UX (web modal, Slack button, IDE dialog)
    • Custom tool — domain operations the built-in nine don't cover
    • Custom Provider — LLM backend not in the box (local Ollama, internal model server)
    • Custom session.Service — persistence beyond eventlog (Redis, custom DB)
    • RemoteAgentSpawner — delegate background subagents to K8s Jobs, Cloud Run, etc.

    Fetch references/extension-points.md to walk them through the relevant one.

  4. Show a full worked example. For non-trivial embeddings (web service, HTTP-served agent), build out a complete program. Use references/http-served-agent.md for the canonical example.
  5. Discuss long-term maintenance. core-agent is pre-1.0; breaking changes can land at any minor version. If the user is shipping production code on top of it:
    • Pin the dep version in go.mod
    • Subscribe to releases / CHANGELOG.md
    • Use the documented agent.Option interface — not internal/private symbols

Triggers in detail

Beyond the description, also match on:

  • "How do I add a custom tool to core-agent"
  • "Build an HTTP-served agent"
  • "Background workers with core-agent"
  • "Integrate core-agent into my existing Go service"
  • "Customize the approval UX for a web app"
  • "Bring my own LLM backend"
  • "Programmatic control of an agent run"

References

Fetch based on what the user is building:

  • references/minimal-embed.md — the smallest working agent.New + Run loop. Read first for any embedding question; it's the foundation.
  • references/extension-points.md — the seven main customization surfaces (WithTools, WithPrompter, WithProvider, WithSessionService, WithCompactor, WithCheckpointer, RemoteAgentSpawner) with one paragraph per. Read when narrowing in on the user's specific extension need.
  • references/http-served-agent.md — full worked HTTP-served agent example. Read when the user is building a web-facing service; covers session-per-request vs persistent-session shapes, prompter integration, streaming responses.

Procedure: minimal embed

Walk the user through this skeleton first. Everything else is variations on it:

package main

import (
    "context"
    "fmt"
    "log"
    "os"

    "github.com/go-steer/core-agent/v3/pkg/agent"
    "github.com/go-steer/core-agent/v3/pkg/models"
    _ "github.com/go-steer/core-agent/v3/pkg/models/gemini"
)

func main() {
    ctx := context.Background()
    provider, err := models.Resolve(nil) // reads .agents/config.json
    if err != nil { log.Fatal(err) }
    model, err := provider.Model(ctx, "gemini-3.7-flash")
    if err != nil { log.Fatal(err) }

    a, err := agent.New(model)
    if err != nil { log.Fatal(err) }

    prompt := os.Args[1]
    for ev, err := range a.Run(ctx, prompt) {
        if err != nil { log.Fatal(err) }
        if ev.Content != nil {
            for _, p := range ev.Content.Parts {
                if p.Text != "" {
                    fmt.Print(p.Text)
                }
            }
        }
    }
    fmt.Println()
}

That's it. Multi-turn conversation: call a.Run(ctx, prompt) again with a new prompt — session history is preserved automatically. Run-to-completion (no streaming): use runner.Headless instead.

Procedure: pick extension points

Walk the user through what they're customizing:

WantExtensionReference
Different approval UXWithPrompter(impl)references/extension-points.md § Prompter
Domain-specific toolWithTools([]tool.Tool{...})references/extension-points.md § Tools
LLM backend not in boxImplement models.Provider, register with models.Registerreferences/extension-points.md § Provider
Custom persistenceWithSessionService(impl)references/extension-points.md § Session
Long-session survivalWithCompactor(...) + WithCheckpointer(...)(built-in defaults usually fine)
Distributed subagent executionImplement background.RemoteAgentSpawnerreferences/extension-points.md § Remote subagents
HTTP-served agentAll of the above + handler shapereferences/http-served-agent.md

For each one, fetch the relevant section and walk through the implementation contract + a minimal example.

Procedure: structured persistence

If the user is building anything beyond a one-shot CLI, push them toward durable sessions early:

import "github.com/go-steer/core-agent/v3/pkg/eventlog"
import "github.com/glebarez/sqlite"

handle, err := eventlog.Open(ctx, sqlite.Open("./sessions.db"))
if err != nil { log.Fatal(err) }
defer handle.Close()

a, err := agent.New(model,
    agent.WithSessionService(handle.Service),
    agent.WithEventLog(handle),
)

Now every turn, every tool call, every model response lands in sessions.db. Crash-resume, audit log, replay, live tail — all unlocked.

Procedure: composition with autonomous + subagents

If the embedded agent is itself autonomous OR spawns subagents, use RunAutonomous + background.Manager:

import "github.com/go-steer/core-agent/v3/pkg/agent"

bgMgr, err := agent.NewBackgroundAgentManager(
    agent.WithBackgroundProvider(provider, "gemini-2.5-flash"),
    agent.WithBackgroundGate(gate),
    agent.WithBackgroundCatalog(builtinTools),
)
if err != nil { log.Fatal(err) }
defer bgMgr.Close()

a, err := agent.New(model,
    agent.WithBackgroundManager(bgMgr),
    agent.WithTools(append(builtinTools, agent.NewBackgroundSpawnTools(bgMgr)...)),
)

The parent now has spawn_agent and stop_agent (subagent results are pushed back via the [Background reports] block; spawn_agent { wait: true } blocks inline). The user's AGENTS.md (or in-prompt instruction) governs when to use them.

When NOT to use this skill

  • The user is using the bundled CLI (core-agent binary) and asking about configuration. Use cli-setup skill.
  • The user is configuring autonomous / unattended runs of the bundled CLI. Use autonomous-setup skill.
  • The user is asking a reference question (function signature, type definition). Answer directly from [library/api]({{< relref "library/api.md" >}}) docs; no need to walk the whole embedding procedure.
  • The user wants to modify core-agent itself (contribute upstream changes). That's a different conversation; point them at CONTRIBUTING.md.

Output style

Code-heavy but with clear narrative. Embedding work is mostly Go — show the code, explain what each block does. Don't generate a wall of code without explanation; the user is going to maintain it.

For non-trivial embeddings, propose a project layout (cmd/, internal/, etc.) before writing code. Give the user a sense of where things go so the snippets fit into context.

When showing extension points, ALWAYS include the interface contract being satisfied. E.g., "you need to implement permissions.Prompter which is interface { AskApproval(ctx, req) (Decision, error) }" — not just "implement a prompter."

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.