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.
In this repository10 other files it gives its agents.
- .agents/AGENTS.mdAGENTS.md
- AGENTS.mdAGENTS.md
- .agents/reviewer/AGENTS.mdAGENTS.md
- adversarial-review-gateSkill
- changelog-bulletSkill
- prefix-failure-verificationSkill
- presubmit-sweepSkill
- stacked-pr-orderSkill
- autonomous-setupSkill
- cli-setupSkill
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
- Very specific: line 13
If the user just wants to customize core-agent's behavior for their project, the CLI + skills covers it without embedding.
- Very specific: line 31
Use the documented agent.Option interface — not internal/private symbols
- Distinctive: line 116
If the user is building anything beyond a one-shot CLI, push them toward durable sessions early:
- Very specific: line 136
If the embedded agent is itself autonomous OR spawns subagents, use RunAutonomous + background.Manager:
- Very specific: line 170
When showing extension points, ALWAYS include the interface contract being satisfied.
≈ “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.
Files
When invoked:
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-agentin 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 thecli-setupskill instead.- Start with the minimal embed. Show the 20-line "hello world" —
agent.New+Run+ iterate events. Most embedding work builds on this base. Usereferences/minimal-embed.md. 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.mdto walk them through the relevant one.- Show a full worked example. For non-trivial embeddings (web service, HTTP-served agent), build out a complete program. Use
references/http-served-agent.mdfor the canonical example. - Discuss long-term maintenance.
core-agentis 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.Optioninterface — not internal/private symbols
- Pin the dep version in
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 workingagent.New+Runloop. 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:
| Want | Extension | Reference |
| Different approval UX | WithPrompter(impl) | references/extension-points.md § Prompter |
| Domain-specific tool | WithTools([]tool.Tool{...}) | references/extension-points.md § Tools |
| LLM backend not in box | Implement models.Provider, register with models.Register | references/extension-points.md § Provider |
| Custom persistence | WithSessionService(impl) | references/extension-points.md § Session |
| Long-session survival | WithCompactor(...) + WithCheckpointer(...) | (built-in defaults usually fine) |
| Distributed subagent execution | Implement background.RemoteAgentSpawner | references/extension-points.md § Remote subagents |
| HTTP-served agent | All of the above + handler shape | references/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-agentbinary) and asking about configuration. Usecli-setupskill. - The user is configuring autonomous / unattended runs of the bundled CLI. Use
autonomous-setupskill. - 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-agentitself (contribute upstream changes). That's a different conversation; point them atCONTRIBUTING.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."
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
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.

