@agenticrun/sdk 0.1.0-alpha.0 → 0.1.0-alpha.1

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/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # @agenticrun/sdk
2
2
 
3
- Agenticrun SDK for trusted Node.js applications (Node.js 24.12 or newer, ESM).
4
- The SDK loads managed agent configuration and credentials from Agenticrun and
3
+ Agentic Run SDK for trusted Node.js applications (Node.js 24.12 or newer, ESM).
4
+ The SDK loads managed agent configuration and credentials from Agentic Run and
5
5
  sends session traces to the backend. Never use it in a browser or expose the
6
6
  Agent API key or returned provider credential to end users.
7
7
 
@@ -16,14 +16,32 @@ Set `AGENTICRUN_AGENT_API_KEY` to your Agent API key. Optionally set
16
16
 
17
17
  ```ts
18
18
  import { createAgenticRun } from '@agenticrun/sdk/langchain'
19
- import { createAgent } from 'langchain'
20
19
 
21
- const { model, middleware, createSession } = await createAgenticRun()
22
- const agent = createAgent({ model, middleware })
23
- const session = createSession()
24
- const result = await agent.invoke({ messages: [{ role: 'user', content: 'Hello!' }] }, session.createInvocationConfig())
20
+ const agenticrun = await createAgenticRun({
21
+ modelOptions: { google: { thinkingBudget: 2_048 } }
22
+ })
23
+ const agent = agenticrun.createAgent({ tools, checkpointer })
24
+ const session = agenticrun.createSession({ id: 'conversation-1' })
25
+ const result = await agent.invoke({ messages: [{ role: 'user', content: 'Hello!' }] }, session)
25
26
  ```
26
27
 
28
+ `createAgenticRun()` loads model configuration and credentials once. Existing
29
+ instances retain that configuration; dashboard changes apply after creating a
30
+ new instance. `createAgent()` supplies the managed model and binds tracing to
31
+ the returned native LangChain agent. For a custom compiled LangGraph, use
32
+ `agenticrun.bind(compiledGraph)` once. Native invocation options and user
33
+ callbacks remain available.
34
+
35
+ `createSession()` only returns a reusable native configuration containing
36
+ `configurable.thread_id`; the checkpointer remains responsible for conversation
37
+ memory. The backend associates sessions by tenant, agent and thread ID. Each
38
+ outer invocation creates a separate trace. `modelInfo` exposes the credential-free
39
+ provider, model ID, label and configuration version loaded by this instance.
40
+ Expected LangGraph interrupts complete the current trace as waiting for input;
41
+ resuming the same thread creates a new trace in the same session. Repeated
42
+ bindings from the same instance are idempotent, while binding an already bound
43
+ runnable to another Agentic Run instance is rejected.
44
+
27
45
  ## Framework-independent core
28
46
 
29
47
  ```ts
@@ -39,7 +57,7 @@ await trace.complete('success')
39
57
 
40
58
  The root entrypoint does not load LangChain. Both entrypoints belong to the same
41
59
  package. Provider and LangChain libraries remain runtime dependencies; shared
42
- Agenticrun code and TypeScript declarations are included in the release.
60
+ Agentic Run code and TypeScript declarations are included in the release.
43
61
 
44
62
  Tracing delivery is timeout-bounded and does not reject the agent result when
45
63
  delivery fails. Heartbeats and recovery of abandoned traces are not implemented.
@@ -738,6 +738,7 @@ const traceCompletedEventSchema = z.strictObject({
738
738
  type: z.literal("trace.completed"),
739
739
  id: z.uuid(),
740
740
  status: z.enum([
741
+ "waiting_for_input",
741
742
  "success",
742
743
  "error",
743
744
  "cancelled"
@@ -1038,7 +1039,7 @@ const createTrace = (context, options) => {
1038
1039
  const spanId = randomUUID();
1039
1040
  let spanCompleted = false;
1040
1041
  let firstTokenAt;
1041
- const model = input.spanType === "model" ? { ...context.model } : void 0;
1042
+ const model = input.spanType === "model" && input.model !== false ? { ...input.model ?? context.model } : void 0;
1042
1043
  const tags = input.tags?.map((tag) => tag.trim().slice(0, 100)).filter(Boolean).slice(0, 50);
1043
1044
  events.push({
1044
1045
  type: "span.started",
@@ -1108,6 +1109,13 @@ const createTrace = (context, options) => {
1108
1109
  const now = () => (/* @__PURE__ */ new Date()).toISOString();
1109
1110
  //#endregion
1110
1111
  //#region src/core/tracing/createTracingSession.ts
1112
+ const validateExternalSessionId = (id) => {
1113
+ tracingSessionResolutionSchema.parse({
1114
+ id: randomUUID(),
1115
+ externalSessionId: id
1116
+ });
1117
+ return id;
1118
+ };
1111
1119
  const createTracingSessionFactory = (context) => (options = {}) => {
1112
1120
  const sensitiveAttribute = Object.keys(options.attributes ?? {}).find(isSensitiveAttributeKey);
1113
1121
  if (sensitiveAttribute) throw new TypeError(`Agentic Run tracing attribute "${sensitiveAttribute}" may contain sensitive data.`);
@@ -1255,4 +1263,4 @@ const createAgenticRunClient = async (options = {}) => {
1255
1263
  };
1256
1264
  };
1257
1265
  //#endregion
1258
- export { safeJson as a, tokenUsageSchema as c, loadAgentRuntimeConfiguration as d, omittedContent as i, tracingLimits as l, createAgenticRunClient as n, validatedAttributes as o, isSensitiveAttributeKey as r, validatedContent as s, AgenticRunConfigurationError as t, AgenticRunApiError as u };
1266
+ export { omittedContent as a, validatedContent as c, AgenticRunApiError as d, loadAgentRuntimeConfiguration as f, isSensitiveAttributeKey as i, tokenUsageSchema as l, createAgenticRunClient as n, safeJson as o, validateExternalSessionId as r, validatedAttributes as s, AgenticRunConfigurationError as t, tracingLimits as u };
@@ -99,6 +99,7 @@ declare const traceCompletedEventSchema: z.ZodReadonly<z.ZodObject<{
99
99
  type: z.ZodLiteral<"trace.completed">;
100
100
  id: z.ZodUUID;
101
101
  status: z.ZodEnum<{
102
+ waiting_for_input: "waiting_for_input";
102
103
  error: "error";
103
104
  success: "success";
104
105
  cancelled: "cancelled";
@@ -451,6 +452,7 @@ type SpanCompletedEvent = z.infer<typeof spanCompletedEventSchema>;
451
452
  //#region src/core/tracing/createTrace.d.ts
452
453
  type StartSpanOptions = Pick<SpanStartedEvent, 'name' | 'spanType' | 'input' | 'attributes' | 'tags' | 'sourceSpanId'> & {
453
454
  readonly parentSpanId?: string;
455
+ readonly model?: ModelCall | false;
454
456
  };
455
457
  type CompleteSpanOptions = Pick<SpanCompletedEvent, 'attributes' | 'usage'> & {
456
458
  readonly responseModelId?: string;
package/dist/index.d.mts CHANGED
@@ -1,2 +1,2 @@
1
- import { _ as TokenUsage, a as AgenticRunOptions, c as CreateTracingSessionOptions, d as CreateTraceOptions, f as StartSpanOptions, g as ModelCall, h as MessageContentBlock, i as AgenticRunConfigurationError, l as AgenticRunTrace, m as Attributes, n as LoadAgentRuntimeConfigurationOptions, o as createAgenticRunClient, p as TraceSpan, r as loadAgentRuntimeConfiguration, s as AgenticRunTracingSession, t as AgenticRunApiError, u as CompleteSpanOptions, v as TraceContent } from "./index-brUCQYsX.mjs";
1
+ import { _ as TokenUsage, a as AgenticRunOptions, c as CreateTracingSessionOptions, d as CreateTraceOptions, f as StartSpanOptions, g as ModelCall, h as MessageContentBlock, i as AgenticRunConfigurationError, l as AgenticRunTrace, m as Attributes, n as LoadAgentRuntimeConfigurationOptions, o as createAgenticRunClient, p as TraceSpan, r as loadAgentRuntimeConfiguration, s as AgenticRunTracingSession, t as AgenticRunApiError, u as CompleteSpanOptions, v as TraceContent } from "./index-BpX7kWI_.mjs";
2
2
  export { AgenticRunApiError, AgenticRunConfigurationError, type AgenticRunOptions, type AgenticRunTrace, type AgenticRunTracingSession, type Attributes, type CompleteSpanOptions, type CreateTraceOptions, type CreateTracingSessionOptions, type LoadAgentRuntimeConfigurationOptions, type MessageContentBlock, type ModelCall, type StartSpanOptions, type TokenUsage, type TraceContent, type TraceSpan, createAgenticRunClient, loadAgentRuntimeConfiguration };
package/dist/index.mjs CHANGED
@@ -1,2 +1,2 @@
1
- import { d as loadAgentRuntimeConfiguration, n as createAgenticRunClient, t as AgenticRunConfigurationError, u as AgenticRunApiError } from "./core-BxLvIHye.mjs";
1
+ import { d as AgenticRunApiError, f as loadAgentRuntimeConfiguration, n as createAgenticRunClient, t as AgenticRunConfigurationError } from "./core-BQOuQ_C7.mjs";
2
2
  export { AgenticRunApiError, AgenticRunConfigurationError, createAgenticRunClient, loadAgentRuntimeConfiguration };
@@ -1,17 +1,99 @@
1
- import { a as AgenticRunOptions, c as CreateTracingSessionOptions, i as AgenticRunConfigurationError, s as AgenticRunTracingSession, t as AgenticRunApiError } from "./index-brUCQYsX.mjs";
1
+ import { a as AgenticRunOptions, c as CreateTracingSessionOptions, i as AgenticRunConfigurationError, t as AgenticRunApiError } from "./index-BpX7kWI_.mjs";
2
2
  import { z } from "zod";
3
3
  import { RunnableConfig } from "@langchain/core/runnables";
4
- //#region src/integrations/langchain/createLangChainSession.d.ts
5
- type LangChainTracingSession = {
4
+ import { ChatAnthropicInput } from "@langchain/anthropic";
5
+ import { ChatGoogleParams } from "@langchain/google/node";
6
+ import { ChatOpenAIFields } from "@langchain/openai";
7
+ import { CreateAgentParams, createAgent } from "langchain";
8
+ import { BaseChatModel } from "@langchain/core/language_models/chat_models";
9
+ //#region ../modules/src/credentials/providers.contract.d.ts
10
+ declare const providerModelPricingSchema: z.ZodReadonly<z.ZodObject<{
11
+ currency: z.ZodString;
12
+ unit: z.ZodLiteral<"million_tokens">;
13
+ rates: z.ZodReadonly<z.ZodObject<{
14
+ input: z.ZodNullable<z.ZodString>;
15
+ cacheRead: z.ZodNullable<z.ZodString>;
16
+ cacheWrite: z.ZodNullable<z.ZodString>;
17
+ output: z.ZodNullable<z.ZodString>;
18
+ reasoning: z.ZodNullable<z.ZodString>;
19
+ }, z.core.$strict>>;
20
+ }, z.core.$strict>>;
21
+ type ProviderModelPricing = z.infer<typeof providerModelPricingSchema>;
22
+ type ProviderAdapter = 'openai' | 'openai-compatible' | 'anthropic' | 'google';
23
+ type ProviderModelDefinition = {
24
+ readonly id: string;
25
+ readonly name: string;
26
+ readonly active: boolean;
27
+ readonly pricing: ProviderModelPricing;
28
+ };
29
+ type ProviderDefinitionBase = {
6
30
  readonly id: string;
7
- createInvocationConfig(): RunnableConfig;
31
+ readonly name: string;
32
+ readonly active: boolean;
33
+ readonly keyHintLength?: number;
34
+ readonly models: readonly ProviderModelDefinition[];
35
+ };
36
+ type NativeProviderDefinition = {
37
+ readonly adapter: Exclude<ProviderAdapter, 'openai-compatible'>;
38
+ readonly baseUrl?: never;
8
39
  };
40
+ type OpenAICompatibleProviderDefinition = {
41
+ readonly adapter: 'openai-compatible';
42
+ readonly baseUrl: string;
43
+ };
44
+ type ProviderDefinition = ProviderDefinitionBase & (NativeProviderDefinition | OpenAICompatibleProviderDefinition);
9
45
  //#endregion
10
- //#region src/integrations/langchain/createAgenticRun.d.ts
11
- export declare const createAgenticRun: (options?: AgenticRunOptions) => Promise<{
12
- model: import("@langchain/core/language_models/chat_models").BaseChatModel<import("@langchain/core/language_models/chat_models").BaseChatModelCallOptions, import("langchain").AIMessageChunk<import("@langchain/core/messages").MessageStructure<import("@langchain/core/messages").MessageToolSet>>>;
13
- middleware: import("langchain").AgentMiddleware<undefined, undefined, unknown, readonly (import("@langchain/core/tools").ClientTool | import("@langchain/core/tools").ServerTool)[], readonly []>[];
14
- createSession: (options?: Parameters<(options?: CreateTracingSessionOptions) => AgenticRunTracingSession>[0]) => LangChainTracingSession;
46
+ //#region src/integrations/langchain/createLangChainModel.d.ts
47
+ type ManagedAnthropicOptions = Omit<ChatAnthropicInput, 'apiKey' | 'clientOptions' | 'createClient' | 'model' | 'modelName'>;
48
+ type ManagedGoogleOptions = Omit<ChatGoogleParams, 'apiKey' | 'baseUrl' | 'model' | 'modelName'>;
49
+ type ManagedOpenAIOptions = Omit<ChatOpenAIFields, 'apiKey' | 'configuration' | 'model' | 'modelName'>;
50
+ type ManagedOpenAICompatibleOptions = ManagedOpenAIOptions;
51
+ type ManagedModelOptions = {
52
+ readonly anthropic?: ManagedAnthropicOptions;
53
+ readonly google?: ManagedGoogleOptions;
54
+ readonly openai?: ManagedOpenAIOptions;
55
+ readonly 'openai-compatible'?: ManagedOpenAICompatibleOptions;
56
+ };
57
+ declare const createLangChainModel: ({ apiKey, model, provider, modelOptions }: {
58
+ readonly apiKey: string;
59
+ readonly model: string;
60
+ readonly provider: ProviderDefinition;
61
+ readonly modelOptions?: ManagedModelOptions;
62
+ }) => BaseChatModel;
63
+ //#endregion
64
+ //#region src/integrations/langchain/createLangChainSession.d.ts
65
+ type LangChainSession = RunnableConfig<{
66
+ readonly thread_id: string;
15
67
  }>;
68
+ declare const createLangChainSession: (options?: {
69
+ readonly id?: string;
70
+ }) => LangChainSession;
71
+ //#endregion
72
+ //#region src/integrations/langchain/createAgenticRun.d.ts
73
+ type LangChainAgenticRunOptions = AgenticRunOptions & {
74
+ readonly modelOptions?: {
75
+ readonly anthropic?: ManagedAnthropicOptions;
76
+ readonly google?: ManagedGoogleOptions;
77
+ readonly openai?: ManagedOpenAIOptions;
78
+ readonly 'openai-compatible'?: ManagedOpenAICompatibleOptions;
79
+ };
80
+ };
81
+ type ManagedCreateAgentParams = Omit<CreateAgentParams, 'model'> & {
82
+ readonly model?: never;
83
+ };
84
+ type AgenticRunModelInfo = {
85
+ readonly provider: string;
86
+ readonly modelId: string;
87
+ readonly label: string;
88
+ readonly configurationVersion: number;
89
+ };
90
+ type LangChainAgenticRun = {
91
+ readonly model: ReturnType<typeof createLangChainModel>;
92
+ readonly modelInfo: AgenticRunModelInfo;
93
+ readonly createAgent: (params: ManagedCreateAgentParams) => ReturnType<typeof createAgent>;
94
+ readonly bind: <T extends object>(runnable: T) => T;
95
+ readonly createSession: typeof createLangChainSession;
96
+ };
97
+ export declare const createAgenticRun: (options?: LangChainAgenticRunOptions) => Promise<LangChainAgenticRun>;
16
98
  //#endregion
17
- export { AgenticRunApiError, AgenticRunConfigurationError, type AgenticRunOptions, type CreateTracingSessionOptions, type LangChainTracingSession };
99
+ export { AgenticRunApiError, AgenticRunConfigurationError, type AgenticRunModelInfo, type AgenticRunOptions, type CreateTracingSessionOptions, type LangChainAgenticRun, type LangChainAgenticRunOptions, type LangChainSession, type ManagedAnthropicOptions, type ManagedGoogleOptions, type ManagedOpenAICompatibleOptions, type ManagedOpenAIOptions };
@@ -1,34 +1,12 @@
1
- import { a as safeJson, c as tokenUsageSchema, i as omittedContent, l as tracingLimits, n as createAgenticRunClient, o as validatedAttributes, r as isSensitiveAttributeKey, s as validatedContent, t as AgenticRunConfigurationError, u as AgenticRunApiError } from "./core-BxLvIHye.mjs";
1
+ import { a as omittedContent, c as validatedContent, d as AgenticRunApiError, i as isSensitiveAttributeKey, l as tokenUsageSchema, n as createAgenticRunClient, o as safeJson, r as validateExternalSessionId, s as validatedAttributes, t as AgenticRunConfigurationError, u as tracingLimits } from "./core-BQOuQ_C7.mjs";
2
2
  import { randomUUID } from "node:crypto";
3
+ import { AIMessage, BaseMessage, coerceMessageLikeToMessage } from "@langchain/core/messages";
4
+ import { BaseCallbackHandler } from "@langchain/core/callbacks/base";
5
+ import { ensureConfig, mergeConfigs } from "@langchain/core/runnables";
3
6
  import { ChatAnthropic } from "@langchain/anthropic";
4
7
  import { ChatGoogle } from "@langchain/google/node";
5
8
  import { ChatOpenAI } from "@langchain/openai";
6
- import { AIMessage, BaseMessage, coerceMessageLikeToMessage } from "@langchain/core/messages";
7
- import { BaseCallbackHandler } from "@langchain/core/callbacks/base";
8
- import { createMiddleware } from "langchain";
9
- //#region src/integrations/langchain/createLangChainModel.ts
10
- const createLangChainModel = ({ apiKey, model, provider }) => {
11
- return {
12
- anthropic: () => new ChatAnthropic({
13
- apiKey,
14
- model
15
- }),
16
- google: () => new ChatGoogle({
17
- apiKey,
18
- model
19
- }),
20
- openai: () => new ChatOpenAI({
21
- apiKey,
22
- model
23
- }),
24
- "openai-compatible": () => new ChatOpenAI({
25
- apiKey,
26
- model,
27
- configuration: { baseURL: provider.baseUrl }
28
- })
29
- }[provider.adapter]();
30
- };
31
- //#endregion
9
+ import { createAgent } from "langchain";
32
10
  //#region src/integrations/langchain/tracing/langChainAttributes.ts
33
11
  const langChainAttributes = (metadata) => {
34
12
  if (!metadata) return void 0;
@@ -226,6 +204,7 @@ const modelCallFromResult = (configured, output) => {
226
204
  //#region src/integrations/langchain/tracing/langChainTracingCallback.ts
227
205
  var AgenticRunTracingCallback = class extends BaseCallbackHandler {
228
206
  name = "AgenticRunTracingCallback";
207
+ ownerId;
229
208
  model;
230
209
  provider;
231
210
  session;
@@ -237,6 +216,7 @@ var AgenticRunTracingCallback = class extends BaseCallbackHandler {
237
216
  raiseError: false,
238
217
  _awaitHandler: true
239
218
  });
219
+ this.ownerId = options.ownerId;
240
220
  this.model = options.model;
241
221
  this.provider = options.provider;
242
222
  this.session = options.session;
@@ -277,18 +257,19 @@ var AgenticRunTracingCallback = class extends BaseCallbackHandler {
277
257
  status: "success",
278
258
  output: contentFromValue(outputs)
279
259
  });
280
- if (runId === this.rootRunId) await this.trace?.complete("success");
260
+ if (runId === this.rootRunId) await this.trace?.complete(hasInterrupt(outputs) ? "waiting_for_input" : "success");
281
261
  }
282
262
  async handleChainError(error, runId) {
283
263
  this.completeSpan(runId, errorResult(error));
284
264
  if (runId === this.rootRunId) await this.trace?.complete(isAbortError(error) ? "cancelled" : "error");
285
265
  }
286
- handleChatModelStart(_model, messages, runId, parentRunId, _extraParams, tags, metadata, runName) {
266
+ handleChatModelStart(serializedModel, messages, runId, parentRunId, _extraParams, tags, metadata, runName) {
287
267
  this.startSpan({
288
268
  runId,
289
269
  parentRunId,
290
270
  name: runName ?? this.model,
291
271
  spanType: "model",
272
+ model: managedModel(serializedModel, this.model, this.provider),
292
273
  input: contentFromMessages(messages.flat()),
293
274
  attributes: compactAttributes({
294
275
  ...langChainAttributes(metadata),
@@ -297,12 +278,13 @@ var AgenticRunTracingCallback = class extends BaseCallbackHandler {
297
278
  tags
298
279
  });
299
280
  }
300
- handleLLMStart(_model, prompts, runId, parentRunId, _extraParams, tags, metadata, runName) {
281
+ handleLLMStart(serializedModel, prompts, runId, parentRunId, _extraParams, tags, metadata, runName) {
301
282
  this.startSpan({
302
283
  runId,
303
284
  parentRunId,
304
285
  name: runName ?? this.model,
305
286
  spanType: "model",
287
+ model: managedModel(serializedModel, this.model, this.provider),
306
288
  input: contentFromValue(prompts),
307
289
  attributes: compactAttributes({
308
290
  ...langChainAttributes(metadata),
@@ -380,6 +362,7 @@ var AgenticRunTracingCallback = class extends BaseCallbackHandler {
380
362
  parentSpanId: input.parentRunId ? this.runs.get(input.parentRunId)?.span.id : void 0,
381
363
  name: input.name,
382
364
  spanType: input.spanType,
365
+ model: input.model,
383
366
  input: input.input,
384
367
  attributes: input.attributes,
385
368
  tags: input.tags
@@ -393,6 +376,25 @@ var AgenticRunTracingCallback = class extends BaseCallbackHandler {
393
376
  this.runs.get(runId)?.span.complete(result, details);
394
377
  }
395
378
  };
379
+ const managedModel = (serialized, model, provider) => {
380
+ const value = safeJson(serialized);
381
+ if (JSON.stringify(value).includes(model)) return {
382
+ providerId: provider,
383
+ modelId: model
384
+ };
385
+ return findDeclaredModel(value) === void 0 ? {
386
+ providerId: provider,
387
+ modelId: model
388
+ } : false;
389
+ };
390
+ const findDeclaredModel = (value) => {
391
+ if (!value || typeof value !== "object") return void 0;
392
+ for (const [key, candidate] of Object.entries(value)) {
393
+ if ((key === "model" || key === "modelName" || key === "model_name") && typeof candidate === "string") return candidate;
394
+ const nested = findDeclaredModel(candidate);
395
+ if (nested !== void 0) return nested;
396
+ }
397
+ };
396
398
  const errorResult = (error) => {
397
399
  const normalized = error instanceof Error ? error : new Error(String(error));
398
400
  return {
@@ -404,6 +406,7 @@ const errorResult = (error) => {
404
406
  };
405
407
  };
406
408
  const isAbortError = (error) => error instanceof Error && error.name === "AbortError";
409
+ const hasInterrupt = (outputs) => Array.isArray(outputs.__interrupt__) && outputs.__interrupt__.length > 0;
407
410
  const parseToolInput = (input) => {
408
411
  try {
409
412
  return safeJson(JSON.parse(input));
@@ -424,42 +427,136 @@ const compactAttributes = (attributes) => {
424
427
  return validatedAttributes(Object.fromEntries(Object.entries(attributes).filter(([, value]) => value !== void 0)));
425
428
  };
426
429
  //#endregion
430
+ //#region src/integrations/langchain/bindTracing.ts
431
+ const binding = Symbol("AgenticRunBinding");
432
+ const bindTracing = (runnable, owner) => {
433
+ if (typeof Reflect.get(runnable, "invoke") !== "function") throw new TypeError("Agentic Run can only bind LangChain runnables with an invoke() method.");
434
+ const existing = Reflect.get(runnable, binding);
435
+ if (existing?.id === owner.id) return runnable;
436
+ if (existing) throw new TypeError("This LangChain runnable is already bound to another Agentic Run instance.");
437
+ return new Proxy(runnable, { get(target, property) {
438
+ if (property === binding) return owner;
439
+ if (property === "invoke" || property === "stream" || property === "streamEvents") return (input, options) => Reflect.apply(Reflect.get(target, property), target, [input, tracedConfig(options, owner)]);
440
+ if (property === "batch") return (inputs, options, batchOptions) => {
441
+ const configurations = Array.isArray(options) ? options.map((option) => tracedConfig(option, owner)) : inputs.map(() => tracedConfig(options, owner));
442
+ return Reflect.apply(Reflect.get(target, property), target, [
443
+ inputs,
444
+ configurations,
445
+ batchOptions
446
+ ]);
447
+ };
448
+ if (property === "withConfig") return (config) => bindTracing(Reflect.apply(Reflect.get(target, property), target, [config]), owner);
449
+ const value = Reflect.get(target, property, target);
450
+ return typeof value === "function" ? value.bind(target) : value;
451
+ } });
452
+ };
453
+ const tracedConfig = (options, owner) => {
454
+ const config = ensureConfig(options);
455
+ if (hasOwnerCallback(config, owner.id)) return config;
456
+ const externalSessionId = readThreadId(config);
457
+ const session = owner.createSession(externalSessionId);
458
+ return mergeConfigs(config, { callbacks: [new AgenticRunTracingCallback({
459
+ ownerId: owner.id,
460
+ model: owner.model,
461
+ provider: owner.provider,
462
+ session
463
+ })] });
464
+ };
465
+ const readThreadId = (config) => {
466
+ const value = config.configurable?.thread_id;
467
+ if (value === void 0) return void 0;
468
+ if (typeof value !== "string") throw new TypeError("LangChain configurable.thread_id must be a string.");
469
+ return value;
470
+ };
471
+ const hasOwnerCallback = (config, ownerId) => {
472
+ const callbacks = config.callbacks;
473
+ return (Array.isArray(callbacks) ? callbacks : callbacks?.handlers)?.some((handler) => handler instanceof AgenticRunTracingCallback && handler.ownerId === ownerId) ?? false;
474
+ };
475
+ //#endregion
476
+ //#region src/integrations/langchain/createLangChainModel.ts
477
+ const createLangChainModel = ({ apiKey, model, provider, modelOptions = {} }) => {
478
+ const selected = modelOptions[provider.adapter] ?? {};
479
+ assertManagedFields(selected);
480
+ return {
481
+ anthropic: () => new ChatAnthropic({
482
+ ...selected,
483
+ apiKey,
484
+ model
485
+ }),
486
+ google: () => new ChatGoogle({
487
+ ...selected,
488
+ apiKey,
489
+ model
490
+ }),
491
+ openai: () => new ChatOpenAI({
492
+ ...selected,
493
+ apiKey,
494
+ model
495
+ }),
496
+ "openai-compatible": () => new ChatOpenAI({
497
+ ...selected,
498
+ apiKey,
499
+ model,
500
+ configuration: { baseURL: provider.baseUrl }
501
+ })
502
+ }[provider.adapter]();
503
+ };
504
+ const managedFields = [
505
+ "apiKey",
506
+ "baseUrl",
507
+ "baseURL",
508
+ "clientOptions",
509
+ "configuration",
510
+ "createClient",
511
+ "model",
512
+ "modelName"
513
+ ];
514
+ const assertManagedFields = (options) => {
515
+ const field = managedFields.find((key) => Object.hasOwn(options, key));
516
+ if (field) throw new TypeError(`Agentic Run model option "${field}" is managed and cannot be overridden.`);
517
+ };
518
+ //#endregion
427
519
  //#region src/integrations/langchain/createLangChainSession.ts
428
- const createLangChainSession = (session, model) => ({
429
- get id() {
430
- return session.id;
431
- },
432
- createInvocationConfig() {
433
- return { callbacks: [new AgenticRunTracingCallback({
434
- ...model,
435
- session
436
- })] };
437
- }
438
- });
520
+ const createLangChainSession = (options = {}) => {
521
+ const threadId = options.id ?? randomUUID();
522
+ if (threadId !== threadId.trim()) throw new TypeError("Agentic Run session IDs cannot start or end with whitespace.");
523
+ validateExternalSessionId(threadId);
524
+ return { configurable: { thread_id: threadId } };
525
+ };
439
526
  //#endregion
440
527
  //#region src/integrations/langchain/createAgenticRun.ts
441
528
  const createAgenticRun = async (options = {}) => {
442
- const client = await createAgenticRunClient(options);
529
+ const { modelOptions, ...clientOptions } = options;
530
+ const client = await createAgenticRunClient(clientOptions);
443
531
  const { configuration, provider } = client;
444
- const middleware = createMiddleware({
445
- name: "AgenticRun",
446
- afterModel: (state) => {
447
- const lastMessage = state.messages.at(-1);
448
- const tokensUsed = lastMessage && AIMessage.isInstance(lastMessage) ? lastMessage.usage_metadata?.total_tokens ?? 0 : 0;
449
- console.log("[Agentic Run] afterModel", { tokensUsed });
450
- }
532
+ const configuredModel = provider.models.find((candidate) => candidate.id === configuration.modelId);
533
+ const model = createLangChainModel({
534
+ apiKey: configuration.credential.apiKey,
535
+ model: configuration.modelId,
536
+ provider,
537
+ modelOptions
451
538
  });
539
+ const owner = {
540
+ id: Symbol("AgenticRunInstance"),
541
+ model: configuration.modelId,
542
+ provider: configuration.provider,
543
+ createSession: (externalSessionId) => client.createSession(externalSessionId === void 0 ? void 0 : { externalSessionId })
544
+ };
545
+ const bind = (runnable) => bindTracing(runnable, owner);
452
546
  return {
453
- model: createLangChainModel({
454
- apiKey: configuration.credential.apiKey,
455
- model: configuration.modelId,
456
- provider
547
+ model,
548
+ modelInfo: Object.freeze({
549
+ provider: configuration.provider,
550
+ modelId: configuration.modelId,
551
+ label: configuredModel.name,
552
+ configurationVersion: configuration.agentConfigurationVersion
457
553
  }),
458
- middleware: [middleware],
459
- createSession: (options) => createLangChainSession(client.createSession(options), {
460
- model: configuration.modelId,
461
- provider: configuration.provider
462
- })
554
+ createAgent: (params) => bind(createAgent({
555
+ ...params,
556
+ model
557
+ })),
558
+ bind,
559
+ createSession: createLangChainSession
463
560
  };
464
561
  };
465
562
  //#endregion
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@agenticrun/sdk",
3
- "version": "0.1.0-alpha.0",
4
- "description": "Agenticrun client and LangChain integration for managed agent configuration and tracing",
3
+ "version": "0.1.0-alpha.1",
4
+ "description": "Agentic Run client and LangChain integration for managed agent configuration and tracing",
5
5
  "license": "UNLICENSED",
6
6
  "type": "module",
7
7
  "engines": {
@@ -26,9 +26,9 @@
26
26
  "tag": "alpha"
27
27
  },
28
28
  "dependencies": {
29
- "@langchain/anthropic": "^1.0.0",
29
+ "@langchain/anthropic": "^1.5.10",
30
30
  "@langchain/core": "^1.0.0",
31
- "@langchain/google": "^0.2.0",
31
+ "@langchain/google": "^0.2.4",
32
32
  "@langchain/openai": "^1.0.0",
33
33
  "langchain": "^1.0.0",
34
34
  "zod": "^4.5.4"