@baseline-labs/adapter-langchain 0.1.0 → 0.1.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.
@@ -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
@@ -140,6 +140,145 @@ function integrationErrorFromClientError(error, phase, context) {
140
140
  cause: error,
141
141
  });
142
142
  }
143
+ const DEFAULT_OPERATION_POLL_ATTEMPTS = 20;
144
+ const DEFAULT_OPERATION_POLL_DELAY_MS = 25;
145
+ function delay(ms) {
146
+ return new Promise((resolve) => {
147
+ setTimeout(resolve, ms);
148
+ });
149
+ }
150
+ function continuationCode(state) {
151
+ switch (state) {
152
+ case "expired":
153
+ return "authority_token_expired";
154
+ case "revoked":
155
+ return "authority_surface_revoked";
156
+ case "reevaluation_required":
157
+ return "policy_reevaluation_required";
158
+ case "invalid":
159
+ return "authority_token_invalid";
160
+ default:
161
+ return undefined;
162
+ }
163
+ }
164
+ function toExecuteResponse(request, operation) {
165
+ const decision = operation.status === "pending_approval"
166
+ ? "defer"
167
+ : operation.status === "denied" || operation.status === "invalidated"
168
+ ? "deny"
169
+ : operation.result === "changed"
170
+ ? "modify"
171
+ : "allow";
172
+ const explanationCode = operation.status === "pending_approval"
173
+ ? "approval_required"
174
+ : continuationCode(operation.continuation.state) ??
175
+ (operation.result === "changed" ? "action_modified" : undefined);
176
+ return {
177
+ requestId: operation.requestId ?? request.requestId,
178
+ decision,
179
+ reason: operation.message,
180
+ risk: {
181
+ score: 0,
182
+ level: "low",
183
+ factors: [],
184
+ },
185
+ execution: {
186
+ allowed: decision !== "deny" && decision !== "defer",
187
+ modified: operation.result === "changed",
188
+ deferred: decision === "defer",
189
+ requiresApproval: operation.status === "pending_approval",
190
+ },
191
+ modification: operation.result === "changed" && operation.nextAction.action
192
+ ? {
193
+ action: operation.nextAction.action,
194
+ }
195
+ : undefined,
196
+ approval: operation.status === "pending_approval"
197
+ ? {
198
+ required: true,
199
+ status: "pending",
200
+ }
201
+ : undefined,
202
+ trace: {
203
+ traceId: operation.operationId,
204
+ runId: operation.operationId,
205
+ authorityToken: operation.continuation.handle,
206
+ authorityExpiresAt: operation.continuation.expiresAt,
207
+ },
208
+ audit: {
209
+ timestamp: operation.updatedAt,
210
+ explanationCode,
211
+ },
212
+ };
213
+ }
214
+ function toCommitResponse(request, operation) {
215
+ const denied = operation.status === "denied" ||
216
+ operation.status === "failed" ||
217
+ operation.status === "invalidated" ||
218
+ operation.status === "superseded";
219
+ const deferred = operation.status === "pending_approval";
220
+ const admitted = operation.status === "completed";
221
+ const explanationCode = operation.status === "pending_approval"
222
+ ? "approval_required"
223
+ : operation.status === "partially_completed"
224
+ ? "partial_commit_requires_operator"
225
+ : operation.status === "rollback_incomplete"
226
+ ? "rollback_incomplete"
227
+ : continuationCode(operation.continuation.state) ??
228
+ (denied ? "commit_denied" : undefined);
229
+ return {
230
+ requestId: operation.requestId ?? request.requestId,
231
+ decision: deferred ? "defer" : denied ? "deny" : "allow",
232
+ reason: operation.message,
233
+ state: operation.status === "pending_approval"
234
+ ? "pending_approval"
235
+ : admitted
236
+ ? "committed"
237
+ : "rejected",
238
+ trace: {
239
+ traceId: operation.operationId,
240
+ runId: operation.operationId,
241
+ },
242
+ approval: operation.approval.state === "pending"
243
+ ? {
244
+ required: true,
245
+ status: "pending",
246
+ }
247
+ : operation.approval.state === "denied"
248
+ ? {
249
+ required: false,
250
+ status: "denied",
251
+ }
252
+ : undefined,
253
+ audit: {
254
+ timestamp: operation.updatedAt,
255
+ explanationCode,
256
+ commitType: request.commitType,
257
+ },
258
+ commit: {
259
+ admitted,
260
+ type: request.commitType,
261
+ state: admitted ? "committed" : deferred ? "pending_approval" : "rejected",
262
+ persisted: admitted,
263
+ },
264
+ };
265
+ }
266
+ async function settleOperation(baseline, operationId, phase) {
267
+ let operation = await baseline.getOperation(operationId);
268
+ for (let attempt = 0; operation.status === "processing" && attempt < DEFAULT_OPERATION_POLL_ATTEMPTS; attempt += 1) {
269
+ await delay(DEFAULT_OPERATION_POLL_DELAY_MS);
270
+ operation = await baseline.getOperation(operationId);
271
+ }
272
+ if (operation.status === "processing") {
273
+ throw new BaselineIntegrationError({
274
+ message: `Baseline operation ${operationId} is still processing.`,
275
+ kind: "request_failed",
276
+ phase,
277
+ reason: operation.message,
278
+ });
279
+ }
280
+ return operation;
281
+ }
143
282
  function rawInvokeFor(tool) {
144
283
  const managedTool = tool;
145
284
  if (managedTool[BASELINE_RAW_INVOKE]) {
@@ -176,7 +315,7 @@ async function invokeManagedTool(tool, input, runtimeContext) {
176
315
  function managedRequestOptions(options) {
177
316
  const managedContext = options.managedContext;
178
317
  return {
179
- traceParent: managedContext?.lastTraceId,
318
+ parentOperationId: managedContext?.lastTraceId,
180
319
  runId: managedContext?.runId,
181
320
  authorityToken: managedContext?.authorityToken,
182
321
  stepIndex: managedContext ? (managedContext.priorActions?.length ?? 0) + 1 : undefined,
@@ -269,7 +408,7 @@ function buildCommitRequest(tool, input, executeDecision, options, managedContex
269
408
  },
270
409
  },
271
410
  commitType: tool.authority.commitType,
272
- supportingTraceId: executeDecision.trace.traceId,
411
+ supportingOperationId: executeDecision.trace.traceId,
273
412
  authorityToken: managedContext?.authorityToken ?? executeDecision.trace.authorityToken,
274
413
  checkpointRef: resolvePlanValue(commitPlan?.checkpointRef, input),
275
414
  rollbackRef: normalizeRollbackRef(tool.authority.commitType, resolvePlanValue(commitPlan?.rollbackRef, input)),
@@ -280,7 +419,11 @@ function buildCommitRequest(tool, input, executeDecision, options, managedContex
280
419
  }
281
420
  async function executeViaBaseline(baseline, request, context) {
282
421
  try {
283
- return await baseline.execute(request);
422
+ const immediate = await baseline.executeV2(request, {
423
+ idempotencyKey: request.requestId,
424
+ });
425
+ const operation = await settleOperation(baseline, immediate.operation.id, "execute");
426
+ return toExecuteResponse(request, operation);
284
427
  }
285
428
  catch (error) {
286
429
  if (error instanceof BaselineClientError) {
@@ -291,7 +434,11 @@ async function executeViaBaseline(baseline, request, context) {
291
434
  }
292
435
  async function commitViaBaseline(baseline, request, context) {
293
436
  try {
294
- return await baseline.commit(request);
437
+ const immediate = await baseline.commitV2(request, {
438
+ idempotencyKey: request.requestId,
439
+ });
440
+ const operation = await settleOperation(baseline, immediate.operation.id, "commit");
441
+ return toCommitResponse(request, operation);
295
442
  }
296
443
  catch (error) {
297
444
  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.1",
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.1"
40
40
  }
41
41
  }