gitlab-ai-provider 6.2.0 → 6.3.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.
package/dist/index.mjs CHANGED
@@ -1582,7 +1582,7 @@ var GitLabOpenAILanguageModel = class {
1582
1582
  import WebSocket from "isomorphic-ws";
1583
1583
 
1584
1584
  // src/version.ts
1585
- var VERSION = true ? "6.1.1" : "0.0.0-dev";
1585
+ var VERSION = true ? "6.2.1" : "0.0.0-dev";
1586
1586
 
1587
1587
  // src/gitlab-workflow-types.ts
1588
1588
  var WorkflowType = /* @__PURE__ */ ((WorkflowType2) => {
@@ -2975,14 +2975,12 @@ var GitLabWorkflowLanguageModel = class _GitLabWorkflowLanguageModel {
2975
2975
  // Cached detected project path
2976
2976
  detectedProjectPath = null;
2977
2977
  // Workflow ID persisted across turns for multi-turn conversations.
2978
- // When DWS sends INPUT_REQUIRED, the workflow stays alive server-side.
2979
- // On the next doStream() call we reuse this ID (skip createWorkflow).
2978
+ // Per-session workflow state. Keyed by opencode sessionID (x-opencode-session header).
2979
+ // Each opencode session gets its own DWS workflow, reused across turns within that session.
2980
+ sessionWorkflows = /* @__PURE__ */ new Map();
2981
+ // Fallback for callers that don't pass x-opencode-session (e.g. direct SDK use).
2980
2982
  currentWorkflowId = null;
2981
- // Track which workflowDefinition/flowConfig the current workflow was created with.
2982
- // When the agent changes, reset the workflow so a new one is created correctly.
2983
2983
  currentWorkflowDefinition = null;
2984
- // Persisted across turns so that cumulative DWS chat logs don't re-emit
2985
- // messages that were already streamed in a previous doStream() call.
2986
2984
  persistedAgentEmitted = /* @__PURE__ */ new Map();
2987
2985
  // Track all active stream clients so stopWorkflow() can stop them all.
2988
2986
  activeClients = /* @__PURE__ */ new Set();
@@ -3044,6 +3042,11 @@ var GitLabWorkflowLanguageModel = class _GitLabWorkflowLanguageModel {
3044
3042
  * Updated when the user chooses "always" in the approval prompt.
3045
3043
  */
3046
3044
  sessionPreapprovedTools = [];
3045
+ /**
3046
+ * The opencode session ID. Set per-stream by the host to key per-session
3047
+ * DWS workflows. Different sessions get different DWS workflows.
3048
+ */
3049
+ sessionID = "";
3047
3050
  /**
3048
3051
  * Set the approval handler callback.
3049
3052
  * Called when DWS requires tool call approval. Host (e.g., opencode) wires this
@@ -3273,9 +3276,14 @@ var GitLabWorkflowLanguageModel = class _GitLabWorkflowLanguageModel {
3273
3276
  * Reset the workflow state, forcing a new workflow to be created on the
3274
3277
  * next doStream() call. Call this when starting a new conversation.
3275
3278
  */
3276
- resetWorkflow() {
3277
- this.currentWorkflowId = null;
3278
- this.persistedAgentEmitted.clear();
3279
+ resetWorkflow(sessionKey) {
3280
+ if (sessionKey) {
3281
+ this.sessionWorkflows.delete(sessionKey);
3282
+ } else {
3283
+ this.sessionWorkflows.clear();
3284
+ this.currentWorkflowId = null;
3285
+ this.persistedAgentEmitted.clear();
3286
+ }
3279
3287
  }
3280
3288
  /**
3281
3289
  * Get the current workflow ID (if any).
@@ -3374,12 +3382,21 @@ var GitLabWorkflowLanguageModel = class _GitLabWorkflowLanguageModel {
3374
3382
  );
3375
3383
  const projectId = await this.resolveProjectId();
3376
3384
  const effectiveDefinition = callFlowConfig ?? callWorkflowDefinition ?? DEFAULT_WORKFLOW_DEFINITION;
3377
- if (this.currentWorkflowId && this.currentWorkflowDefinition !== effectiveDefinition) {
3385
+ const sessionKey = this.sessionID;
3386
+ let sess = this.sessionWorkflows.get(sessionKey);
3387
+ if (sess && sess.workflowDefinition !== effectiveDefinition) {
3388
+ this.sessionWorkflows.delete(sessionKey);
3389
+ sess = void 0;
3390
+ }
3391
+ const useLegacy = sessionKey === "";
3392
+ if (useLegacy && this.currentWorkflowId && this.currentWorkflowDefinition !== effectiveDefinition) {
3378
3393
  this.currentWorkflowId = null;
3379
3394
  this.currentWorkflowDefinition = null;
3380
3395
  }
3381
3396
  let workflowId;
3382
- if (this.currentWorkflowId) {
3397
+ if (sess) {
3398
+ workflowId = sess.workflowId;
3399
+ } else if (useLegacy && this.currentWorkflowId) {
3383
3400
  workflowId = this.currentWorkflowId;
3384
3401
  } else {
3385
3402
  workflowId = await this.tokenClient.createWorkflow(goal, {
@@ -3389,8 +3406,17 @@ var GitLabWorkflowLanguageModel = class _GitLabWorkflowLanguageModel {
3389
3406
  agentPrivileges: this.workflowOptions.agentPrivileges,
3390
3407
  aiCatalogItemVersionId: callAiCatalogItemVersionId
3391
3408
  });
3392
- this.currentWorkflowId = workflowId;
3393
- this.currentWorkflowDefinition = effectiveDefinition;
3409
+ if (useLegacy) {
3410
+ this.currentWorkflowId = workflowId;
3411
+ this.currentWorkflowDefinition = effectiveDefinition;
3412
+ } else {
3413
+ this.sessionWorkflows.set(sessionKey, {
3414
+ workflowId,
3415
+ workflowDefinition: effectiveDefinition,
3416
+ agentEmitted: /* @__PURE__ */ new Map()
3417
+ });
3418
+ sess = this.sessionWorkflows.get(sessionKey);
3419
+ }
3394
3420
  }
3395
3421
  const wsClient = new GitLabWorkflowClient();
3396
3422
  this.activeClients.add(wsClient);
@@ -3403,10 +3429,11 @@ var GitLabWorkflowLanguageModel = class _GitLabWorkflowLanguageModel {
3403
3429
  approvalPending: false,
3404
3430
  deferredClose: null,
3405
3431
  activeTextBlockId: null,
3406
- agentMessageEmitted: new Map(this.persistedAgentEmitted),
3432
+ agentMessageEmitted: new Map(sess?.agentEmitted ?? this.persistedAgentEmitted),
3407
3433
  currentAgentMessageId: "",
3408
3434
  activeClient: wsClient,
3409
- processedRequestIDs: /* @__PURE__ */ new Set()
3435
+ processedRequestIDs: /* @__PURE__ */ new Set(),
3436
+ sessionKey
3410
3437
  };
3411
3438
  for (const msg of options.prompt) {
3412
3439
  if (msg.role === "system") {
@@ -3517,7 +3544,13 @@ var GitLabWorkflowLanguageModel = class _GitLabWorkflowLanguageModel {
3517
3544
  wsClient.close();
3518
3545
  this.activeClients.delete(wsClient);
3519
3546
  ss.activeClient = null;
3520
- this.currentWorkflowId = null;
3547
+ if (!ss.streamClosed) {
3548
+ if (ss.sessionKey) {
3549
+ this.sessionWorkflows.delete(ss.sessionKey);
3550
+ } else {
3551
+ this.currentWorkflowId = null;
3552
+ }
3553
+ }
3521
3554
  }
3522
3555
  });
3523
3556
  return {
@@ -3641,7 +3674,7 @@ var GitLabWorkflowLanguageModel = class _GitLabWorkflowLanguageModel {
3641
3674
  toolExecutor,
3642
3675
  nextTextId,
3643
3676
  availableToolNames
3644
- ).catch(() => {
3677
+ ).catch((_err) => {
3645
3678
  ss.approvalPending = false;
3646
3679
  if (ss.deferredClose) {
3647
3680
  const close = ss.deferredClose;
@@ -3667,7 +3700,7 @@ var GitLabWorkflowLanguageModel = class _GitLabWorkflowLanguageModel {
3667
3700
  });
3668
3701
  ss.streamClosed = true;
3669
3702
  controller.close();
3670
- this.cleanupClient(ss);
3703
+ this.cleanupClient(ss, false);
3671
3704
  };
3672
3705
  if (ss.pendingToolCount > 0 || ss.approvalPending) {
3673
3706
  ss.deferredClose = doCompleteClose;
@@ -3725,7 +3758,7 @@ var GitLabWorkflowLanguageModel = class _GitLabWorkflowLanguageModel {
3725
3758
  });
3726
3759
  ss.streamClosed = true;
3727
3760
  controller.close();
3728
- this.cleanupClient(ss);
3761
+ this.cleanupClient(ss, false);
3729
3762
  }
3730
3763
  };
3731
3764
  if (ss.pendingToolCount > 0 || ss.approvalPending) {
@@ -3794,7 +3827,8 @@ var GitLabWorkflowLanguageModel = class _GitLabWorkflowLanguageModel {
3794
3827
  });
3795
3828
  ss.streamedOutputChars += delta.length;
3796
3829
  ss.agentMessageEmitted.set(msgId, content.length);
3797
- this.persistedAgentEmitted.set(msgId, content.length);
3830
+ const target = this.sessionWorkflows.get(ss.sessionKey)?.agentEmitted ?? this.persistedAgentEmitted;
3831
+ target.set(msgId, content.length);
3798
3832
  ss.currentAgentMessageId = msgId;
3799
3833
  }
3800
3834
  }
@@ -3900,8 +3934,12 @@ var GitLabWorkflowLanguageModel = class _GitLabWorkflowLanguageModel {
3900
3934
  ss.activeClient = null;
3901
3935
  }
3902
3936
  if (clearWorkflow) {
3903
- this.currentWorkflowId = null;
3904
- this.persistedAgentEmitted.clear();
3937
+ if (ss.sessionKey) {
3938
+ this.sessionWorkflows.delete(ss.sessionKey);
3939
+ } else {
3940
+ this.currentWorkflowId = null;
3941
+ this.persistedAgentEmitted.clear();
3942
+ }
3905
3943
  }
3906
3944
  }
3907
3945
  async approveAndResume(ss, tools, startReq, controller, toolExecutor, nextTextId, availableToolNames) {
@@ -3924,9 +3962,14 @@ var GitLabWorkflowLanguageModel = class _GitLabWorkflowLanguageModel {
3924
3962
  return;
3925
3963
  }
3926
3964
  ss.approvalPending = false;
3965
+ ss.deferredClose = null;
3927
3966
  this.cleanupClient(ss, false);
3928
3967
  const approval = decision.approved ? { approval: { tool_name: tools[0]?.name, tool_args_json: tools[0]?.args } } : { rejection: { message: decision.message ?? "User rejected" } };
3929
- const newStartReq = { ...startReq, approval };
3968
+ const newStartReq = {
3969
+ ...startReq,
3970
+ approval,
3971
+ preapproved_tools: decision.approved ? [...startReq.preapproved_tools ?? [], ...tools.map((t) => t.name)] : startReq.preapproved_tools ?? []
3972
+ };
3930
3973
  const newClient = new GitLabWorkflowClient();
3931
3974
  this.activeClients.add(newClient);
3932
3975
  ss.activeClient = newClient;