@dudousxd/nestjs-agent-core 0.3.0 → 0.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -181,6 +181,8 @@ interface AgentRunInput {
181
181
  */
182
182
  interface AgentDefinition {
183
183
  name: string;
184
+ /** Human-readable summary from `@Agent({ description })`. Surfaced by the `GET agents` catalog. */
185
+ description?: string;
184
186
  /** Base prompt for this agent. A flat string, or a {@link PromptBuilder} resolved per turn. */
185
187
  systemPrompt?: string | PromptBuilder;
186
188
  /** Allow-list of tool names this agent may use (subset of all registered tools). */
@@ -190,6 +192,16 @@ interface AgentDefinition {
190
192
  modelId?: string;
191
193
  maxSteps?: number;
192
194
  }
195
+ /**
196
+ * The read-model the `GET agents` endpoint returns to a client — the safe public subset of an
197
+ * {@link AgentDefinition} so a host can render a persona picker instead of hardcoding one.
198
+ */
199
+ interface AgentCatalogEntry {
200
+ name: string;
201
+ description: string;
202
+ /** Whether this is the agent a turn uses when the caller names none. Omitted when not the default. */
203
+ isDefault?: boolean;
204
+ }
193
205
  interface ThreadSummary {
194
206
  id: string;
195
207
  title: string;
@@ -592,11 +604,12 @@ interface AgentRunner {
592
604
  * an identity is never invented from a default. See `HeaderActorResolver` for a header-based
593
605
  * resolver suitable for demos and gateways that strip/re-set the headers.
594
606
  *
595
- * `req` is the transport request object, typed `unknown` to keep core framework-agnostic;
596
- * a NestJS/Express app receives the express `Request`.
607
+ * `req` is the transport request object. Defaults to `unknown` to keep core framework-agnostic
608
+ * (a NestJS/Express app receives the express `Request`) — a host may narrow it via
609
+ * `ActorResolver<Request>` instead of writing its own `unknown`-narrowing type guard.
597
610
  */
598
- interface ActorResolver {
599
- resolve(req: unknown): Actor | Promise<Actor>;
611
+ interface ActorResolver<TReq = unknown> {
612
+ resolve(req: TReq): Actor | Promise<Actor>;
600
613
  }
601
614
 
602
615
  /**
@@ -631,6 +644,17 @@ interface ActorSpendRow {
631
644
  requests: number;
632
645
  totalTokens: number;
633
646
  costUsd: number;
647
+ /** Distinct threads the actor used in the range. */
648
+ threadCount: number;
649
+ }
650
+ /** Spend + token totals for one thread over a range. */
651
+ interface ThreadSpendRow {
652
+ threadId: string;
653
+ title: string;
654
+ actorRef: string;
655
+ requests: number;
656
+ totalTokens: number;
657
+ costUsd: number;
634
658
  }
635
659
  /** One point on the daily usage/cost trend. */
636
660
  interface UsageTrendPoint {
@@ -664,11 +688,81 @@ interface ThreadActivityRow {
664
688
  interface AgentGovernanceQueries {
665
689
  spendByModel(range: GovernanceRange): Promise<ModelSpendRow[]>;
666
690
  spendByActor(range: GovernanceRange): Promise<ActorSpendRow[]>;
691
+ /** Top threads by spend within the range, highest cost first, capped at `limit`. */
692
+ spendByThread(range: GovernanceRange, limit: number): Promise<ThreadSpendRow[]>;
667
693
  usageTrend(range: GovernanceRange): Promise<UsageTrendPoint[]>;
668
694
  recentToolCalls(limit: number): Promise<ToolCallActivityRow[]>;
669
695
  recentThreads(limit: number): Promise<ThreadActivityRow[]>;
670
696
  }
671
697
 
698
+ /**
699
+ * The pure aggregation core shared by every {@link import('../spi/governance-queries.js').AgentGovernanceQueries}
700
+ * adapter (MikroORM, Drizzle, in-memory). An adapter's only job is the DB-specific row fetch; the
701
+ * cost formula, the group→sort bucketing, and the day-bounds math live here so all three surfaces
702
+ * report identical numbers.
703
+ */
704
+ /** The current per-1M token prices for one model; cache rates fall back to the input rate. */
705
+ interface ModelPrice {
706
+ inputPricePer1m: number;
707
+ outputPricePer1m: number;
708
+ cacheWritePricePer1m?: number | null;
709
+ cacheReadPricePer1m?: number | null;
710
+ }
711
+ /** The token split of one turn needed to estimate its cost. */
712
+ interface CostUsage {
713
+ inputTokens: number;
714
+ outputTokens: number;
715
+ cacheWriteTokens?: number | null | undefined;
716
+ cacheReadTokens?: number | null | undefined;
717
+ }
718
+ /**
719
+ * A normalized usage row the bucketers consume. Each adapter maps its raw DB row into this shape
720
+ * (MikroORM reads `thread.id` + `createdAt`, Drizzle/in-memory read the flat `threadId` + `day`).
721
+ */
722
+ interface GovernanceUsageInput extends CostUsage {
723
+ modelId: string;
724
+ actorRef: string;
725
+ threadId: string;
726
+ /** The `YYYY-MM-DD` UTC day the row belongs to (its trend bucket). */
727
+ day: string;
728
+ /** Provider-reported spend for the row; wins over the token estimate when present. */
729
+ costUsd?: number | null | undefined;
730
+ }
731
+ /** Thread metadata joined onto a spend bucket. */
732
+ interface ThreadMeta {
733
+ title: string;
734
+ actorRef: string;
735
+ }
736
+ /**
737
+ * Token-ledger estimate for one turn against a pricing row: the uncached input at the input rate,
738
+ * cache-write/cache-read tokens at their own rates (falling back to the input rate when unpriced),
739
+ * plus output at the output rate. An unpriced model (`price === undefined`) contributes 0 — its
740
+ * tokens still count. Cache token counts are subsets of `inputTokens`, so the uncached remainder is
741
+ * the difference.
742
+ */
743
+ declare function estimateCost(usage: CostUsage, price: ModelPrice | undefined): number;
744
+ /** Aggregate usage rows into per-model spend, highest cost first then modelId ascending. */
745
+ declare function bucketByModel(rows: GovernanceUsageInput[], prices: ReadonlyMap<string, ModelPrice>): ModelSpendRow[];
746
+ /** Aggregate usage rows into per-actor spend (with distinct thread counts), highest cost first. */
747
+ declare function bucketByActor(rows: GovernanceUsageInput[], prices: ReadonlyMap<string, ModelPrice>): ActorSpendRow[];
748
+ /**
749
+ * Aggregate usage rows into per-thread spend, highest cost first then threadId ascending, capped at
750
+ * `limit`. A thread absent from `threads` is dropped when `includeUnknownThreads` is false (the SQL
751
+ * adapters fetch only non-deleted threads, so a soft-deleted thread's rows vanish from the ranking);
752
+ * when true it is kept with blank title/actor (the in-memory adapter's semantics).
753
+ */
754
+ declare function bucketByThread(rows: GovernanceUsageInput[], prices: ReadonlyMap<string, ModelPrice>, threads: ReadonlyMap<string, ThreadMeta>, options: {
755
+ limit: number;
756
+ includeUnknownThreads: boolean;
757
+ }): ThreadSpendRow[];
758
+ /** Aggregate usage rows into a daily token/cost trend, ascending by day. */
759
+ declare function bucketUsageTrend(rows: GovernanceUsageInput[], prices: ReadonlyMap<string, ModelPrice>): UsageTrendPoint[];
760
+ /** Turn an inclusive `YYYY-MM-DD` day range into the UTC datetime bounds used to filter usage rows. */
761
+ declare function dayBoundsUtc(range: GovernanceRange): {
762
+ start: Date;
763
+ end: Date;
764
+ };
765
+
672
766
  /** First filter layer: drop tools the actor's role may not invoke. `can` may be async (authz). */
673
767
  declare function filterToolsByRole(tools: ToolSpec[], actor: Actor, policy: RolesPolicy): Promise<ToolSpec[]>;
674
768
  /** Second filter layer: if the agent pins an allow-list, keep only those tool names. */
@@ -877,4 +971,4 @@ declare function publishAgentRunFailed(payload: AgentRunFailed): void;
877
971
  declare function publishAgentDelegated(payload: AgentDelegated): void;
878
972
  declare function publishAgentRetrieved(payload: AgentRetrieved): void;
879
973
 
880
- export { AGENT_ACTOR_RESOLVER, AGENT_DEPS_FACTORY, AGENT_DURABLE_RUNNER, AGENT_EMBEDDING_PROVIDER, AGENT_GOVERNANCE_QUERIES, AGENT_MODEL, AGENT_OPTIONS, AGENT_PRICING_STORE, AGENT_PROMPT_CONTRIBUTORS, AGENT_QUOTA_STORE, AGENT_REGISTRY, AGENT_RETRIEVER, AGENT_ROLES_POLICY, AGENT_RUNNER, AGENT_SINK, AGENT_STORE, AGENT_TOOL_REGISTRY, type Actor, type ActorResolver, type ActorSpendRow, type AgentDefinition, type AgentDelegated, type AgentGovernanceQueries, type AgentLoopDeps, type AgentLoopHooks, type AgentMessageEvent, type AgentPricingStore, type AgentQuotaExceeded, AgentRegistry, type AgentRetrieved, type AgentRunFailed, type AgentRunFinished, type AgentRunInput, type AgentRunStarted, type AgentRunner, type AgentStore, AgentStreamError, type AgentToolCallEvent, type AiToolCtx, type AppendMessageInput, type CreateThreadInput, type CurrentModelPrice, type Decision, DefaultRolesPolicy, type EmbeddingProvider, type GovernanceRange, type MessageRole, type MessageUsage, type ModelMessage, type ModelPriceInput, type ModelProvider, type ModelSpendRow, type ModelTurnArgs, type ModelTurnResult, type PageContext, type Passage, type PromptBuilder, type PromptContext, type PromptContributor, QuotaExceededError, type QuotaState, type QuotaStore, type QuotaView, type RecordToolCallInput, type RecordUsageInput, type RerankOptions, type Reranker, type RetrieveOptions, type Retriever, type RolesPolicy, type SinkWriter, type StoredMessage, type StreamError, type ThreadActivityRow, type ThreadDetail, type ThreadSummary, type TokenStreamSink, type ToolCallActivityRow, type ToolCallRequest, type ToolCallStatus, type ToolDefinition, ToolForbiddenError, type ToolHandler, ToolInputInvalidError, type ToolKind, ToolNotFoundError, ToolRegistry, type ToolResult, type ToolSpec, type UpdateToolCallInput, type UsagePurpose, type UsageTrendPoint, filterToolsByAllowList, filterToolsByRole, publishAgentDelegated, publishAgentMessage, publishAgentQuotaExceeded, publishAgentRetrieved, publishAgentRunFailed, publishAgentRunFinished, publishAgentRunStarted, publishAgentToolCall, runAgentLoop, seedModelPrices };
974
+ export { AGENT_ACTOR_RESOLVER, AGENT_DEPS_FACTORY, AGENT_DURABLE_RUNNER, AGENT_EMBEDDING_PROVIDER, AGENT_GOVERNANCE_QUERIES, AGENT_MODEL, AGENT_OPTIONS, AGENT_PRICING_STORE, AGENT_PROMPT_CONTRIBUTORS, AGENT_QUOTA_STORE, AGENT_REGISTRY, AGENT_RETRIEVER, AGENT_ROLES_POLICY, AGENT_RUNNER, AGENT_SINK, AGENT_STORE, AGENT_TOOL_REGISTRY, type Actor, type ActorResolver, type ActorSpendRow, type AgentCatalogEntry, type AgentDefinition, type AgentDelegated, type AgentGovernanceQueries, type AgentLoopDeps, type AgentLoopHooks, type AgentMessageEvent, type AgentPricingStore, type AgentQuotaExceeded, AgentRegistry, type AgentRetrieved, type AgentRunFailed, type AgentRunFinished, type AgentRunInput, type AgentRunStarted, type AgentRunner, type AgentStore, AgentStreamError, type AgentToolCallEvent, type AiToolCtx, type AppendMessageInput, type CostUsage, type CreateThreadInput, type CurrentModelPrice, type Decision, DefaultRolesPolicy, type EmbeddingProvider, type GovernanceRange, type GovernanceUsageInput, type MessageRole, type MessageUsage, type ModelMessage, type ModelPrice, type ModelPriceInput, type ModelProvider, type ModelSpendRow, type ModelTurnArgs, type ModelTurnResult, type PageContext, type Passage, type PromptBuilder, type PromptContext, type PromptContributor, QuotaExceededError, type QuotaState, type QuotaStore, type QuotaView, type RecordToolCallInput, type RecordUsageInput, type RerankOptions, type Reranker, type RetrieveOptions, type Retriever, type RolesPolicy, type SinkWriter, type StoredMessage, type StreamError, type ThreadActivityRow, type ThreadDetail, type ThreadMeta, type ThreadSpendRow, type ThreadSummary, type TokenStreamSink, type ToolCallActivityRow, type ToolCallRequest, type ToolCallStatus, type ToolDefinition, ToolForbiddenError, type ToolHandler, ToolInputInvalidError, type ToolKind, ToolNotFoundError, ToolRegistry, type ToolResult, type ToolSpec, type UpdateToolCallInput, type UsagePurpose, type UsageTrendPoint, bucketByActor, bucketByModel, bucketByThread, bucketUsageTrend, dayBoundsUtc, estimateCost, filterToolsByAllowList, filterToolsByRole, publishAgentDelegated, publishAgentMessage, publishAgentQuotaExceeded, publishAgentRetrieved, publishAgentRunFailed, publishAgentRunFinished, publishAgentRunStarted, publishAgentToolCall, runAgentLoop, seedModelPrices };
package/dist/index.d.ts CHANGED
@@ -181,6 +181,8 @@ interface AgentRunInput {
181
181
  */
182
182
  interface AgentDefinition {
183
183
  name: string;
184
+ /** Human-readable summary from `@Agent({ description })`. Surfaced by the `GET agents` catalog. */
185
+ description?: string;
184
186
  /** Base prompt for this agent. A flat string, or a {@link PromptBuilder} resolved per turn. */
185
187
  systemPrompt?: string | PromptBuilder;
186
188
  /** Allow-list of tool names this agent may use (subset of all registered tools). */
@@ -190,6 +192,16 @@ interface AgentDefinition {
190
192
  modelId?: string;
191
193
  maxSteps?: number;
192
194
  }
195
+ /**
196
+ * The read-model the `GET agents` endpoint returns to a client — the safe public subset of an
197
+ * {@link AgentDefinition} so a host can render a persona picker instead of hardcoding one.
198
+ */
199
+ interface AgentCatalogEntry {
200
+ name: string;
201
+ description: string;
202
+ /** Whether this is the agent a turn uses when the caller names none. Omitted when not the default. */
203
+ isDefault?: boolean;
204
+ }
193
205
  interface ThreadSummary {
194
206
  id: string;
195
207
  title: string;
@@ -592,11 +604,12 @@ interface AgentRunner {
592
604
  * an identity is never invented from a default. See `HeaderActorResolver` for a header-based
593
605
  * resolver suitable for demos and gateways that strip/re-set the headers.
594
606
  *
595
- * `req` is the transport request object, typed `unknown` to keep core framework-agnostic;
596
- * a NestJS/Express app receives the express `Request`.
607
+ * `req` is the transport request object. Defaults to `unknown` to keep core framework-agnostic
608
+ * (a NestJS/Express app receives the express `Request`) — a host may narrow it via
609
+ * `ActorResolver<Request>` instead of writing its own `unknown`-narrowing type guard.
597
610
  */
598
- interface ActorResolver {
599
- resolve(req: unknown): Actor | Promise<Actor>;
611
+ interface ActorResolver<TReq = unknown> {
612
+ resolve(req: TReq): Actor | Promise<Actor>;
600
613
  }
601
614
 
602
615
  /**
@@ -631,6 +644,17 @@ interface ActorSpendRow {
631
644
  requests: number;
632
645
  totalTokens: number;
633
646
  costUsd: number;
647
+ /** Distinct threads the actor used in the range. */
648
+ threadCount: number;
649
+ }
650
+ /** Spend + token totals for one thread over a range. */
651
+ interface ThreadSpendRow {
652
+ threadId: string;
653
+ title: string;
654
+ actorRef: string;
655
+ requests: number;
656
+ totalTokens: number;
657
+ costUsd: number;
634
658
  }
635
659
  /** One point on the daily usage/cost trend. */
636
660
  interface UsageTrendPoint {
@@ -664,11 +688,81 @@ interface ThreadActivityRow {
664
688
  interface AgentGovernanceQueries {
665
689
  spendByModel(range: GovernanceRange): Promise<ModelSpendRow[]>;
666
690
  spendByActor(range: GovernanceRange): Promise<ActorSpendRow[]>;
691
+ /** Top threads by spend within the range, highest cost first, capped at `limit`. */
692
+ spendByThread(range: GovernanceRange, limit: number): Promise<ThreadSpendRow[]>;
667
693
  usageTrend(range: GovernanceRange): Promise<UsageTrendPoint[]>;
668
694
  recentToolCalls(limit: number): Promise<ToolCallActivityRow[]>;
669
695
  recentThreads(limit: number): Promise<ThreadActivityRow[]>;
670
696
  }
671
697
 
698
+ /**
699
+ * The pure aggregation core shared by every {@link import('../spi/governance-queries.js').AgentGovernanceQueries}
700
+ * adapter (MikroORM, Drizzle, in-memory). An adapter's only job is the DB-specific row fetch; the
701
+ * cost formula, the group→sort bucketing, and the day-bounds math live here so all three surfaces
702
+ * report identical numbers.
703
+ */
704
+ /** The current per-1M token prices for one model; cache rates fall back to the input rate. */
705
+ interface ModelPrice {
706
+ inputPricePer1m: number;
707
+ outputPricePer1m: number;
708
+ cacheWritePricePer1m?: number | null;
709
+ cacheReadPricePer1m?: number | null;
710
+ }
711
+ /** The token split of one turn needed to estimate its cost. */
712
+ interface CostUsage {
713
+ inputTokens: number;
714
+ outputTokens: number;
715
+ cacheWriteTokens?: number | null | undefined;
716
+ cacheReadTokens?: number | null | undefined;
717
+ }
718
+ /**
719
+ * A normalized usage row the bucketers consume. Each adapter maps its raw DB row into this shape
720
+ * (MikroORM reads `thread.id` + `createdAt`, Drizzle/in-memory read the flat `threadId` + `day`).
721
+ */
722
+ interface GovernanceUsageInput extends CostUsage {
723
+ modelId: string;
724
+ actorRef: string;
725
+ threadId: string;
726
+ /** The `YYYY-MM-DD` UTC day the row belongs to (its trend bucket). */
727
+ day: string;
728
+ /** Provider-reported spend for the row; wins over the token estimate when present. */
729
+ costUsd?: number | null | undefined;
730
+ }
731
+ /** Thread metadata joined onto a spend bucket. */
732
+ interface ThreadMeta {
733
+ title: string;
734
+ actorRef: string;
735
+ }
736
+ /**
737
+ * Token-ledger estimate for one turn against a pricing row: the uncached input at the input rate,
738
+ * cache-write/cache-read tokens at their own rates (falling back to the input rate when unpriced),
739
+ * plus output at the output rate. An unpriced model (`price === undefined`) contributes 0 — its
740
+ * tokens still count. Cache token counts are subsets of `inputTokens`, so the uncached remainder is
741
+ * the difference.
742
+ */
743
+ declare function estimateCost(usage: CostUsage, price: ModelPrice | undefined): number;
744
+ /** Aggregate usage rows into per-model spend, highest cost first then modelId ascending. */
745
+ declare function bucketByModel(rows: GovernanceUsageInput[], prices: ReadonlyMap<string, ModelPrice>): ModelSpendRow[];
746
+ /** Aggregate usage rows into per-actor spend (with distinct thread counts), highest cost first. */
747
+ declare function bucketByActor(rows: GovernanceUsageInput[], prices: ReadonlyMap<string, ModelPrice>): ActorSpendRow[];
748
+ /**
749
+ * Aggregate usage rows into per-thread spend, highest cost first then threadId ascending, capped at
750
+ * `limit`. A thread absent from `threads` is dropped when `includeUnknownThreads` is false (the SQL
751
+ * adapters fetch only non-deleted threads, so a soft-deleted thread's rows vanish from the ranking);
752
+ * when true it is kept with blank title/actor (the in-memory adapter's semantics).
753
+ */
754
+ declare function bucketByThread(rows: GovernanceUsageInput[], prices: ReadonlyMap<string, ModelPrice>, threads: ReadonlyMap<string, ThreadMeta>, options: {
755
+ limit: number;
756
+ includeUnknownThreads: boolean;
757
+ }): ThreadSpendRow[];
758
+ /** Aggregate usage rows into a daily token/cost trend, ascending by day. */
759
+ declare function bucketUsageTrend(rows: GovernanceUsageInput[], prices: ReadonlyMap<string, ModelPrice>): UsageTrendPoint[];
760
+ /** Turn an inclusive `YYYY-MM-DD` day range into the UTC datetime bounds used to filter usage rows. */
761
+ declare function dayBoundsUtc(range: GovernanceRange): {
762
+ start: Date;
763
+ end: Date;
764
+ };
765
+
672
766
  /** First filter layer: drop tools the actor's role may not invoke. `can` may be async (authz). */
673
767
  declare function filterToolsByRole(tools: ToolSpec[], actor: Actor, policy: RolesPolicy): Promise<ToolSpec[]>;
674
768
  /** Second filter layer: if the agent pins an allow-list, keep only those tool names. */
@@ -877,4 +971,4 @@ declare function publishAgentRunFailed(payload: AgentRunFailed): void;
877
971
  declare function publishAgentDelegated(payload: AgentDelegated): void;
878
972
  declare function publishAgentRetrieved(payload: AgentRetrieved): void;
879
973
 
880
- export { AGENT_ACTOR_RESOLVER, AGENT_DEPS_FACTORY, AGENT_DURABLE_RUNNER, AGENT_EMBEDDING_PROVIDER, AGENT_GOVERNANCE_QUERIES, AGENT_MODEL, AGENT_OPTIONS, AGENT_PRICING_STORE, AGENT_PROMPT_CONTRIBUTORS, AGENT_QUOTA_STORE, AGENT_REGISTRY, AGENT_RETRIEVER, AGENT_ROLES_POLICY, AGENT_RUNNER, AGENT_SINK, AGENT_STORE, AGENT_TOOL_REGISTRY, type Actor, type ActorResolver, type ActorSpendRow, type AgentDefinition, type AgentDelegated, type AgentGovernanceQueries, type AgentLoopDeps, type AgentLoopHooks, type AgentMessageEvent, type AgentPricingStore, type AgentQuotaExceeded, AgentRegistry, type AgentRetrieved, type AgentRunFailed, type AgentRunFinished, type AgentRunInput, type AgentRunStarted, type AgentRunner, type AgentStore, AgentStreamError, type AgentToolCallEvent, type AiToolCtx, type AppendMessageInput, type CreateThreadInput, type CurrentModelPrice, type Decision, DefaultRolesPolicy, type EmbeddingProvider, type GovernanceRange, type MessageRole, type MessageUsage, type ModelMessage, type ModelPriceInput, type ModelProvider, type ModelSpendRow, type ModelTurnArgs, type ModelTurnResult, type PageContext, type Passage, type PromptBuilder, type PromptContext, type PromptContributor, QuotaExceededError, type QuotaState, type QuotaStore, type QuotaView, type RecordToolCallInput, type RecordUsageInput, type RerankOptions, type Reranker, type RetrieveOptions, type Retriever, type RolesPolicy, type SinkWriter, type StoredMessage, type StreamError, type ThreadActivityRow, type ThreadDetail, type ThreadSummary, type TokenStreamSink, type ToolCallActivityRow, type ToolCallRequest, type ToolCallStatus, type ToolDefinition, ToolForbiddenError, type ToolHandler, ToolInputInvalidError, type ToolKind, ToolNotFoundError, ToolRegistry, type ToolResult, type ToolSpec, type UpdateToolCallInput, type UsagePurpose, type UsageTrendPoint, filterToolsByAllowList, filterToolsByRole, publishAgentDelegated, publishAgentMessage, publishAgentQuotaExceeded, publishAgentRetrieved, publishAgentRunFailed, publishAgentRunFinished, publishAgentRunStarted, publishAgentToolCall, runAgentLoop, seedModelPrices };
974
+ export { AGENT_ACTOR_RESOLVER, AGENT_DEPS_FACTORY, AGENT_DURABLE_RUNNER, AGENT_EMBEDDING_PROVIDER, AGENT_GOVERNANCE_QUERIES, AGENT_MODEL, AGENT_OPTIONS, AGENT_PRICING_STORE, AGENT_PROMPT_CONTRIBUTORS, AGENT_QUOTA_STORE, AGENT_REGISTRY, AGENT_RETRIEVER, AGENT_ROLES_POLICY, AGENT_RUNNER, AGENT_SINK, AGENT_STORE, AGENT_TOOL_REGISTRY, type Actor, type ActorResolver, type ActorSpendRow, type AgentCatalogEntry, type AgentDefinition, type AgentDelegated, type AgentGovernanceQueries, type AgentLoopDeps, type AgentLoopHooks, type AgentMessageEvent, type AgentPricingStore, type AgentQuotaExceeded, AgentRegistry, type AgentRetrieved, type AgentRunFailed, type AgentRunFinished, type AgentRunInput, type AgentRunStarted, type AgentRunner, type AgentStore, AgentStreamError, type AgentToolCallEvent, type AiToolCtx, type AppendMessageInput, type CostUsage, type CreateThreadInput, type CurrentModelPrice, type Decision, DefaultRolesPolicy, type EmbeddingProvider, type GovernanceRange, type GovernanceUsageInput, type MessageRole, type MessageUsage, type ModelMessage, type ModelPrice, type ModelPriceInput, type ModelProvider, type ModelSpendRow, type ModelTurnArgs, type ModelTurnResult, type PageContext, type Passage, type PromptBuilder, type PromptContext, type PromptContributor, QuotaExceededError, type QuotaState, type QuotaStore, type QuotaView, type RecordToolCallInput, type RecordUsageInput, type RerankOptions, type Reranker, type RetrieveOptions, type Retriever, type RolesPolicy, type SinkWriter, type StoredMessage, type StreamError, type ThreadActivityRow, type ThreadDetail, type ThreadMeta, type ThreadSpendRow, type ThreadSummary, type TokenStreamSink, type ToolCallActivityRow, type ToolCallRequest, type ToolCallStatus, type ToolDefinition, ToolForbiddenError, type ToolHandler, ToolInputInvalidError, type ToolKind, ToolNotFoundError, ToolRegistry, type ToolResult, type ToolSpec, type UpdateToolCallInput, type UsagePurpose, type UsageTrendPoint, bucketByActor, bucketByModel, bucketByThread, bucketUsageTrend, dayBoundsUtc, estimateCost, filterToolsByAllowList, filterToolsByRole, publishAgentDelegated, publishAgentMessage, publishAgentQuotaExceeded, publishAgentRetrieved, publishAgentRunFailed, publishAgentRunFinished, publishAgentRunStarted, publishAgentToolCall, runAgentLoop, seedModelPrices };
package/dist/index.js CHANGED
@@ -41,6 +41,142 @@ async function seedModelPrices(store, prices) {
41
41
  }
42
42
  __name(seedModelPrices, "seedModelPrices");
43
43
 
44
+ // src/governance/compute.ts
45
+ function estimateCost(usage, price) {
46
+ if (price === void 0) {
47
+ return 0;
48
+ }
49
+ const cacheWriteTokens = usage.cacheWriteTokens ?? 0;
50
+ const cacheReadTokens = usage.cacheReadTokens ?? 0;
51
+ const uncachedInputTokens = usage.inputTokens - cacheWriteTokens - cacheReadTokens;
52
+ return uncachedInputTokens / 1e6 * price.inputPricePer1m + cacheWriteTokens / 1e6 * (price.cacheWritePricePer1m ?? price.inputPricePer1m) + cacheReadTokens / 1e6 * (price.cacheReadPricePer1m ?? price.inputPricePer1m) + usage.outputTokens / 1e6 * price.outputPricePer1m;
53
+ }
54
+ __name(estimateCost, "estimateCost");
55
+ function rowCost(row, prices) {
56
+ return row.costUsd ?? estimateCost(row, prices.get(row.modelId));
57
+ }
58
+ __name(rowCost, "rowCost");
59
+ function bucketByModel(rows, prices) {
60
+ const byModel = /* @__PURE__ */ new Map();
61
+ for (const row of rows) {
62
+ const bucket = byModel.get(row.modelId) ?? {
63
+ requests: 0,
64
+ inputTokens: 0,
65
+ outputTokens: 0,
66
+ costUsd: 0
67
+ };
68
+ bucket.requests += 1;
69
+ bucket.inputTokens += row.inputTokens;
70
+ bucket.outputTokens += row.outputTokens;
71
+ bucket.costUsd += rowCost(row, prices);
72
+ byModel.set(row.modelId, bucket);
73
+ }
74
+ const result = [];
75
+ for (const [modelId, bucket] of byModel) {
76
+ result.push({
77
+ modelId,
78
+ requests: bucket.requests,
79
+ inputTokens: bucket.inputTokens,
80
+ outputTokens: bucket.outputTokens,
81
+ costUsd: bucket.costUsd
82
+ });
83
+ }
84
+ result.sort((left, right) => right.costUsd - left.costUsd || left.modelId.localeCompare(right.modelId));
85
+ return result;
86
+ }
87
+ __name(bucketByModel, "bucketByModel");
88
+ function bucketByActor(rows, prices) {
89
+ const byActor = /* @__PURE__ */ new Map();
90
+ for (const row of rows) {
91
+ const bucket = byActor.get(row.actorRef) ?? {
92
+ requests: 0,
93
+ totalTokens: 0,
94
+ costUsd: 0,
95
+ threadIds: /* @__PURE__ */ new Set()
96
+ };
97
+ bucket.requests += 1;
98
+ bucket.totalTokens += row.inputTokens + row.outputTokens;
99
+ bucket.costUsd += rowCost(row, prices);
100
+ bucket.threadIds.add(row.threadId);
101
+ byActor.set(row.actorRef, bucket);
102
+ }
103
+ const result = [];
104
+ for (const [actorRef, bucket] of byActor) {
105
+ result.push({
106
+ actorRef,
107
+ requests: bucket.requests,
108
+ totalTokens: bucket.totalTokens,
109
+ costUsd: bucket.costUsd,
110
+ threadCount: bucket.threadIds.size
111
+ });
112
+ }
113
+ result.sort((left, right) => right.costUsd - left.costUsd || left.actorRef.localeCompare(right.actorRef));
114
+ return result;
115
+ }
116
+ __name(bucketByActor, "bucketByActor");
117
+ function bucketByThread(rows, prices, threads, options) {
118
+ const byThread = /* @__PURE__ */ new Map();
119
+ for (const row of rows) {
120
+ const bucket = byThread.get(row.threadId) ?? {
121
+ requests: 0,
122
+ totalTokens: 0,
123
+ costUsd: 0
124
+ };
125
+ bucket.requests += 1;
126
+ bucket.totalTokens += row.inputTokens + row.outputTokens;
127
+ bucket.costUsd += rowCost(row, prices);
128
+ byThread.set(row.threadId, bucket);
129
+ }
130
+ const result = [];
131
+ for (const [threadId, bucket] of byThread) {
132
+ const thread = threads.get(threadId);
133
+ if (thread === void 0 && !options.includeUnknownThreads) {
134
+ continue;
135
+ }
136
+ result.push({
137
+ threadId,
138
+ title: thread?.title ?? "",
139
+ actorRef: thread?.actorRef ?? "",
140
+ requests: bucket.requests,
141
+ totalTokens: bucket.totalTokens,
142
+ costUsd: bucket.costUsd
143
+ });
144
+ }
145
+ result.sort((left, right) => right.costUsd - left.costUsd || left.threadId.localeCompare(right.threadId));
146
+ return result.slice(0, options.limit);
147
+ }
148
+ __name(bucketByThread, "bucketByThread");
149
+ function bucketUsageTrend(rows, prices) {
150
+ const byDay = /* @__PURE__ */ new Map();
151
+ for (const row of rows) {
152
+ const bucket = byDay.get(row.day) ?? {
153
+ totalTokens: 0,
154
+ costUsd: 0
155
+ };
156
+ bucket.totalTokens += row.inputTokens + row.outputTokens;
157
+ bucket.costUsd += rowCost(row, prices);
158
+ byDay.set(row.day, bucket);
159
+ }
160
+ const result = [];
161
+ for (const [day, bucket] of byDay) {
162
+ result.push({
163
+ day,
164
+ totalTokens: bucket.totalTokens,
165
+ costUsd: bucket.costUsd
166
+ });
167
+ }
168
+ result.sort((left, right) => left.day.localeCompare(right.day));
169
+ return result;
170
+ }
171
+ __name(bucketUsageTrend, "bucketUsageTrend");
172
+ function dayBoundsUtc(range) {
173
+ return {
174
+ start: /* @__PURE__ */ new Date(`${range.fromDay}T00:00:00.000Z`),
175
+ end: /* @__PURE__ */ new Date(`${range.toDay}T23:59:59.999Z`)
176
+ };
177
+ }
178
+ __name(dayBoundsUtc, "dayBoundsUtc");
179
+
44
180
  // src/tool-filters.ts
45
181
  async function filterToolsByRole(tools, actor, policy) {
46
182
  const checked = await Promise.all(tools.map(async (tool) => ({
@@ -721,6 +857,12 @@ export {
721
857
  ToolInputInvalidError,
722
858
  ToolNotFoundError,
723
859
  ToolRegistry,
860
+ bucketByActor,
861
+ bucketByModel,
862
+ bucketByThread,
863
+ bucketUsageTrend,
864
+ dayBoundsUtc,
865
+ estimateCost,
724
866
  filterToolsByAllowList,
725
867
  filterToolsByRole,
726
868
  publishAgentDelegated,