output

package
v1.19.1 Latest Latest
Warning

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

Go to latest
Published: Jul 24, 2026 License: Apache-2.0 Imports: 9 Imported by: 0

Documentation

Overview

Package output is Harbor's structured-output strategy + downgrade chain (RFC §6.5).

The wrapper sits OUTSIDE the corrections layer:

Open() → retry(downgrade(corrections(safety(driver))))

— a settled ordering. Reasoning: a downgrade rewrites the request's `ResponseFormat` (e.g. `json_schema` → `json_object`); the corrections layer must re-apply its per-provider envelope shaping on the rewritten request, so corrections compose INSIDE downgrade. The safety net sees the final outgoing payload (post-corrections, post-downgrade) on each attempt.

Three Harbor-side strategies make up `OutputMode`:

  1. `OutputModeNative` — pass `FormatJSONSchema` through. The provider enforces strict schema mode (OpenAI / Anthropic / etc).
  2. `OutputModeTools` — encode the schema into a *Harbor-side prompted* envelope `{"name":"respond_with","arguments":{...}}`. The runtime parses the response locally. **This is NOT provider-native tool-calling** — the static guard against bifrost's provider tool-call API symbols extends to this package (see the package's static smoke guard).
  3. `OutputModePrompted` — coerce `FormatJSONObject` and append the schema as a system-prompt instruction.

The downgrade chain is `current → next` on `llm.IsInvalidJSONSchemaError(err)`. Order:

Native → Prompted → Text   (max 3 attempts including the initial)
Tools → Prompted → Text
Prompted → Text            (already 2-step)

Each downgrade emits `llm.mode_downgraded` with identity + From / To / Reason; exhausting the chain surfaces `ErrDowngradeExhausted` wrapping the underlying failure.

Concurrent-reuse: the wrapper is stateless across calls. A `Wrap` returns a value holding the inner `LLMClient`, the snapshot, and the bus reference; all are read-only after construction.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ParseRespondWith added in v1.9.0

func ParseRespondWith(content string) (json.RawMessage, bool)

ParseRespondWith is the READ half of the `OutputModeTools` structured-output envelope (the write half is `renderToolsEnvelopeInstruction`). It attempts to unwrap content as a `{"name":"respond_with","arguments":<args>}` JSON object and, on a match, returns the nested `arguments` payload verbatim (its own raw bytes — no lossy re-encode) with ok=true.

Returns ok=false — never an error — when content does not parse as the envelope shape (malformed JSON, a JSON value that isn't an object, a `name` field other than "respond_with", or a missing `arguments` field): the caller's contract is "unwrap when possible, pass through unchanged otherwise", so a non-envelope response (the common case for Native/Prompted profiles, or a model that ignored the Tools-mode instruction) is not an error condition here — the caller decides what to do with the original content.

This closes the seam `shapeRequestForMode`'s OutputModeTools branch opened one-sided: the downgrade layer instructs the model to emit the envelope, but nothing parsed it back until this function existed, which meant a Tools-mode profile's schema Validator (and the terminal Finish payload) saw the ENVELOPE `{"name":...,"arguments":...}` instead of the caller's schema-shaped `arguments` — guaranteed validation failure even against a perfectly schema-compliant model.

func Wrap

func Wrap(inner llm.LLMClient, cfg llm.ConfigSnapshot, deps llm.Deps) llm.LLMClient

Wrap composes the downgrade chain on top of `inner`. The returned client wraps each `Complete` invocation in a per-attempt `ResponseFormat` rewrite + classifier check.

Nil `inner` panics — composition error caught at boot.

Types

This section is empty.

Jump to

Keyboard shortcuts

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