Documentation
¶
Overview ¶
Package jobsclient is the runtime-side client to the openotters daemon's async-jobs API. It exists so an agent's runtime can submit long-running BIN jobs against its own spawn env, check on them later, or block until they complete — without pinning the agent's turn-loop goroutine for the duration.
Configuration comes from two env vars planted in the spawn env by the executor (see agentfile/executor/env.go's BuildLockedEnv):
- OTTERSD_URL where to dial the daemon. unix://<path> for the system executor; an http:// URL for docker (the executor sets host.docker.internal so the same value resolves on macOS Docker Desktop and Linux Docker via ExtraHosts).
- OTTERS_AGENT_TOKEN the JWT minted by the daemon at CreateAgent. Attached as `Authorization: Bearer …` on every RPC. Empty token → constructor returns nil (caller treats that as "the daemon callback path isn't wired").
The client lazy-dials on first use so a runtime that never invokes a job tool pays nothing for the dependency.
Index ¶
- Constants
- type Client
- func (c *Client) CancelJob(ctx context.Context, jobID string) error
- func (c *Client) Close() error
- func (c *Client) GetJob(ctx context.Context, jobID string) (*JobView, error)
- func (c *Client) SubmitJob(ctx context.Context, bin string, args []string, stdin string, ...) (string, error)
- func (c *Client) WatchJob(ctx context.Context, jobID string) (*JobView, error)
- type Config
- type JobView
Constants ¶
const ( EnvDaemonURL = "OTTERSD_URL" EnvAgentToken = "OTTERS_AGENT_TOKEN" )
Env names — exported so tests / callers can override programmatically without re-coding the convention.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client wraps the daemon's RuntimeClient with bearer-token injection and lazy dialing. Safe for concurrent use; the underlying gRPC connection multiplexes RPCs.
func New ¶
New constructs a client without dialing. cfg.URL + cfg.Token both required — empty values yield an immediate error on first call.
func (*Client) CancelJob ¶
CancelJob requests immediate cancellation. The job transitions to `cancelled` once the daemon's pool reaps it (~250 ms typical).
func (*Client) Close ¶
Close releases the underlying gRPC connection. Safe to call multiple times; first call wins.
func (*Client) GetJob ¶
GetJob is the non-blocking snapshot. Useful for "did it finish yet" polling without holding the agent's turn open.
func (*Client) SubmitJob ¶
func (c *Client) SubmitJob( ctx context.Context, bin string, args []string, stdin string, labels map[string]string, ) (string, error)
SubmitJob dispatches a BIN against the agent's spawn env. The daemon binds agent_ref to the JWT's claim, so the request-side value is ignored — agents can't submit jobs on behalf of another agent regardless of what they put in the request.
func (*Client) WatchJob ¶
WatchJob blocks until the job reaches a terminal status, then returns the final snapshot. Forwards ctx cancellation to a CancelAsyncJob call so an interrupted agent turn doesn't leave orphaned jobs running on the daemon.
The daemon's WatchAsyncJob is a server-stream that emits the current state immediately and on every material change; this helper drains until terminal.
type Config ¶
type Config struct {
URL string // OTTERSD_URL — unix://<path> or http://host:port
Token string // OTTERS_AGENT_TOKEN — JWT presented as Bearer
}
Config holds the dial inputs. Use FromEnv to populate from the spawn env; the explicit struct exists for testing.
type JobView ¶
type JobView struct {
JobID string `json:"job_id"`
Status string `json:"status"` // pending|running|done|error|cancelled|orphaned
ExitCode int `json:"exit_code"`
Stdout string `json:"stdout"`
Stderr string `json:"stderr"`
Error string `json:"error,omitempty"`
}
JobView is the agent-facing snapshot of an async job. Mirrors the proto's AsyncJob but trims fields the agent doesn't need (handle, labels, started_at, …) so the tool's JSON Schema stays small in the model's prompt.
func (*JobView) IsTerminal ¶
IsTerminal reports whether the job has reached a final status. The daemon's status string is the source of truth; this helper just names the four values so call sites read better.