3434db3c59
- Add event_type and framework filters to events query endpoint - Add /agents SPA route to web-ui server - Add Agents nav link and route in frontend - Add agents page CSS (timeline, VM pills, stats panel) - Build VM status strip, activity timeline, and real-time stats - Add agentmon hook for OpenClaw (HOOK.md + handler.ts) - Add docker-compose, Dockerfile, and supporting infra files Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
212 lines
4.9 KiB
Markdown
212 lines
4.9 KiB
Markdown
# Agentmon SDK
|
|
|
|
The agentmon SDK provides a Go client for sending telemetry events to the agentmon backend.
|
|
|
|
## Installation
|
|
|
|
```bash
|
|
go get agentmon/internal/sdk
|
|
```
|
|
|
|
## Quick Start
|
|
|
|
```go
|
|
package main
|
|
|
|
import (
|
|
"context"
|
|
"log"
|
|
|
|
"agentmon/internal/sdk"
|
|
)
|
|
|
|
func main() {
|
|
emitter, err := sdk.NewEmitter(sdk.Config{
|
|
ServerURL: "http://localhost:8080",
|
|
Framework: "my-agent",
|
|
ClientID: "my-client-001",
|
|
Host: "localhost",
|
|
BufferSize: 100,
|
|
})
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
defer emitter.Close(context.Background())
|
|
|
|
ctx := context.Background()
|
|
sessionID := "session-123"
|
|
|
|
// Start a session
|
|
sessionStart := sdk.NewSessionStart(sessionID, sdk.WithSource(emitter))
|
|
if err := emitter.Emit(ctx, sessionStart); err != nil {
|
|
log.Printf("Error: %v", err)
|
|
}
|
|
|
|
// ... do work ...
|
|
|
|
// End the session
|
|
sessionEnd := sdk.NewSessionEnd(sessionID, sdk.WithSource(emitter))
|
|
if err := emitter.Emit(ctx, sessionEnd); err != nil {
|
|
log.Printf("Error: %v", err)
|
|
}
|
|
|
|
// Flush buffered events
|
|
if err := emitter.Flush(ctx); err != nil {
|
|
log.Printf("Error: %v", err)
|
|
}
|
|
}
|
|
```
|
|
|
|
## Configuration
|
|
|
|
The `Config` struct configures the emitter:
|
|
|
|
| Field | Type | Required | Default | Description |
|
|
|-------|------|----------|---------|-------------|
|
|
| `ServerURL` | string | Yes | - | URL of the ingest gateway (e.g., `http://localhost:8080`) |
|
|
| `APIKey` | string | No | - | Optional API key for authentication |
|
|
| `Framework` | string | Yes | - | Name of the framework (e.g., `opencode`, `claude-code`) |
|
|
| `ClientID` | string | Yes | - | Stable identifier for this emitter instance |
|
|
| `Host` | string | No | `localhost` | Hostname where events originate |
|
|
| `BufferSize` | int | No | `100` | Max number of events to buffer before flushing |
|
|
| `UseWebSocket` | bool | No | `false` | Enable WebSocket streaming mode |
|
|
| `EnableLogging` | bool | No | `false` | Enable debug logging |
|
|
|
|
## Event Types
|
|
|
|
### Session Events
|
|
|
|
```go
|
|
// Start a session
|
|
sessionStart := sdk.NewSessionStart(sessionID,
|
|
sdk.WithSource(emitter),
|
|
sdk.WithAttributes(map[string]any{
|
|
"cwd": "/home/user/project",
|
|
"repo": "myrepo",
|
|
"branch": "main",
|
|
}),
|
|
)
|
|
|
|
// End a session
|
|
sessionEnd := sdk.NewSessionEnd(sessionID,
|
|
sdk.WithSource(emitter),
|
|
)
|
|
```
|
|
|
|
### Run Events
|
|
|
|
```go
|
|
// Start a run
|
|
runStart := sdk.NewRunStart(sessionID, runID,
|
|
sdk.WithSource(emitter),
|
|
sdk.WithAttributes(map[string]any{
|
|
"command": "my-command",
|
|
"agent": "my-agent",
|
|
}),
|
|
)
|
|
|
|
// End a run
|
|
runEnd := sdk.NewRunEnd(sessionID, runID, "success", 60000,
|
|
sdk.WithSource(emitter),
|
|
sdk.WithLLMUsage("claude-3-opus", 1000, 500, 0.015),
|
|
)
|
|
```
|
|
|
|
### Span Events
|
|
|
|
```go
|
|
// Start a span
|
|
spanStart := sdk.NewSpanStart(sessionID, runID, traceID, spanID,
|
|
sdk.WithSource(emitter),
|
|
sdk.WithSpanKind("tool"),
|
|
sdk.WithName("Bash"),
|
|
sdk.WithAttributes(map[string]any{
|
|
"command": "echo hello",
|
|
}),
|
|
)
|
|
|
|
// End a span
|
|
spanEnd := sdk.NewSpanEnd(sessionID, runID, traceID, spanID, "success", 1000,
|
|
sdk.WithSource(emitter),
|
|
sdk.WithSpanKind("tool"),
|
|
sdk.WithName("Bash"),
|
|
)
|
|
```
|
|
|
|
### Error Events
|
|
|
|
```go
|
|
errEvent := sdk.NewError(sessionID, runID, traceID, spanID,
|
|
"validation", "invalid input",
|
|
sdk.WithSource(emitter),
|
|
sdk.WithErrorDetails("VAL001", false),
|
|
)
|
|
```
|
|
|
|
### Metric Snapshots
|
|
|
|
```go
|
|
metrics := sdk.NewMetricSnapshot(sessionID, runID, map[string]any{
|
|
"tokens_in": 1000.0,
|
|
"tokens_out": 500.0,
|
|
"cost_usd": 0.015,
|
|
"latency_ms": 300.0,
|
|
"error_count": 0,
|
|
})
|
|
```
|
|
|
|
## Event Options
|
|
|
|
Event options are functions that modify events before sending:
|
|
|
|
- `WithSource(emitter)` - Add source information (framework, client_id, host)
|
|
- `WithAttributes(attrs)` - Add arbitrary attributes
|
|
- `WithSpanKind(kind)` - Set the span_kind attribute (`llm`, `tool`, `skill`, `internal`)
|
|
- `WithName(name)` - Set the name attribute
|
|
- `WithParentSpanID(parentID)` - Set the parent span ID
|
|
- `WithPayload(payload)` - Set custom payload
|
|
- `WithSeq(seq)` - Set sequence number (for WebSocket mode)
|
|
- `WithLLMUsage(model, inTokens, outTokens, costUSD)` - Add LLM usage to run.end or span.end
|
|
- `WithErrorDetails(code, retryable)` - Add error details
|
|
|
|
## Span Kinds
|
|
|
|
Common span kinds:
|
|
|
|
- `llm` - LLM API calls
|
|
- `tool` - Tool/function calls
|
|
- `skill` - Skill execution
|
|
- `internal` - Internal operations
|
|
|
|
## WebSocket Mode
|
|
|
|
For real-time streaming, enable WebSocket mode:
|
|
|
|
```go
|
|
emitter, err := sdk.NewEmitter(sdk.Config{
|
|
ServerURL: "http://localhost:8080",
|
|
Framework: "my-agent",
|
|
ClientID: "my-client-001",
|
|
Host: "localhost",
|
|
UseWebSocket: true,
|
|
})
|
|
```
|
|
|
|
In WebSocket mode, events are sent immediately rather than buffered.
|
|
|
|
## Example
|
|
|
|
See `examples/sdk-example/main.go` for a complete example.
|
|
|
|
## Testing
|
|
|
|
Run tests with:
|
|
|
|
```bash
|
|
go test ./internal/sdk/...
|
|
```
|
|
|
|
## License
|
|
|
|
Same license as the agentmon project.
|