package openai import ( "context" "encoding/json" "fmt" "net/http" "strings" "sync" ) const defaultArtifactFrontierCapacity = 1024 type artifactFrontierPhase string const ( artifactPhasePinned artifactFrontierPhase = "pinned" artifactPhasePreparePending artifactFrontierPhase = "prepare_pending" artifactPhasePairReady artifactFrontierPhase = "pair_ready" artifactPhasePairPending artifactFrontierPhase = "pair_pending" artifactPhaseLocalEligible artifactFrontierPhase = "local_eligible" ) type artifactDispositionKind string const ( artifactDispositionResumeSelector artifactDispositionKind = "resume_selector" artifactDispositionLocalEligible artifactDispositionKind = "local_eligible" ) type artifactDisposition struct { Kind artifactDispositionKind SelectorStageID string PrimaryError *hotPathEndpointError } // presetIngressResult carries a control decision that the public handler must // consume before it can construct or submit another provider-pool request. // It deliberately keeps the artifact disposition out of caller-controlled // metadata, which is only a transport for trusted logical request IDs. type presetIngressResult struct { Artifact artifactDisposition Light hotPathLightDisposition Cleanup *hotPathCleanupTurn Terminal *hotPathTerminalIntent } func (r presetIngressResult) localStageEligible() bool { return r.Artifact.Kind == artifactDispositionLocalEligible } func (r presetIngressResult) lightStageContinuation() bool { return r.Light.RequestID != "" && r.Light.Terminal == nil } func (r presetIngressResult) cleanupIssued() bool { return r.Cleanup != nil } func (r presetIngressResult) terminalReady() bool { return r.Terminal != nil } type artifactFrontierRecord struct { requestID string ownerEdgeID string principalRef string protocol string selectorStageID string lineage logicalRequestLineage binding *workspaceBinding phase artifactFrontierPhase pending map[string]*workspaceEncodedPayload pendingHash string consumedHashes map[string]struct{} consumedIDs map[string]struct{} } // artifactFrontierStore owns the request-local workspace binding and the sole // prepare/pair receipt frontier. Its fixed capacity prevents abandoned caller // continuations from growing Edge-local state without bound. type artifactFrontierStore struct { mu sync.Mutex capacity int records map[string]*artifactFrontierRecord } func newArtifactFrontierStore(capacity int) *artifactFrontierStore { if capacity <= 0 { capacity = defaultArtifactFrontierCapacity } return &artifactFrontierStore{capacity: capacity, records: make(map[string]*artifactFrontierRecord)} } func (s *artifactFrontierStore) pin( requestID, ownerEdgeID, principalRef, protocol, selectorStageID string, lineage logicalRequestLineage, binding *workspaceBinding, ) error { if s == nil || binding == nil { return fmt.Errorf("artifact frontier binding is unavailable") } if !validLogicalRequestID(requestID) || !validLogicalRequestID(selectorStageID) { return fmt.Errorf("artifact frontier identity is invalid") } if strings.TrimSpace(ownerEdgeID) == "" || strings.TrimSpace(principalRef) == "" { return fmt.Errorf("artifact frontier owner and principal are required") } if !artifactProtocolMatchesLineage(protocol, lineage) { return fmt.Errorf("artifact frontier protocol does not match request lineage") } s.mu.Lock() defer s.mu.Unlock() if _, exists := s.records[requestID]; exists { return fmt.Errorf("artifact frontier already exists") } if len(s.records) >= s.capacity { return fmt.Errorf("artifact frontier capacity reached") } s.records[requestID] = &artifactFrontierRecord{ requestID: requestID, ownerEdgeID: ownerEdgeID, principalRef: principalRef, protocol: protocol, selectorStageID: selectorStageID, lineage: lineage, binding: binding, phase: artifactPhasePinned, consumedHashes: make(map[string]struct{}), consumedIDs: make(map[string]struct{}), } return nil } func artifactProtocolMatchesLineage(protocol string, lineage logicalRequestLineage) bool { switch protocol { case "openai": return lineage.Endpoint == logicalRequestEndpointChat case "anthropic": return lineage.Endpoint == logicalRequestEndpointAnthropic default: return false } } func (s *artifactFrontierStore) remove(requestID, ownerEdgeID string) { if s == nil || requestID == "" { return } s.mu.Lock() defer s.mu.Unlock() if record := s.records[requestID]; record != nil && record.ownerEdgeID == ownerEdgeID { delete(s.records, requestID) } } func (s *artifactFrontierStore) has(requestID, ownerEdgeID string) bool { if s == nil || requestID == "" { return false } s.mu.Lock() defer s.mu.Unlock() record := s.records[requestID] return record != nil && record.ownerEdgeID == ownerEdgeID } // pairRequired reports whether the retained selector may only author the // exact Plan/Review pair. The store owns the phase and keeps this observation // lock-safe so a handler cannot infer it from untrusted request metadata. func (s *artifactFrontierStore) pairRequired(requestID, ownerEdgeID string) bool { if s == nil || requestID == "" { return false } s.mu.Lock() defer s.mu.Unlock() record := s.records[requestID] return record != nil && record.ownerEdgeID == ownerEdgeID && record.phase == artifactPhasePairReady } func (s *artifactFrontierStore) issue( turn *hotPathTurn, output normalizedStageOutput, coordinator *logicalRequestCoordinator, ) (normalizedStageOutput, error) { if s == nil || coordinator == nil || turn == nil { return normalizedStageOutput{}, fmt.Errorf("artifact frontier is unavailable") } s.mu.Lock() defer s.mu.Unlock() record := s.records[turn.RequestID] if record == nil { return normalizedStageOutput{}, fmt.Errorf("artifact frontier is not pinned") } if record.ownerEdgeID != turn.OwnerEdgeID || record.principalRef != turn.PrincipalRef { return normalizedStageOutput{}, fmt.Errorf("artifact frontier owner or principal mismatch") } if record.protocol != turn.Protocol || record.selectorStageID != turn.StageID { return normalizedStageOutput{}, fmt.Errorf("artifact frontier selector stage mismatch") } wantPrepare := false switch record.phase { case artifactPhasePinned: wantPrepare = !record.binding.createsParents() case artifactPhasePairReady: wantPrepare = false default: return normalizedStageOutput{}, fmt.Errorf("artifact frontier already has a pending or consumed turn") } mapped, payloads, err := mapArtifactOutput(record, output, wantPrepare, coordinator) if err != nil { return normalizedStageOutput{}, err } if turn.Protocol == "anthropic" { mapped.TerminalReason = "tool_use" } if turn.OuterTurn != nil { ctx := context.Background() if turn.Request != nil { ctx = turn.Request.Context() } if !output.ProgressivelyReleased { if err := runHotPathCollectedStage(ctx, turn.OuterTurn, turn.StageID, mapped); err != nil { return normalizedStageOutput{}, fmt.Errorf("collect artifact outer turn: %w", err) } } visible := hotPathCompatibilityOutput(turn.OuterTurn, mapped, turn.Protocol) if len(visible.ToolCalls) == 0 && turn.OuterTurn.outputBudget().Exhausted { turn.OuterTurn.commitLengthTerminal() return hotPathCompatibilityOutput(turn.OuterTurn, mapped, turn.Protocol), nil } if err := turn.OuterTurn.projectToolIdentities(mapped.ToolCalls); err != nil { return normalizedStageOutput{}, err } mapped = hotPathCompatibilityOutput(turn.OuterTurn, mapped, turn.Protocol) } issuedHash, err := directIssuedCallHash(turn.Protocol, mapped) if err != nil { return normalizedStageOutput{}, fmt.Errorf("fingerprint artifact calls: %w", err) } expected := make([]logicalRequestExpectedTool, 0, len(mapped.ToolCalls)) for _, call := range mapped.ToolCalls { expected = append(expected, logicalRequestExpectedTool{ PublicCallID: call.ID, ProviderCallID: call.ProviderCallID, }) } if _, err := coordinator.awaitToolResults( turn.RequestID, turn.OwnerEdgeID, turn.StageID, expected, issuedHash, ); err != nil { return normalizedStageOutput{}, fmt.Errorf("await artifact results: %w", err) } record.pending = payloads record.pendingHash = issuedHash if wantPrepare { record.phase = artifactPhasePreparePending } else { record.phase = artifactPhasePairPending } return mapped, nil } func mapArtifactOutput( record *artifactFrontierRecord, output normalizedStageOutput, wantPrepare bool, coordinator *logicalRequestCoordinator, ) (normalizedStageOutput, map[string]*workspaceEncodedPayload, error) { issued := newReservedPaths(record.requestID) calls := append([]normalizedToolCall(nil), output.ToolCalls...) if wantPrepare { if len(calls) != 1 { return normalizedStageOutput{}, nil, fmt.Errorf("artifact prepare turn must contain exactly one call") } mapped, payload, err := mapArtifactCall(record.binding, calls[0], opKindPrepare, issued.JobDir, coordinator) if err != nil { return normalizedStageOutput{}, nil, err } return artifactResponseOutput(output, []normalizedToolCall{mapped}), map[string]*workspaceEncodedPayload{mapped.ID: payload}, nil } if len(calls) != 2 { return normalizedStageOutput{}, nil, fmt.Errorf("artifact pair turn must contain exactly two calls") } byPath := make(map[string]normalizedToolCall, len(calls)) for _, call := range calls { paths := reservedPathsFromToolCall(call) if len(paths) != 1 { return normalizedStageOutput{}, nil, fmt.Errorf("artifact pair call has an ambiguous reserved path") } clean := cleanRelativePath(paths[0]) if _, duplicate := byPath[clean]; duplicate { return normalizedStageOutput{}, nil, fmt.Errorf("artifact pair contains a duplicate path") } byPath[clean] = call } orderedPaths := []string{issued.PlanPath, issued.ReviewPath} mappedCalls := make([]normalizedToolCall, 0, 2) payloads := make(map[string]*workspaceEncodedPayload, 2) for _, requiredPath := range orderedPaths { call, ok := byPath[cleanRelativePath(requiredPath)] if !ok { return normalizedStageOutput{}, nil, fmt.Errorf("artifact pair is missing reserved path %q", requiredPath) } mapped, payload, err := mapArtifactCall(record.binding, call, opKindWrite, requiredPath, coordinator) if err != nil { return normalizedStageOutput{}, nil, err } mappedCalls = append(mappedCalls, mapped) payloads[mapped.ID] = payload } return artifactResponseOutput(output, mappedCalls), payloads, nil } func mapArtifactCall( binding *workspaceBinding, providerCall normalizedToolCall, operation workspaceOperationKind, requiredPath string, coordinator *logicalRequestCoordinator, ) (normalizedToolCall, *workspaceEncodedPayload, error) { providerID := strings.TrimSpace(providerCall.ProviderCallID) if providerID == "" { providerID = strings.TrimSpace(providerCall.ID) } if !validLogicalRequestID(providerID) { return normalizedToolCall{}, nil, fmt.Errorf("artifact provider tool id is invalid") } publicID, err := coordinator.newCallID() if err != nil { return normalizedToolCall{}, nil, fmt.Errorf("allocate artifact public tool id: %w", err) } providerCall.ID = publicID providerCall.ProviderCallID = providerID payload, err := encodeWorkspaceCall(binding, operation, providerCall) if err != nil { return normalizedToolCall{}, nil, fmt.Errorf("encode artifact %s call: %w", operation, err) } if payload.safePath != cleanRelativePath(requiredPath) { return normalizedToolCall{}, nil, fmt.Errorf("artifact call targets %q, want %q", payload.safePath, requiredPath) } rawArgs, err := json.Marshal(payload.structuredArgs) if err != nil { return normalizedToolCall{}, nil, fmt.Errorf("encode artifact arguments: %w", err) } mapped := normalizedToolCall{ ID: publicID, ProviderCallID: providerID, Name: payload.toolName, Arguments: cloneAnyMap(payload.structuredArgs), RawArgs: string(rawArgs), Path: payload.safePath, } return mapped, payload, nil } func artifactResponseOutput(source normalizedStageOutput, calls []normalizedToolCall) normalizedStageOutput { return normalizedStageOutput{ ResponseID: source.ResponseID, Created: source.Created, Content: source.Content, Reasoning: source.Reasoning, ReasoningSignature: source.ReasoningSignature, ToolCalls: calls, TerminalReason: "tool_calls", Usage: cloneRawJSON(source.Usage), OpenAIUsage: source.OpenAIUsage, } } func (s *Server) runArtifactPairTurn(turn *hotPathTurn, output normalizedStageOutput, gate hotPathSelectorGate) error { if turn == nil { return fmt.Errorf("artifact turn is unavailable") } if strings.TrimSpace(turn.PrincipalRef) == "" { turn.PrincipalRef = strings.TrimSpace(turn.Dispatch.PrincipalRef) if turn.PrincipalRef == "" { turn.PrincipalRef = "anonymous" } } mapped, err := s.artifactFrontiers.issue(turn, output, s.requestCoordinator) if err != nil { s.terminalPresetRequest(turn.RequestID, turn.OwnerEdgeID) return s.writeDirectError(turn, 400, "invalid_request_error", fmt.Sprintf("artifact turn rejected: %v", err)) } if turn.OuterTurn != nil && len(mapped.ToolCalls) == 0 && turn.OuterTurn.outputBudget().Exhausted { s.terminalPresetRequest(turn.RequestID, turn.OwnerEdgeID) return s.writeDirectResponse(turn, mapped) } if s.lightFlows.has(turn.RequestID, turn.OwnerEdgeID) { if err := s.lightFlows.commitSelector(turn.RequestID, turn.OwnerEdgeID, output, gate); err != nil { s.terminalPresetRequest(turn.RequestID, turn.OwnerEdgeID) return s.writeDirectError(turn, 400, "invalid_request_error", fmt.Sprintf("light selector commit rejected: %v", err)) } } if turn.OuterTurn != nil { turn.OuterTurn.commitTerminalSuccess(mapped.TerminalReason) mapped = hotPathCompatibilityOutput(turn.OuterTurn, mapped, turn.Protocol) } if err := s.writeDirectResponse(turn, mapped); err != nil { s.terminalPresetRequest(turn.RequestID, turn.OwnerEdgeID) return err } return nil } func (s *Server) applyArtifactDisposition( snap logicalRequestSnapshot, disposition artifactDisposition, metadata map[string]string, ) error { if metadata == nil { return fmt.Errorf("artifact continuation metadata is unavailable") } callID, err := s.requestCoordinator.newCallID() if err != nil { return err } metadata["iop_logical_request_id"] = snap.ID metadata["iop_call_id"] = callID metadata["iop_stage_id"] = disposition.SelectorStageID return nil } func (s *artifactFrontierStore) consumeChat( ownerEdgeID, principalRef string, rawBody []byte, lineage logicalRequestContinuationLineage, coordinator *logicalRequestCoordinator, lightFlows *hotPathLightStore, ) (logicalRequestSnapshot, artifactDisposition, bool, error) { results, err := decodeChatWorkspaceResults(rawBody) if err != nil { return logicalRequestSnapshot{}, artifactDisposition{}, true, err } return s.consume(ownerEdgeID, principalRef, "openai", lineage, results, coordinator, lightFlows) } func (s *artifactFrontierStore) consumeAnthropic( ownerEdgeID, principalRef string, rawBody []byte, lineage logicalRequestContinuationLineage, coordinator *logicalRequestCoordinator, lightFlows *hotPathLightStore, ) (logicalRequestSnapshot, artifactDisposition, bool, error) { results, err := decodeAnthropicWorkspaceResults(rawBody) if err != nil { return logicalRequestSnapshot{}, artifactDisposition{}, true, err } return s.consume(ownerEdgeID, principalRef, "anthropic", lineage, results, coordinator, lightFlows) } func (s *artifactFrontierStore) consume( ownerEdgeID, principalRef, protocol string, lineage logicalRequestContinuationLineage, results []workspaceResult, coordinator *logicalRequestCoordinator, lightFlows *hotPathLightStore, ) (logicalRequestSnapshot, artifactDisposition, bool, error) { if s == nil || coordinator == nil { return logicalRequestSnapshot{}, artifactDisposition{}, false, nil } s.mu.Lock() defer s.mu.Unlock() record, matched, err := s.matchRecordLocked(ownerEdgeID, principalRef, protocol, lineage) if !matched || err != nil { return logicalRequestSnapshot{}, artifactDisposition{}, matched, err } if record.pending == nil || record.pendingHash == "" { return logicalRequestSnapshot{}, artifactDisposition{}, true, fmt.Errorf("artifact frontier has no pending calls") } if len(results) != len(record.pending) { return logicalRequestSnapshot{}, artifactDisposition{}, true, fmt.Errorf("artifact result set size mismatch") } seen := make(map[string]struct{}, len(results)) var primaryFailure *hotPathEndpointError for _, result := range results { payload := record.pending[result.callID] if payload == nil { return logicalRequestSnapshot{}, artifactDisposition{}, true, fmt.Errorf("artifact result id is not in the pending frontier") } if _, duplicate := seen[result.callID]; duplicate { return logicalRequestSnapshot{}, artifactDisposition{}, true, fmt.Errorf("artifact result id is duplicated") } seen[result.callID] = struct{}{} receipt := matchResultReceipt(record.binding, payload, result) if !receipt.matched { // A valid request lineage, pending call, and immutable issue // correlation route an exact receipt-matcher failure to primary // cleanup without trusting the result as a success. An invalid issue // correlation, or an opaque/malformed result that is not an exact // caller report, stays an immediate fail-closed rejection. if matchResultCorrelation(record.binding, payload, result) != "" || !workspaceResultIsExact(result) { return logicalRequestSnapshot{}, artifactDisposition{}, true, fmt.Errorf("artifact receipt rejected: %s", receipt.mismatchReason) } if primaryFailure == nil { primaryFailure = &hotPathEndpointError{ Status: http.StatusBadRequest, Type: "invalid_request_error", Message: "artifact continuation rejected: artifact receipt rejected: " + receipt.mismatchReason, } } continue } } if primaryFailure != nil && (lightFlows == nil || !lightFlows.has(record.requestID, record.ownerEdgeID)) { return logicalRequestSnapshot{}, artifactDisposition{}, true, fmt.Errorf("artifact receipt rejected: result contains an explicit error signal") } snap, err := coordinator.consumeContinuationByLineage(ownerEdgeID, principalRef, lineage) if err != nil { return logicalRequestSnapshot{}, artifactDisposition{}, true, err } for id := range record.pending { record.consumedIDs[id] = struct{}{} } record.consumedHashes[record.pendingHash] = struct{}{} record.pending = nil record.pendingHash = "" record.lineage = lineage.Committed if primaryFailure != nil { return snap, artifactDisposition{ Kind: artifactDispositionLocalEligible, SelectorStageID: record.selectorStageID, PrimaryError: primaryFailure, }, true, nil } switch record.phase { case artifactPhasePreparePending: snap, err = coordinator.activateStage(record.requestID, record.ownerEdgeID, record.selectorStageID) if err != nil { return logicalRequestSnapshot{}, artifactDisposition{}, true, fmt.Errorf("resume artifact selector stage: %w", err) } record.phase = artifactPhasePairReady return snap, artifactDisposition{Kind: artifactDispositionResumeSelector, SelectorStageID: record.selectorStageID}, true, nil case artifactPhasePairPending: record.phase = artifactPhaseLocalEligible return snap, artifactDisposition{Kind: artifactDispositionLocalEligible, SelectorStageID: record.selectorStageID}, true, nil default: return logicalRequestSnapshot{}, artifactDisposition{}, true, fmt.Errorf("artifact frontier phase cannot consume results") } } func (s *artifactFrontierStore) matchRecordLocked( ownerEdgeID, principalRef, protocol string, lineage logicalRequestContinuationLineage, ) (*artifactFrontierRecord, bool, error) { var candidates []*artifactFrontierRecord for _, record := range s.records { pendingRelated := record.pending != nil && (record.pendingHash == lineage.IssuedCallHash || artifactIDsIntersect(record, lineage.ResultIDs) || record.lineage == lineage.Prefix) _, consumedHash := record.consumedHashes[lineage.IssuedCallHash] if pendingRelated || consumedHash || artifactConsumedIDsIntersect(record, lineage.ResultIDs) { candidates = append(candidates, record) } } if len(candidates) == 0 { return nil, false, nil } for _, record := range candidates { if _, replay := record.consumedHashes[lineage.IssuedCallHash]; replay { return nil, true, fmt.Errorf("artifact frontier replay rejected") } } for _, record := range candidates { if record.pendingHash != lineage.IssuedCallHash { continue } if record.ownerEdgeID != ownerEdgeID { return nil, true, errLogicalRequestOwnerMismatch } if record.principalRef != principalRef { return nil, true, errLogicalRequestPrincipal } if record.protocol != protocol || record.lineage != lineage.Prefix { return nil, true, errLogicalRequestLineage } return record, true, nil } for _, record := range candidates { if record.ownerEdgeID == ownerEdgeID && record.principalRef == principalRef && record.protocol == protocol && record.lineage == lineage.Prefix { return record, true, nil } } return nil, true, errLogicalRequestLineage } func artifactIDsIntersect(record *artifactFrontierRecord, ids []string) bool { for _, id := range ids { if record.pending[id] != nil { return true } } return false } func artifactConsumedIDsIntersect(record *artifactFrontierRecord, ids []string) bool { for _, id := range ids { if _, consumed := record.consumedIDs[id]; consumed { return true } } return false } func decodeChatWorkspaceResults(rawBody []byte) ([]workspaceResult, error) { var envelope struct { Messages []struct { Role string `json:"role"` ToolCallID string `json:"tool_call_id"` Content json.RawMessage `json:"content"` } `json:"messages"` } if err := json.Unmarshal(rawBody, &envelope); err != nil { return nil, fmt.Errorf("decode Chat artifact results: %w", err) } var reversed []workspaceResult for i := len(envelope.Messages) - 1; i >= 0; i-- { message := envelope.Messages[i] if message.Role != "tool" { break } body, err := workspaceResultBody(message.Content) if err != nil { return nil, fmt.Errorf("decode Chat tool result %q: %w", message.ToolCallID, err) } reversed = append(reversed, workspaceResult{callID: message.ToolCallID, status: "success", body: body}) } results := make([]workspaceResult, len(reversed)) for i := range reversed { results[len(reversed)-1-i] = reversed[i] } if len(results) == 0 { return nil, fmt.Errorf("Chat artifact continuation has no tool results") } return results, nil } func decodeAnthropicWorkspaceResults(rawBody []byte) ([]workspaceResult, error) { var envelope struct { Messages []struct { Role string `json:"role"` Content json.RawMessage `json:"content"` } `json:"messages"` } if err := json.Unmarshal(rawBody, &envelope); err != nil { return nil, fmt.Errorf("decode Messages artifact results: %w", err) } if len(envelope.Messages) == 0 || envelope.Messages[len(envelope.Messages)-1].Role != "user" { return nil, fmt.Errorf("Messages artifact continuation has no trailing user results") } var blocks []struct { Type string `json:"type"` ToolUseID string `json:"tool_use_id"` Content json.RawMessage `json:"content"` IsError bool `json:"is_error,omitempty"` } if err := json.Unmarshal(envelope.Messages[len(envelope.Messages)-1].Content, &blocks); err != nil { return nil, fmt.Errorf("decode Messages artifact result blocks: %w", err) } results := make([]workspaceResult, 0, len(blocks)) for _, block := range blocks { if block.Type != "tool_result" { return nil, fmt.Errorf("Messages artifact result contains non-tool_result block") } body, err := workspaceResultBody(block.Content) if err != nil { return nil, fmt.Errorf("decode Messages tool result %q: %w", block.ToolUseID, err) } status := "success" if block.IsError { status = "error" } results = append(results, workspaceResult{callID: block.ToolUseID, status: status, body: body}) } if len(results) == 0 { return nil, fmt.Errorf("Messages artifact continuation has no tool results") } return results, nil } func workspaceResultBody(raw json.RawMessage) (json.RawMessage, error) { trimmed := strings.TrimSpace(string(raw)) if trimmed == "" || trimmed == "null" { return nil, nil } var text string if err := json.Unmarshal(raw, &text); err == nil { return json.RawMessage(strings.TrimSpace(text)), nil } var value any if err := json.Unmarshal(raw, &value); err != nil { return nil, err } return append(json.RawMessage(nil), raw...), nil } func decodeArtifactTools(protocol string, rawBody []byte) (any, error) { switch protocol { case "openai": var envelope struct { Tools []any `json:"tools"` } decoder := json.NewDecoder(strings.NewReader(string(rawBody))) decoder.UseNumber() if err := decoder.Decode(&envelope); err != nil { return nil, fmt.Errorf("decode Chat workspace tools: %w", err) } return envelope.Tools, nil case "anthropic": var envelope struct { Tools []anthropicTool `json:"tools"` } if err := json.Unmarshal(rawBody, &envelope); err != nil { return nil, fmt.Errorf("decode Messages workspace tools: %w", err) } return envelope.Tools, nil default: return nil, fmt.Errorf("unsupported artifact protocol %q", protocol) } }