assemble

package
v1.8.0 Latest Latest
Warning

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

Go to latest
Published: Jun 27, 2026 License: Apache-2.0 Imports: 1 Imported by: 0

Documentation

Overview

Package assemble is the public SDK facade over Harbor's internal/runtime/assemble package — the ONE composition fan-out that turns a validated config into a running headless stack (RFC §3.6, §6.4; D-204/D-197). Alias-based re-exports only: no behavior lives here. Blank-import sdk/drivers/prod alongside this package so every Open the assembly performs resolves the production driver set; see docs/recipes/embed-harbor-headless.md for the full embedding walkthrough.

Example

Example shows the golden one-call path: Assemble composes a headless runtime from a validated config, and Stack.RunOnce turns a goal plus the mandatory (tenant, user, session) identity triple into a terminal answer envelope in a single blocking call.

package main

import (
	"context"
	"fmt"
	"log"

	// Production driver aggregator — the SAME sdk-facade blank import a
	// headless embedder adds (see docs/recipes/embed-harbor-headless.md)
	// so every Open the assembly performs resolves the production driver
	// set. Copyable as-is: it stays inside the sdk facade.

	// Dev-only mock LLM (D-089): explicit opt-in, never in the aggregator,
	// and deliberately has no sdk facade. It is imported here ONLY to keep
	// the example deterministic and offline; a real deployment configures a
	// real provider in harbor.yaml and drops this import.

	"github.com/hurtener/Harbor/sdk/assemble"
	"github.com/hurtener/Harbor/sdk/config"
	_ "github.com/hurtener/Harbor/sdk/drivers/prod"
	"github.com/hurtener/Harbor/sdk/identity"

	_ "github.com/hurtener/Harbor/internal/llm/mock"
)

// mockRunnableConfig builds the canonical baseline configuration and
// points the LLM seam at the deterministic, offline mock driver. It
// keeps the example bodies focused on the one-call run surface.
func mockRunnableConfig() *config.Config {
	cfg := config.Defaults()
	cfg.Telemetry.LogLevel = "error"
	cfg.LLM.Driver = "mock"
	cfg.LLM.Model = "mock/echo"
	cfg.LLM.ModelProfiles = map[string]config.LLMModelProfileConfig{
		"mock/echo": {ContextWindowTokens: 100000, TokenEstimator: "chars_div_4"},
	}
	return cfg
}

func main() {
	ctx := context.Background()

	cfg := mockRunnableConfig()
	stack, err := assemble.Assemble(ctx, cfg, assemble.Options{})
	if err != nil {
		log.Fatalf("assemble: %v", err)
	}
	defer func() { _ = stack.Close(ctx) }()

	id := identity.Identity{TenantID: "acme", UserID: "u-1", SessionID: "s-1"}
	env, err := stack.RunOnce(ctx, "Summarise the deployment status.", id)
	if err != nil {
		fmt.Println("run:", err)
		return
	}

	fmt.Println(env.FinishReason)
}
Output:
goal
Example (Streaming)

Example_streaming shows RunOnce driving the same run while a WithStream sink observes its StreamEvents — token deltas, planner-step boundaries, and tool dispatches — as they occur. RunOnce still blocks and returns the same terminal envelope; the sink fires synchronously on the run goroutine, so every StreamEvent arrives before RunOnce returns. Here the sink reassembles the streamed content tokens, which reproduce the final answer exactly.

package main

import (
	"context"
	"fmt"
	"log"
	"strings"

	// Production driver aggregator — the SAME sdk-facade blank import a
	// headless embedder adds (see docs/recipes/embed-harbor-headless.md)
	// so every Open the assembly performs resolves the production driver
	// set. Copyable as-is: it stays inside the sdk facade.

	// Dev-only mock LLM (D-089): explicit opt-in, never in the aggregator,
	// and deliberately has no sdk facade. It is imported here ONLY to keep
	// the example deterministic and offline; a real deployment configures a
	// real provider in harbor.yaml and drops this import.

	"github.com/hurtener/Harbor/sdk/assemble"
	"github.com/hurtener/Harbor/sdk/config"
	_ "github.com/hurtener/Harbor/sdk/drivers/prod"
	"github.com/hurtener/Harbor/sdk/identity"

	_ "github.com/hurtener/Harbor/internal/llm/mock"
)

// mockRunnableConfig builds the canonical baseline configuration and
// points the LLM seam at the deterministic, offline mock driver. It
// keeps the example bodies focused on the one-call run surface.
func mockRunnableConfig() *config.Config {
	cfg := config.Defaults()
	cfg.Telemetry.LogLevel = "error"
	cfg.LLM.Driver = "mock"
	cfg.LLM.Model = "mock/echo"
	cfg.LLM.ModelProfiles = map[string]config.LLMModelProfileConfig{
		"mock/echo": {ContextWindowTokens: 100000, TokenEstimator: "chars_div_4"},
	}
	return cfg
}

func main() {
	ctx := context.Background()

	cfg := mockRunnableConfig()
	stack, err := assemble.Assemble(ctx, cfg, assemble.Options{})
	if err != nil {
		log.Fatalf("assemble: %v", err)
	}
	defer func() { _ = stack.Close(ctx) }()

	var streamed strings.Builder
	sink := func(e assemble.StreamEvent) {
		// Content deltas only — skip reasoning tokens and non-token events.
		if e.Kind == assemble.StreamToken && !e.Reasoning {
			streamed.WriteString(e.Text)
		}
	}

	id := identity.Identity{TenantID: "acme", UserID: "u-1", SessionID: "s-1"}
	env, err := stack.RunOnce(ctx, "Ping.", id, assemble.WithStream(sink))
	if err != nil {
		fmt.Println("run:", err)
		return
	}

	fmt.Println(streamed.String() == env.Answer)
}
Output:
true

Index

Examples

Constants

View Source
const (
	StreamToken          = internal.StreamToken
	StreamToolDispatched = internal.StreamToolDispatched
	StreamStep           = internal.StreamStep
)

Streaming-sink event kinds: StreamToken (incremental output delta), StreamToolDispatched (a tool was dispatched), StreamStep (a planner-step boundary).

Variables

View Source
var Assemble = internal.Assemble

Assemble composes the full dependency-ordered runtime from a validated config, with partial-failure cleanup (a failed Assemble returns the partial Stack so the caller can drain it via Close).

View Source
var DefaultMCPIdentity = internal.DefaultMCPIdentity

DefaultMCPIdentity is the fallback transport-event identity for attached MCP servers.

View Source
var ErrNotRunnable = internal.ErrNotRunnable

ErrNotRunnable is returned by Stack.RunOnce when the stack was assembled without a planner/run loop (no LLM driver, or SkipSteering/SkipRunLoop). Compare via errors.Is.

View Source
var WithInputArtifacts = internal.WithInputArtifacts

WithInputArtifacts pre-resolves operator-uploaded artifact IDs into the run's first-turn multimodal inputs.

View Source
var WithRunID = internal.WithRunID

WithRunID pins the run's RunID instead of synthesising a fresh ULID.

View Source
var WithStream = internal.WithStream

WithStream registers a per-run streaming sink on a RunOnce invocation. RunOnce still blocks and returns the terminal answer envelope; the sink receives StreamEvents synchronously on the run goroutine, so every event arrives before RunOnce returns.

Functions

This section is empty.

Types

type Options

type Options = internal.Options

Options carries Assemble's injection points (logger, LLM snapshot override, planner override, skip knobs).

type RunOption added in v1.8.0

type RunOption = internal.RunOption

RunOption configures a Stack.RunOnce invocation. The functional-option shape keeps RunOnce's signature stable as new per-run knobs land.

type Stack

type Stack = internal.Stack

Stack is the composed runtime bundle Assemble returns (stores, bus, LLM, memory, skills, tasks, catalog, executor, planner, run loop) with reverse-order Close.

type StreamEvent added in v1.8.0

type StreamEvent = internal.StreamEvent

StreamEvent is one observation a WithStream sink receives while RunOnce drives a run — a token delta, a planner-step boundary, or a tool dispatch. Minimal by design: progress signals only, never raw tool arguments or results.

type StreamEventKind added in v1.8.0

type StreamEventKind = internal.StreamEventKind

StreamEventKind is the sealed enum discriminating a StreamEvent (token / tool_dispatched / step).

Jump to

Keyboard shortcuts

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