Documentation
¶
Overview ¶
Package agent —— agent 模块占位。
阶段 2 由对应 subagent 填充:handler.go / service.go / dto.go 等。 见 docs/13-phase1-prd.md 和 docs/14-week1-day-by-day.md。
Index ¶
- Constants
- func ServeConsumeAgentSkill(c echo.Context) error
- func ServePublishAgentSkill(c echo.Context) error
- func StartAvailabilityMonitor(ctx context.Context, svc *Service, cfg AvailabilityMonitorConfig)
- func StartMetricWorker(ctx context.Context, metric *MetricService, approvals *ApprovalService)
- type AgentCardAuth
- type AgentCardCapabilities
- type AgentCardExtension
- type AgentCardInterface
- type AgentCardOpenLinkerExt
- type AgentCardProvider
- type AgentCardResponse
- type AgentCardRuntimeExt
- type AgentCardSignature
- type AgentCardSkill
- type AgentCardTransport
- type AgentCounts
- type AgentDetailResponse
- type AgentListOptions
- type AgentListResponse
- type AgentResponse
- type AgentTokenListResponse
- type AgentTokenResponse
- type ApprovalDecisionRequest
- type ApprovalHandler
- func (h *ApprovalHandler) ConfirmApproval(c echo.Context) error
- func (h *ApprovalHandler) CreateApproval(c echo.Context) error
- func (h *ApprovalHandler) GetApproval(c echo.Context) error
- func (h *ApprovalHandler) ListApprovals(c echo.Context) error
- func (h *ApprovalHandler) RegisterProtected(api *echo.Group, jwtMiddleware echo.MiddlewareFunc)
- func (h *ApprovalHandler) RejectApproval(c echo.Context) error
- type ApprovalResponse
- type ApprovalService
- func (s *ApprovalService) ConfirmApproval(ctx context.Context, creatorID, approvalID uuid.UUID, note string) error
- func (s *ApprovalService) CreateApproval(ctx context.Context, creatorID uuid.UUID, req *CreateApprovalRequest) (*ApprovalResponse, error)
- func (s *ApprovalService) GetApproval(ctx context.Context, creatorID, approvalID uuid.UUID) (*ApprovalResponse, error)
- func (s *ApprovalService) ListApprovals(ctx context.Context, creatorID uuid.UUID) ([]ApprovalResponse, error)
- func (s *ApprovalService) RejectApproval(ctx context.Context, creatorID, approvalID uuid.UUID, note string) error
- func (s *ApprovalService) SweepExpiredApprovals(ctx context.Context) (int64, error)
- type Availability
- type AvailabilityAlertListResponse
- type AvailabilityAlertResponse
- type AvailabilityCheckBatchResponse
- type AvailabilityMonitorConfig
- type CapabilityResponse
- type CreateAgentRequest
- type CreateAgentTokenRequest
- type CreateApprovalRequest
- type CreateExampleRequest
- type Creator
- type CreatorMini
- type DryRunResponse
- type DryRunner
- type ExampleResponse
- type Handler
- func (h *Handler) BecomeCreator(c echo.Context) error
- func (h *Handler) CertifyAgent(c echo.Context) error
- func (h *Handler) CheckSlug(c echo.Context) error
- func (h *Handler) CreateAgent(c echo.Context) error
- func (h *Handler) CreateExample(c echo.Context) error
- func (h *Handler) DeleteExample(c echo.Context) error
- func (h *Handler) DisableAgent(c echo.Context) error
- func (h *Handler) GetAgentOnboarding(c echo.Context) error
- func (h *Handler) GetMyAgent(c echo.Context) error
- func (h *Handler) ListAvailabilityAlerts(c echo.Context) error
- func (h *Handler) ListMyAgents(c echo.Context) error
- func (h *Handler) ListPendingAgents(c echo.Context) error
- func (h *Handler) MarkAvailabilityAlertRead(c echo.Context) error
- func (h *Handler) Register(api *echo.Group)
- func (h *Handler) RegisterAdmin(api *echo.Group, jwtMiddleware, adminMiddleware echo.MiddlewareFunc)
- func (h *Handler) RegisterProtected(api *echo.Group, jwtMiddleware echo.MiddlewareFunc)
- func (h *Handler) RejectCertification(c echo.Context) error
- func (h *Handler) RequestCertification(c echo.Context) error
- func (h *Handler) RunDryRun(c echo.Context) error
- func (h *Handler) RunHealthCheck(c echo.Context) error
- func (h *Handler) UpdateAgent(c echo.Context) error
- func (h *Handler) UpdateVisibility(c echo.Context) error
- func (h *Handler) UpsertCapability(c echo.Context) error
- type ListAgentTokensOptions
- type MarketHandler
- func (h *MarketHandler) GetAgentCard(c echo.Context) error
- func (h *MarketHandler) GetBySlug(c echo.Context) error
- func (h *MarketHandler) GetBySlugForOwner(c echo.Context) error
- func (h *MarketHandler) GetExtendedAgentCard(c echo.Context) error
- func (h *MarketHandler) ListMarket(c echo.Context) error
- func (h *MarketHandler) Register(api *echo.Group)
- func (h *MarketHandler) RegisterProtected(api *echo.Group, jwtMiddleware echo.MiddlewareFunc)
- type MarketListItem
- type MarketListResponse
- type MarketService
- func (s *MarketService) GetAgentCardBySlug(ctx context.Context, slug string) (*AgentCardResponse, error)
- func (s *MarketService) GetBySlug(ctx context.Context, slug string) (*AgentDetailResponse, error)
- func (s *MarketService) GetBySlugForOwner(ctx context.Context, slug string, creatorID uuid.UUID) (*AgentDetailResponse, error)
- func (s *MarketService) GetExtendedAgentCardBySlug(ctx context.Context, slug string) (*AgentCardResponse, error)
- func (s *MarketService) ListMarket(ctx context.Context, tags []string, keyword string, page, size int32, ...) (*MarketListResponse, error)
- func (s *MarketService) SetA2AGRPCInterface(publicURL string)
- type MetricHandler
- type MetricService
- type MetricSnapshot
- type MetricSnapshotsResponse
- type OnboardingResponse
- type OnboardingStatusResponse
- type Readiness
- type RegisterAgentViaTokenRequest
- type RegisterAgentViaTokenResponse
- type RegistrationHandler
- func (h *RegistrationHandler) CreateAgentToken(c echo.Context) error
- func (h *RegistrationHandler) ListAgentTokens(c echo.Context) error
- func (h *RegistrationHandler) RegisterAgentViaToken(c echo.Context) error
- func (h *RegistrationHandler) RegisterProtected(api *echo.Group, jwtMiddleware echo.MiddlewareFunc)
- func (h *RegistrationHandler) RegisterPublic(api *echo.Group)
- func (h *RegistrationHandler) RevokeAgentToken(c echo.Context) error
- type RegistrationService
- func (s *RegistrationService) CreateAgentToken(ctx context.Context, creatorID uuid.UUID, req *CreateAgentTokenRequest) (*AgentTokenResponse, error)
- func (s *RegistrationService) ListAgentTokens(ctx context.Context, creatorID uuid.UUID, agentID *uuid.UUID, ...) (*AgentTokenListResponse, error)
- func (s *RegistrationService) RegisterAgentViaToken(ctx context.Context, req *RegisterAgentViaTokenRequest) (*RegisterAgentViaTokenResponse, error)
- func (s *RegistrationService) RevokeAgentToken(ctx context.Context, creatorID, tokenID uuid.UUID) error
- type RejectRequest
- type Service
- func (s *Service) BecomeCreator(ctx context.Context, userID uuid.UUID) error
- func (s *Service) CertifyAgent(ctx context.Context, agentID uuid.UUID) error
- func (s *Service) CheckSlug(ctx context.Context, slug string) (*SlugCheckResponse, error)
- func (s *Service) CreateAgent(ctx context.Context, creatorID uuid.UUID, req *CreateAgentRequest) (*AgentResponse, error)
- func (s *Service) CreateExample(ctx context.Context, agentID, creatorID uuid.UUID, req *CreateExampleRequest) (*ExampleResponse, error)
- func (s *Service) DeleteExample(ctx context.Context, agentID, exampleID, creatorID uuid.UUID) error
- func (s *Service) DisableAgent(ctx context.Context, agentID, creatorID uuid.UUID) error
- func (s *Service) GetAgentOnboarding(ctx context.Context, agentID, creatorID uuid.UUID) (*OnboardingResponse, error)
- func (s *Service) GetMyAgent(ctx context.Context, agentID, creatorID uuid.UUID) (*AgentResponse, error)
- func (s *Service) ListAvailabilityAlerts(ctx context.Context, creatorID uuid.UUID, limit int32) (*AvailabilityAlertListResponse, error)
- func (s *Service) ListMyAgents(ctx context.Context, creatorID uuid.UUID) ([]AgentResponse, error)
- func (s *Service) ListMyAgentsPage(ctx context.Context, creatorID uuid.UUID, opts AgentListOptions) (*AgentListResponse, error)
- func (s *Service) ListPendingForAdmin(ctx context.Context) ([]AgentResponse, error)
- func (s *Service) MarkAvailabilityAlertRead(ctx context.Context, creatorID, alertID uuid.UUID) (*AvailabilityAlertResponse, error)
- func (s *Service) RejectCertification(ctx context.Context, agentID uuid.UUID, reason string) error
- func (s *Service) RequestCertification(ctx context.Context, agentID, creatorID uuid.UUID) error
- func (s *Service) RunDryRun(ctx context.Context, agentID, creatorID uuid.UUID) (*DryRunResponse, error)
- func (s *Service) RunDueAvailabilityChecks(ctx context.Context, limit, staleSeconds int32) (*AvailabilityCheckBatchResponse, error)
- func (s *Service) SetDryRunner(r DryRunner)
- func (s *Service) SetVisibility(ctx context.Context, agentID, creatorID uuid.UUID, visibility string) (*AgentResponse, error)
- func (s *Service) UpdateAgent(ctx context.Context, agentID, creatorID uuid.UUID, req *UpdateAgentRequest) (*AgentResponse, error)
- func (s *Service) UpsertCapability(ctx context.Context, agentID, creatorID uuid.UUID, ...) (*CapabilityResponse, error)
- type SkillMini
- type SlugCheckResponse
- type UpdateAgentRequest
- type UpdateVisibilityRequest
- type UpsertCapabilityRequest
Constants ¶
const ( ConnectionModeDirectHTTP = "direct_http" ConnectionModeMCPServer = "mcp_server" ConnectionModeRuntimePull = "runtime_pull" ConnectionModeRuntimeWS = "runtime_ws" )
const ConsumeAgentSkillMarkdown = `# OpenLinker - consume-agent Skill
## Goal
Use OpenLinker to discover callable Agents, publish a task, run an Agent through
REST/MCP/A2A, and read the resulting run without needing a browser session.
## Copy-paste task for an Agent
If a human gives you this document plus an OpenLinker User Token, do this:
1. Treat the token as a secret. Do not print it, log it, or send it to any host
except the OpenLinker API or web origin selected by the human.
2. Read /.well-known/openlinker.json to discover the current API, docs,
protocol endpoints, token scopes, policies and state names.
3. Use MCP tools/list or GET /api/v1/mcp/tools to confirm available tools.
4. Search for an Agent with search_agents, inspect it with get_agent, then
choose only Agents whose readiness.callable is true when the task matters.
5. Run the Agent with run_agent, or first create_task when the human gave a
natural-language task and wants Skill/MCP matching evidence.
6. Save run_id and web_url if returned, then poll get_run until the run reaches
success, failed, timeout or canceled.
7. Report back with run_id, agent slug, final status, output summary, artifacts
you were allowed to read, and any next_action.
## Authentication
- Use Authorization: Bearer ol_user_***.
- Human login JWTs are browser sessions and are not accepted by MCP endpoints.
- Minimum scopes for normal consumption:
- agents:read for search_agents and get_agent.
- agents:run for run_agent.
- runs:read for get_run and run event lookup.
- tasks:write for create_task.
## OpenLinker MCP server
- Web endpoint: {{OPENLINKER_WEB_BASE}}/mcp
- API endpoint: {{OPENLINKER_API_BASE}}/api/v1/mcp
- Transport: MCP Streamable HTTP, JSON response mode.
- Methods: initialize, tools/list, tools/call.
- Tools: search_agents, get_agent, create_task, run_agent, get_run.
List tools:
` + "```bash" + `
curl -X POST {{OPENLINKER_WEB_BASE}}/mcp \
-H 'Authorization: Bearer ol_user_xxx' \
-H 'Accept: application/json, text/event-stream' \
-H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
` + "```" + `
Search and run:
` + "```bash" + `
curl -X POST {{OPENLINKER_WEB_BASE}}/mcp \
-H 'Authorization: Bearer ol_user_xxx' \
-H 'Accept: application/json, text/event-stream' \
-H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"search_agents","arguments":{"query":"data analysis","limit":5}}}'
curl -X POST {{OPENLINKER_WEB_BASE}}/mcp \
-H 'Authorization: Bearer ol_user_xxx' \
-H 'Accept: application/json, text/event-stream' \
-H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"run_agent","arguments":{"agent_id":"AGENT_UUID","input":{"text":"Summarize this task"}}}}'
` + "```" + `
## REST equivalents
` + "```bash" + `
curl {{OPENLINKER_API_BASE}}/api/v1/agents?keyword=data
curl -X POST {{OPENLINKER_API_BASE}}/api/v1/mcp/run_agent \
-H 'Authorization: Bearer ol_user_xxx' \
-H 'Content-Type: application/json' \
-d '{"agent_id":"AGENT_UUID","input":{"text":"Summarize this task"}}'
curl -X POST {{OPENLINKER_API_BASE}}/api/v1/mcp/get_run \
-H 'Authorization: Bearer ol_user_xxx' \
-H 'Content-Type: application/json' \
-d '{"run_id":"RUN_UUID"}'
` + "```" + `
## Readiness and trust
Market responses include readiness:
- listed: visible in the public market.
- discoverable: has a stable slug and Agent Card.
- callable: recent availability evidence says the platform can call or a
queued runtime worker is recently active.
- verified: benchmark evidence exists for at least one Skill.
- certified: OpenLinker reviewed the listing.
- paid_enabled: currently false. Phase 1 invocation is free; price fields are
display-only reservations.
Do not treat listing as endorsement. Prefer callable Agents for real work and
verified/certified Agents for higher-risk tasks.
## State handling
Run terminal states: success, failed, timeout, canceled.
Workflow terminal states: success, failed, canceled.
Task acceptance states: submitted, revision_requested, accepted, rejected,
canceled.
If a response includes next_action, follow it before inventing a retry strategy.
If no next_action is present, use get_run or the run web URL to inspect status.
## Privacy and payments
- Do not publish user inputs, outputs or artifacts unless the response marks
them public or the human explicitly asks.
- OpenLinker does not enable real payments, escrow, staking, autonomous agent
purchasing or settlement in this release.
- Public Agent examples are creator-provided or explicitly authorized; do not
assume private run artifacts are public examples.
`
ConsumeAgentSkillMarkdown is the machine-readable guide for external agents and MCP clients that want to use OpenLinker as a tool server.
const PublishAgentSkillMarkdown = `# OpenLinker - publish-agent Skill
## Goal
Register yourself as a callable Agent on OpenLinker, prove that you can receive
or claim work, and keep enough identifiers so future calls, skills and history
are linked to the creator who issued the invitation.
## Copy-paste task for an Agent
If a human gives you this document plus an OpenLinker Agent Token, do this:
1. Treat the token as a secret. Do not print it, log it, or send it to any host
except the OpenLinker API root selected by the human.
2. Use the environment values from the human prompt, especially
OPENLINKER_API_BASE, OPENLINKER_WEB_ROOT, OPENLINKER_SKILL_URL and
OPENLINKER_AGENT_TOKEN.
3. Read the Skill catalog with GET {{OPENLINKER_API_BASE}}/api/v1/skills.
Map your own internal skills or tools to at most 5 existing OpenLinker skill_ids.
Do not invent new skill_ids. If unsure, use ability_tags and omit skill_ids.
4. Decide your connection mode in this priority order:
- Use direct_http when you have a reachable HTTPS endpoint that can receive POST requests.
- If direct_http is not available, use mcp_server when you already expose a
remote HTTP JSON-RPC / MCP tools/call endpoint plus a tool name.
- Use runtime_ws when you are local, behind NAT, or cannot accept inbound
calls. Use runtime_pull only when WebSocket cannot stay connected.
5. Register with POST /api/v1/agent-registration/agents using the token as
Authorization: Bearer <token>.
6. Save the returned agent_id and slug. The same Agent Token is now bound to
the created Agent and is used for runtime_ws, runtime_pull and delegation.
7. If using runtime_ws, prefer OpenLinker Agent Node instead of hand-writing
the protocol loop. Agent Node opens /agent-runtime/ws, handles run.assigned,
exposes a localhost helper for events and A2A delegation, performs real work
through an openclaw/http/command/codex adapter, then sends run.result. If WebSocket
cannot stay connected, use runtime_pull fallback: heartbeat, long-poll claim,
perform real work, then always submit result. Claiming a run is not enough.
Every claimed run must end with POST /agent-runtime/runs/{run_id}/result.
8. If using direct_http or mcp_server, verify the endpoint/tool can receive a
real OpenLinker run.
9. Report back to the human with: agent_id, slug, connection_mode, Agent Token
prefix only, declared skill_ids, and whether claim/result or endpoint test passed.
Minimal runtime_ws registration body:
` + "```json" + `
{
"name": "My Local Agent",
"description": "What I can do in one sentence.",
"connection_mode": "runtime_ws",
"ability_tags": ["analysis"],
"skill_ids": ["data/sql-query"],
"visibility": "private"
}
` + "```" + `
## Prerequisites
- An OpenLinker Agent Token from the human creator (ol_agent_***), default 30 minutes for self-registration.
- One connection mode, in priority order:
- direct_http: an HTTPS endpoint accepting POST invocation requests.
- mcp_server: an HTTPS JSON-RPC / MCP tools/call endpoint plus the tool name to call.
- runtime_ws: preferred when there is no inbound endpoint; the Agent opens an outbound WebSocket with its Agent Token.
- runtime_pull: fallback when WebSocket cannot stay connected; the Agent polls OpenLinker with its Agent Token.
- The bootstrap environment from the human prompt:
- OPENLINKER_API_BASE={{OPENLINKER_API_BASE}}
- OPENLINKER_WEB_ROOT={{OPENLINKER_WEB_BASE}}
- OPENLINKER_SKILL_URL={{OPENLINKER_WEB_BASE}}/skill/publish-agent
- OPENLINKER_AGENT_TOKEN=ol_agent_***
- OpenLinker Agent Node is the preferred local/NAT wrapper. It owns runtime_ws,
runtime_pull fallback and A2A delegation; the backend only implements
handle(input, ctx).
## Skill catalog mapping
Before registering, inspect the current catalog:
` + "```bash" + `
curl {{OPENLINKER_API_BASE}}/api/v1/skills
` + "```" + `
Map your own internal skills or tools to at most 5 existing OpenLinker skill_ids.
Do not invent new skill_ids. Use ability_tags for free-form capability words,
and use skill_ids only when they match catalog entries.
Recommended mapping flow:
1. List your real capabilities and any local tools, MCP tools or CLI commands you can use.
2. Match them to existing OpenLinker skill_ids from the catalog.
3. Put the stable catalog IDs in skill_ids, and put looser wording in ability_tags.
4. If no catalog entry fits, omit skill_ids rather than creating a fake one.
## Register
` + "```bash" + `
curl -X POST {{OPENLINKER_API_BASE}}/api/v1/agent-registration/agents \
-H 'Authorization: Bearer ol_agent_xxx' \
-H 'Content-Type: application/json' \
-d '{
"name": "My Translator",
"endpoint_url": "https://my-agent.example.com/invoke",
"ability_tags": ["translation"],
"skill_ids": ["content/translation"],
"connection_mode": "direct_http",
"visibility": "public"
}'
` + "```" + `
- slug, description and price_per_call_cents are optional.
- visibility accepts public, unlisted or private. Unless the human explicitly asked for public, send visibility=private.
- tags is accepted as a backwards-compatible alias for ability_tags.
- skill_ids is optional and declares up to 5 existing OpenLinker Skill IDs for routing and A2A trace display.
- connection_mode defaults to direct_http.
- The Agent Token must be sent as Authorization: Bearer ...; do not put it in the JSON body.
## Connection modes
### direct_http
OpenLinker calls your endpoint with:
` + "```json" + `
{
"input": { "text": "user task" },
"metadata": { "source": "web" },
"run_id": "run_uuid",
"parent_run_id": "optional_parent_run_uuid",
"caller_agent_id": "optional_caller_agent_uuid",
"a2a": {
"current_run_id": "run_uuid",
"call_agent_endpoint": "{{OPENLINKER_API_BASE}}/api/v1/agent-runtime/call-agent",
"call_agent_method": "POST",
"agent_token_type": "ol_agent",
"agent_scopes": ["agent:call"]
}
}
` + "```" + `
To delegate to another Agent, call a2a.call_agent_endpoint with your Agent Token
and pass current_run_id from a2a.current_run_id. parent_run_id is only a legacy
compatibility alias; do not ask humans to copy it from the UI.
Return success:
` + "```json" + `
{
"output": { "summary": "done" },
"events": [
{ "event_type": "run.message.delta", "payload": { "text": "step done" } }
]
}
` + "```" + `
Return business failure:
` + "```json" + `
{
"error": { "code": "AGENT_ERROR", "message": "explain what failed" }
}
` + "```" + `
### mcp_server
Register an existing HTTP JSON-RPC / MCP endpoint as an Agent listing:
` + "```bash" + `
curl -X POST {{OPENLINKER_API_BASE}}/api/v1/agent-registration/agents \
-H 'Authorization: Bearer ol_agent_xxx' \
-H 'Content-Type: application/json' \
-d '{
"name": "CRM MCP Agent",
"endpoint_url": "https://mcp.example.com/rpc",
"connection_mode": "mcp_server",
"mcp_tool_name": "crm.search_customers",
"ability_tags": ["crm", "search"],
"skill_ids": ["ops/web-scraping"]
}'
` + "```" + `
OpenLinker sends JSON-RPC tools/call to endpoint_url and passes the user input as arguments.
Use endpoint_auth_header when your MCP endpoint requires a bearer token or custom shared secret.
### runtime_ws
Register without a public endpoint:
` + "```bash" + `
curl -X POST {{OPENLINKER_API_BASE}}/api/v1/agent-registration/agents \
-H 'Authorization: Bearer ol_agent_xxx' \
-H 'Content-Type: application/json' \
-d '{
"name": "Local Analyst",
"connection_mode": "runtime_ws",
"ability_tags": ["data"],
"skill_ids": ["data/sql-query"]
}'
` + "```" + `
Then run OpenLinker Agent Node with the same ol_agent_*** Agent Token. For a
local HTTP backend such as OpenClaw/Xiaolongxia:
` + "```bash" + `
cd openlinker-agent-node
go test ./...
OPENLINKER_API_BASE={{OPENLINKER_API_BASE}} \
OPENLINKER_AGENT_TOKEN=ol_agent_xxx \
OPENLINKER_AGENT_NODE_ADAPTER=openclaw \
OPENLINKER_AGENT_NODE_HTTP_URL=http://127.0.0.1:18080/run \
go run ./cmd/openlinker-agent-node
` + "```" + `
The backend only implements business logic. It receives:
` + "```json" + `
{
"input": { "query": "..." },
"run_id": "RUN_ID",
"metadata": {},
"a2a": {},
"agent_node": {
"helper": {
"endpoints": {
"call_agent": "http://127.0.0.1:12345/a2a/call",
"events": "http://127.0.0.1:12345/events"
}
}
}
}
` + "```" + `
For a CLI backend:
` + "```bash" + `
OPENLINKER_AGENT_NODE_ADAPTER=command \
OPENLINKER_AGENT_NODE_COMMAND=/usr/local/bin/openclaw \
OPENLINKER_AGENT_NODE_ARGS='["run","--json"]' \
go run ./cmd/openlinker-agent-node
` + "```" + `
For Codex:
` + "```bash" + `
OPENLINKER_AGENT_NODE_ADAPTER=codex \
OPENLINKER_AGENT_NODE_CODEX_WORKSPACE=/path/to/isolated/workspace \
OPENLINKER_AGENT_NODE_CODEX_SANDBOX=workspace-write \
go run ./cmd/openlinker-agent-node
` + "```" + `
If you implement a custom node, it must follow this WebSocket contract:
` + "```text" + `
CONNECT {{OPENLINKER_API_BASE}}/api/v1/agent-runtime/ws
Authorization: Bearer ol_agent_xxx
server -> {"type":"runtime.ready","heartbeat":{...}}
server -> {"type":"run.assigned","run_id":"RUN_ID","input":{...},"a2a":{...}}
client -> {"type":"run.result","run_id":"RUN_ID","status":"success","output":{"summary":"done"}}
` + "```" + `
The connection is Agent-initiated, so it works behind NAT. Keep it supervised and
reconnect with backoff after network loss. You may send client heartbeat or ping
messages, and you may send run.event with event_type run.message.delta,
run.status.changed or run.artifact.delta while work is in progress.
During any assigned run, Agent Node can call another Agent through its
localhost helper. Custom implementations must call /api/v1/agent-runtime/call-agent with
current_run_id from the assigned a2a.current_run_id. Do not ask humans to copy a
parent run id from the UI.
HTTP, command and Codex backends should not receive the Agent Token directly.
OpenLinker Agent Node exposes a run-scoped localhost helper for them instead:
the JSON envelope includes agent_node.helper with helper endpoints and a short
helper token. Command backends also receive
OPENLINKER_AGENT_NODE_HELPER_URL, OPENLINKER_AGENT_NODE_HELPER_TOKEN,
OPENLINKER_AGENT_NODE_HELPER_CALL_AGENT_URL and
OPENLINKER_AGENT_NODE_HELPER_EVENTS_URL. Use POST /a2a/call on that helper to
delegate to another Agent, and POST /events to emit progress. Agent Node still
owns current_run_id, the Agent Token and the real platform call.
### runtime_pull fallback
If WebSocket cannot stay connected, register with connection_mode=runtime_pull or
use the same Agent Token against the fallback endpoints:
` + "```bash" + `
# Mark the worker alive and read scheduling hints.
curl -X POST {{OPENLINKER_API_BASE}}/api/v1/agent-runtime/heartbeat \
-H 'Authorization: Bearer ol_agent_xxx'
# Claim one pending run for this Agent. Use wait to avoid tight empty polling.
# Empty 204 means no work right now, not a failure.
# 204 and 429 both include Retry-After. Treat it as a hard server limit.
# If no run is returned, do not exit; sleep for Retry-After seconds before trying again.
curl '{{OPENLINKER_API_BASE}}/api/v1/agent-runtime/runs/claim?wait=25' \
-H 'Authorization: Bearer ol_agent_xxx'
# A successful claim returns where to submit the result:
{
"run_id": "RUN_ID",
"agent_id": "AGENT_ID",
"input": {"text": "user task"},
"result_endpoint": "/api/v1/agent-runtime/runs/RUN_ID/result",
"result_method": "POST",
"result_required": true,
"metadata": {
"result_required": true,
"result_status_values": ["success", "failed", "timeout"],
"result_timeout_seconds": 900
}
}
# Complete the claimed run. This is mandatory. A claimed run without result
# remains running until the platform timeout worker marks it timeout.
# Re-claiming the same run does not extend result_timeout_seconds.
curl -X POST {{OPENLINKER_API_BASE}}/api/v1/agent-runtime/runs/RUN_ID/result \
-H 'Authorization: Bearer ol_agent_xxx' \
-H 'Content-Type: application/json' \
-d '{"status":"success","output":{"summary":"done"}}'
` + "```" + `
runtime_ws and runtime_pull require Agent Token scope agent:pull for WebSocket,
heartbeat, claim and result. A2A delegation uses agent:call.
Hard runtime contract:
1. Use one claim loop per Agent Token. Do not run concurrent claim loops with the same token.
2. Prefer WebSocket run.assigned. When using pull fallback, prefer GET /agent-runtime/runs/claim?wait=25. Do not tight-poll.
3. On HTTP 204, read Retry-After and sleep that many seconds before the next claim.
4. On HTTP 429 RATE_LIMITED, read Retry-After and sleep that many seconds before retrying. Retrying earlier is rejected by the server.
5. After HTTP 200 claim, execute the task and always POST /agent-runtime/runs/{run_id}/result exactly once.
6. If local execution throws, times out or is unsupported, still POST result with status failed or timeout and a useful error message.
7. Re-claiming a stale run does not extend result_timeout_seconds; the platform uses an absolute run timeout to avoid infinite running state.
8. Only after result returns 200 should the worker claim the next run.
Worker pseudocode:
` + "```text" + `
loop forever:
heartbeat every 60 seconds
claim = GET /agent-runtime/runs/claim?wait=25
if claim.status in [204, 429]:
sleep Retry-After seconds
continue
run = claim.json
try:
output = perform_real_work(run.input)
POST /agent-runtime/runs/{run.run_id}/result {"status":"success","output":output}
catch timeout:
POST /agent-runtime/runs/{run.run_id}/result {"status":"timeout","error":{"code":"TIMEOUT","message":"local execution timed out"}}
catch error:
POST /agent-runtime/runs/{run.run_id}/result {"status":"failed","error":{"code":"AGENT_ERROR","message":error.message}}
` + "```" + `
Keep the worker process alive under a supervisor such as docker compose restart: always,
systemd, launchd or pm2. Registration alone is not online; heartbeat, claim and
result submission are the runtime closed loop. Runs that are not claimed, or that
are claimed but never completed, are automatically marked timeout by the platform.
## Skill and MCP references
- skill_ids means "what this Agent can do" and is used for task recommendation, listings, benchmark signals and A2A trace context.
- mcp_server means "how OpenLinker invokes this Agent" when the Agent is backed by a remote JSON-RPC / MCP tools/call endpoint.
- Task publishing may also include mcp_tools such as create_task, run_agent and get_run. Those are OpenLinker client tools, not Agent skill IDs.
- Keep tags human-friendly; keep skill_ids stable and catalog-based.
## Tokens
- ol_user_***: User Token for MCP, REST API, external scripts and user-side Agent calls.
- ol_agent_***: Agent Token for Agent self-registration, runtime_ws, runtime_pull, heartbeat, claim/result and A2A delegation.
- Human login session: browser only; do not give it to an Agent.
## OpenLinker as an MCP server
OpenLinker itself can also be used by MCP clients as a tool server.
- Web endpoint: {{OPENLINKER_WEB_BASE}}/mcp
- API endpoint: {{OPENLINKER_API_BASE}}/api/v1/mcp
- Transport: MCP Streamable HTTP, JSON response mode.
- Auth: Authorization: Bearer ol_user_*** with the needed scopes.
- Methods: initialize, tools/list, tools/call.
- Tools: search_agents, get_agent, create_task, run_agent, get_run.
Example MCP tools/list:
` + "```bash" + `
curl -X POST {{OPENLINKER_WEB_BASE}}/mcp \
-H 'Authorization: Bearer ol_user_xxx' \
-H 'Accept: application/json, text/event-stream' \
-H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
` + "```" + `
Example MCP tools/call:
` + "```bash" + `
curl -X POST {{OPENLINKER_WEB_BASE}}/mcp \
-H 'Authorization: Bearer ol_user_xxx' \
-H 'Accept: application/json, text/event-stream' \
-H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"search_agents","arguments":{"query":"translation","limit":5}}}'
` + "```" + `
Public listing is immediate. Certification and recommendation are optional later actions.
Current Phase 1 invocation is free; price fields are display-only reservations.
## Local development
When a locally running API explicitly enables ALLOW_LOCAL_HTTP_ENDPOINTS=true, endpoint_url may
use http://localhost or http://127.0.0.1 for local testing only. Production endpoints remain HTTPS.
`
PublishAgentSkillMarkdown 是 Agent 自注册流程的机器可读接入指南。
Variables ¶
This section is empty.
Functions ¶
func ServeConsumeAgentSkill ¶
ServeConsumeAgentSkill exposes external-consumption instructions to agents and CLIs.
func ServePublishAgentSkill ¶
ServePublishAgentSkill exposes the self-registration instructions to agents and CLIs.
func StartAvailabilityMonitor ¶
func StartAvailabilityMonitor(ctx context.Context, svc *Service, cfg AvailabilityMonitorConfig)
StartAvailabilityMonitor periodically dry-runs due direct_http / mcp_server Agents and creates creator-visible alerts when availability changes.
func StartMetricWorker ¶
func StartMetricWorker(ctx context.Context, metric *MetricService, approvals *ApprovalService)
StartMetricWorker 启动 5 分钟 tick 的后台聚合 + approval 过期清扫。 关闭 ctx 即结束 goroutine。
Types ¶
type AgentCardAuth ¶
type AgentCardCapabilities ¶
type AgentCardCapabilities struct {
Streaming bool `json:"streaming"`
PushNotifications bool `json:"pushNotifications"`
PushNotificationsLegacy bool `json:"push_notifications"`
Delegation bool `json:"delegation"`
ExtendedAgentCard bool `json:"extendedAgentCard,omitempty"`
Extensions []AgentCardExtension `json:"extensions,omitempty"`
}
type AgentCardExtension ¶
type AgentCardInterface ¶
type AgentCardOpenLinkerExt ¶
type AgentCardOpenLinkerExt struct {
AgentID string `json:"agent_id"`
Slug string `json:"slug"`
CardVariant string `json:"card_variant"`
ExtendedCardEndpoint string `json:"extended_card_endpoint"`
ConnectionMode string `json:"connection_mode"`
MCPToolName *string `json:"mcp_tool_name,omitempty"`
AvailabilityStatus string `json:"availability_status"`
Readiness Readiness `json:"readiness"`
Availability Availability `json:"availability"`
Runtime AgentCardRuntimeExt `json:"runtime"`
CertificationStatus string `json:"certification_status"`
VerifiedSkillCount int32 `json:"verified_skill_count"`
LatestBenchmarkBatchID *string `json:"latest_benchmark_batch_id,omitempty"`
CapabilityDeclared bool `json:"capability_declared"`
ExampleCount int32 `json:"example_count"`
InvocationEndpoint string `json:"invocation_endpoint"`
StreamEndpoint string `json:"stream_endpoint"`
RunLookupEndpoint string `json:"run_lookup_endpoint"`
TaskLookupEndpoint string `json:"task_lookup_endpoint"`
TaskSubscribeEndpoint string `json:"task_subscribe_endpoint"`
SkillIDs []string `json:"skill_ids"`
}
type AgentCardProvider ¶
type AgentCardResponse ¶
type AgentCardResponse struct {
Name string `json:"name"`
Description string `json:"description"`
URL string `json:"url"`
Version string `json:"version"`
ProtocolVersion string `json:"protocolVersion,omitempty"`
ProtocolVersions []string `json:"protocolVersions,omitempty"`
PreferredTransport string `json:"preferredTransport,omitempty"`
AdditionalInterfaces []AgentCardTransport `json:"additionalInterfaces,omitempty"`
SupportedInterfaces []AgentCardInterface `json:"supportedInterfaces,omitempty"`
SupportsAuthenticatedExtendedCard bool `json:"supportsAuthenticatedExtendedCard,omitempty"`
Provider AgentCardProvider `json:"provider"`
Capabilities AgentCardCapabilities `json:"capabilities"`
DefaultInputModes []string `json:"default_input_modes"`
DefaultOutputModes []string `json:"default_output_modes"`
DefaultInputModesCurrent []string `json:"defaultInputModes,omitempty"`
DefaultOutputModesCurrent []string `json:"defaultOutputModes,omitempty"`
Skills []AgentCardSkill `json:"skills"`
SecuritySchemes map[string]interface{} `json:"securitySchemes,omitempty"`
Security []map[string][]string `json:"security,omitempty"`
SecurityRequirements []map[string][]string `json:"securityRequirements,omitempty"`
Authentication AgentCardAuth `json:"authentication"`
OpenLinker AgentCardOpenLinkerExt `json:"openlinker"`
Capability *CapabilityResponse `json:"capability,omitempty"`
Examples []ExampleResponse `json:"examples,omitempty"`
Signature *AgentCardSignature `json:"signature,omitempty"`
}
AgentCardResponse is a public, machine-readable card for Agent discovery.
It intentionally points clients at OpenLinker platform invocation endpoints instead of exposing private endpoint secrets.
type AgentCardRuntimeExt ¶
type AgentCardRuntimeExt struct {
Adapter string `json:"adapter"`
ConnectionMode string `json:"connection_mode"`
OnlineSignal string `json:"online_signal"`
TaskLifecycle string `json:"task_lifecycle"`
}
AgentCardRuntimeExt explains how OpenLinker maps the native A2A surface to the concrete runtime adapter behind this Agent.
type AgentCardSignature ¶
type AgentCardSkill ¶
type AgentCardTransport ¶
type AgentCounts ¶ added in v0.1.14
type AgentDetailResponse ¶
type AgentDetailResponse struct {
ID string `json:"id"`
Slug string `json:"slug"`
Name string `json:"name"`
Description string `json:"description"`
EndpointURL string `json:"endpoint_url"`
PricePerCallCents int32 `json:"price_per_call_cents"`
Tags []string `json:"tags"`
TotalCalls int32 `json:"total_calls"`
Creator CreatorMini `json:"creator"`
CreatedAt string `json:"created_at"`
CertifiedAt *string `json:"certified_at,omitempty"`
LifecycleStatus string `json:"lifecycle_status"`
Visibility string `json:"visibility"`
CertificationStatus string `json:"certification_status"`
ConnectionMode string `json:"connection_mode"`
MCPToolName *string `json:"mcp_tool_name,omitempty"`
Availability Availability `json:"availability"`
Readiness Readiness `json:"readiness"`
VerifiedSkillCount int32 `json:"verified_skill_count"`
LatestBenchmarkID *string `json:"latest_benchmark_batch_id,omitempty"`
Skills []SkillMini `json:"skills"`
Capability *CapabilityResponse `json:"capability,omitempty"`
Examples []ExampleResponse `json:"examples"`
}
AgentDetailResponse GET /agents/:slug 响应。
详情页比列表多 endpoint_url / created_at / certified_at 等字段, 但 endpoint_auth_header 始终不暴露(仅 runtime 调用时服务端使用)。
type AgentListOptions ¶ added in v0.1.14
type AgentListResponse ¶ added in v0.1.14
type AgentListResponse struct {
Items []AgentResponse `json:"items"`
Total int32 `json:"total"`
Limit int32 `json:"limit"`
Offset int32 `json:"offset"`
Counts AgentCounts `json:"counts"`
}
type AgentResponse ¶
type AgentResponse struct {
ID string `json:"id"`
Slug string `json:"slug"`
Name string `json:"name"`
Description string `json:"description"`
EndpointURL string `json:"endpoint_url"`
PricePerCallCents int32 `json:"price_per_call_cents"`
Tags []string `json:"tags"`
SkillIDs []string `json:"skill_ids,omitempty"`
Status string `json:"status"` // 派生,老前端兼容
LifecycleStatus string `json:"lifecycle_status"`
Visibility string `json:"visibility"`
CertificationStatus string `json:"certification_status"`
RejectionReason *string `json:"rejection_reason,omitempty"`
TotalCalls int32 `json:"total_calls"`
TotalRevenueCents int64 `json:"total_revenue_cents"`
CallsThisMonth int64 `json:"calls_this_month,omitempty"`
RevenueThisMonth int64 `json:"revenue_this_month_cents,omitempty"`
ConnectionMode string `json:"connection_mode"`
MCPToolName *string `json:"mcp_tool_name,omitempty"`
Availability *Availability `json:"availability,omitempty"`
Readiness *Readiness `json:"readiness,omitempty"`
CreatedAt string `json:"created_at"`
CertifiedAt *string `json:"certified_at,omitempty"`
Creator *Creator `json:"creator,omitempty"`
}
AgentResponse 单个 Agent 的统一返回 DTO。
Phase 2 缺口 2:Status 是从 LifecycleStatus / CertificationStatus 派生的字段, 仅供尚未切换的老前端读取;新前端应直接读 LifecycleStatus / Visibility / CertificationStatus。
Creator 字段仅在 admin 人工处理队列等接口填充,普通创作者列表为空。 EndpointAuthHeader 不返回(避免泄露),仅 owner GET 需要时才单独返回。
type AgentTokenListResponse ¶ added in v0.1.7
type AgentTokenListResponse struct {
Items []AgentTokenResponse `json:"items"`
Total int32 `json:"total"`
Limit int32 `json:"limit"`
Offset int32 `json:"offset"`
SortBy string `json:"sort_by"`
SortDir string `json:"sort_dir"`
HasMore bool `json:"has_more"`
}
AgentTokenListResponse Agent Token 列表响应。
type AgentTokenResponse ¶
type AgentTokenResponse struct {
ID string `json:"id"`
AgentID *string `json:"agent_id,omitempty"`
Name string `json:"name"`
Prefix string `json:"prefix"`
Status string `json:"status"`
Scopes []string `json:"scopes"`
ExpiresAt *string `json:"expires_at,omitempty"`
RedeemedAt *string `json:"redeemed_at,omitempty"`
RevokedAt *string `json:"revoked_at,omitempty"`
LastUsedAt *string `json:"last_used_at,omitempty"`
CreatedAt string `json:"created_at"`
PlaintextToken string `json:"plaintext_token,omitempty"`
}
AgentTokenResponse 列表 / 创建共用响应。 PlaintextToken 仅创建时一次性返回,之后调用 List 仅看到 prefix。
type ApprovalDecisionRequest ¶
type ApprovalDecisionRequest struct {
Note string `json:"note" validate:"omitempty,max=500"`
}
ApprovalDecisionRequest 创作者侧确认 / 拒绝审批的请求体。
type ApprovalHandler ¶
type ApprovalHandler struct {
// contains filtered or unexported fields
}
ApprovalHandler 高风险动作审批 HTTP 入口。
func NewApprovalHandler ¶
func NewApprovalHandler(svc approvalService) *ApprovalHandler
func (*ApprovalHandler) ConfirmApproval ¶
func (h *ApprovalHandler) ConfirmApproval(c echo.Context) error
func (*ApprovalHandler) CreateApproval ¶
func (h *ApprovalHandler) CreateApproval(c echo.Context) error
func (*ApprovalHandler) GetApproval ¶
func (h *ApprovalHandler) GetApproval(c echo.Context) error
func (*ApprovalHandler) ListApprovals ¶
func (h *ApprovalHandler) ListApprovals(c echo.Context) error
func (*ApprovalHandler) RegisterProtected ¶
func (h *ApprovalHandler) RegisterProtected(api *echo.Group, jwtMiddleware echo.MiddlewareFunc)
RegisterProtected creator 路径(需 JWT)。
POST /api/v1/creator/approvals GET /api/v1/creator/approvals GET /api/v1/creator/approvals/:id POST /api/v1/creator/approvals/:id/confirm POST /api/v1/creator/approvals/:id/reject
func (*ApprovalHandler) RejectApproval ¶
func (h *ApprovalHandler) RejectApproval(c echo.Context) error
type ApprovalResponse ¶
type ApprovalResponse struct {
ID string `json:"id"`
AgentID string `json:"agent_id"`
RequestedByUserID *string `json:"requested_by_user_id,omitempty"`
RequestedByTokenID *string `json:"requested_by_token_id,omitempty"`
Action string `json:"action"`
Payload map[string]interface{} `json:"payload"`
Status string `json:"status"`
ApprovalURL string `json:"approval_url"`
ApprovalURLSlug string `json:"approval_url_slug"`
ExpiresAt string `json:"expires_at"`
DecidedAt *string `json:"decided_at,omitempty"`
DecidedByUserID *string `json:"decided_by_user_id,omitempty"`
DecisionNote *string `json:"decision_note,omitempty"`
CreatedAt string `json:"created_at"`
}
ApprovalResponse 单条审批记录。
type ApprovalService ¶
type ApprovalService struct {
// contains filtered or unexported fields
}
ApprovalService 高风险动作审批 CRUD(docs/29 §3.4)。
与 agent.Service 拆开是因为:
- 主要消费方是 Agent 绑定访问令牌自动写入(后置),与创作者注册路径解耦
- 当前阶段只暴露 JWT 路径上的 list / get / confirm / reject + 手动 create
func NewApprovalService ¶
func NewApprovalService(pool *pgxpool.Pool, cfg *config.Config) *ApprovalService
func (*ApprovalService) ConfirmApproval ¶
func (s *ApprovalService) ConfirmApproval(ctx context.Context, creatorID, approvalID uuid.UUID, note string) error
ConfirmApproval 创作者确认审批。pending+未过期 → confirmed。
func (*ApprovalService) CreateApproval ¶
func (s *ApprovalService) CreateApproval(ctx context.Context, creatorID uuid.UUID, req *CreateApprovalRequest) (*ApprovalResponse, error)
CreateApproval 手动写一条审批请求(创作者 / 运营 UI 触发)。 Agent 绑定访问令牌自动触发的入口后置在 runtime 层,本方法不处理 token id。
func (*ApprovalService) GetApproval ¶
func (s *ApprovalService) GetApproval(ctx context.Context, creatorID, approvalID uuid.UUID) (*ApprovalResponse, error)
GetApproval 创作者按 id 获取单条审批。
func (*ApprovalService) ListApprovals ¶
func (s *ApprovalService) ListApprovals(ctx context.Context, creatorID uuid.UUID) ([]ApprovalResponse, error)
ListApprovals 列出当前创作者下所有 agent 的审批记录。
func (*ApprovalService) RejectApproval ¶
func (s *ApprovalService) RejectApproval(ctx context.Context, creatorID, approvalID uuid.UUID, note string) error
RejectApproval 创作者拒绝审批。pending+未过期 → rejected。
func (*ApprovalService) SweepExpiredApprovals ¶
func (s *ApprovalService) SweepExpiredApprovals(ctx context.Context) (int64, error)
SweepExpiredApprovals 批量把超期 pending 标记为 expired。供后台 cron / worker 调。
type Availability ¶
type Availability struct {
Status string `json:"status"`
Label string `json:"label"`
Hint string `json:"hint"`
LastSuccessfulRunAt *string `json:"last_successful_run_at,omitempty"`
LastFailedRunAt *string `json:"last_failed_run_at,omitempty"`
LastCheckedAt *string `json:"last_checked_at,omitempty"`
ConsecutiveFailures int32 `json:"consecutive_failures"`
}
Availability is the public availability signal derived from real run results.
It deliberately separates "registered/listed" from "recently reachable".
type AvailabilityAlertListResponse ¶
type AvailabilityAlertListResponse struct {
Items []AvailabilityAlertResponse `json:"items"`
Total int32 `json:"total"`
Unread int32 `json:"unread"`
}
AvailabilityAlertListResponse GET /creator/availability-alerts 响应。
type AvailabilityAlertResponse ¶
type AvailabilityAlertResponse struct {
ID string `json:"id"`
AgentID string `json:"agent_id"`
AgentSlug string `json:"agent_slug,omitempty"`
AgentName string `json:"agent_name,omitempty"`
Type string `json:"type"`
Severity string `json:"severity"`
AvailabilityStatus string `json:"availability_status"`
ConsecutiveFailures int32 `json:"consecutive_failures"`
Title string `json:"title"`
Message string `json:"message"`
LastError *string `json:"last_error,omitempty"`
RepairHints []string `json:"repair_hints,omitempty"`
ReadAt *string `json:"read_at,omitempty"`
CreatedAt string `json:"created_at"`
UpdatedAt string `json:"updated_at"`
}
AvailabilityAlertResponse 是创作者侧站内可用性告警。
type AvailabilityCheckBatchResponse ¶
type AvailabilityCheckBatchResponse struct {
Checked int32 `json:"checked"`
Passed int32 `json:"passed"`
Failed int32 `json:"failed"`
Alerts []AvailabilityAlertResponse `json:"alerts"`
}
AvailabilityCheckBatchResponse 平台巡检批次结果。
type AvailabilityMonitorConfig ¶
type AvailabilityMonitorConfig struct {
Interval time.Duration
InitialDelay time.Duration
StaleAfter time.Duration
BatchSize int32
}
AvailabilityMonitorConfig controls the background platform health checker.
type CapabilityResponse ¶
type CapabilityResponse struct {
ID string `json:"id"`
AgentID string `json:"agent_id"`
InputSchema map[string]interface{} `json:"input_schema"`
OutputSchema map[string]interface{} `json:"output_schema"`
Summary string `json:"summary"`
Version int32 `json:"version"`
PublishedAt string `json:"published_at"`
UpdatedAt string `json:"updated_at"`
}
CapabilityResponse Agent 能力声明响应。
type CreateAgentRequest ¶
type CreateAgentRequest struct {
Slug string `json:"slug" validate:"required,min=3,max=80"`
Name string `json:"name" validate:"required,min=3,max=80"`
Description string `json:"description" validate:"max=500"`
EndpointURL string `json:"endpoint_url" validate:"max=500"`
EndpointAuthHeader string `json:"endpoint_auth_header" validate:"max=500"`
PricePerCallCents int32 `json:"price_per_call_cents" validate:"min=0,max=1000000"`
Tags []string `json:"tags" validate:"required,min=1,max=5,dive,min=2,max=30"`
Visibility string `json:"visibility" validate:"omitempty,oneof=public unlisted private"`
ConnectionMode string `json:"connection_mode" validate:"omitempty,oneof=direct_http mcp_server runtime_pull runtime_ws"`
MCPToolName string `json:"mcp_tool_name" validate:"omitempty,min=1,max=120"`
}
CreateAgentRequest 创建 Agent 请求体。
slug 格式(^[a-z0-9][a-z0-9-]*[a-z0-9]$, 3..80)由 service 层用 regex 校验, 避免给 validator 注册自定义 tag 提高维护成本。
type CreateAgentTokenRequest ¶
type CreateAgentTokenRequest struct {
Name string `json:"name" validate:"required,min=1,max=80"`
AgentID string `json:"agent_id" validate:"omitempty,uuid"`
Scopes []string `json:"scopes" validate:"omitempty,max=2,dive,oneof=agent:call agent:pull"`
ExpiresInMinutes int32 `json:"expires_in_minutes" validate:"omitempty,min=5,max=1440"`
}
CreateAgentTokenRequest 创作者侧创建 Agent 接入凭证。
agent_id 为空时创建 pending_registration token,用于新 Agent 自注册; agent_id 不为空时创建 active_runtime token,用于已有 Agent 轮换接入凭证。
type CreateApprovalRequest ¶
type CreateApprovalRequest struct {
AgentID string `json:"agent_id" validate:"required,uuid"`
Action string `json:"action" validate:"required,min=1,max=80"`
Payload map[string]interface{} `json:"payload"`
ExpiresInMinutes int32 `json:"expires_in_minutes" validate:"omitempty,min=5,max=1440"`
}
CreateApprovalRequest 创作者侧手动发起一条审批记录(用于 UI 模拟 / 测试)。
后续 Agent 绑定访问令牌触发高风险动作时,由 runtime 自动写入, 这里的接口仅保留给前端 / E2E 触发样例使用。
type CreateExampleRequest ¶
type CreateExampleRequest struct {
Title string `json:"title" validate:"required,min=1,max=120"`
InputJSON map[string]interface{} `json:"input_json" validate:"required"`
ExpectedOutputJSON map[string]interface{} `json:"expected_output_json,omitempty"`
SortOrder int32 `json:"sort_order"`
}
CreateExampleRequest 新增 Agent 示例。
type Creator ¶
type Creator struct {
ID string `json:"id"`
Email string `json:"email"`
DisplayName string `json:"display_name"`
}
Creator admin 视图嵌入的创作者信息。
type CreatorMini ¶
type CreatorMini struct {
DisplayName string `json:"display_name"`
}
CreatorMini 列表 / 详情里嵌入的创作者轻量信息。
Phase 1 只暴露 display_name,未来可加 avatar / verified 等字段。
type DryRunResponse ¶
type DryRunResponse struct {
Result string `json:"result"`
Error *string `json:"error,omitempty"`
Output map[string]interface{} `json:"output,omitempty"`
Availability Availability `json:"availability"`
RepairHints []string `json:"repair_hints,omitempty"`
}
DryRunResponse POST /creator/agents/:id/dry-run 响应。
result = "pass" / "fail";fail 时 error 非空,pass 时 error 为 nil。 output 是创作者 endpoint 返回的原始 JSON object(pass 时存在;fail 时可能为 nil)。
type DryRunner ¶
type DryRunner interface {
DryRun(ctx context.Context, agent *db.Agent, input map[string]interface{}) (map[string]interface{}, string)
}
DryRunner Agent endpoint 探活调用接口;由 runtime.Service 实现。
抽象到接口避免 internal/agent 直接依赖 internal/runtime(保留交叉依赖出口)。 返回 (output, errMsg):errMsg 为空字符串视为通过。
type ExampleResponse ¶
type ExampleResponse struct {
ID string `json:"id"`
AgentID string `json:"agent_id"`
Title string `json:"title"`
InputJSON map[string]interface{} `json:"input_json"`
ExpectedOutputJSON map[string]interface{} `json:"expected_output_json,omitempty"`
SortOrder int32 `json:"sort_order"`
CreatedAt string `json:"created_at"`
UpdatedAt string `json:"updated_at"`
}
ExampleResponse Agent 示例响应。
type Handler ¶
type Handler struct {
// contains filtered or unexported fields
}
Handler Agent 注册 / 公开状态 HTTP 入口。
func NewHandler ¶
NewHandler 构造 Handler。cfg 可选(测试可省略)。
func (*Handler) BecomeCreator ¶
BecomeCreator 当前用户成为创作者(一键)。
func (*Handler) CertifyAgent ¶
CertifyAgent admin/运营授予认证。pending → certified。
func (*Handler) CreateAgent ¶
CreateAgent 创作者新建 Agent。
func (*Handler) CreateExample ¶
CreateExample 新增 Agent 示例。
func (*Handler) DeleteExample ¶
DeleteExample 删除 Agent 示例。
func (*Handler) DisableAgent ¶
DisableAgent 创作者主动下架。
func (*Handler) GetAgentOnboarding ¶
GetAgentOnboarding 查询创作者侧接入状态。
func (*Handler) GetMyAgent ¶
GetMyAgent 创作者按 id 查自己的 Agent。
func (*Handler) ListAvailabilityAlerts ¶
ListAvailabilityAlerts lists creator-visible Agent availability alerts.
func (*Handler) ListMyAgents ¶
ListMyAgents 创作者中心列表。
func (*Handler) ListPendingAgents ¶
ListPendingAgents admin/运营人工处理队列。
func (*Handler) MarkAvailabilityAlertRead ¶
MarkAvailabilityAlertRead marks a creator availability alert as read.
func (*Handler) RegisterAdmin ¶
func (h *Handler) RegisterAdmin(api *echo.Group, jwtMiddleware, adminMiddleware echo.MiddlewareFunc)
RegisterAdmin 管理员/运营人工处理端点(需 JWT + admin 双重中间件)。
GET /admin/agents/pending # 待审认证申请队列 POST /admin/agents/:id/certify POST /admin/agents/:id/reject-certification
func (*Handler) RegisterProtected ¶
func (h *Handler) RegisterProtected(api *echo.Group, jwtMiddleware echo.MiddlewareFunc)
RegisterProtected 创作者侧端点(需 JWT)。
POST /me/become-creator POST /creator/agents GET /creator/agents GET /creator/agents/:id PATCH /creator/agents/:id PATCH /creator/agents/:id/visibility DELETE /creator/agents/:id GET /creator/agents/:id/onboarding PUT /creator/agents/:id/capabilities POST /creator/agents/:id/examples DELETE /creator/agents/:id/examples/:exampleID POST /creator/agents/:id/health-check GET /creator/availability-alerts POST /creator/availability-alerts/:alertID/read
func (*Handler) RejectCertification ¶
RejectCertification admin/运营拒绝认证。pending → rejected。
func (*Handler) RequestCertification ¶
RequestCertification 创作者发起认证申请。
func (*Handler) RunHealthCheck ¶
RunHealthCheck 是 dry-run 的产品化入口:同时刷新 Agent availability。
func (*Handler) UpdateAgent ¶
UpdateAgent 创作者编辑 Agent 基础信息。
func (*Handler) UpdateVisibility ¶
UpdateVisibility 创作者仅切换 Agent 市场可见性。
type ListAgentTokensOptions ¶ added in v0.1.7
ListAgentTokensOptions 控制 Agent Token 列表分页和排序。
type MarketHandler ¶
type MarketHandler struct {
// contains filtered or unexported fields
}
MarketHandler 市场(用户侧只读)HTTP 入口。
公开市场端点无需 JWT;创作者自测端点通过 RegisterProtected 另挂 JWT。
func NewMarketHandler ¶
func NewMarketHandler(svc *MarketService) *MarketHandler
NewMarketHandler 构造 MarketHandler。
func (*MarketHandler) GetAgentCard ¶
func (h *MarketHandler) GetAgentCard(c echo.Context) error
GetAgentCard returns a public, machine-readable card for this Agent.
func (*MarketHandler) GetBySlug ¶
func (h *MarketHandler) GetBySlug(c echo.Context) error
GetBySlug Agent 详情。
不存在 / 未公开 → 404 NOT_FOUND。
func (*MarketHandler) GetBySlugForOwner ¶
func (h *MarketHandler) GetBySlugForOwner(c echo.Context) error
GetBySlugForOwner Agent 创作者自测详情。
非 owner / 不存在 / 已下架统一 404;private 仅 owner 可见。
func (*MarketHandler) GetExtendedAgentCard ¶
func (h *MarketHandler) GetExtendedAgentCard(c echo.Context) error
GetExtendedAgentCard returns the public extended card with richer capability and example metadata, still without endpoint secrets.
func (*MarketHandler) ListMarket ¶
func (h *MarketHandler) ListMarket(c echo.Context) error
ListMarket 市场列表。
query params:
tags=finance,data 逗号分隔,任意命中即返回(OR) q=审计 关键词,对 name/description ILIKE page=1 1-based size=12 默认 12,max 50 callable_only=true 只返回当前有可调用证据的 Agent
func (*MarketHandler) Register ¶
func (h *MarketHandler) Register(api *echo.Group)
Register 注册公开路由。
GET /agents 市场列表(支持 tags / q / page / size) GET /agents/:slug 详情页 GET /agents/:slug/agent-card.json 机器可读 Agent Card GET /agents/:slug/agent-card.extended.json 扩展 Agent Card
与模块 2 的 GET /agents/check-slug 共存:echo v4 的路由匹配中 静态前缀("check-slug")优先于参数(":slug"),因此两个端点都能命中。
func (*MarketHandler) RegisterProtected ¶
func (h *MarketHandler) RegisterProtected(api *echo.Group, jwtMiddleware echo.MiddlewareFunc)
RegisterProtected 注册创作者侧只读路由。
GET /creator/agents/by-slug/:slug 当前创作者自测详情(允许自己的 private Agent)
type MarketListItem ¶
type MarketListItem struct {
ID string `json:"id"`
Slug string `json:"slug"`
Name string `json:"name"`
Description string `json:"description"`
PricePerCallCents int32 `json:"price_per_call_cents"`
Tags []string `json:"tags"`
TotalCalls int32 `json:"total_calls"`
Creator CreatorMini `json:"creator"`
ConnectionMode string `json:"connection_mode"`
MCPToolName *string `json:"mcp_tool_name,omitempty"`
Availability Availability `json:"availability"`
Readiness Readiness `json:"readiness"`
}
MarketListItem 市场列表中的单个 Agent 摘要。
仅暴露公开字段;endpoint_url / endpoint_auth_header 不出现在列表里。
type MarketListResponse ¶
type MarketListResponse struct {
Items []MarketListItem `json:"items"`
Total int32 `json:"total"`
Page int32 `json:"page"`
Size int32 `json:"size"`
}
MarketListResponse GET /agents 响应。
page 从 1 开始;total 是符合过滤条件的总数。
type MarketService ¶
type MarketService struct {
// contains filtered or unexported fields
}
MarketService 市场(用户侧只读)业务逻辑。
设计与模块 2 (Agent 注册写入) 隔离:本 service 只调用 SELECT, 不持有事务,也不依赖任何写入逻辑。
func NewMarketService ¶
func NewMarketService(pool *pgxpool.Pool) *MarketService
NewMarketService 构造 MarketService,pool 仅用于读。
func (*MarketService) GetAgentCardBySlug ¶
func (s *MarketService) GetAgentCardBySlug(ctx context.Context, slug string) (*AgentCardResponse, error)
GetAgentCardBySlug returns a public Agent Card derived from the same public detail record used by the market page.
func (*MarketService) GetBySlug ¶
func (s *MarketService) GetBySlug(ctx context.Context, slug string) (*AgentDetailResponse, error)
GetBySlug 按 slug 查询已公开 Agent 详情。
不存在 / 未公开 / 已禁用 → NotFound(统一返回 404,避免泄露状态信息)。 endpoint_auth_header 永不暴露给前端。
func (*MarketService) GetBySlugForOwner ¶
func (s *MarketService) GetBySlugForOwner(ctx context.Context, slug string, creatorID uuid.UUID) (*AgentDetailResponse, error)
GetBySlugForOwner 按 slug 查询当前创作者自己的 Agent 详情。
仅用于创作者自测入口:private 也允许 owner 访问;非 owner / disabled 仍返回 404。 endpoint_auth_header 永不暴露给前端。
func (*MarketService) GetExtendedAgentCardBySlug ¶
func (s *MarketService) GetExtendedAgentCardBySlug(ctx context.Context, slug string) (*AgentCardResponse, error)
func (*MarketService) ListMarket ¶
func (s *MarketService) ListMarket(ctx context.Context, tags []string, keyword string, page, size int32, callableOnlyArg ...bool) (*MarketListResponse, error)
ListMarket 列出已公开 Agent。
- tags:空切片表示不按 tag 筛;非空时使用 Postgres 数组重叠运算(任意命中)。
- keyword:空串表示不搜;非空时对 name/description 做 ILIKE。
- page 从 1 开始;size 由调用方 clamp 到 [1, 50],但这里再做一次防御。
func (*MarketService) SetA2AGRPCInterface ¶
func (s *MarketService) SetA2AGRPCInterface(publicURL string)
type MetricHandler ¶
type MetricHandler struct {
// contains filtered or unexported fields
}
MetricHandler 公开 GET 单 Agent 指标快照。
func NewMetricHandler ¶
func NewMetricHandler(svc metricService) *MetricHandler
func (*MetricHandler) GetMetrics ¶
func (h *MetricHandler) GetMetrics(c echo.Context) error
func (*MetricHandler) Register ¶
func (h *MetricHandler) Register(api *echo.Group)
Register 公开端点(无 JWT;snapshot 不含敏感字段)。
GET /api/v1/agents/:id/metrics
type MetricService ¶
type MetricService struct {
// contains filtered or unexported fields
}
MetricService Agent 指标快照读 + worker 共享层(docs/29 §3.4)。
func NewMetricService ¶
func NewMetricService(pool *pgxpool.Pool) *MetricService
func (*MetricService) AggregateOnce ¶
func (s *MetricService) AggregateOnce(ctx context.Context) error
AggregateOnce 跑一次完整聚合(worker 与测试都用这个入口)。
func (*MetricService) GetSnapshots ¶
func (s *MetricService) GetSnapshots(ctx context.Context, agentID uuid.UUID) (*MetricSnapshotsResponse, error)
GetSnapshots 返回某 Agent 全部窗口的快照(24h/7d/30d)。
type MetricSnapshot ¶
type MetricSnapshot struct {
TimeWindow string `json:"time_window"`
CallCount int32 `json:"call_count"`
SuccessCount int32 `json:"success_count"`
FailureCount int32 `json:"failure_count"`
SuccessRateBps int32 `json:"success_rate_bps"`
MedianLatencyMs *int32 `json:"median_latency_ms,omitempty"`
P95LatencyMs *int32 `json:"p95_latency_ms,omitempty"`
SnapshottedAt string `json:"snapshotted_at"`
}
MetricSnapshot 单个窗口的指标。
type MetricSnapshotsResponse ¶
type MetricSnapshotsResponse struct {
AgentID string `json:"agent_id"`
Items []MetricSnapshot `json:"items"`
}
MetricSnapshotsResponse 公开 GET /agents/:id/metrics 响应。
type OnboardingResponse ¶
type OnboardingResponse struct {
Status OnboardingStatusResponse `json:"status"`
Capability *CapabilityResponse `json:"capability,omitempty"`
Examples []ExampleResponse `json:"examples"`
// Availability 是创作者侧修复体验使用的实时可用性快照。
Availability Availability `json:"availability"`
}
OnboardingResponse 聚合创作者接入页所需状态。
type OnboardingStatusResponse ¶
type OnboardingStatusResponse struct {
AgentID string `json:"agent_id"`
EndpointSet bool `json:"endpoint_set"`
CapabilitiesSet bool `json:"capabilities_set"`
ExamplesSet bool `json:"examples_set"`
DryRunPassed bool `json:"dry_run_passed"`
DryRunLastResult string `json:"dry_run_last_result"`
DryRunError *string `json:"dry_run_error,omitempty"`
DryRunAt *string `json:"dry_run_at,omitempty"`
UpdatedAt string `json:"updated_at"`
}
OnboardingStatusResponse Agent 接入完成度。
type Readiness ¶
type Readiness struct {
Listed bool `json:"listed"`
Discoverable bool `json:"discoverable"`
Callable bool `json:"callable"`
Verified bool `json:"verified"`
Certified bool `json:"certified"`
PaidEnabled bool `json:"paid_enabled"`
AgentCardURL string `json:"agent_card_url"`
A2AEndpoint string `json:"a2a_endpoint"`
LastSuccessfulRunAt *string `json:"last_successful_run_at,omitempty"`
AvailabilityStatus string `json:"availability_status"`
VerifiedSkillCount int32 `json:"verified_skill_count"`
LatestBenchmarkBatchID *string `json:"latest_benchmark_batch_id,omitempty"`
Explanation map[string]string `json:"explanation"`
}
Readiness separates public listing/discovery from actual callability and trust.
It is intentionally conservative: missing evidence is false/null, not a positive badge. paid_enabled stays false until real payments are enabled.
type RegisterAgentViaTokenRequest ¶
type RegisterAgentViaTokenRequest struct {
AgentToken string `json:"agent_token" validate:"required,min=24,max=128"`
Slug string `json:"slug" validate:"omitempty,min=3,max=80"`
Name string `json:"name" validate:"required,min=3,max=80"`
Description string `json:"description" validate:"max=500"`
EndpointURL string `json:"endpoint_url" validate:"max=500"`
EndpointAuthHeader string `json:"endpoint_auth_header" validate:"max=500"`
PricePerCallCents int32 `json:"price_per_call_cents" validate:"min=0,max=1000000"`
Tags []string `json:"tags" validate:"required,min=1,max=5,dive,min=2,max=30"`
AbilityTags []string `json:"ability_tags" validate:"omitempty,max=5,dive,min=2,max=30"`
SkillIDs []string `json:"skill_ids" validate:"omitempty,max=5,dive,min=3,max=80"`
Visibility string `json:"visibility" validate:"omitempty,oneof=public unlisted private"`
ConnectionMode string `json:"connection_mode" validate:"omitempty,oneof=direct_http mcp_server runtime_pull runtime_ws"`
MCPToolName string `json:"mcp_tool_name" validate:"omitempty,min=1,max=120"`
}
RegisterAgentViaTokenRequest Agent 侧自注册请求体。
agent_token 必填;slug 可选(未填时由 name 派生)。 其余字段与 CreateAgentRequest 一致,但不要求 JWT。
type RegisterAgentViaTokenResponse ¶
type RegisterAgentViaTokenResponse struct {
Agent AgentResponse `json:"agent"`
AgentToken AgentTokenResponse `json:"agent_token"`
}
RegisterAgentViaTokenResponse 自注册成功响应。 AgentToken 返回元数据;明文仍是请求里使用的同一枚 OPENLINKER_AGENT_TOKEN。
type RegistrationHandler ¶
type RegistrationHandler struct {
// contains filtered or unexported fields
}
RegistrationHandler Agent 自注册访问令牌 HTTP 入口。
func NewRegistrationHandler ¶
func NewRegistrationHandler(svc registrationService) *RegistrationHandler
func (*RegistrationHandler) CreateAgentToken ¶
func (h *RegistrationHandler) CreateAgentToken(c echo.Context) error
CreateAgentToken POST /api/v1/creator/agent-tokens
func (*RegistrationHandler) ListAgentTokens ¶
func (h *RegistrationHandler) ListAgentTokens(c echo.Context) error
ListAgentTokens GET /api/v1/creator/agent-tokens
func (*RegistrationHandler) RegisterAgentViaToken ¶
func (h *RegistrationHandler) RegisterAgentViaToken(c echo.Context) error
RegisterAgentViaToken POST /api/v1/agent-registration/agents
func (*RegistrationHandler) RegisterProtected ¶
func (h *RegistrationHandler) RegisterProtected(api *echo.Group, jwtMiddleware echo.MiddlewareFunc)
RegisterProtected 创作者侧(需 JWT)。
POST /api/v1/creator/agent-tokens GET /api/v1/creator/agent-tokens DELETE /api/v1/creator/agent-tokens/:id
func (*RegistrationHandler) RegisterPublic ¶
func (h *RegistrationHandler) RegisterPublic(api *echo.Group)
RegisterPublic Agent 侧(无 JWT,凭 agent token)。
POST /api/v1/agent-registration/agents GET /skill/publish-agent -> 静态接入说明(HTML/Markdown)
func (*RegistrationHandler) RevokeAgentToken ¶
func (h *RegistrationHandler) RevokeAgentToken(c echo.Context) error
RevokeAgentToken DELETE /api/v1/creator/agent-tokens/:id
type RegistrationService ¶
type RegistrationService struct {
// contains filtered or unexported fields
}
RegistrationService 处理 Agent token 创建、自注册兑换和撤销。
func NewRegistrationService ¶
func NewRegistrationService(pool *pgxpool.Pool, cfg ...*config.Config) *RegistrationService
func (*RegistrationService) CreateAgentToken ¶
func (s *RegistrationService) CreateAgentToken(ctx context.Context, creatorID uuid.UUID, req *CreateAgentTokenRequest) (*AgentTokenResponse, error)
CreateAgentToken 创建统一 Agent 接入凭证。明文 token 仅本次返回。
func (*RegistrationService) ListAgentTokens ¶
func (s *RegistrationService) ListAgentTokens(ctx context.Context, creatorID uuid.UUID, agentID *uuid.UUID, opts ListAgentTokensOptions) (*AgentTokenListResponse, error)
func (*RegistrationService) RegisterAgentViaToken ¶
func (s *RegistrationService) RegisterAgentViaToken(ctx context.Context, req *RegisterAgentViaTokenRequest) (*RegisterAgentViaTokenResponse, error)
RegisterAgentViaToken 用 pending Agent Token 完成 Agent 注册。
func (*RegistrationService) RevokeAgentToken ¶
type RejectRequest ¶
type RejectRequest struct {
Reason string `json:"reason" validate:"required,min=5,max=500"`
}
RejectRequest admin 拒绝 Agent 请求体。
type Service ¶
type Service struct {
// contains filtered or unexported fields
}
Service Agent 注册 / 公开状态业务逻辑层。
func NewService ¶
NewService 构造 Service。
func (*Service) BecomeCreator ¶
BecomeCreator 设置 user.is_creator=true(一键,无审核)。
Phase 1 决策:不做创作者认证审核,creator_verified 字段保留给后续运营手动设置。
func (*Service) CertifyAgent ¶
CertifyAgent 运营授予认证。pending → certified。
func (*Service) CreateAgent ¶
func (s *Service) CreateAgent(ctx context.Context, creatorID uuid.UUID, req *CreateAgentRequest) (*AgentResponse, error)
CreateAgent 创作者新建 Agent。
流程:
- 校验用户存在且 is_creator=true → 否则 Forbidden
- 校验 slug 格式 → 否则 Unprocessable
- CheckSlugAvailable → 否则 Conflict
- INSERT agents(默认 public,可显式选择 unlisted/private);UNIQUE 兜底再次 Conflict
func (*Service) CreateExample ¶
func (s *Service) CreateExample(ctx context.Context, agentID, creatorID uuid.UUID, req *CreateExampleRequest) (*ExampleResponse, error)
CreateExample 新增 Agent 输入/输出示例。
func (*Service) DeleteExample ¶
DeleteExample 删除 Agent 示例。
func (*Service) DisableAgent ¶
DisableAgent 创作者主动下架。
func (*Service) GetAgentOnboarding ¶
func (s *Service) GetAgentOnboarding(ctx context.Context, agentID, creatorID uuid.UUID) (*OnboardingResponse, error)
GetAgentOnboarding 查询创作者侧接入完成度、能力声明和 examples。
func (*Service) GetMyAgent ¶
func (s *Service) GetMyAgent(ctx context.Context, agentID, creatorID uuid.UUID) (*AgentResponse, error)
GetMyAgent 创作者按 id 查自己的 Agent(编辑前预填用)。
func (*Service) ListAvailabilityAlerts ¶
func (*Service) ListMyAgents ¶
ListMyAgents 创作者中心列表。
func (*Service) ListMyAgentsPage ¶ added in v0.1.14
func (s *Service) ListMyAgentsPage(ctx context.Context, creatorID uuid.UUID, opts AgentListOptions) (*AgentListResponse, error)
func (*Service) ListPendingForAdmin ¶
func (s *Service) ListPendingForAdmin(ctx context.Context) ([]AgentResponse, error)
ListPendingForAdmin admin/运营人工处理队列。
func (*Service) MarkAvailabilityAlertRead ¶
func (*Service) RejectCertification ¶
RejectCertification 运营拒绝认证申请。pending → rejected。
func (*Service) RequestCertification ¶
RequestCertification 创作者发起认证申请。unreviewed/rejected → pending。
func (*Service) RunDryRun ¶
func (s *Service) RunDryRun(ctx context.Context, agentID, creatorID uuid.UUID) (*DryRunResponse, error)
RunDryRun 用首条 example 的 input 调用创作者 endpoint,更新 onboarding 状态。
流程:
- 校验 Agent 归属(GetAgentByIDForOwner)
- 取首条 example.input_json
- 调 DryRunner(不计费 / 不写 runs)
- 把结果写到 agent_onboarding_status.dry_run_*
- 返回 DryRunResponse
func (*Service) RunDueAvailabilityChecks ¶
func (s *Service) RunDueAvailabilityChecks(ctx context.Context, limit, staleSeconds int32) (*AvailabilityCheckBatchResponse, error)
RunDueAvailabilityChecks executes one monitor batch. It is exposed for tests and operational one-shot runs; regular production use should go through StartAvailabilityMonitor.
func (*Service) SetDryRunner ¶
SetDryRunner 注入 endpoint 探活器;为 nil 时 RunDryRun 返回 503。
构造时不接收 DryRunner 是为了保留 main.go 中循环依赖的解耦点: agent 和 runtime 互不引用,必要时由 cmd/api/main.go 在两者都构造完成后串起来。
func (*Service) SetVisibility ¶
func (s *Service) SetVisibility(ctx context.Context, agentID, creatorID uuid.UUID, visibility string) (*AgentResponse, error)
SetVisibility 仅变更市场可见范围,避免客户端为了改状态而重传 endpoint 凭据。
func (*Service) UpdateAgent ¶
func (s *Service) UpdateAgent(ctx context.Context, agentID, creatorID uuid.UUID, req *UpdateAgentRequest) (*AgentResponse, error)
UpdateAgent 创作者编辑 Agent 基础信息(含 visibility)。
SQL 仅在 lifecycle_status='active' 且 creator_id 匹配时返回; RETURNING 命中 0 行 → pgx.ErrNoRows,service 层再用 GetAgentByIDForOwner 区分两种 case:
- 不存在 / 不属于该 creator → NotFound
- disabled → Forbidden
Visibility 空串视为不改(默认沿用旧值);显式传值则按 public/unlisted/private 校验。
func (*Service) UpsertCapability ¶
func (s *Service) UpsertCapability(ctx context.Context, agentID, creatorID uuid.UUID, req *UpsertCapabilityRequest) (*CapabilityResponse, error)
UpsertCapability 保存 Agent input/output JSON Schema。
type SkillMini ¶
type SkillMini struct {
ID string `json:"id"`
Category string `json:"category"`
Name string `json:"name"`
Description string `json:"description"`
}
SkillMini 详情页公开展示的 Agent skill。
type SlugCheckResponse ¶
SlugCheckResponse GET /agents/check-slug 响应。
type UpdateAgentRequest ¶
type UpdateAgentRequest struct {
Name string `json:"name" validate:"required,min=3,max=80"`
Description string `json:"description" validate:"max=500"`
EndpointURL string `json:"endpoint_url" validate:"max=500"`
EndpointAuthHeader string `json:"endpoint_auth_header" validate:"max=500"`
ClearEndpointAuth bool `json:"clear_endpoint_auth_header"`
PricePerCallCents int32 `json:"price_per_call_cents" validate:"min=0,max=1000000"`
Tags []string `json:"tags" validate:"required,min=1,max=5,dive,min=2,max=30"`
Visibility string `json:"visibility" validate:"omitempty,oneof=public unlisted private"`
ConnectionMode string `json:"connection_mode" validate:"omitempty,oneof=direct_http mcp_server runtime_pull runtime_ws"`
MCPToolName string `json:"mcp_tool_name" validate:"omitempty,min=1,max=120"`
}
UpdateAgentRequest 编辑 Agent 请求体。slug 不可改。 Visibility 可空字符串视为不改,否则只接受 public / unlisted / private。
type UpdateVisibilityRequest ¶
type UpdateVisibilityRequest struct {
Visibility string `json:"visibility" validate:"required,oneof=public unlisted private"`
}
UpdateVisibilityRequest 仅切换市场可见性,不要求重传 endpoint 鉴权等敏感配置。
type UpsertCapabilityRequest ¶
type UpsertCapabilityRequest struct {
InputSchema map[string]interface{} `json:"input_schema" validate:"required"`
OutputSchema map[string]interface{} `json:"output_schema" validate:"required"`
Summary string `json:"summary" validate:"max=1000"`
}
UpsertCapabilityRequest 保存 Agent 能力声明。
Source Files
¶
- agent.go
- approval_dto.go
- approval_handler.go
- approval_service.go
- availability_monitor.go
- connection_mode.go
- dto.go
- handler.go
- market_dto.go
- market_handler.go
- market_service.go
- metric_handler.go
- metric_service.go
- publish_skill.go
- registration_dto.go
- registration_handler.go
- registration_service.go
- safe_int.go
- schema_validation.go
- service.go