@baseline-labs/adapter-langchain 0.1.0 → 0.1.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.
@@ -7,6 +7,7 @@ export interface BuildLangChainExecuteRequestOptions {
7
7
  source?: string;
8
8
  toolAuthority?: ToolAuthoritySpec;
9
9
  traceParent?: string;
10
+ parentOperationId?: string;
10
11
  runId?: string;
11
12
  authorityToken?: string;
12
13
  stepIndex?: number;
@@ -28,6 +28,7 @@ export function buildExecuteRequest(tool, input, options) {
28
28
  }
29
29
  : undefined,
30
30
  metadata: {
31
+ parentOperationId: options.parentOperationId,
31
32
  traceParent: options.traceParent,
32
33
  runId: options.runId,
33
34
  authorityToken: options.authorityToken,
package/dist/native.d.ts CHANGED
@@ -3,7 +3,7 @@ import type { BaselineManagedToolRecord, BaselineRequestContext, BaselineToolDef
3
3
  import { type InvokableTool, type ManagedExecutionContext } from "./wrapTool.js";
4
4
  export { BaselineIntegrationError } from "./wrapTool.js";
5
5
  export interface BaselineLangChainOptions {
6
- baseline: BaselineClient | Pick<BaselineClient, "execute" | "commit"> | (BaselineClientConfig & {
6
+ baseline: BaselineClient | Pick<BaselineClient, "executeV2" | "commitV2" | "getOperation"> | (BaselineClientConfig & {
7
7
  authorityDefaults?: BaselineRequestContext;
8
8
  agentId?: string;
9
9
  sessionId?: string;
package/dist/native.js CHANGED
@@ -7,10 +7,12 @@ const DEFAULT_AGENT_ID = "baseline-langchain";
7
7
  function isBaselineClientExecutor(value) {
8
8
  return (typeof value === "object" &&
9
9
  value !== null &&
10
- "execute" in value &&
11
- typeof value.execute === "function" &&
12
- "commit" in value &&
13
- typeof value.commit === "function");
10
+ "executeV2" in value &&
11
+ typeof value.executeV2 === "function" &&
12
+ "commitV2" in value &&
13
+ typeof value.commitV2 === "function" &&
14
+ "getOperation" in value &&
15
+ typeof value.getOperation === "function");
14
16
  }
15
17
  function contextFromDefaults(defaults) {
16
18
  if (!defaults) {
@@ -49,4 +49,6 @@ export interface ManagedExecutionContext {
49
49
  priorActions: NonNullable<ExecuteRequest["state"]>["priorActions"];
50
50
  history: BaselineManagedToolRecord[];
51
51
  }
52
- export declare function wrapTool<Input = unknown, Output = unknown>(tool: InvokableTool<Input, Output>, baseline: BaselineClient, options: WrapToolOptions): InvokableTool<Input, Output>;
52
+ type BaselineV2ClientExecutor = Pick<BaselineClient, "executeV2" | "commitV2" | "getOperation">;
53
+ export declare function wrapTool<Input = unknown, Output = unknown>(tool: InvokableTool<Input, Output>, baseline: BaselineV2ClientExecutor, options: WrapToolOptions): InvokableTool<Input, Output>;
54
+ export {};
package/dist/wrapTool.js CHANGED
@@ -80,6 +80,7 @@ function formatIntegrationErrorMessage(input) {
80
80
  kind: input.kind,
81
81
  authority: input.authority,
82
82
  code: input.code,
83
+ reason: input.reason,
83
84
  });
84
85
  if (suggestion) {
85
86
  lines.push("", "Suggestion:", suggestion);
@@ -140,6 +141,145 @@ function integrationErrorFromClientError(error, phase, context) {
140
141
  cause: error,
141
142
  });
142
143
  }
144
+ const DEFAULT_OPERATION_POLL_ATTEMPTS = 20;
145
+ const DEFAULT_OPERATION_POLL_DELAY_MS = 25;
146
+ function delay(ms) {
147
+ return new Promise((resolve) => {
148
+ setTimeout(resolve, ms);
149
+ });
150
+ }
151
+ function continuationCode(state) {
152
+ switch (state) {
153
+ case "expired":
154
+ return "authority_token_expired";
155
+ case "revoked":
156
+ return "authority_surface_revoked";
157
+ case "reevaluation_required":
158
+ return "policy_reevaluation_required";
159
+ case "invalid":
160
+ return "authority_token_invalid";
161
+ default:
162
+ return undefined;
163
+ }
164
+ }
165
+ function toExecuteResponse(request, operation) {
166
+ const decision = operation.status === "pending_approval"
167
+ ? "defer"
168
+ : operation.status === "denied" || operation.status === "invalidated"
169
+ ? "deny"
170
+ : operation.result === "changed"
171
+ ? "modify"
172
+ : "allow";
173
+ const explanationCode = operation.status === "pending_approval"
174
+ ? "approval_required"
175
+ : continuationCode(operation.continuation.state) ??
176
+ (operation.result === "changed" ? "action_modified" : undefined);
177
+ return {
178
+ requestId: operation.requestId ?? request.requestId,
179
+ decision,
180
+ reason: operation.message,
181
+ risk: {
182
+ score: 0,
183
+ level: "low",
184
+ factors: [],
185
+ },
186
+ execution: {
187
+ allowed: decision !== "deny" && decision !== "defer",
188
+ modified: operation.result === "changed",
189
+ deferred: decision === "defer",
190
+ requiresApproval: operation.status === "pending_approval",
191
+ },
192
+ modification: operation.result === "changed" && operation.nextAction.action
193
+ ? {
194
+ action: operation.nextAction.action,
195
+ }
196
+ : undefined,
197
+ approval: operation.status === "pending_approval"
198
+ ? {
199
+ required: true,
200
+ status: "pending",
201
+ }
202
+ : undefined,
203
+ trace: {
204
+ traceId: operation.operationId,
205
+ runId: operation.operationId,
206
+ authorityToken: operation.continuation.handle,
207
+ authorityExpiresAt: operation.continuation.expiresAt,
208
+ },
209
+ audit: {
210
+ timestamp: operation.updatedAt,
211
+ explanationCode,
212
+ },
213
+ };
214
+ }
215
+ function toCommitResponse(request, operation) {
216
+ const denied = operation.status === "denied" ||
217
+ operation.status === "failed" ||
218
+ operation.status === "invalidated" ||
219
+ operation.status === "superseded";
220
+ const deferred = operation.status === "pending_approval";
221
+ const admitted = operation.status === "completed";
222
+ const explanationCode = operation.status === "pending_approval"
223
+ ? "approval_required"
224
+ : operation.status === "partially_completed"
225
+ ? "partial_commit_requires_operator"
226
+ : operation.status === "rollback_incomplete"
227
+ ? "rollback_incomplete"
228
+ : continuationCode(operation.continuation.state) ??
229
+ (denied ? "commit_denied" : undefined);
230
+ return {
231
+ requestId: operation.requestId ?? request.requestId,
232
+ decision: deferred ? "defer" : denied ? "deny" : "allow",
233
+ reason: operation.message,
234
+ state: operation.status === "pending_approval"
235
+ ? "pending_approval"
236
+ : admitted
237
+ ? "committed"
238
+ : "rejected",
239
+ trace: {
240
+ traceId: operation.operationId,
241
+ runId: operation.operationId,
242
+ },
243
+ approval: operation.approval.state === "pending"
244
+ ? {
245
+ required: true,
246
+ status: "pending",
247
+ }
248
+ : operation.approval.state === "denied"
249
+ ? {
250
+ required: false,
251
+ status: "denied",
252
+ }
253
+ : undefined,
254
+ audit: {
255
+ timestamp: operation.updatedAt,
256
+ explanationCode,
257
+ commitType: request.commitType,
258
+ },
259
+ commit: {
260
+ admitted,
261
+ type: request.commitType,
262
+ state: admitted ? "committed" : deferred ? "pending_approval" : "rejected",
263
+ persisted: admitted,
264
+ },
265
+ };
266
+ }
267
+ async function settleOperation(baseline, operationId, phase) {
268
+ let operation = await baseline.getOperation(operationId);
269
+ for (let attempt = 0; operation.status === "processing" && attempt < DEFAULT_OPERATION_POLL_ATTEMPTS; attempt += 1) {
270
+ await delay(DEFAULT_OPERATION_POLL_DELAY_MS);
271
+ operation = await baseline.getOperation(operationId);
272
+ }
273
+ if (operation.status === "processing") {
274
+ throw new BaselineIntegrationError({
275
+ message: `Baseline operation ${operationId} is still processing.`,
276
+ kind: "request_failed",
277
+ phase,
278
+ reason: operation.message,
279
+ });
280
+ }
281
+ return operation;
282
+ }
143
283
  function rawInvokeFor(tool) {
144
284
  const managedTool = tool;
145
285
  if (managedTool[BASELINE_RAW_INVOKE]) {
@@ -176,7 +316,7 @@ async function invokeManagedTool(tool, input, runtimeContext) {
176
316
  function managedRequestOptions(options) {
177
317
  const managedContext = options.managedContext;
178
318
  return {
179
- traceParent: managedContext?.lastTraceId,
319
+ parentOperationId: managedContext?.lastTraceId,
180
320
  runId: managedContext?.runId,
181
321
  authorityToken: managedContext?.authorityToken,
182
322
  stepIndex: managedContext ? (managedContext.priorActions?.length ?? 0) + 1 : undefined,
@@ -269,7 +409,7 @@ function buildCommitRequest(tool, input, executeDecision, options, managedContex
269
409
  },
270
410
  },
271
411
  commitType: tool.authority.commitType,
272
- supportingTraceId: executeDecision.trace.traceId,
412
+ supportingOperationId: executeDecision.trace.traceId,
273
413
  authorityToken: managedContext?.authorityToken ?? executeDecision.trace.authorityToken,
274
414
  checkpointRef: resolvePlanValue(commitPlan?.checkpointRef, input),
275
415
  rollbackRef: normalizeRollbackRef(tool.authority.commitType, resolvePlanValue(commitPlan?.rollbackRef, input)),
@@ -280,7 +420,11 @@ function buildCommitRequest(tool, input, executeDecision, options, managedContex
280
420
  }
281
421
  async function executeViaBaseline(baseline, request, context) {
282
422
  try {
283
- return await baseline.execute(request);
423
+ const immediate = await baseline.executeV2(request, {
424
+ idempotencyKey: request.requestId,
425
+ });
426
+ const operation = await settleOperation(baseline, immediate.operation.id, "execute");
427
+ return toExecuteResponse(request, operation);
284
428
  }
285
429
  catch (error) {
286
430
  if (error instanceof BaselineClientError) {
@@ -291,7 +435,11 @@ async function executeViaBaseline(baseline, request, context) {
291
435
  }
292
436
  async function commitViaBaseline(baseline, request, context) {
293
437
  try {
294
- return await baseline.commit(request);
438
+ const immediate = await baseline.commitV2(request, {
439
+ idempotencyKey: request.requestId,
440
+ });
441
+ const operation = await settleOperation(baseline, immediate.operation.id, "commit");
442
+ return toCommitResponse(request, operation);
295
443
  }
296
444
  catch (error) {
297
445
  if (error instanceof BaselineClientError) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@baseline-labs/adapter-langchain",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "Authority-aware LangChain tool integration for Baseline.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -35,7 +35,7 @@
35
35
  "authority"
36
36
  ],
37
37
  "dependencies": {
38
- "@baseline-labs/sdk": "^0.1.0",
39
- "@baseline-labs/types": "^0.1.0"
38
+ "@baseline-labs/sdk": "^0.1.1",
39
+ "@baseline-labs/types": "^0.1.2"
40
40
  }
41
41
  }