/**
 * Node-safe headless entry point for the AI assistant driver stack (`@genesislcap/ai-assistant/chat-driver`).
 *
 * Re-exports ONLY the framework-agnostic pieces — {@link ChatDriver}, `OrchestratingDriver`, the
 * agent-config surface (`defineAgent`, `defineStatefulAgent`, and the config/input types), and the
 * activity-bus types/`NOOP_ACTIVITY_BUS` — WITHOUT the DOM/FAST component layer that the package's
 * main entry (`.`) pulls in via `main/main`. This lets a Node / CommonJS host (server, unit tests,
 * benches) construct and drive `ChatDriver` over `foundation-ai` providers with no jsdom and no
 * custom-element registration.
 *
 * Every module re-exported here is DOM-clean at import time (no `window`/`document`/`sessionStorage`
 * eval-time access, no `@genesislcap/web-core`). The activity bus is imported for its types and the
 * no-op default; its cross-tab `BroadcastChannel` is created lazily and only in a browser, so
 * pulling this entry into Node opens nothing.
 *
 * @packageDocumentation
 * @beta
 */
export * from './components/chat-driver';
export * from './components/orchestrating-driver';
export * from './channel/ai-activity-channel';
export * from './channel/ai-activity-bus';
export * from './config/config';
export * from './config/define-stateful-agent';
export * from './config/fallback-agents';

// Provider-construction surface, re-exported from `@genesislcap/foundation-ai` so a headless
// consumer builds its registry from the SAME bundled foundation-ai instance the driver uses. That
// shared identity matters: `ChatDriver`'s malformed/truncated handling does `instanceof` on the
// transports' error classes, so a second foundation-ai copy (a separate dep) would silently break
// those checks. NAMED re-exports only — `export *` would drag in the FAST-DI module
// (`@microsoft/fast-foundation` → `fast-element` → `document` at eval); by naming just these,
// esbuild tree-shakes the DI module out and the bundle stays Node-loadable.
export {
  AnthropicProvider,
  AnthropicTransport,
  GeminiProvider,
  GeminiTransport,
  MutableAIProviderRegistry,
  // Supported-model allowlists — so a headless consumer validates a configured model id against
  // foundation-ai's REAL list instead of maintaining a parallel hardcoded copy that silently drifts
  // as the platform adds models (a valid new model would otherwise look like a misconfiguration).
  // GENC-1461, create PR #1644 review.
  SUPPORTED_ANTHROPIC_MODEL_IDS,
  SUPPORTED_GEMINI_MODEL_IDS,
  // The provider wall (GENC-1506). Re-exported for the same anti-drift reason as the model lists
  // above, and it matters more here because the other end of this contract is in ANOTHER REPO:
  // genesis-create's ai-service stamps `PROVIDER_REFUSED_CODE` onto its proxy responses and shows
  // `DEFAULT_PROVIDER_REFUSED_MESSAGE` on its own generation surfaces. Hand-copying either would
  // drift silently — a renamed code stops classifying, and a second copy of the sentence survives
  // the first reword. `ProviderRefusedError` is here so a headless caller can `instanceof` it
  // against the same bundled instance the driver throws from.
  DEFAULT_PROVIDER_REFUSED_MESSAGE,
  PROVIDER_REFUSED_CODE,
  ProviderRefusedError,
  isObservableAIProviderRegistry,
  // Request pricing. Re-exported HERE, not left to a direct `@genesislcap/foundation-ai`
  // import, for the same reason as everything above it: a headless host that adds its own
  // foundation-ai dependency gets a second copy, and the driver's malformed/truncated
  // handling does `instanceof` on the transports' error classes. Reaching the pricing
  // should not cost a consumer that guarantee.
  //
  // These take RAW provider usage rather than a `ChatMessage` — see the foundation-ai
  // module docs. They are for the path where nothing stamped a cost (a proxied or
  // server-side call holding a usage block); when a message already carries `cost`, use
  // it, because it was computed with the per-TTL cache split the message no longer has.
  ANTHROPIC_CACHE_READ_MULTIPLIER,
  ANTHROPIC_CACHE_WRITE_1H_MULTIPLIER,
  ANTHROPIC_CACHE_WRITE_5M_MULTIPLIER,
  anthropicRatesFor,
  anthropicTokenCost,
  GEMINI_CACHED_INPUT_MULTIPLIER,
  GEMINI_LONG_CONTEXT_THRESHOLD,
  geminiRatesFor,
  geminiTokenCost,
  // Resolves a model id to its vendor, so a caller holding only `message.model` can pick
  // between the two cost functions above without maintaining its own model→vendor map.
  vendorOfModel,
} from '@genesislcap/foundation-ai';
export type {
  // Re-exported alongside `sumUsage` below — a consumer that can call the function but cannot NAME
  // its return type has to restate the shape by hand, which is how the buckets get mis-summed.
  AggregateUsage,
  AIProvider,
  AIProviderRegistry,
  AnthropicModelId,
  CachePolicy,
  ChatFallback,
  ChatMessage,
  ChatRequestOptions,
  ChatThinkingPolicy,
  ChatToolChoice,
  ChatToolDefinition,
  ChatToolHandlers,
  GeminiModelId,
  // Pricing input/output shapes, alongside the functions re-exported above — a caller that
  // can invoke them but cannot name their argument or result has to restate the shape by
  // hand, which is how the token buckets get mixed up between the two providers.
  AnthropicUsageRecord,
  GeminiUsageRecord,
  TokenCost,
  TokenCostBreakdown,
  TokenRates,
} from '@genesislcap/foundation-ai';

// Usage/cost summation. A headless consumer attributing spend to a run has no other route to it:
// the transports' `getLifetimeCost()` is per-instance and lifetime-scoped, so a shared registry
// makes it unattributable, and re-deriving cost from token counts is wrong in the one direction
// that matters (`inputTokens` is total prompt size INCLUDING the cached part, so re-pricing charges
// every cached token at full rate). `sumUsage` reads the per-request cost the transports already
// stamped, and recurses into `toolCalls[].subAgentTrace` — where the entire spend of a delegating
// agent lives — and into `compaction.rolledUpUsage`, which is spend whose messages no longer exist.
// Both are invisible when omitted: the total is merely too low, which reads as a cheap run.
//
// `addUsage`/`emptyUsage` are the composition primitives for a conversation that CONTINUES across
// rounds — see the guidance on `sumUsage` itself. `totalTokens` exists because the four buckets of
// an `AggregateUsage` are disjoint and safe to add, which the per-message fields are NOT.
//
// `messageUsage` is the single-message projection of the same arithmetic — what ONE request
// cost, in the same four-bucket shape. It is what prices a turn snapshot (see
// `TurnSnapshot.usage`), and the reason a consumer needs it separately is that the response
// to a *failed* attempt never reaches history, so `sumUsage` over the transcript cannot see
// that spend at all.
export { addUsage, emptyUsage, messageUsage, sumUsage, totalTokens } from './utils/sum-usage';

// Per-call projection, for the cases an aggregate cannot serve: usage rows for
// per-project attribution, a cost dashboard, or auditing which turns came back
// unpriced. `usageRows` is guaranteed to reconcile with `sumUsage` — including spend a
// compaction banked, which has no message of its own and which a naive per-message walk
// therefore drops while the total keeps it. Both take RAW history; `UsageRow` is
// deliberately not a `ChatMessage`, so passing rows back into `sumUsage` (which recurses
// itself, and would double-count) does not compile.
export { usageRows } from './utils/usage-rows';
export type { UsageRow } from './utils/usage-rows';

// Debug-log harvesting (GENC-1461 unified diagnostics). A headless consumer collates its driver's
// log — `buildTimelineEntries({ turnSnapshots: driver.getTurnSnapshots(), messages:
// driver.getHistory(), metaEvents: getMetaEvents(sessionKey) })` → `DiagnosticEntry[]` — ships it to
// the client, which folds it into the assistant's debug log via `InteractionResult.diagnostics`
// (see `ChatDriver.getExternalDiagnostics`). `clearSession(sessionKey)` drops the per-request
// meta-event bucket so the long-lived server process's module registry doesn't grow unbounded.
// All three modules are DOM-clean, so the node entry stays Node-loadable.
export { clearSession, getMetaEvents } from './state/debug-event-log';
export type { MetaEvent } from './state/debug-event-log';
export { buildTimelineEntries } from './state/persistence/build-timeline-entries';
export type { TurnSnapshotLike } from './state/persistence/build-timeline-entries';
// `withFreshMetaSnapshot` matters to a headless consumer that stitches a STORED stream: the
// newest stored `meta-snapshot` is frozen at the last config-signature change, so its context
// and cost figures are as old as that. Pass a fresh snapshot of your own through this before
// `assembleDebugLog`, or state in your own output that the totals are historical.
export { assembleDebugLog, withFreshMetaSnapshot } from './state/persistence/diagnostics';
export type { DebugLog, DiagnosticEntry } from './state/persistence/diagnostics';
