- Add status_provider_test.go for queue status coverage - Update model_queue.go with queue simplification - Update run_dispatch.go with dispatch logic improvements - Update status_provider.go with status tracking - Update server tests for a2a, openai, and opsconsole - Remove archived PLAN and CODE_REVIEW documents for 02+01 surface snapshot contract - Archive 02+01_surface_snapshot_contract to 2026/06
117 lines
3.3 KiB
Go
117 lines
3.3 KiB
Go
package service
|
|
|
|
import (
|
|
edgenode "iop/apps/edge/internal/node"
|
|
iop "iop/proto/gen/iop"
|
|
)
|
|
|
|
// NodeSnapshot is a surface-neutral view of a registered node, suitable for
|
|
// CLI, HTTP, or other transports. Label is the short display label (node0, node1).
|
|
// AgentKind and LifecycleState carry the registry entry's generic node
|
|
// classification and lifecycle.
|
|
type NodeSnapshot struct {
|
|
NodeID string
|
|
Alias string
|
|
Label string
|
|
AgentKind string
|
|
LifecycleState string
|
|
Config *iop.NodeConfigPayload
|
|
ProviderSnapshots []*iop.ProviderSnapshot
|
|
}
|
|
|
|
// ListNodeSnapshots returns surface-neutral node descriptors derived from the
|
|
// current registry contents.
|
|
func (s *Service) ListNodeSnapshots() []NodeSnapshot {
|
|
entries := s.registry.All()
|
|
out := make([]NodeSnapshot, 0, len(entries))
|
|
for _, entry := range entries {
|
|
snap := NodeSnapshot{
|
|
NodeID: entry.NodeID,
|
|
Alias: entry.Alias,
|
|
Label: nodeLabel(entry),
|
|
AgentKind: entry.AgentKind,
|
|
LifecycleState: entry.LifecycleState,
|
|
}
|
|
var rec *edgenode.NodeRecord
|
|
if s.nodeStore != nil {
|
|
if r, ok := s.nodeStore.FindByID(entry.NodeID); ok {
|
|
rec = r
|
|
if payload, err := edgenode.BuildConfigPayload(r); err == nil {
|
|
snap.Config = payload
|
|
}
|
|
}
|
|
}
|
|
if rec != nil && s.queue != nil {
|
|
snap.ProviderSnapshots = s.queue.getSnapshotForNode(entry.NodeID, rec)
|
|
}
|
|
out = append(out, snap)
|
|
}
|
|
return out
|
|
}
|
|
|
|
// NodeEntrySnapshot converts a registry entry into the surface-neutral DTO.
|
|
func NodeEntrySnapshot(entry *edgenode.NodeEntry) NodeSnapshot {
|
|
if entry == nil {
|
|
return NodeSnapshot{}
|
|
}
|
|
return NodeSnapshot{
|
|
NodeID: entry.NodeID,
|
|
Alias: entry.Alias,
|
|
Label: nodeLabel(entry),
|
|
AgentKind: entry.AgentKind,
|
|
LifecycleState: entry.LifecycleState,
|
|
}
|
|
}
|
|
|
|
func (s *Service) ResolveNode(ref string) (*edgenode.NodeEntry, error) {
|
|
return s.registry.Resolve(ref)
|
|
}
|
|
|
|
// ResolveNodeSnapshot returns a surface-neutral DTO for the resolved node.
|
|
func (s *Service) ResolveNodeSnapshot(ref string) (NodeSnapshot, error) {
|
|
entry, err := s.ResolveNode(ref)
|
|
if err != nil {
|
|
return NodeSnapshot{}, err
|
|
}
|
|
return NodeEntrySnapshot(entry), nil
|
|
}
|
|
|
|
func (s *Service) GetCapabilities() []*iop.EdgeCapabilitySummary {
|
|
var entries []*edgenode.NodeEntry
|
|
if s.registry != nil {
|
|
entries = s.registry.All()
|
|
}
|
|
if len(entries) == 0 {
|
|
return nil
|
|
}
|
|
return []*iop.EdgeCapabilitySummary{
|
|
{
|
|
Kind: "run",
|
|
Available: true,
|
|
Status: "ready",
|
|
Summary: "Generic execution node available",
|
|
},
|
|
}
|
|
}
|
|
|
|
func (s *Service) GetDomainAgents() []*iop.EdgeDomainAgentSummary {
|
|
return nil
|
|
}
|
|
|
|
// HealthStatusView is the Edge-owned status summary used by control commands
|
|
// such as health.check. It is derived from the live node registry and
|
|
// capability snapshot rather than a fixed simulation delay.
|
|
type HealthStatusView struct {
|
|
Nodes []NodeSnapshot
|
|
Capabilities []*iop.EdgeCapabilitySummary
|
|
}
|
|
|
|
// HealthStatus returns a status summary derived from the current node registry
|
|
// and capability snapshot. It is the real Edge-owned boundary that backs the
|
|
// health.check control command.
|
|
func (s *Service) HealthStatus() HealthStatusView {
|
|
return HealthStatusView{
|
|
Nodes: s.ListNodeSnapshots(),
|
|
Capabilities: s.GetCapabilities(),
|
|
}
|
|
}
|