@agentfield/sdk 0.1.111-rc.1 → 0.1.111-rc.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.ts CHANGED
@@ -150,6 +150,15 @@ declare class AIClient {
150
150
  * Exposed for use by the tool-calling loop.
151
151
  */
152
152
  getModel(options?: AIRequestOptions): _ai_sdk_provider.LanguageModelV3;
153
+ /**
154
+ * Resolve the effective provider/model pair for a request without building
155
+ * the model. Used by usage tracking to attribute token/cost entries to the
156
+ * model actually called.
157
+ */
158
+ resolveModelChoice(options?: AIRequestOptions): {
159
+ provider: NonNullable<AIConfig['provider']>;
160
+ modelName: string;
161
+ };
153
162
  private buildModel;
154
163
  private buildEmbeddingModel;
155
164
  private openRouterHeaders;
@@ -372,6 +381,142 @@ declare class ExecutionLogger {
372
381
  }
373
382
  declare function createExecutionLogger(options?: ExecutionLoggerOptions): ExecutionLogger;
374
383
 
384
+ /**
385
+ * Per-execution LLM cost and token-usage tracking.
386
+ *
387
+ * Mirrors the Python SDK's `agentfield/cost_tracker.py`: a `CostTracker`
388
+ * accumulates one `CostEntry` per LLM (or coding-agent harness) call made
389
+ * during a single reasoner execution, and `serialize()` emits the
390
+ * cross-language wire contract consumed by the control plane's usage-ingest
391
+ * path (see the Go `parseUsageEntries`).
392
+ */
393
+ /**
394
+ * Reserved envelope key used to attach the serialized usage summary to a
395
+ * synchronous 200 result body. Namespaced so it cannot collide with user data:
396
+ * a plain "usage" key in an agent's own result object is user payload and must
397
+ * never be touched. The control plane strips exactly this key back out (see
398
+ * the Go `extractUsageFromResult`). `__agentfield_`-prefixed keys are reserved
399
+ * for SDK<->control-plane transport.
400
+ */
401
+ declare const USAGE_ENVELOPE_KEY = "__agentfield_usage__";
402
+ /** A single LLM (or harness) call usage record. */
403
+ interface CostEntry {
404
+ model: string;
405
+ inputTokens: number;
406
+ outputTokens: number;
407
+ totalTokens: number;
408
+ /**
409
+ * Cost may be unknown (provider gave no figure) — tokens are recorded
410
+ * regardless, so cost is nullable and never gates them.
411
+ */
412
+ costUsd: number | null;
413
+ reasonerName: string | null;
414
+ /** "llm" for direct model calls, "harness" for coding-agent runs. */
415
+ source: 'llm' | 'harness';
416
+ /** e.g. "anthropic", "openrouter" — derived from the model slug if unset. */
417
+ provider: string | null;
418
+ /** e.g. "claude_code" for harness-originated entries; null for plain LLM. */
419
+ harness: string | null;
420
+ cacheReadTokens: number;
421
+ cacheCreationTokens: number;
422
+ /** Where costUsd came from: "provider" | null. */
423
+ costSource: string | null;
424
+ }
425
+ /** Input accepted by {@link CostTracker.record}. */
426
+ interface CostEntryInit {
427
+ model: string;
428
+ inputTokens?: number;
429
+ outputTokens?: number;
430
+ totalTokens?: number;
431
+ costUsd?: number | null;
432
+ reasonerName?: string | null;
433
+ source?: 'llm' | 'harness';
434
+ provider?: string | null;
435
+ harness?: string | null;
436
+ cacheReadTokens?: number;
437
+ cacheCreationTokens?: number;
438
+ costSource?: string | null;
439
+ }
440
+ /** Wire form of a single usage entry (snake_case cross-language contract). */
441
+ interface UsageEntryWire {
442
+ source: string;
443
+ provider: string | null;
444
+ model: string;
445
+ harness: string | null;
446
+ reasoner: string | null;
447
+ input_tokens: number;
448
+ output_tokens: number;
449
+ cache_read_tokens: number;
450
+ cache_creation_tokens: number;
451
+ total_tokens: number;
452
+ cost_usd: number | null;
453
+ cost_source: string | null;
454
+ }
455
+ /** Wire form of the usage summary attached to execution envelopes. */
456
+ interface UsageSummaryWire {
457
+ /** Null when no entry had a known cost; otherwise sum rounded to 6 decimals. */
458
+ total_cost_usd: number | null;
459
+ total_input_tokens: number;
460
+ total_output_tokens: number;
461
+ total_tokens: number;
462
+ entries: UsageEntryWire[];
463
+ }
464
+ /**
465
+ * Best-effort provider name from a model slug.
466
+ *
467
+ * `anthropic/claude-opus-4-8` -> `anthropic`,
468
+ * `openrouter/anthropic/claude` -> `openrouter`,
469
+ * a bare `gpt-4o` (no provider prefix) -> `null`.
470
+ */
471
+ declare function deriveProvider(model: string | null | undefined): string | null;
472
+ /** Accumulates LLM/harness usage for a single execution run. */
473
+ declare class CostTracker {
474
+ private entries;
475
+ /**
476
+ * Record a single call's usage.
477
+ *
478
+ * Cost is optional: a call with known token counts but unknown price is
479
+ * still recorded (`costUsd: null`) so tokens are never discarded.
480
+ */
481
+ record(init: CostEntryInit): void;
482
+ /** Total accumulated cost in USD (unknown costs count as zero). */
483
+ get totalCostUsd(): number;
484
+ /** Total tokens used across all calls (per-entry total, no fallback). */
485
+ get totalTokens(): number;
486
+ /** Number of calls tracked. */
487
+ get callCount(): number;
488
+ get hasEntries(): boolean;
489
+ /**
490
+ * Return the transport contract form attached to execution envelopes.
491
+ *
492
+ * Matches the Python SDK's `CostTracker.serialize()` byte-for-byte in shape:
493
+ * unset string fields serialize as null, `total_cost_usd` is null when no
494
+ * entry had a known cost, and a per-entry `total_tokens` of zero falls back
495
+ * to input + output.
496
+ */
497
+ serialize(): UsageSummaryWire;
498
+ /** Clear all tracked entries. */
499
+ reset(): void;
500
+ }
501
+ /**
502
+ * Return the transport `usage` object, or null when there is nothing to
503
+ * report. Zero entries means no usage key at all per the contract, so callers
504
+ * must skip attaching `usage` on null.
505
+ */
506
+ declare function usageSummaryOrNull(tracker: CostTracker | undefined | null): UsageSummaryWire | null;
507
+ /**
508
+ * Attach usage to a synchronous 200 result body.
509
+ *
510
+ * The summary is merged as a sibling under the reserved
511
+ * {@link USAGE_ENVELOPE_KEY}; the control plane strips exactly that key back
512
+ * out, so a user result that legitimately contains its own "usage" key is
513
+ * never touched. Only plain-object results can carry usage this way —
514
+ * non-object results (arrays, scalars, class instances, null) are returned
515
+ * unchanged and their usage flows via the async status-callback path instead
516
+ * (the production path). No-usage trackers leave any result unchanged.
517
+ */
518
+ declare function attachUsageToSyncResult(result: unknown, tracker: CostTracker | undefined | null): unknown;
519
+
375
520
  interface ExecutionStatusUpdate {
376
521
  status?: string;
377
522
  result?: Record<string, any>;
@@ -531,6 +676,13 @@ declare class AgentFieldClient {
531
676
  durationMs?: number;
532
677
  completedAt?: string;
533
678
  reasoner?: string;
679
+ /**
680
+ * Serialized token/cost usage summary for the execution (the
681
+ * CostTracker wire contract). Omitted entirely when the execution
682
+ * recorded no usage. Attached on failure/timeout/cancelled terminal
683
+ * reports too — a reasoner may have consumed tokens before ending.
684
+ */
685
+ usage?: UsageSummaryWire;
534
686
  }, maxRetries?: number): Promise<boolean>;
535
687
  discoverCapabilities(options?: DiscoveryOptions): Promise<DiscoveryResult>;
536
688
  private mapDiscoveryResponse;
@@ -598,12 +750,21 @@ declare class ExecutionContext {
598
750
  readonly req: express.Request;
599
751
  readonly res: express.Response;
600
752
  readonly agent: Agent;
753
+ /**
754
+ * Per-execution LLM/harness usage accumulator. Each top-level execution
755
+ * binds a fresh tracker (isolated across concurrent executions via the
756
+ * AsyncLocalStorage this context lives in); nested local `agent.call()`
757
+ * executions inherit the parent's tracker so their usage rolls up into the
758
+ * parent's report.
759
+ */
760
+ readonly costTracker: CostTracker;
601
761
  constructor(params: {
602
762
  input: any;
603
763
  metadata: ExecutionMetadata;
604
764
  req: express.Request;
605
765
  res: express.Response;
606
766
  agent: Agent;
767
+ costTracker?: CostTracker;
607
768
  });
608
769
  get logger(): ExecutionLogger;
609
770
  static run<T>(ctx: ExecutionContext, fn: () => T): T;
@@ -838,7 +999,10 @@ declare function buildToolConfig(toolsParam: ToolsOption, agent: Agent): Promise
838
999
  config: ToolCallConfig;
839
1000
  needsLazyHydration: boolean;
840
1001
  }>;
841
- declare function executeToolCallLoop(agent: Agent, prompt: string, toolMap: ToolSet, config: ToolCallConfig, needsLazyHydration: boolean, buildModel: () => any, options?: AIRequestOptions): Promise<{
1002
+ declare function executeToolCallLoop(agent: Agent, prompt: string, toolMap: ToolSet, config: ToolCallConfig, needsLazyHydration: boolean, buildModel: () => any, options?: AIRequestOptions, modelChoice?: {
1003
+ provider?: string;
1004
+ modelName?: string;
1005
+ }): Promise<{
842
1006
  text: string;
843
1007
  trace: ToolCallTrace;
844
1008
  }>;
@@ -968,6 +1132,13 @@ declare class ReasonerContext<TInput = any> {
968
1132
  readonly memory: MemoryInterface;
969
1133
  readonly workflow: WorkflowReporter;
970
1134
  readonly did: DidInterface;
1135
+ /**
1136
+ * Per-execution token/cost usage accumulator. LLM calls made through
1137
+ * `ctx.ai()` / `ctx.aiWithTools()` and harness runs record into it
1138
+ * automatically; reasoner authors may also `record()` custom entries. Its
1139
+ * serialized summary is attached to the execution's terminal report.
1140
+ */
1141
+ readonly costTracker: CostTracker;
971
1142
  /**
972
1143
  * AbortSignal that fires when the control plane cancels this execution
973
1144
  * (per-execution cancel, the bottom-up cancel-tree endpoint, or any
@@ -1005,6 +1176,7 @@ declare class ReasonerContext<TInput = any> {
1005
1176
  workflow: WorkflowReporter;
1006
1177
  did: DidInterface;
1007
1178
  signal?: AbortSignal;
1179
+ costTracker?: CostTracker;
1008
1180
  trigger?: TriggerContext;
1009
1181
  });
1010
1182
  ai<T>(prompt: string, options: AIRequestOptions & {
@@ -1184,6 +1356,14 @@ interface Metrics {
1184
1356
  totalCostUsd?: number;
1185
1357
  usage?: Record<string, unknown>;
1186
1358
  sessionId: string;
1359
+ /** Token counts parsed from the provider's result payload (best effort). */
1360
+ inputTokens?: number;
1361
+ outputTokens?: number;
1362
+ cacheReadTokens?: number;
1363
+ cacheCreationTokens?: number;
1364
+ totalTokens?: number;
1365
+ /** Model reported by the provider, when available. */
1366
+ model?: string;
1187
1367
  }
1188
1368
  interface RawResult {
1189
1369
  result?: string;
@@ -1202,6 +1382,14 @@ interface HarnessResult {
1202
1382
  durationMs: number;
1203
1383
  sessionId: string;
1204
1384
  messages: Array<Record<string, unknown>>;
1385
+ /** Token counts reported by the harness provider, when available. */
1386
+ inputTokens?: number;
1387
+ outputTokens?: number;
1388
+ cacheReadTokens?: number;
1389
+ cacheCreationTokens?: number;
1390
+ totalTokens?: number;
1391
+ /** Model reported by the harness provider, when available. */
1392
+ model?: string;
1205
1393
  readonly text: string;
1206
1394
  }
1207
1395
  declare function createHarnessResult(partial?: Partial<Omit<HarnessResult, 'text'>>): HarnessResult;
@@ -1600,6 +1788,15 @@ declare class Agent {
1600
1788
  getExecutionLogger(): ExecutionLogger;
1601
1789
  getHarnessRunner(): Promise<HarnessRunner>;
1602
1790
  harness(prompt: string, options?: HarnessOptions): Promise<HarnessResult>;
1791
+ /**
1792
+ * Record a harness run's token/cost usage into the current execution's
1793
+ * tracker. Mirrors the Python SDK's `_record_harness_usage`: a no-op when
1794
+ * the harness reported neither tokens nor cost (the common case for
1795
+ * providers that don't expose usage) so empty entries are never emitted;
1796
+ * cost is threaded even when tokens are unknown, and vice versa. Never
1797
+ * throws — usage capture is best-effort.
1798
+ */
1799
+ private recordHarnessUsage;
1603
1800
  getMemoryInterface(metadata?: ExecutionMetadata): MemoryInterface;
1604
1801
  getWorkflowReporter(metadata: ExecutionMetadata): WorkflowReporter;
1605
1802
  getDidInterface(metadata: ExecutionMetadata, defaultInput?: any, targetName?: string): DidInterface;
@@ -2769,4 +2966,4 @@ declare function simulateSchedule<R>(handler: (ctx: SimulatedContext) => R | Pro
2769
2966
  */
2770
2967
  declare function loadFixture(source: string): Record<string, unknown>;
2771
2968
 
2772
- export { ACTIVE_STATUSES, AIClient, type AIConfig, type AIEmbeddingOptions, type AIRequestOptions, type AIStream, type AIToolRequestOptions, Agent, type AgentCapability, type AgentConfig, type AgentHandler, AgentRouter, type AgentRouterOptions, type AgentState, ApprovalClient, type ApprovalDecision, type ApprovalRequestResponse, ApprovalResult, type ApprovalStatusResponse, Audio, type AudioOutput, type AudioRequest, type AuditTrailExport, type AuditTrailFilters, type Awaitable, CANONICAL_STATUSES, type CompactCapability, type CompactDiscoveryResponse, DIDAuthenticator, type DIDIdentity, type DIDIdentityPackage, type DIDRegistrationRequest, type DIDRegistrationResponse, type DeploymentType, DidClient, DidInterface, DidManager, type DidResolver, type DiscoveryFormat, type DiscoveryOptions, type DiscoveryPagination, type DiscoveryResponse, type DiscoveryResult, type EventTriggerBinding, type EventTriggerSpec, ExecutionContext, type ExecutionCredential, type ExecutionLogAttributes, type ExecutionLogBatchPayload, type ExecutionLogContext, type ExecutionLogEmitOptions, type ExecutionLogEntry, type ExecutionLogLevel, type ExecutionLogTransport, type ExecutionLogTransportPayload, type ExecutionLogWireEntry, ExecutionLogger, type ExecutionLoggerOptions, type ExecutionMetadata, ExecutionStatus, type ExecutionStatusValue, File, type FileOutput, type GenerateCredentialOptions, type GenerateCredentialParams, HEADER_CALLER_DID, HEADER_DID_NONCE, HEADER_DID_SIGNATURE, HEADER_DID_TIMESTAMP, type HarnessConfig, type HarnessOptions, type HarnessProvider, type HarnessResult, HarnessRunner, type HealthStatus, Image, type ImageOutput, type ImageRequest, JWE_ALG, JWE_ENC, KEY_AGREEMENT_TYPE, type MediaProvider, MediaProviderError, type MediaResponse, MediaRouter, type MemoryChangeEvent, MemoryClient, MemoryClientBase, type MemoryConfig, MemoryEventClient, type MemoryEventHandler, type MemoryEventHistoryOptions, MemoryInterface, type MemoryRequestMetadata, type MemoryRequestOptions, type MemoryScope, type MemoryWatchHandler, type Metrics, type MultimodalContent, MultimodalResponse, OpenRouterMediaProvider, type OpenRouterMediaProviderOptions, PauseClock, PauseManager, type Payload, PayloadEncryptionError, RateLimitError, type RateLimiterOptions, type RawExecutionContext, type RawResult, RealtimeSession, type ReasonerCapability, ReasonerContext, type ReasonerDefinition, type ReasonerHandler, type ReasonerOptions, type RequestApprovalPayload, SUPPORTED_PROVIDERS, SUPPORTED_SESSION_TRANSPORTS, type ScheduleTriggerBinding, type ScheduleTriggerSpec, type ServerlessAdapter, type ServerlessEvent, type ServerlessResponse, type SessionDefinition, type SessionOptions, type SessionProvider, type SessionTransport, type SessionTransportCapability, SessionTransportError, type SessionTurn, type SimulateScheduleOptions, type SimulateTriggerOptions, type SimulatedContext, type SkillCapability, SkillContext, type SkillDefinition, type SkillHandler, type SkillOptions, StatelessRateLimiter, TERMINAL_STATUSES, Text, type ToolCallConfig, type ToolCallRecord, type ToolCallTrace, type ToolsOption, type TriggerBinding, type TriggerContext, type TriggerEnvelope, type UnwrapResult, type VectorSearchOptions, type VectorSearchResult, Video, type VideoFrameImage, type VideoInputReference, type VideoRequest, type WaitForApprovalOptions, type WorkflowCredential, type WorkflowMetadata, type WorkflowProgressOptions, WorkflowReporter, type ZodSchema, applyTriggerTransform, audioFromBase64, audioFromBuffer, audioFromFile, audioFromUrl, buildProvider, buildSessionDefinition, buildToolConfig, capabilitiesToTools, capabilityToMetadataTool, capabilityToTool, createExecutionLogger, createHarnessResult, createMetrics, createMultimodalResponse, createRawResult, decrypt, decryptToString, encryptForDid, encryptToJwk, eventTrigger, executeToolCallLoop, extractKeyAgreementJwk, fileFromBase64, fileFromBuffer, fileFromPath, fileFromUrl, generateX25519KeyPair, getCurrentContext, getCurrentSkillContext, imageFromBase64, imageFromBuffer, imageFromFile, imageFromUrl, installApprovalWebhookRoute, isActive, isExecutionLogBatchPayload, isTerminal, isTriggerEnvelope, loadFixture, normalizeExecutionLogEntry, normalizeSessionTransportValue, normalizeStatus, scheduleTrigger, serializeExecutionLogEntry, simulateSchedule, simulateTrigger, text, triggerToPayload, unwrapEnvelope, validateSessionTransport, videoFromBase64, videoFromBuffer, videoFromFile, videoFromUrl };
2969
+ export { ACTIVE_STATUSES, AIClient, type AIConfig, type AIEmbeddingOptions, type AIRequestOptions, type AIStream, type AIToolRequestOptions, Agent, type AgentCapability, type AgentConfig, type AgentHandler, AgentRouter, type AgentRouterOptions, type AgentState, ApprovalClient, type ApprovalDecision, type ApprovalRequestResponse, ApprovalResult, type ApprovalStatusResponse, Audio, type AudioOutput, type AudioRequest, type AuditTrailExport, type AuditTrailFilters, type Awaitable, CANONICAL_STATUSES, type CompactCapability, type CompactDiscoveryResponse, type CostEntry, type CostEntryInit, CostTracker, DIDAuthenticator, type DIDIdentity, type DIDIdentityPackage, type DIDRegistrationRequest, type DIDRegistrationResponse, type DeploymentType, DidClient, DidInterface, DidManager, type DidResolver, type DiscoveryFormat, type DiscoveryOptions, type DiscoveryPagination, type DiscoveryResponse, type DiscoveryResult, type EventTriggerBinding, type EventTriggerSpec, ExecutionContext, type ExecutionCredential, type ExecutionLogAttributes, type ExecutionLogBatchPayload, type ExecutionLogContext, type ExecutionLogEmitOptions, type ExecutionLogEntry, type ExecutionLogLevel, type ExecutionLogTransport, type ExecutionLogTransportPayload, type ExecutionLogWireEntry, ExecutionLogger, type ExecutionLoggerOptions, type ExecutionMetadata, ExecutionStatus, type ExecutionStatusValue, File, type FileOutput, type GenerateCredentialOptions, type GenerateCredentialParams, HEADER_CALLER_DID, HEADER_DID_NONCE, HEADER_DID_SIGNATURE, HEADER_DID_TIMESTAMP, type HarnessConfig, type HarnessOptions, type HarnessProvider, type HarnessResult, HarnessRunner, type HealthStatus, Image, type ImageOutput, type ImageRequest, JWE_ALG, JWE_ENC, KEY_AGREEMENT_TYPE, type MediaProvider, MediaProviderError, type MediaResponse, MediaRouter, type MemoryChangeEvent, MemoryClient, MemoryClientBase, type MemoryConfig, MemoryEventClient, type MemoryEventHandler, type MemoryEventHistoryOptions, MemoryInterface, type MemoryRequestMetadata, type MemoryRequestOptions, type MemoryScope, type MemoryWatchHandler, type Metrics, type MultimodalContent, MultimodalResponse, OpenRouterMediaProvider, type OpenRouterMediaProviderOptions, PauseClock, PauseManager, type Payload, PayloadEncryptionError, RateLimitError, type RateLimiterOptions, type RawExecutionContext, type RawResult, RealtimeSession, type ReasonerCapability, ReasonerContext, type ReasonerDefinition, type ReasonerHandler, type ReasonerOptions, type RequestApprovalPayload, SUPPORTED_PROVIDERS, SUPPORTED_SESSION_TRANSPORTS, type ScheduleTriggerBinding, type ScheduleTriggerSpec, type ServerlessAdapter, type ServerlessEvent, type ServerlessResponse, type SessionDefinition, type SessionOptions, type SessionProvider, type SessionTransport, type SessionTransportCapability, SessionTransportError, type SessionTurn, type SimulateScheduleOptions, type SimulateTriggerOptions, type SimulatedContext, type SkillCapability, SkillContext, type SkillDefinition, type SkillHandler, type SkillOptions, StatelessRateLimiter, TERMINAL_STATUSES, Text, type ToolCallConfig, type ToolCallRecord, type ToolCallTrace, type ToolsOption, type TriggerBinding, type TriggerContext, type TriggerEnvelope, USAGE_ENVELOPE_KEY, type UnwrapResult, type UsageEntryWire, type UsageSummaryWire, type VectorSearchOptions, type VectorSearchResult, Video, type VideoFrameImage, type VideoInputReference, type VideoRequest, type WaitForApprovalOptions, type WorkflowCredential, type WorkflowMetadata, type WorkflowProgressOptions, WorkflowReporter, type ZodSchema, applyTriggerTransform, attachUsageToSyncResult, audioFromBase64, audioFromBuffer, audioFromFile, audioFromUrl, buildProvider, buildSessionDefinition, buildToolConfig, capabilitiesToTools, capabilityToMetadataTool, capabilityToTool, createExecutionLogger, createHarnessResult, createMetrics, createMultimodalResponse, createRawResult, decrypt, decryptToString, deriveProvider, encryptForDid, encryptToJwk, eventTrigger, executeToolCallLoop, extractKeyAgreementJwk, fileFromBase64, fileFromBuffer, fileFromPath, fileFromUrl, generateX25519KeyPair, getCurrentContext, getCurrentSkillContext, imageFromBase64, imageFromBuffer, imageFromFile, imageFromUrl, installApprovalWebhookRoute, isActive, isExecutionLogBatchPayload, isTerminal, isTriggerEnvelope, loadFixture, normalizeExecutionLogEntry, normalizeSessionTransportValue, normalizeStatus, scheduleTrigger, serializeExecutionLogEntry, simulateSchedule, simulateTrigger, text, triggerToPayload, unwrapEnvelope, usageSummaryOrNull, validateSessionTransport, videoFromBase64, videoFromBuffer, videoFromFile, videoFromUrl };