adapters

package
v0.4.41 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 28, 2026 License: MIT Imports: 25 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func NewPlatformClient

func NewPlatformClient(serverURL, devKey string) (*platformapi.ClientWithResponses, error)

NewPlatformClient builds a platform-api ClientWithResponses with an optional dev key. When devKey is non-empty, every request carries an Authorization: Bearer header so the platform widens scope from public-only to workspace-private.

func ScenarioGetForTest

func ScenarioGetForTest(ctx context.Context, k *kube.Client, name string) (*v1alpha1.TinyScenario, error)

ScenarioGetForTest fetches a TinyScenario by resource name. Only used by cmd/test-scaffold to verify auto-scaffold output; the public ScenarioManager interface intentionally doesn't expose Get because tools that need scenario data should go through UpdateScenarioPort / ListScenarios semantics.

Types

type DashboardReader

type DashboardReader struct {
	// contains filtered or unexported fields
}

DashboardReader implements sdktools.DashboardReader.

The dashboard is DERIVED from the nodes themselves: a node is a widget iff it carries the DashboardLabel. The node is the single source of truth — delete the node and its widget is gone, with nothing else to clean up. This mirrors the platform (project/get-stream.go), and replaces an earlier design that kept a separate TinyWidgetPage store which went stale when a node was deleted from another surface.

func NewDashboardReader

func NewDashboardReader(k *kube.Client) *DashboardReader

func (*DashboardReader) ReadDashboard

func (d *DashboardReader) ReadDashboard(ctx context.Context, projectName string) (*sdktools.DashboardData, error)

ReadDashboard lists the project's dashboard-labelled nodes and renders each as a widget over its _control port.

type DashboardWriter added in v0.4.41

type DashboardWriter struct {
	// contains filtered or unexported fields
}

DashboardWriter implements sdktools.DashboardWriter by toggling the node's DashboardLabel.

The widget IS the node: a node with DashboardLabel="true" is on the dashboard, and there is no separate widget object to create or clean up. Deleting the node removes the widget for free. This matches how the platform and the SaveFlow path treat it — one source of truth, the node.

func NewDashboardWriter added in v0.4.41

func NewDashboardWriter(k *kube.Client) *DashboardWriter

func (*DashboardWriter) SetNodeWidget added in v0.4.41

func (d *DashboardWriter) SetNodeWidget(ctx context.Context, projectName, nodeID, _ string, enabled bool) (string, error)

SetNodeWidget adds the node to the dashboard (label = "true") or removes it. portName is accepted for interface compatibility but ignored — a node's widget is always its control form. Returns the project name as the "page".

Idempotent: setting an already-set label or clearing an already-clear one is a no-op, and a missing node is not an error (nothing to pin).

type FlowLifecycle

type FlowLifecycle struct {
	// contains filtered or unexported fields
}

FlowLifecycle implements sdktools.FlowCreator and sdktools.FlowDeleter. Flows are thin label containers in the cluster — a TinyFlow CRD with a project-name label is all there is.

func NewFlowLifecycle

func NewFlowLifecycle(k *kube.Client) *FlowLifecycle

func (*FlowLifecycle) CreateFlow

func (f *FlowLifecycle) CreateFlow(ctx context.Context, projectName, flowName string) (string, error)

CreateFlow creates a TinyFlow resource in the project.

The input flowName may be a human-readable title ("Test Flow") or an already-valid resource name ("test-flow-abc12"). The returned string is always the k8s resource name of the created (or existing) flow. The original human name, if slugified, is preserved on the flow-description annotation so callers can surface it in UIs.

Idempotent: if a valid-name flow already exists, the existing name is returned unchanged.

func (*FlowLifecycle) DeleteFlow

func (f *FlowLifecycle) DeleteFlow(ctx context.Context, projectName, flowName string) error

DeleteFlow deletes a TinyFlow and all TinyNodes belonging to it. Nodes are identified via the flow-name label.

type ModuleCatalog

type ModuleCatalog struct {
	// contains filtered or unexported fields
}

ModuleCatalog implements sdktools.ModuleCatalog by reading TinyModule CRDs.

When the module operator publishes per-component port schemas in TinyModule.Status.Components[].Ports (SDK commit 04944f7 and later), those surface on the returned ModuleInfo so get_component_info returns full upfront schemas. Older operators that don't yet publish ports yield ComponentInfo entries with empty port-detail slices; callers fall back to get_node_port_schema on placed nodes.

func NewModuleCatalog

func NewModuleCatalog(k *kube.Client) *ModuleCatalog

func (*ModuleCatalog) GetModule

func (c *ModuleCatalog) GetModule(ctx context.Context, name string) (*sdktools.ModuleInfo, error)

GetModule finds a single module by name. The lookup is permissive: it accepts the hosted platform's slash-qualified form ("tinysystems/common-module-v0"), the kubernetes resource form with dashes ("tinysystems-common-module-v0"), and bare names without any workspace prefix ("common-module-v0"). Case-insensitive.

func (*ModuleCatalog) ListModules

func (c *ModuleCatalog) ListModules(ctx context.Context) ([]sdktools.ModuleInfo, error)

ListModules returns every TinyModule in the target namespace.

type NodeEditor

type NodeEditor struct {
	// contains filtered or unexported fields
}

NodeEditor implements the five SDK interfaces that mutate flow state: NodeAdder, EdgeAdder, EdgeConfigurer, NodeSettingsConfigurer, and FlowModifier. Each operation translates directly to a CRD CRUD call.

The v0.1.0 implementation is deliberately minimal: it handles the common happy path (create a node, wire an edge, set configuration) without the platform's richer validation (cluster-wide conflict detection, schema simulation, batch optimization). Error responses surface Kubernetes errors as-is.

func NewNodeEditor

func NewNodeEditor(k *kube.Client) *NodeEditor

func (*NodeEditor) AddEdge

func (e *NodeEditor) AddEdge(ctx context.Context, projectName, flowName, fromNode, fromPort, toNode, toPort string) (*sdktools.AddEdgeResult, error)

AddEdge appends a TinyNodeEdge to the source node's Spec.Edges. The edge ID follows the platform convention "<fromNode>_<fromPort>-<toNode>_<toPort>".

func (*NodeEditor) AddNode

func (e *NodeEditor) AddNode(ctx context.Context, projectName, flowName, component, moduleName string, tracker sdktools.PositionTracker) (*sdktools.AddNodeResult, error)

AddNode creates a TinyNode CRD in the target namespace, tagged with the flow and project labels so the reconciler picks it up.

func (*NodeEditor) ApplyFlowChanges

func (e *NodeEditor) ApplyFlowChanges(ctx context.Context, projectName, flowName string, operations []sdktools.FlowOperation) ([]sdktools.OperationResult, error)

ApplyFlowChanges applies a batch of delete/update operations. Add operations are intentionally not supported here — use the dedicated AddNode / AddEdge methods instead so callers get typed results.

func (*NodeEditor) ConfigureEdge

func (e *NodeEditor) ConfigureEdge(ctx context.Context, projectName, flowName, edgeID string, config map[string]interface{}, schema map[string]interface{}, traceID string) (*sdktools.ConfigureEdgeResult, error)

ConfigureEdge stores the edge configuration on the TARGET node's Ports entry. The target node is identified by parsing the edge ID, which contains both endpoints.

Before persisting, every {{expression}} in the config is checked against the SOURCE port's schema. If an expression references a JSONPath that does not exist in the source schema, the edge is rejected with a hint listing the real field names — so the LLM has a concrete feedback loop for self-correction.

traceID is accepted but ignored in v0.1.0 — trace-based validation is a platform-only feature.

func (*NodeEditor) ConfigureNodeSettings

func (e *NodeEditor) ConfigureNodeSettings(ctx context.Context, projectName, flowName, nodeID string, settings map[string]interface{}, schema map[string]interface{}) (*sdktools.ConfigureNodeSettingsResult, error)

ConfigureNodeSettings writes the settings bytes to the node's `_settings` Port entry.

type PortInspector

type PortInspector struct {
	// contains filtered or unexported fields
}

PortInspector implements sdktools.PortInspector. It reads a node's reconciled port schema and enriches it with any configurable overlays set on the node's own _settings port, so callers can see the actual shape of user-configured fields like context.

This is narrower than the platform's recursive-simulation inspector (which walks the entire graph). We only apply the node's OWN settings as an overlay on its OWN ports. Full cross-node propagation requires Fix 2 (publishing component schemas to TinyModule.Status) or scenario-based validation, both of which land separately.

traceID is accepted but ignored — trace-based inspection is not implemented in v0.1.0.

func NewPortInspector

func NewPortInspector(k *kube.Client) *PortInspector

func (*PortInspector) InspectPort

func (p *PortInspector) InspectPort(ctx context.Context, projectName, nodeID, portName, traceID string) (*sdktools.PortInspectResult, error)

type ProjectLister

type ProjectLister struct {
	// contains filtered or unexported fields
}

ProjectLister implements sdktools.ProjectLister by enumerating TinyProject CRDs in the configured namespace. The display name comes from the same annotation the platform uses (v1alpha1.ProjectNameAnnotation), falling back to the resource name when the annotation is missing.

func NewProjectLister

func NewProjectLister(k *kube.Client) *ProjectLister

func (*ProjectLister) ListProjects

func (p *ProjectLister) ListProjects(ctx context.Context) ([]sdktools.ProjectInfo, error)

type ProjectReader

type ProjectReader struct {
	// contains filtered or unexported fields
}

ProjectReader implements sdktools.ProjectReader by reading TinyFlow and TinyNode CRDs labelled with the given project name.

The output shape matches what the platform returns so the same SDK tools that render project state (read_project) work identically against a local cluster.

func NewProjectReader

func NewProjectReader(k *kube.Client) *ProjectReader

func (*ProjectReader) ReadProjectElements

func (p *ProjectReader) ReadProjectElements(ctx context.Context, projectName string) (*sdktools.ProjectElements, error)

ReadProjectElements returns all flows and nodes in the given project.

type PublicModuleCatalog

type PublicModuleCatalog struct {
	// contains filtered or unexported fields
}

PublicModuleCatalog implements sdktools.PublicModuleCatalog by calling the Tiny Systems REST API at /v1/modules. When constructed without a dev key, only public modules are visible. With a dev key, the platform widens scope to include workspace-private modules owned by the key's workspace.

func NewPublicModuleCatalog

func NewPublicModuleCatalog(serverURL, devKey string) (*PublicModuleCatalog, error)

NewPublicModuleCatalog builds an adapter against the given server URL and optional dev key. Pass an empty devKey for anonymous access.

func (*PublicModuleCatalog) GetPublicModule

func (p *PublicModuleCatalog) GetPublicModule(ctx context.Context, name string) (*sdktools.PublicModuleDetails, error)

GetPublicModule calls GET /v1/modules/{name} and returns the full PublicModuleDetails payload. Returns nil (no error) on 404 so callers can distinguish "not found" from transport errors.

func (*PublicModuleCatalog) SearchModules

func (p *PublicModuleCatalog) SearchModules(ctx context.Context, keyword string, limit int) ([]sdktools.PublicModuleSummary, error)

SearchModules calls GET /v1/modules/search and returns summaries.

type PublicSolutionSearcher

type PublicSolutionSearcher struct {
	// contains filtered or unexported fields
}

PublicSolutionSearcher implements sdktools.SolutionSearcher by calling the Tiny Systems REST API at /v1/solutions. When constructed without a dev key, only public solutions are visible. With a dev key, the platform widens scope to include workspace-private solutions owned by the key's workspace.

func NewPublicSolutionSearcher

func NewPublicSolutionSearcher(serverURL, devKey string) (*PublicSolutionSearcher, error)

NewPublicSolutionSearcher builds an adapter against the given server URL and optional dev key. Pass an empty devKey for anonymous access.

func (*PublicSolutionSearcher) GetSolution

GetSolution calls GET /v1/solutions/{uuid} and returns the full details. Returns nil (no error) when the server reports 404 so callers can distinguish "not found" from transport errors.

func (*PublicSolutionSearcher) SearchSolutions

func (p *PublicSolutionSearcher) SearchSolutions(ctx context.Context, keyword string, tags []string, limit int) ([]sdktools.SolutionSummary, error)

SearchSolutions calls GET /v1/solutions/search and returns summaries. keyword and tags are both optional; limit is clamped by the server to [1, 100].

type ScenarioManager

type ScenarioManager struct {
	// contains filtered or unexported fields
}

ScenarioManager implements sdktools.ScenarioManager by CRUD'ing TinyScenario CRDs in the target namespace.

Scenarios are scoped per project via the project-name label. CreateScenarioFromTrace pins a real execution: it reads the trace's output-port spans through the TraceReader, redacts credential-shaped values (sample data lands in etcd and in exports — an agent flow's context carries the apiKey on every hop), and stores one port entry per span payload.

func NewScenarioManager

func NewScenarioManager(k *kube.Client, traces sdktools.TraceReader) *ScenarioManager

func (*ScenarioManager) CreateEmptyScenario

func (s *ScenarioManager) CreateEmptyScenario(ctx context.Context, projectName, name string) (*sdktools.ScenarioItem, error)

func (*ScenarioManager) CreateScenarioFromTrace

func (s *ScenarioManager) CreateScenarioFromTrace(ctx context.Context, projectName, name, traceID string) (*sdktools.ScenarioItem, error)

CreateScenarioFromTrace pins a trace as a scenario: one port entry per output-port span payload, secrets redacted before anything is persisted.

func (*ScenarioManager) DeleteScenario

func (s *ScenarioManager) DeleteScenario(ctx context.Context, projectName, resourceName string) error

func (*ScenarioManager) ListScenarios

func (s *ScenarioManager) ListScenarios(ctx context.Context, projectName string) ([]sdktools.ScenarioItem, error)

func (*ScenarioManager) UpdateScenarioPort

func (s *ScenarioManager) UpdateScenarioPort(ctx context.Context, projectName, resourceName, port string, data []byte) error

type SignalSender

type SignalSender struct {
	// contains filtered or unexported fields
}

SignalSender publishes signals via NATS. The TinySignal CRD fallback was removed alongside the SDK's v0.10.38 cleanup — the cluster's nats service must be reachable from this process for SendSignal to work. kube is kept on the struct because future adapters (port-forward setup, namespace lookups) need it.

func NewSignalSender

func NewSignalSender(k *kube.Client, nc *nats.Conn, connect func() *nats.Conn) *SignalSender

NewSignalSender takes the connection dialed at boot (may be nil) plus a connect func that (re)dials on demand.

Binding the connection once at boot made send_signal permanently dead whenever tiny started before the cluster's NATS was reachable — the common case when `tiny` runs against a cluster that is still provisioning, since nothing retries and the only cure was restarting the process. Dial lazily instead: a boot-time failure is no longer terminal, and a connection that drops later is re-established on the next signal.

func (*SignalSender) SendSignal

func (s *SignalSender) SendSignal(ctx context.Context, projectName, nodeID, portName string, data []byte, traceID string) error

SendSignal delivers data to <nodeID>:<portName> via NATS. traceID is accepted for compatibility with the tools.SignalSender interface but currently propagates through the OTel context only.

type TraceReader

type TraceReader struct {
	// contains filtered or unexported fields
}

TraceReader implements sdktools.TraceReader by port-forwarding to the in-cluster otel-collector and querying its gRPC statistics service.

The SDK already provides the full client (utils.TraceService) — this adapter just feeds it a PortForwarder and converts the SDK's trace-shaped responses to the tool-facing types.

func NewTraceReader

func NewTraceReader(opts TraceReaderOptions) (*TraceReader, error)

func (*TraceReader) Close

func (r *TraceReader) Close()

Close releases port-forward connections.

func (*TraceReader) ReadTraceDetail

func (r *TraceReader) ReadTraceDetail(ctx context.Context, projectName, traceID string) ([]sdktools.TraceSpanInfo, error)

ReadTraceDetail returns the full span list for a specific trace.

func (*TraceReader) ReadTraceSpans

func (r *TraceReader) ReadTraceSpans(ctx context.Context, projectName, traceID string) ([]utils.Span, error)

ReadTraceSpans returns the trace's raw spans (with absolute timing and attributes intact), for callers that render a waterfall rather than the tool-facing summary. The editor's Statistics service uses this so span start/end times survive the mapping.

func (*TraceReader) ReadTraces

func (r *TraceReader) ReadTraces(ctx context.Context, projectName, flowName string, lookback time.Duration, offset, limit int) ([]sdktools.TraceSummary, error)

ReadTraces returns traces for the given project/flow within the lookback window.

type TraceReaderOptions

type TraceReaderOptions struct {
	KubeClient  *kube.Client
	ServiceName string // e.g. "tinysystems-otel-collector"
	ServicePort int    // e.g. 2345
}

TraceReaderOptions configures how the reader reaches the otel-collector.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL