Skip to main content

Harness stream parts

An adapter emits harness.StreamPart values while a turn runs. harness.Agent translates them into provider.StreamChunk values for ai.NewStreamTextResultFromParts, so a harness turn streams like a StreamText call. Each part marshals to the JSON shape of the TypeScript HarnessV1StreamPart, so parts persisted by one SDK decode in the other.

The adapter interface is in Harness adapters.

Part types​

StreamPart.PartType() returns the type discriminator. The harness.PartType* constants hold the values.

ConstanttypeGo typeDescription
harness.PartTypeStreamStartstream-start*harness.StreamStartPartStart of a turn.
harness.PartTypeTextStarttext-start*harness.TextStartPartA text block opens.
harness.PartTypeTextDeltatext-delta*harness.TextDeltaPartA piece of text.
harness.PartTypeTextEndtext-end*harness.TextEndPartA text block closes.
harness.PartTypeReasoningStartreasoning-start*harness.ReasoningStartPartA reasoning block opens.
harness.PartTypeReasoningDeltareasoning-delta*harness.ReasoningDeltaPartA piece of reasoning.
harness.PartTypeReasoningEndreasoning-end*harness.ReasoningEndPartA reasoning block closes.
harness.PartTypeToolInputStarttool-input-start*harness.ToolInputStartPartTool input starts streaming.
harness.PartTypeToolInputDeltatool-input-delta*harness.ToolInputDeltaPartA piece of tool input.
harness.PartTypeToolInputEndtool-input-end*harness.ToolInputEndPartTool input is complete.
harness.PartTypeToolCalltool-call*harness.ToolCallPartA tool call. Carries nativeName and stepToolCallCount in addition to the model tool call fields.
harness.PartTypeToolApprovalRequesttool-approval-request*harness.ToolApprovalRequestPartThe runtime asks for approval.
harness.PartTypeToolResulttool-result*harness.ToolResultPartA tool result.
harness.PartTypeFinishStepfinish-step*harness.FinishStepPartEnd of a step inside a turn.
harness.PartTypeFinishfinish*harness.FinishPartEnd of the turn.
harness.PartTypeFileChangefile-change*harness.FileChangePartA workspace change made through an opaque mechanism.
harness.PartTypeCompactioncompaction*harness.CompactionPartThe runtime compacted its context.
harness.PartTypeErrorerror*harness.ErrorPartAn error.
harness.PartTypeRawraw*harness.RawPartAdapter-specific passthrough.

Fields​

FieldTypeDescription
Warnings[]CallWarning
ModelIDstringModelID is the model the runtime resolved to for this turn, when known.
FieldTypeDescription
IDstring
Deltastring
HarnessMetadataMetadata
FieldTypeDescription
ToolCallIDstring
ToolNamestring
InputstringInput is the stringified JSON tool input.
ProviderExecutedboolProviderExecuted is true for runtime-executed builtins.
Dynamicbool
ProviderMetadataProviderMetadata
NativeNamestringNativeName is the runtime's native name when it differs from ToolName.
StepToolCallCount*intStepToolCallCount is the total tool calls in the current model step, when known up front. Must be a positive integer when set.
FieldTypeDescription
ApprovalIDstring
ToolCallIDstring
ProviderMetadataProviderMetadata
FieldTypeDescription
ToolCallIDstring
ToolNamestring
Resultany
IsErrorbool
Preliminarybool
Dynamicbool
ProviderMetadataProviderMetadata
FieldTypeDescription
FinishReasonFinishReason
UsageUsage
HarnessMetadataMetadata
FieldTypeDescription
FinishReasonFinishReason
TotalUsageUsage
HarnessMetadataMetadata
FieldTypeDescription
Eventstring
Pathstring
HarnessMetadataMetadata
FieldTypeDescription
Triggerstring
Summarystring
TokensBefore*float64
TokensAfter*float64
HarnessMetadataMetadata
FieldTypeDescription
Errorany
FieldTypeDescription
RawValueany

The block parts all carry an id. Text and reasoning parts also carry harnessMetadata, and the delta parts add a delta string. The tool input parts carry providerMetadata. harness.ToolInputStartPart adds toolName, providerExecuted, dynamic and title. These parts are harness.TextStartPart, harness.TextEndPart, harness.ReasoningStartPart, harness.ReasoningDeltaPart, harness.ReasoningEndPart, harness.ToolInputStartPart, harness.ToolInputDeltaPart and harness.ToolInputEndPart.

Constants​

GroupValues
File change kindsharness.FileChangeCreate, harness.FileChangeModify, harness.FileChangeDelete
Compaction triggersharness.CompactionTriggerManual, harness.CompactionTriggerAuto
Finish reasonsharness.FinishReasonStop, harness.FinishReasonLength, harness.FinishReasonContentFilter, harness.FinishReasonToolCalls, harness.FinishReasonError, harness.FinishReasonOther

Usage​

harness.FinishReason is the harness wire encoding of the model finish reason. harness.Usage is the wire encoding of model usage, with harness.InputTokenUsage and harness.OutputTokenUsage for the token breakdowns.

FieldTypeDescription
InputTokensInputTokenUsage
OutputTokensOutputTokenUsage
Rawmap[string]any
FieldTypeDescription
Total*int
NoCache*int
CacheRead*int
CacheWrite*int
FieldTypeDescription
Total*int
Text*int
Reasoning*int

harness.Metadata is adapter-namespaced opaque data attached to events, keyed by harness ID. harness.ProviderMetadata is the provider metadata shape on tool parts.

Translation​

func TranslatePart(part StreamPart, opts TranslateOptions) []provider.StreamChunk

Converts one part to zero or more chunks. Most parts map one to one. These are the exceptions:

  • tool-call is not translated here. harness.Agent validates it against the merged tool set first.
  • A failed tool-result from a provider-executed tool becomes a tool result with an error.
  • file-change and compaction have no chunk type of their own. Each becomes a dynamic, provider-executed tool call and tool result pair named fileChange or compaction, so the event stays visible.
  • stream-start, finish-step and finish return nil. harness.Agent owns step and turn boundaries.
FieldTypeDescription
IsProviderExecutedfunc(toolCallID string) boolIsProviderExecuted reports whether the tool call that produced a tool-result event ran inside the harness runtime. Host results are echoed back as tool-result events too, so the event alone cannot say who ran the tool — only the originating tool-call can, and correlating the two is the caller's job (run_prompt.go tracks it). A nil func treats every failure as provider-executed, matching TS's ?? true default.

JSON helpers​

FunctionDescription
harness.DecodeStreamPart(data []byte) (StreamPart, error)Parses and validates one JSON part. Returns harness.ErrUnknownPartType for an unknown type.
harness.MarshalStreamPart(part StreamPart) ([]byte, error)Encodes a part with type as the first key.
harness.IsStreamPartType(typ string) boolReports whether typ is a part discriminator.
harness.MarshalTagged(typ string, v any) ([]byte, error)Encodes a struct as a JSON object with "type" first.
harness.ReadTagged(data []byte) (string, map[string]json.RawMessage, error)Returns the type and the raw top-level fields of a JSON object.
harness.RequireKeys(typ string, fields map[string]json.RawMessage, required []string) errorChecks that the required keys are present.
harness.StripWorkDir(part StreamPart, sessionWorkDir string) StreamPartReturns a copy of the part with the session work directory removed from path fields.
harness.EmitFuncfunc(part StreamPart). Receives every part an adapter produces during a turn.
harness.AgentStreamPartConsumer-facing alias of StreamPart.