@agenticrun/sdk 0.1.0-alpha.0

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.
@@ -0,0 +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";
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 ADDED
@@ -0,0 +1,2 @@
1
+ import { d as loadAgentRuntimeConfiguration, n as createAgenticRunClient, t as AgenticRunConfigurationError, u as AgenticRunApiError } from "./core-BxLvIHye.mjs";
2
+ export { AgenticRunApiError, AgenticRunConfigurationError, createAgenticRunClient, loadAgentRuntimeConfiguration };
@@ -0,0 +1,17 @@
1
+ import { a as AgenticRunOptions, c as CreateTracingSessionOptions, i as AgenticRunConfigurationError, s as AgenticRunTracingSession, t as AgenticRunApiError } from "./index-brUCQYsX.mjs";
2
+ import { z } from "zod";
3
+ import { RunnableConfig } from "@langchain/core/runnables";
4
+ //#region src/integrations/langchain/createLangChainSession.d.ts
5
+ type LangChainTracingSession = {
6
+ readonly id: string;
7
+ createInvocationConfig(): RunnableConfig;
8
+ };
9
+ //#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;
15
+ }>;
16
+ //#endregion
17
+ export { AgenticRunApiError, AgenticRunConfigurationError, type AgenticRunOptions, type CreateTracingSessionOptions, type LangChainTracingSession };
@@ -0,0 +1,466 @@
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";
2
+ import { randomUUID } from "node:crypto";
3
+ import { ChatAnthropic } from "@langchain/anthropic";
4
+ import { ChatGoogle } from "@langchain/google/node";
5
+ 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
32
+ //#region src/integrations/langchain/tracing/langChainAttributes.ts
33
+ const langChainAttributes = (metadata) => {
34
+ if (!metadata) return void 0;
35
+ const attributes = {};
36
+ for (const [key, value] of Object.entries(metadata)) {
37
+ if (isSensitiveAttributeKey(key) || key.startsWith("agenticrun.")) continue;
38
+ if (isAttributeValue(value)) attributes[`langchain.${key}`] = value;
39
+ }
40
+ return validatedAttributes(attributes);
41
+ };
42
+ const isAttributeValue = (value) => value === null || [
43
+ "string",
44
+ "number",
45
+ "boolean"
46
+ ].includes(typeof value) || Array.isArray(value) && value.length <= tracingLimits.attributeArrayEntries && value.every((item) => typeof item === "string" || typeof item === "number" || typeof item === "boolean");
47
+ //#endregion
48
+ //#region src/integrations/langchain/tracing/langChainContent.ts
49
+ const contentFromMessages = (messages) => {
50
+ const normalized = [];
51
+ for (const message of messages) {
52
+ const content = [];
53
+ if (typeof message.content === "string") content.push({
54
+ type: "text",
55
+ text: message.content
56
+ });
57
+ else for (const block of message.content) {
58
+ const normalizedBlock = normalizeContentBlock(block);
59
+ if (!normalizedBlock) return omittedContent(message.content, "unsupported");
60
+ content.push(normalizedBlock);
61
+ }
62
+ if (AIMessage.isInstance(message)) for (const toolCall of message.tool_calls ?? []) content.push({
63
+ type: "tool-call",
64
+ toolName: toolCall.name,
65
+ callId: toolCall.id ?? randomUUID(),
66
+ arguments: safeJson(toolCall.args)
67
+ });
68
+ const toolCallId = propertyString(message, "tool_call_id");
69
+ if (message.type === "tool" && toolCallId) {
70
+ normalized.push({
71
+ ...message.id ? { id: message.id } : {},
72
+ role: "tool",
73
+ ...message.name ? { name: message.name } : {},
74
+ content: [{
75
+ type: "tool-result",
76
+ callId: toolCallId,
77
+ result: safeJson(message.content)
78
+ }]
79
+ });
80
+ continue;
81
+ }
82
+ normalized.push({
83
+ ...message.id ? { id: message.id } : {},
84
+ role: messageRole(message),
85
+ ...message.name ? { name: message.name } : {},
86
+ content: content.length > 0 ? content : [{
87
+ type: "text",
88
+ text: ""
89
+ }]
90
+ });
91
+ }
92
+ return validatedContent({
93
+ type: "messages",
94
+ messages: normalized
95
+ });
96
+ };
97
+ const contentFromValue = (value) => {
98
+ const candidates = Array.isArray(value) ? value : isRecord(value) && Array.isArray(value.messages) ? value.messages : void 0;
99
+ if (candidates?.length && candidates.every((message) => BaseMessage.isInstance(message) || isRecord(message) && [
100
+ "user",
101
+ "assistant",
102
+ "system",
103
+ "developer",
104
+ "tool"
105
+ ].includes(String(message.role)) && (typeof message.content === "string" || Array.isArray(message.content)))) try {
106
+ return contentFromMessages(candidates.map((message) => coerceMessageLikeToMessage(message)));
107
+ } catch {}
108
+ if (typeof value === "string") return validatedContent({
109
+ type: "text",
110
+ text: value
111
+ });
112
+ return validatedContent({
113
+ type: "json",
114
+ value: safeJson(value)
115
+ });
116
+ };
117
+ const contentFromToolCall = (toolName, callId, argumentsValue) => validatedContent({
118
+ type: "tool-call",
119
+ toolName,
120
+ callId,
121
+ arguments: safeJson(argumentsValue)
122
+ });
123
+ const contentFromToolResult = (callId, result) => validatedContent({
124
+ type: "tool-result",
125
+ callId,
126
+ result: safeJson(result)
127
+ });
128
+ const contentFromDocuments = (documents) => validatedContent({
129
+ type: "documents",
130
+ documents: documents.map((document) => ({
131
+ ...document.id ? { id: document.id } : {},
132
+ content: document.pageContent,
133
+ attributes: langChainAttributes(document.metadata)
134
+ }))
135
+ });
136
+ const contentFromLlmResult = (output) => {
137
+ const messages = output.generations.flatMap((generations) => generations.flatMap((generation) => "message" in generation && BaseMessage.isInstance(generation.message) ? [generation.message] : []));
138
+ if (messages.length > 0) return contentFromMessages(messages);
139
+ return contentFromValue(output.generations.map((generations) => generations.map((generation) => generation.text)));
140
+ };
141
+ const normalizeContentBlock = (block) => {
142
+ if (!isRecord(block) || typeof block.type !== "string") return {
143
+ type: "json",
144
+ value: safeJson(block)
145
+ };
146
+ if (block.type === "text" && typeof block.text === "string") return {
147
+ type: "text",
148
+ text: block.text
149
+ };
150
+ if ((block.type === "tool-call" || block.type === "tool_call") && typeof block.name === "string") return {
151
+ type: "tool-call",
152
+ toolName: block.name,
153
+ callId: typeof block.id === "string" ? block.id : randomUUID(),
154
+ arguments: safeJson(block.args)
155
+ };
156
+ if (block.type === "reasoning" && typeof block.reasoning === "string") return {
157
+ type: "reasoning",
158
+ text: block.reasoning
159
+ };
160
+ if (block.type === "thinking" && typeof block.thinking === "string") return {
161
+ type: "reasoning",
162
+ text: block.thinking
163
+ };
164
+ if (/(image|audio|file)/i.test(block.type)) return void 0;
165
+ return {
166
+ type: "json",
167
+ value: safeJson(block)
168
+ };
169
+ };
170
+ const messageRole = (message) => {
171
+ if (message.type === "human") return "user";
172
+ if (message.type === "ai") return "assistant";
173
+ if (message.type === "tool") return "tool";
174
+ if (message.type === "system") return propertyString(message, "role") === "developer" ? "developer" : "system";
175
+ return "user";
176
+ };
177
+ const propertyString = (value, key) => {
178
+ const property = value[key];
179
+ return typeof property === "string" && property.length > 0 ? property : void 0;
180
+ };
181
+ const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
182
+ //#endregion
183
+ //#region src/integrations/langchain/tracing/langChainModelResult.ts
184
+ const usageFromLlmResult = (output, provider) => {
185
+ const generations = output.generations.flat();
186
+ if (generations.length !== 1) return void 0;
187
+ const generation = generations[0];
188
+ if (!("message" in generation) || !AIMessage.isInstance(generation.message)) return void 0;
189
+ const usage = generation.message.usage_metadata;
190
+ if (!usage) return void 0;
191
+ const result = tokenUsageSchema.safeParse({
192
+ inputTokensTotal: usage.input_tokens,
193
+ inputTokensCacheRead: usage.input_token_details?.cache_read,
194
+ inputTokensCacheWrite: provider === "google" && usage.input_token_details?.cache_creation === void 0 ? 0 : usage.input_token_details?.cache_creation,
195
+ outputTokensTotal: usage.output_tokens,
196
+ outputTokensReasoning: usage.output_token_details?.reasoning
197
+ });
198
+ return result.success ? result.data : void 0;
199
+ };
200
+ const responseAttributesFromLlmResult = (output, provider) => {
201
+ const generation = output.generations[0]?.[0];
202
+ const metadata = (generation && "message" in generation && BaseMessage.isInstance(generation.message) ? generation.message : void 0)?.response_metadata;
203
+ const candidates = {
204
+ [`${provider}.response_model`]: metadata?.model_name ?? metadata?.model ?? metadata?.response_model,
205
+ [`${provider}.finish_reason`]: metadata?.finish_reason ?? metadata?.finishReason ?? metadata?.stop_reason ?? generation?.generationInfo?.finish_reason,
206
+ [`${provider}.request_id`]: metadata?.request_id ?? metadata?.id,
207
+ [`${provider}.system_fingerprint`]: metadata?.system_fingerprint
208
+ };
209
+ const attributes = Object.fromEntries(Object.entries(candidates).filter((entry) => [
210
+ "string",
211
+ "number",
212
+ "boolean"
213
+ ].includes(typeof entry[1])));
214
+ return validatedAttributes(attributes);
215
+ };
216
+ const modelCallFromResult = (configured, output) => {
217
+ const generation = output.generations[0]?.[0];
218
+ const metadata = generation && "message" in generation && AIMessage.isInstance(generation.message) ? generation.message.response_metadata : {};
219
+ const responseModelId = metadata.model_name ?? metadata.model ?? metadata.response_model ?? output.llmOutput?.model;
220
+ return {
221
+ ...configured,
222
+ ...typeof responseModelId === "string" && responseModelId.trim().length > 0 && responseModelId.length <= 200 ? { responseModelId } : {}
223
+ };
224
+ };
225
+ //#endregion
226
+ //#region src/integrations/langchain/tracing/langChainTracingCallback.ts
227
+ var AgenticRunTracingCallback = class extends BaseCallbackHandler {
228
+ name = "AgenticRunTracingCallback";
229
+ model;
230
+ provider;
231
+ session;
232
+ runs = /* @__PURE__ */ new Map();
233
+ rootRunId;
234
+ trace;
235
+ constructor(options) {
236
+ super({
237
+ raiseError: false,
238
+ _awaitHandler: true
239
+ });
240
+ this.model = options.model;
241
+ this.provider = options.provider;
242
+ this.session = options.session;
243
+ }
244
+ async handleChainStart(_chain, inputs, runId, _runType, tags, metadata, runName, parentRunId) {
245
+ if (this.trace?.completed) return;
246
+ const rootSpan = {
247
+ sourceSpanId: runId,
248
+ name: runName ?? "agent",
249
+ spanType: "agent",
250
+ input: contentFromValue(inputs),
251
+ attributes: langChainAttributes(metadata),
252
+ tags
253
+ };
254
+ if (!this.trace) {
255
+ this.rootRunId = runId;
256
+ this.trace = this.session.createTrace({
257
+ sourceTraceId: runId,
258
+ attributes: compactAttributes({
259
+ "langchain.run_name": runName,
260
+ [`${this.provider}.provider`]: this.provider,
261
+ [`${this.provider}.request_model`]: this.model
262
+ }),
263
+ rootSpan
264
+ });
265
+ this.runs.set(runId, { span: this.trace.rootSpan });
266
+ await this.trace.started;
267
+ } else this.startSpan({
268
+ runId,
269
+ parentRunId,
270
+ ...rootSpan,
271
+ name: runName ?? "workflow",
272
+ spanType: "workflow"
273
+ });
274
+ }
275
+ async handleChainEnd(outputs, runId) {
276
+ this.completeSpan(runId, {
277
+ status: "success",
278
+ output: contentFromValue(outputs)
279
+ });
280
+ if (runId === this.rootRunId) await this.trace?.complete("success");
281
+ }
282
+ async handleChainError(error, runId) {
283
+ this.completeSpan(runId, errorResult(error));
284
+ if (runId === this.rootRunId) await this.trace?.complete(isAbortError(error) ? "cancelled" : "error");
285
+ }
286
+ handleChatModelStart(_model, messages, runId, parentRunId, _extraParams, tags, metadata, runName) {
287
+ this.startSpan({
288
+ runId,
289
+ parentRunId,
290
+ name: runName ?? this.model,
291
+ spanType: "model",
292
+ input: contentFromMessages(messages.flat()),
293
+ attributes: compactAttributes({
294
+ ...langChainAttributes(metadata),
295
+ [`${this.provider}.request_model`]: this.model
296
+ }),
297
+ tags
298
+ });
299
+ }
300
+ handleLLMStart(_model, prompts, runId, parentRunId, _extraParams, tags, metadata, runName) {
301
+ this.startSpan({
302
+ runId,
303
+ parentRunId,
304
+ name: runName ?? this.model,
305
+ spanType: "model",
306
+ input: contentFromValue(prompts),
307
+ attributes: compactAttributes({
308
+ ...langChainAttributes(metadata),
309
+ [`${this.provider}.request_model`]: this.model
310
+ }),
311
+ tags
312
+ });
313
+ }
314
+ handleLLMNewToken(_token, _indices, runId) {
315
+ this.runs.get(runId)?.span.markFirstToken();
316
+ }
317
+ handleLLMEnd(output, runId) {
318
+ this.completeSpan(runId, {
319
+ status: "success",
320
+ output: contentFromLlmResult(output)
321
+ }, {
322
+ usage: usageFromLlmResult(output, this.provider),
323
+ responseModelId: modelCallFromResult({
324
+ providerId: this.provider,
325
+ modelId: this.model
326
+ }, output).responseModelId,
327
+ attributes: responseAttributesFromLlmResult(output, this.provider)
328
+ });
329
+ }
330
+ handleLLMError(error, runId) {
331
+ this.completeSpan(runId, errorResult(error));
332
+ }
333
+ handleToolStart(tool, input, runId, parentRunId, tags, metadata, runName, toolCallId) {
334
+ const name = runName ?? serializedName(tool) ?? "tool";
335
+ this.startSpan({
336
+ runId,
337
+ parentRunId,
338
+ name,
339
+ spanType: "tool",
340
+ input: contentFromToolCall(name, toolCallId ?? runId, parseToolInput(input)),
341
+ attributes: langChainAttributes(metadata),
342
+ tags,
343
+ toolCallId: toolCallId ?? runId
344
+ });
345
+ }
346
+ handleToolEnd(output, runId) {
347
+ const run = this.runs.get(runId);
348
+ this.completeSpan(runId, {
349
+ status: "success",
350
+ output: contentFromToolResult(run?.toolCallId ?? runId, output)
351
+ });
352
+ }
353
+ handleToolError(error, runId) {
354
+ this.completeSpan(runId, errorResult(error));
355
+ }
356
+ handleRetrieverStart(_retriever, query, runId, parentRunId, tags, metadata, name) {
357
+ this.startSpan({
358
+ runId,
359
+ parentRunId,
360
+ name: name ?? "retriever",
361
+ spanType: "retrieval",
362
+ input: contentFromValue(query),
363
+ attributes: langChainAttributes(metadata),
364
+ tags
365
+ });
366
+ }
367
+ handleRetrieverEnd(documents, runId) {
368
+ this.completeSpan(runId, {
369
+ status: "success",
370
+ output: contentFromDocuments(documents)
371
+ });
372
+ }
373
+ handleRetrieverError(error, runId) {
374
+ this.completeSpan(runId, errorResult(error));
375
+ }
376
+ startSpan(input) {
377
+ if (!this.trace || this.runs.has(input.runId)) return;
378
+ const span = this.trace.startSpan({
379
+ sourceSpanId: input.runId,
380
+ parentSpanId: input.parentRunId ? this.runs.get(input.parentRunId)?.span.id : void 0,
381
+ name: input.name,
382
+ spanType: input.spanType,
383
+ input: input.input,
384
+ attributes: input.attributes,
385
+ tags: input.tags
386
+ });
387
+ if (span) this.runs.set(input.runId, {
388
+ span,
389
+ toolCallId: input.toolCallId
390
+ });
391
+ }
392
+ completeSpan(runId, result, details = {}) {
393
+ this.runs.get(runId)?.span.complete(result, details);
394
+ }
395
+ };
396
+ const errorResult = (error) => {
397
+ const normalized = error instanceof Error ? error : new Error(String(error));
398
+ return {
399
+ status: isAbortError(error) ? "cancelled" : "error",
400
+ error: {
401
+ type: (normalized.name || "Error").slice(0, 200),
402
+ message: normalized.message.slice(0, 32768)
403
+ }
404
+ };
405
+ };
406
+ const isAbortError = (error) => error instanceof Error && error.name === "AbortError";
407
+ const parseToolInput = (input) => {
408
+ try {
409
+ return safeJson(JSON.parse(input));
410
+ } catch {
411
+ return input;
412
+ }
413
+ };
414
+ const serializedName = (value) => {
415
+ if (!value || typeof value !== "object") return void 0;
416
+ const record = value;
417
+ if (typeof record.name === "string") return record.name;
418
+ if (Array.isArray(record.id)) {
419
+ const name = record.id.at(-1);
420
+ return typeof name === "string" ? name : void 0;
421
+ }
422
+ };
423
+ const compactAttributes = (attributes) => {
424
+ return validatedAttributes(Object.fromEntries(Object.entries(attributes).filter(([, value]) => value !== void 0)));
425
+ };
426
+ //#endregion
427
+ //#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
+ });
439
+ //#endregion
440
+ //#region src/integrations/langchain/createAgenticRun.ts
441
+ const createAgenticRun = async (options = {}) => {
442
+ const client = await createAgenticRunClient(options);
443
+ 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
+ }
451
+ });
452
+ return {
453
+ model: createLangChainModel({
454
+ apiKey: configuration.credential.apiKey,
455
+ model: configuration.modelId,
456
+ provider
457
+ }),
458
+ middleware: [middleware],
459
+ createSession: (options) => createLangChainSession(client.createSession(options), {
460
+ model: configuration.modelId,
461
+ provider: configuration.provider
462
+ })
463
+ };
464
+ };
465
+ //#endregion
466
+ export { AgenticRunApiError, AgenticRunConfigurationError, createAgenticRun };
package/package.json ADDED
@@ -0,0 +1,36 @@
1
+ {
2
+ "name": "@agenticrun/sdk",
3
+ "version": "0.1.0-alpha.0",
4
+ "description": "Agenticrun client and LangChain integration for managed agent configuration and tracing",
5
+ "license": "UNLICENSED",
6
+ "type": "module",
7
+ "engines": {
8
+ "node": ">=24.12.0"
9
+ },
10
+ "exports": {
11
+ ".": {
12
+ "types": "./dist/index.d.mts",
13
+ "import": "./dist/index.mjs"
14
+ },
15
+ "./langchain": {
16
+ "types": "./dist/langchain.d.mts",
17
+ "import": "./dist/langchain.mjs"
18
+ }
19
+ },
20
+ "files": [
21
+ "dist",
22
+ "README.md"
23
+ ],
24
+ "publishConfig": {
25
+ "access": "public",
26
+ "tag": "alpha"
27
+ },
28
+ "dependencies": {
29
+ "@langchain/anthropic": "^1.0.0",
30
+ "@langchain/core": "^1.0.0",
31
+ "@langchain/google": "^0.2.0",
32
+ "@langchain/openai": "^1.0.0",
33
+ "langchain": "^1.0.0",
34
+ "zod": "^4.5.4"
35
+ }
36
+ }