import {
  ConfigError
} from "./chunk-YEJR7IXO.js";

// src/runtime/supervise/model-policy.ts
function assertModelAllowed(model, allowed) {
  if (!allowed || model === void 0) return;
  if (!allowed.includes(model)) {
    throw new ConfigError(
      `model ${JSON.stringify(model)} is not in the allowed set ${JSON.stringify([...allowed])}`
    );
  }
}

// src/sanitize.ts
function sanitizeKnowledgeReadinessReport(report, options = {}) {
  return {
    taskId: report.taskId,
    readinessScore: report.readinessScore,
    recommendedAction: report.recommendedAction,
    severity: report.severity,
    reason: report.reason,
    blockingMissingRequirements: report.blockingMissingRequirements.map(
      (requirement) => sanitizeKnowledgeRequirement(requirement, options)
    ),
    nonBlockingGaps: report.nonBlockingGaps.map(
      (requirement) => sanitizeKnowledgeRequirement(requirement, options)
    ),
    evidenceCount: report.bundle.evidenceIds.length,
    evidenceIds: options.includeEvidenceIds ? report.bundle.evidenceIds : void 0,
    missingRequirementIds: report.bundle.missing.map((requirement) => requirement.id)
  };
}
function sanitizeAgentRuntimeEvent(event, options = {}) {
  const base = { type: event.type, task: sanitizeTask(event.task, options) };
  if (event.type === "readiness_start" || event.type === "task_start" || event.type === "control_start") {
    return event.type === "control_start" ? { ...base, knowledge: sanitizeKnowledgeReadinessReport(event.knowledge, options) } : base;
  }
  if (event.type === "readiness_end") {
    return { ...base, knowledge: sanitizeKnowledgeReadinessReport(event.knowledge, options) };
  }
  if (event.type === "questions_start") {
    return {
      ...base,
      questions: event.questions.map((question) => sanitizeQuestion(question, options))
    };
  }
  if (event.type === "questions_end") {
    return {
      ...base,
      questions: event.questions.map((question) => sanitizeQuestion(question, options)),
      userAnswers: options.includeUserAnswers ? event.userAnswers : redactRecord(event.userAnswers)
    };
  }
  if (event.type === "acquisition_start") {
    return { ...base, acquisitionPlans: event.acquisitionPlans.map(sanitizeAcquisitionPlan) };
  }
  if (event.type === "acquisition_end") {
    return {
      ...base,
      acquisitionPlans: event.acquisitionPlans.map(sanitizeAcquisitionPlan),
      acquiredEvidenceCount: event.acquiredEvidenceIds.length,
      acquiredEvidenceIds: options.includeEvidenceIds ? event.acquiredEvidenceIds : void 0
    };
  }
  if (event.type === "control_step") {
    return { ...base, step: sanitizeControlStep(event.step, options) };
  }
  if (event.type === "control_end") {
    return { ...base, control: sanitizeControlRun(event.control, options) };
  }
  return { ...base, status: event.status, reason: event.reason };
}
function sanitizeRuntimeStreamEvent(event, options = {}) {
  const withTask = "task" in event && event.task ? { task: sanitizeTask(event.task, options) } : {};
  const withSession = "session" in event && event.session ? { session: sanitizeRuntimeSession(event.session, options) } : {};
  if (event.type === "readiness_end") {
    return {
      type: event.type,
      ...withTask,
      timestamp: event.timestamp,
      decision: event.decision,
      knowledge: sanitizeKnowledgeReadinessReport(event.knowledge, options)
    };
  }
  if (event.type === "questions_start") {
    return {
      type: event.type,
      ...withTask,
      timestamp: event.timestamp,
      questions: event.questions.map((question) => sanitizeQuestion(question, options))
    };
  }
  if (event.type === "questions_end") {
    return {
      type: event.type,
      ...withTask,
      timestamp: event.timestamp,
      questions: event.questions.map((question) => sanitizeQuestion(question, options)),
      userAnswers: options.includeUserAnswers ? event.userAnswers : redactRecord(event.userAnswers)
    };
  }
  if (event.type === "acquisition_start") {
    return {
      type: event.type,
      ...withTask,
      timestamp: event.timestamp,
      acquisitionPlans: event.acquisitionPlans.map(sanitizeAcquisitionPlan)
    };
  }
  if (event.type === "acquisition_end") {
    return {
      type: event.type,
      ...withTask,
      timestamp: event.timestamp,
      acquisitionPlans: event.acquisitionPlans.map(sanitizeAcquisitionPlan),
      acquiredEvidenceCount: event.acquiredEvidenceIds.length,
      acquiredEvidenceIds: options.includeEvidenceIds ? event.acquiredEvidenceIds : void 0
    };
  }
  if (event.type === "tool_call") {
    return {
      type: event.type,
      ...withTask,
      ...withSession,
      timestamp: event.timestamp,
      toolName: event.toolName,
      toolCallId: event.toolCallId,
      args: options.includeControlPayloads ? event.args : void 0
    };
  }
  if (event.type === "tool_result") {
    return {
      type: event.type,
      ...withTask,
      ...withSession,
      timestamp: event.timestamp,
      toolName: event.toolName,
      toolCallId: event.toolCallId,
      result: options.includeControlPayloads ? event.result : void 0
    };
  }
  if (event.type === "llm_call") {
    return {
      type: event.type,
      ...withTask,
      ...withSession,
      timestamp: event.timestamp,
      model: event.model,
      tokensIn: event.tokensIn,
      tokensOut: event.tokensOut,
      costUsd: event.costUsd,
      latencyMs: event.latencyMs,
      finishReason: event.finishReason
    };
  }
  if (event.type === "artifact") {
    return {
      type: event.type,
      ...withTask,
      ...withSession,
      timestamp: event.timestamp,
      artifactId: event.artifactId,
      name: event.name,
      mimeType: event.mimeType,
      uri: options.includeEvidenceIds ? event.uri : void 0,
      content: options.includeControlPayloads ? event.content : void 0,
      metadata: options.includeMetadata ? event.metadata : void 0
    };
  }
  if (event.type === "proposal_created") {
    return {
      type: event.type,
      ...withTask,
      ...withSession,
      timestamp: event.timestamp,
      proposalId: event.proposalId,
      title: options.includeControlPayloads ? event.title : void 0,
      content: options.includeControlPayloads ? event.content : void 0,
      status: event.status
    };
  }
  if (event.type === "final") {
    const sanitizedError = event.error !== void 0 ? {
      kind: event.error.kind,
      message: event.error.message,
      status: event.error.status,
      body: options.includeControlPayloads ? event.error.body : void 0
    } : void 0;
    return {
      type: event.type,
      ...withTask,
      ...withSession,
      timestamp: event.timestamp,
      status: event.status,
      reason: event.reason,
      text: options.includeControlPayloads ? event.text : void 0,
      metadata: options.includeMetadata ? event.metadata : void 0,
      ...sanitizedError !== void 0 ? { error: sanitizedError } : {}
    };
  }
  return {
    type: event.type,
    ...withTask,
    ...withSession,
    timestamp: "timestamp" in event ? event.timestamp : void 0,
    ...pickPublicStreamFields(event)
  };
}
function sanitizeTask(task, options) {
  return {
    id: task.id,
    intent: task.intent,
    domain: task.domain,
    inputs: options.includeInputs ? task.inputs : task.inputs ? "[redacted]" : void 0,
    requiredKnowledge: task.requiredKnowledge?.map(
      (requirement) => sanitizeKnowledgeRequirement(requirement, options)
    ),
    metadata: options.includeMetadata ? task.metadata : task.metadata ? "[redacted]" : void 0
  };
}
function sanitizeRuntimeSession(session, options) {
  return {
    id: session.id,
    backend: session.backend,
    status: session.status,
    hasResumeToken: Boolean(session.resumeToken),
    createdAt: session.createdAt,
    updatedAt: session.updatedAt,
    metadata: options.includeMetadata ? session.metadata : session.metadata ? "[redacted]" : void 0
  };
}
function sanitizeKnowledgeRequirement(requirement, options) {
  const includeDescription = options.includeRequirementDescriptions && requirement.sensitivity !== "secret";
  return {
    id: requirement.id,
    description: includeDescription ? requirement.description : void 0,
    requiredFor: requirement.requiredFor,
    category: requirement.category,
    acquisitionMode: requirement.acquisitionMode,
    importance: requirement.importance,
    freshness: requirement.freshness,
    sensitivity: requirement.sensitivity,
    confidenceNeeded: requirement.confidenceNeeded,
    currentConfidence: requirement.currentConfidence,
    evidenceCount: requirement.evidenceIds.length,
    evidenceIds: options.includeEvidenceIds ? requirement.evidenceIds : void 0,
    fallbackPolicy: requirement.fallbackPolicy
  };
}
function sanitizeQuestion(question, options) {
  return {
    id: question.id,
    question: options.includeRequirementDescriptions && question.answerType !== "credential" ? question.question : void 0,
    reason: options.includeRequirementDescriptions ? question.reason : void 0,
    requirementId: question.requirementId,
    importance: question.importance,
    answerType: question.answerType,
    impactIfUnknown: options.includeRequirementDescriptions ? question.impactIfUnknown : void 0,
    optionCount: question.options?.length ?? 0
  };
}
function sanitizeAcquisitionPlan(plan) {
  return {
    id: plan.id,
    requirementIds: plan.requirementIds,
    mode: plan.mode,
    priority: plan.priority,
    expectedEvidenceCount: plan.expectedEvidenceIds?.length ?? 0,
    questionCount: plan.questions?.length ?? 0
  };
}
function sanitizeControlStep(step, options) {
  const actionOutcome = step.actionOutcome;
  return {
    index: step.index,
    decisionType: step.decision.type,
    reason: step.decision.reason,
    action: options.includeControlPayloads && step.decision.type === "continue" ? step.decision.action : void 0,
    result: options.includeControlPayloads && actionOutcome?.ok ? actionOutcome.result : void 0,
    actionOk: actionOutcome?.ok,
    actionError: actionOutcome?.ok === false ? actionOutcome.error : void 0,
    durationMs: actionOutcome?.durationMs,
    evalsBefore: summarizeEvals(step.evalsBefore, options),
    evalsAfter: summarizeEvals(step.evalsAfter, options),
    startedAt: step.startedAt,
    endedAt: step.endedAt
  };
}
function sanitizeControlRun(control, options) {
  return {
    pass: control.pass,
    completed: control.completed,
    reason: control.reason,
    score: control.score,
    stepCount: control.steps.length,
    wallMs: control.wallMs,
    spentCostUsd: control.spentCostUsd,
    failureClass: control.failureClass,
    stoppedBy: control.stoppedBy,
    runId: control.runId,
    runtimeErrorCount: control.runtimeErrors.length,
    finalEvals: summarizeEvals(control.finalEvals, options)
  };
}
function summarizeEvals(evals, options) {
  return evals.map((evalResult) => ({
    id: evalResult.id,
    passed: evalResult.passed,
    score: evalResult.score,
    severity: evalResult.severity,
    objective: evalResult.objective,
    detail: options.includeEvalDetails ? evalResult.detail : void 0,
    evidence: options.includeEvalDetails ? evalResult.evidence : void 0
  }));
}
function redactRecord(record) {
  return Object.fromEntries(Object.keys(record).map((key) => [key, "[redacted]"]));
}
function pickPublicStreamFields(event) {
  if (event.type === "session_created" || event.type === "session_resumed") return {};
  if (event.type === "backend_start" || event.type === "backend_end")
    return { backend: event.backend };
  if (event.type === "backend_error") {
    const sanitizedError = event.error !== void 0 ? {
      kind: event.error.kind,
      status: event.error.status
    } : void 0;
    return {
      backend: event.backend,
      message: event.message,
      recoverable: event.recoverable,
      ...sanitizedError !== void 0 ? { error: sanitizedError } : {}
    };
  }
  if (event.type === "task_end") return { status: event.status, reason: event.reason };
  if (event.type === "text_delta" || event.type === "reasoning_delta") return { text: event.text };
  return {};
}
function createRuntimeEventCollector(options = {}) {
  const events = [];
  return {
    events,
    onEvent: (event) => {
      events.push(sanitizeAgentRuntimeEvent(event, options));
    }
  };
}
function createRuntimeStreamEventCollector(options = {}) {
  const events = [];
  const eventCountsByType = {};
  let firstSessionId;
  let finalStatus;
  let finalReason;
  let finalText = "";
  return {
    events,
    onEvent: (event) => {
      events.push(sanitizeRuntimeStreamEvent(event, options));
      eventCountsByType[event.type] = (eventCountsByType[event.type] ?? 0) + 1;
      if (event.type === "text_delta") finalText += event.text;
      if (!firstSessionId && (event.type === "session_created" || event.type === "session_resumed")) {
        firstSessionId = event.session.id;
      }
      if (event.type === "final") {
        finalStatus = event.status;
        finalReason = event.reason;
      }
    },
    summary() {
      return {
        eventCount: events.length,
        eventCountsByType: { ...eventCountsByType },
        firstSessionId,
        finalStatus,
        finalReason,
        finalText
      };
    }
  };
}

// src/otel-export.ts
var SCOPE = { name: "@tangle-network/agent-runtime", version: "0.83.0" };
var GEN_AI = {
  operation: "gen_ai.operation.name",
  agentName: "gen_ai.agent.name",
  conversationId: "gen_ai.conversation.id",
  inputTokens: "gen_ai.usage.input_tokens",
  outputTokens: "gen_ai.usage.output_tokens"
};
function createOtelExporter(config) {
  const resolvedEndpoint = config?.endpoint ?? (typeof process !== "undefined" ? process.env.OTEL_EXPORTER_OTLP_ENDPOINT : void 0);
  if (!resolvedEndpoint) return void 0;
  const endpoint = resolvedEndpoint;
  const headers = config?.headers ?? parseHeadersFromEnv();
  const batchSize = config?.batchSize ?? 64;
  const flushIntervalMs = config?.flushIntervalMs ?? 5e3;
  const serviceName = config?.serviceName ?? "agent-runtime";
  const resourceAttrs = config?.resourceAttributes ?? {};
  const pending = [];
  let timer;
  let stopped = false;
  const exporter = {
    exportSpan(span) {
      if (stopped) return;
      pending.push(span);
      if (pending.length >= batchSize) {
        void doFlush();
      }
    },
    async flush() {
      await doFlush();
    },
    async shutdown() {
      stopped = true;
      if (timer !== void 0) {
        clearInterval(timer);
        timer = void 0;
      }
      await doFlush();
    }
  };
  timer = setInterval(() => {
    if (pending.length > 0) void doFlush();
  }, flushIntervalMs);
  if (typeof timer === "object" && "unref" in timer) {
    ;
    timer.unref();
  }
  async function doFlush() {
    if (pending.length === 0) return;
    const batch = pending.splice(0);
    const body = {
      resourceSpans: [
        {
          resource: {
            attributes: toAttributes({
              "service.name": serviceName,
              ...resourceAttrs
            })
          },
          scopeSpans: [{ scope: SCOPE, spans: batch }]
        }
      ]
    };
    const url = `${endpoint.replace(/\/+$/, "")}/v1/traces`;
    try {
      await fetch(url, {
        method: "POST",
        headers: { "content-type": "application/json", ...headers },
        body: JSON.stringify(body)
      });
    } catch {
    }
  }
  return exporter;
}
function loopEventToOtelSpan(event, traceId, parentSpanId) {
  const spanId = generateSpanId();
  const attrs = {
    "loop.event_kind": event.kind,
    "loop.run_id": event.runId
  };
  for (const [k, v] of Object.entries(event.payload)) {
    if (typeof v === "string" || typeof v === "number" || typeof v === "boolean") {
      attrs[`loop.${k}`] = v;
    }
  }
  const ts = msToNs(event.timestamp);
  return {
    traceId: padTraceId(traceId),
    spanId,
    parentSpanId: parentSpanId ? padSpanId(parentSpanId) : void 0,
    name: event.kind,
    kind: 1,
    startTimeUnixNano: ts,
    endTimeUnixNano: ts,
    attributes: toAttributes(attrs),
    status: { code: 1 }
  };
}
function flatOtelSpan(name, attributes, traceId, timestampMs, parentSpanId, endTimestampMs = timestampMs) {
  const start = msToNs(timestampMs);
  const end = msToNs(Math.max(timestampMs, endTimestampMs));
  return {
    traceId: padTraceId(traceId),
    spanId: generateSpanId(),
    parentSpanId: parentSpanId ? padSpanId(parentSpanId) : void 0,
    name,
    kind: 1,
    startTimeUnixNano: start,
    endTimeUnixNano: end,
    attributes: toAttributes(attributes),
    status: { code: 1 }
  };
}
function eventTimestampMs(event) {
  if ("timestamp" in event && typeof event.timestamp === "string") {
    const parsed = Date.parse(event.timestamp);
    if (Number.isFinite(parsed)) return parsed;
  }
  return Date.now();
}
function serialized(value) {
  try {
    return JSON.stringify(value) ?? String(value);
  } catch {
    return String(value);
  }
}
function mcpIdentity(toolName) {
  if (!toolName.startsWith("mcp__")) return {};
  const [, server, ...toolParts] = toolName.split("__");
  return {
    ...server ? { server } : {},
    ...toolParts.length > 0 ? { tool: toolParts.join("__") } : {}
  };
}
function buildRuntimeEventOtelSpans(events, traceId, parentSpanId, options = {}) {
  return events.map((event) => {
    const sanitized = sanitizeRuntimeStreamEvent(event, options);
    const safe = options.redact ? options.redact(sanitized) : sanitized;
    const record = safe && typeof safe === "object" && !Array.isArray(safe) ? safe : { value: safe };
    const attrs = {
      "tangle.runtime.event_type": event.type,
      "tangle.runtime.event": serialized(record)
    };
    let name = `tangle.runtime.${event.type}`;
    if (event.type === "tool_call" || event.type === "tool_result") {
      name = `agent.${event.type}`;
      attrs["tool.name"] = event.toolName;
      if (event.toolCallId) attrs["tool.call_id"] = event.toolCallId;
      const mcp = mcpIdentity(event.toolName);
      if (mcp.server) attrs["mcp.server"] = mcp.server;
      if (mcp.tool) attrs["mcp.tool.name"] = mcp.tool;
      const payload = event.type === "tool_call" ? record.args : record.result;
      if (payload !== void 0) {
        attrs[event.type === "tool_call" ? "tool.input" : "tool.output"] = serialized(payload);
      }
    } else if (event.type === "llm_call") {
      name = "gen_ai.client.inference";
      attrs["gen_ai.request.model"] = event.model;
      if (event.tokensIn !== void 0) attrs["gen_ai.usage.input_tokens"] = event.tokensIn;
      if (event.tokensOut !== void 0) attrs["gen_ai.usage.output_tokens"] = event.tokensOut;
      if (event.costUsd !== void 0) attrs["tangle.cost.usd"] = event.costUsd;
      if (event.latencyMs !== void 0) attrs["tangle.latency_ms"] = event.latencyMs;
      if (event.finishReason !== void 0)
        attrs["gen_ai.response.finish_reasons"] = event.finishReason;
    } else if (event.type === "backend_error") {
      attrs["error.type"] = event.error?.kind ?? "backend";
      attrs["error.message"] = event.message;
    } else if (event.type === "final") {
      attrs["tangle.outcome.status"] = event.status;
      attrs["tangle.outcome.reason"] = event.reason;
      if (event.error) {
        attrs["error.type"] = event.error.kind;
        attrs["error.message"] = event.error.message;
      }
    }
    const startMs = eventTimestampMs(event);
    const endMs = event.type === "llm_call" && event.latencyMs !== void 0 && Number.isFinite(event.latencyMs) ? startMs + event.latencyMs : startMs;
    const span = flatOtelSpan(name, attrs, traceId, startMs, parentSpanId, endMs);
    if (event.type === "backend_error" || event.type === "final" && event.status !== "completed") {
      span.status = { code: 2, message: attrs["error.message"]?.toString() ?? event.type };
    }
    return span;
  });
}
function buildLoopOtelSpans(events, traceId, rootParentSpanId) {
  const tid = padTraceId(traceId);
  return buildLoopSpanNodes(events).map((node) => ({
    traceId: tid,
    spanId: node.spanId,
    parentSpanId: node.parentSpanId ? padSpanId(node.parentSpanId) : rootParentSpanId ? padSpanId(rootParentSpanId) : void 0,
    name: node.name,
    kind: 1,
    startTimeUnixNano: msToNs(node.startMs),
    endTimeUnixNano: msToNs(node.endMs),
    attributes: toAttributes(node.attrs),
    status: { code: node.error ? 2 : 1 }
  }));
}
function buildLoopSpanNodes(events) {
  if (events.length === 0) return [];
  const out = [];
  const num = (v) => typeof v === "number" && Number.isFinite(v) ? v : void 0;
  const str = (v) => typeof v === "string" && v.length > 0 ? v : void 0;
  const rec = (v) => v && typeof v === "object" ? v : {};
  const started = events.find((e) => e.kind === "loop.started");
  const ended = events.find((e) => e.kind === "loop.ended");
  const runId = events[0]?.runId ?? "";
  const rootStart = started?.timestamp ?? events[0].timestamp;
  const rootEnd = ended?.timestamp ?? events[events.length - 1].timestamp;
  const rootId = generateSpanId();
  const make = (spanId, parentSpanId, name, kind, startMs, endMs, attrs, error = false) => ({
    spanId,
    parentSpanId,
    name,
    kind,
    startMs,
    endMs,
    attrs,
    error
  });
  const sp = rec(started?.payload);
  const rootAttrs = {
    [GEN_AI.operation]: "invoke_workflow",
    [GEN_AI.conversationId]: runId,
    // Explicit run identity under the tangle namespace so a consuming system of
    // record (Tangle Intelligence's run spine) maps this span tree to one run
    // deterministically, instead of inferring it from the conversation id.
    "tangle.run.id": runId,
    "tangle.loop.driver": str(sp.driver) ?? "driver"
  };
  if (Array.isArray(sp.agentRunNames) && sp.agentRunNames.length > 0) {
    rootAttrs["tangle.loop.agents"] = sp.agentRunNames.map(String).join(",");
    rootAttrs["tangle.subject.key"] = String(sp.agentRunNames[0]);
  }
  if (ended) {
    const ep = rec(ended.payload);
    const win = num(ep.winnerIterationIndex);
    if (win !== void 0) rootAttrs["tangle.loop.winner.iteration_index"] = win;
    const cost = num(ep.totalCostUsd);
    if (cost !== void 0) rootAttrs["tangle.cost.usd"] = cost;
    const dur = num(ep.durationMs);
    if (dur !== void 0) rootAttrs["tangle.loop.duration_ms"] = dur;
    const iters = num(ep.iterations);
    if (iters !== void 0) rootAttrs["tangle.loop.iterations"] = iters;
  }
  out.push(make(rootId, void 0, "loop", "loop", rootStart, rootEnd, rootAttrs));
  const iterStartTs = /* @__PURE__ */ new Map();
  const placementByIdx = /* @__PURE__ */ new Map();
  let currentRoundId;
  let pendingRound;
  const flushRound = (endMs) => {
    if (!pendingRound) return;
    out.push(
      make(
        pendingRound.id,
        rootId,
        "loop.round",
        "round",
        pendingRound.start,
        endMs,
        pendingRound.attrs
      )
    );
    pendingRound = void 0;
  };
  for (const e of events) {
    const p = rec(e.payload);
    switch (e.kind) {
      case "loop.plan": {
        flushRound(e.timestamp);
        const id = generateSpanId();
        const roundIdx = num(p.roundIndex) ?? 0;
        const attrs = {
          [GEN_AI.operation]: "invoke_workflow",
          "tangle.loop.round.index": roundIdx,
          "tangle.loop.move.kind": str(p.moveKind) ?? "unknown",
          "tangle.loop.move.round": roundIdx,
          "tangle.loop.move.width": num(p.plannedCount) ?? 0
        };
        const r = str(p.rationale);
        if (r) attrs["tangle.loop.move.rationale"] = r;
        const parent = num(p.parentIndex);
        if (parent !== void 0) attrs["tangle.loop.move.parent_index"] = parent;
        if (Array.isArray(p.childIndices) && p.childIndices.length > 0) {
          attrs["tangle.loop.move.child_indices"] = p.childIndices.map(String).join(",");
        }
        pendingRound = { id, start: e.timestamp, attrs };
        currentRoundId = id;
        break;
      }
      case "loop.iteration.started": {
        const idx = num(p.iterationIndex);
        if (idx !== void 0) iterStartTs.set(idx, e.timestamp);
        break;
      }
      case "loop.iteration.dispatch": {
        const idx = num(p.iterationIndex);
        if (idx === void 0) break;
        const place = {};
        const kind = str(p.placement);
        if (kind) place["tangle.loop.placement.kind"] = kind;
        const sid = str(p.sandboxId);
        if (sid) place["tangle.sandbox.id"] = sid;
        const fid = str(p.fleetId);
        if (fid) place["tangle.fleet.id"] = fid;
        const mid = str(p.machineId);
        if (mid) place["tangle.machine.id"] = mid;
        placementByIdx.set(idx, place);
        break;
      }
      case "loop.iteration.ended": {
        const idx = num(p.iterationIndex) ?? 0;
        const start = iterStartTs.get(idx) ?? e.timestamp;
        const err = str(p.error);
        const attrs = {
          [GEN_AI.operation]: "invoke_agent",
          "tangle.loop.iteration.index": idx
        };
        const agent = str(p.agentRunName);
        if (agent) attrs[GEN_AI.agentName] = agent;
        const tu = rec(p.tokenUsage);
        const inTok = num(tu.input);
        if (inTok !== void 0) attrs[GEN_AI.inputTokens] = inTok;
        const outTok = num(tu.output);
        if (outTok !== void 0) attrs[GEN_AI.outputTokens] = outTok;
        const cost = num(p.costUsd);
        if (cost !== void 0) attrs["tangle.cost.usd"] = cost;
        const verdict = rec(p.verdict);
        if (typeof verdict.valid === "boolean") attrs["tangle.loop.verdict.valid"] = verdict.valid;
        const score = num(verdict.score);
        if (score !== void 0) attrs["tangle.loop.verdict.score"] = score;
        if (err) attrs["tangle.loop.error"] = err;
        const gid = num(p.groupId);
        if (gid !== void 0) attrs["tangle.loop.iteration.group_id"] = gid;
        const par = num(p.parentIndex);
        if (par !== void 0) attrs["tangle.loop.iteration.parent_index"] = par;
        const dur = num(p.durationMs);
        if (dur !== void 0) attrs["tangle.loop.iteration.duration_ms"] = dur;
        const preview = str(p.outputPreview);
        if (preview) attrs["tangle.loop.iteration.output_preview"] = preview;
        Object.assign(attrs, placementByIdx.get(idx) ?? {});
        out.push(
          make(
            generateSpanId(),
            currentRoundId ?? rootId,
            "loop.iteration",
            "branch",
            start,
            e.timestamp,
            attrs,
            err !== void 0
          )
        );
        break;
      }
      case "loop.decision": {
        if (pendingRound) {
          const dec = str(p.decision);
          if (dec) pendingRound.attrs["tangle.loop.decision"] = dec;
          flushRound(e.timestamp);
        }
        currentRoundId = void 0;
        break;
      }
    }
  }
  flushRound(rootEnd);
  return out;
}
function parseHeadersFromEnv() {
  if (typeof process === "undefined") return {};
  const raw = process.env.OTEL_EXPORTER_OTLP_HEADERS;
  if (!raw) return {};
  const out = {};
  for (const pair of raw.split(",")) {
    const eq = pair.indexOf("=");
    if (eq < 0) continue;
    const key = pair.slice(0, eq).trim();
    const value = pair.slice(eq + 1).trim();
    if (key) out[key] = value;
  }
  return out;
}
function toAttributes(record) {
  return Object.entries(record).flatMap(([key, value]) => {
    if (typeof value === "number" && !Number.isFinite(value)) return [];
    return [
      {
        key,
        value: typeof value === "number" ? Number.isInteger(value) ? { intValue: value.toString() } : { doubleValue: value } : typeof value === "boolean" ? { boolValue: value } : { stringValue: value }
      }
    ];
  });
}
function msToNs(ms) {
  const safeMs = Number.isFinite(ms) ? ms : Date.now();
  return (BigInt(Math.floor(safeMs)) * 1000000n).toString();
}
function padSpanId(id) {
  const cleaned = id.replace(/-/g, "");
  return cleaned.slice(0, 16).padEnd(16, "0");
}
function padTraceId(id) {
  const cleaned = id.replace(/-/g, "");
  return cleaned.slice(0, 32).padEnd(32, "0");
}
function generateSpanId() {
  const bytes = new Uint8Array(8);
  if (typeof globalThis.crypto?.getRandomValues === "function") {
    globalThis.crypto.getRandomValues(bytes);
  } else {
    for (let i = 0; i < 8; i++) bytes[i] = Math.floor(Math.random() * 256);
  }
  return Array.from(bytes).map((b) => b.toString(16).padStart(2, "0")).join("");
}
var INTELLIGENCE_WIRE_VERSION = "2026-05-26.v1";
var DEFAULT_INTELLIGENCE_BASE = "https://intelligence.tangle.tools";
async function exportEvalRuns(events, config) {
  if (events.length === 0) return { ok: true, status: 0, accepted: 0, rejected: [] };
  const apiKey = config?.apiKey ?? (typeof process !== "undefined" ? process.env.TANGLE_API_KEY : void 0);
  if (!apiKey)
    throw new Error("exportEvalRuns: apiKey required (pass config.apiKey or set TANGLE_API_KEY)");
  const base = config?.base ?? (typeof process !== "undefined" ? process.env.TANGLE_INTELLIGENCE_URL : void 0) ?? DEFAULT_INTELLIGENCE_BASE;
  const url = `${base.replace(/\/+$/, "")}/v1/ingest/eval-runs`;
  const res = await fetch(url, {
    method: "POST",
    headers: {
      "content-type": "application/json",
      authorization: `Bearer ${apiKey}`,
      "X-Tangle-Wire-Version": INTELLIGENCE_WIRE_VERSION,
      ...config?.idempotencyKey ? { "Idempotency-Key": config.idempotencyKey } : {}
    },
    body: JSON.stringify({ wireVersion: INTELLIGENCE_WIRE_VERSION, events })
  });
  let parsed = {};
  try {
    parsed = await res.json();
  } catch {
  }
  return {
    ok: res.ok,
    status: res.status,
    accepted: parsed.accepted ?? (res.ok ? events.length : 0),
    rejected: parsed.rejected ?? []
  };
}

export {
  assertModelAllowed,
  sanitizeKnowledgeReadinessReport,
  sanitizeAgentRuntimeEvent,
  sanitizeRuntimeStreamEvent,
  createRuntimeEventCollector,
  createRuntimeStreamEventCollector,
  createOtelExporter,
  loopEventToOtelSpan,
  flatOtelSpan,
  buildRuntimeEventOtelSpans,
  buildLoopOtelSpans,
  buildLoopSpanNodes,
  INTELLIGENCE_WIRE_VERSION,
  exportEvalRuns
};
//# sourceMappingURL=chunk-ISTDY47H.js.map