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/CHANGELOG.md +11 -0
- package/dist/gitlab-ai-provider-6.3.0.tgz +0 -0
- package/dist/index.d.mts +7 -1
- package/dist/index.d.ts +7 -1
- package/dist/index.js +67 -24
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +67 -24
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/dist/gitlab-ai-provider-6.2.0.tgz +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,17 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
4
4
|
|
|
5
|
+
## 6.3.0 (2026-03-31)
|
|
6
|
+
|
|
7
|
+
- fix(model): clear deferredClose before reconnect to prevent stream dying after batch approval ([017f8fe](https://gitlab.com/vglafirov/gitlab-ai-provider/commit/017f8fe))
|
|
8
|
+
- fix(tests): use class mock for GitLabWorkflowTokenClient to support new in all environments ([e3f0e24](https://gitlab.com/vglafirov/gitlab-ai-provider/commit/e3f0e24))
|
|
9
|
+
- chore: rebuild dist ([71bdc51](https://gitlab.com/vglafirov/gitlab-ai-provider/commit/71bdc51))
|
|
10
|
+
- feat(model): per-session DWS workflow lifecycle and tool call approval ([aa7a09a](https://gitlab.com/vglafirov/gitlab-ai-provider/commit/aa7a09a))
|
|
11
|
+
|
|
12
|
+
## <small>6.2.1 (2026-03-31)</small>
|
|
13
|
+
|
|
14
|
+
- fix(model): pre-approve all batch tools on approval reconnect to prevent re-triggering ([d7f80e2](https://gitlab.com/vglafirov/gitlab-ai-provider/commit/d7f80e2))
|
|
15
|
+
|
|
5
16
|
## 6.2.0 (2026-03-30)
|
|
6
17
|
|
|
7
18
|
- feat: support aiCatalogItemVersionId in createWorkflow for custom agent session linking ([861c98d](https://gitlab.com/vglafirov/gitlab-ai-provider/commit/861c98d))
|
|
Binary file
|
package/dist/index.d.mts
CHANGED
|
@@ -703,6 +703,7 @@ declare class GitLabWorkflowLanguageModel implements LanguageModelV3 {
|
|
|
703
703
|
private readonly modelDiscovery;
|
|
704
704
|
private readonly modelCache;
|
|
705
705
|
private detectedProjectPath;
|
|
706
|
+
private readonly sessionWorkflows;
|
|
706
707
|
private currentWorkflowId;
|
|
707
708
|
private currentWorkflowDefinition;
|
|
708
709
|
private persistedAgentEmitted;
|
|
@@ -756,6 +757,11 @@ declare class GitLabWorkflowLanguageModel implements LanguageModelV3 {
|
|
|
756
757
|
* Updated when the user chooses "always" in the approval prompt.
|
|
757
758
|
*/
|
|
758
759
|
sessionPreapprovedTools: string[];
|
|
760
|
+
/**
|
|
761
|
+
* The opencode session ID. Set per-stream by the host to key per-session
|
|
762
|
+
* DWS workflows. Different sessions get different DWS workflows.
|
|
763
|
+
*/
|
|
764
|
+
sessionID: string;
|
|
759
765
|
/**
|
|
760
766
|
* Set the approval handler callback.
|
|
761
767
|
* Called when DWS requires tool call approval. Host (e.g., opencode) wires this
|
|
@@ -843,7 +849,7 @@ declare class GitLabWorkflowLanguageModel implements LanguageModelV3 {
|
|
|
843
849
|
* Reset the workflow state, forcing a new workflow to be created on the
|
|
844
850
|
* next doStream() call. Call this when starting a new conversation.
|
|
845
851
|
*/
|
|
846
|
-
resetWorkflow(): void;
|
|
852
|
+
resetWorkflow(sessionKey?: string): void;
|
|
847
853
|
/**
|
|
848
854
|
* Get the current workflow ID (if any).
|
|
849
855
|
* Useful for consumers that need to track workflow state.
|
package/dist/index.d.ts
CHANGED
|
@@ -703,6 +703,7 @@ declare class GitLabWorkflowLanguageModel implements LanguageModelV3 {
|
|
|
703
703
|
private readonly modelDiscovery;
|
|
704
704
|
private readonly modelCache;
|
|
705
705
|
private detectedProjectPath;
|
|
706
|
+
private readonly sessionWorkflows;
|
|
706
707
|
private currentWorkflowId;
|
|
707
708
|
private currentWorkflowDefinition;
|
|
708
709
|
private persistedAgentEmitted;
|
|
@@ -756,6 +757,11 @@ declare class GitLabWorkflowLanguageModel implements LanguageModelV3 {
|
|
|
756
757
|
* Updated when the user chooses "always" in the approval prompt.
|
|
757
758
|
*/
|
|
758
759
|
sessionPreapprovedTools: string[];
|
|
760
|
+
/**
|
|
761
|
+
* The opencode session ID. Set per-stream by the host to key per-session
|
|
762
|
+
* DWS workflows. Different sessions get different DWS workflows.
|
|
763
|
+
*/
|
|
764
|
+
sessionID: string;
|
|
759
765
|
/**
|
|
760
766
|
* Set the approval handler callback.
|
|
761
767
|
* Called when DWS requires tool call approval. Host (e.g., opencode) wires this
|
|
@@ -843,7 +849,7 @@ declare class GitLabWorkflowLanguageModel implements LanguageModelV3 {
|
|
|
843
849
|
* Reset the workflow state, forcing a new workflow to be created on the
|
|
844
850
|
* next doStream() call. Call this when starting a new conversation.
|
|
845
851
|
*/
|
|
846
|
-
resetWorkflow(): void;
|
|
852
|
+
resetWorkflow(sessionKey?: string): void;
|
|
847
853
|
/**
|
|
848
854
|
* Get the current workflow ID (if any).
|
|
849
855
|
* Useful for consumers that need to track workflow state.
|
package/dist/index.js
CHANGED
|
@@ -1653,7 +1653,7 @@ var GitLabOpenAILanguageModel = class {
|
|
|
1653
1653
|
var import_isomorphic_ws = __toESM(require("isomorphic-ws"));
|
|
1654
1654
|
|
|
1655
1655
|
// src/version.ts
|
|
1656
|
-
var VERSION = true ? "6.
|
|
1656
|
+
var VERSION = true ? "6.2.1" : "0.0.0-dev";
|
|
1657
1657
|
|
|
1658
1658
|
// src/gitlab-workflow-types.ts
|
|
1659
1659
|
var WorkflowType = /* @__PURE__ */ ((WorkflowType2) => {
|
|
@@ -3046,14 +3046,12 @@ var GitLabWorkflowLanguageModel = class _GitLabWorkflowLanguageModel {
|
|
|
3046
3046
|
// Cached detected project path
|
|
3047
3047
|
detectedProjectPath = null;
|
|
3048
3048
|
// Workflow ID persisted across turns for multi-turn conversations.
|
|
3049
|
-
//
|
|
3050
|
-
//
|
|
3049
|
+
// Per-session workflow state. Keyed by opencode sessionID (x-opencode-session header).
|
|
3050
|
+
// Each opencode session gets its own DWS workflow, reused across turns within that session.
|
|
3051
|
+
sessionWorkflows = /* @__PURE__ */ new Map();
|
|
3052
|
+
// Fallback for callers that don't pass x-opencode-session (e.g. direct SDK use).
|
|
3051
3053
|
currentWorkflowId = null;
|
|
3052
|
-
// Track which workflowDefinition/flowConfig the current workflow was created with.
|
|
3053
|
-
// When the agent changes, reset the workflow so a new one is created correctly.
|
|
3054
3054
|
currentWorkflowDefinition = null;
|
|
3055
|
-
// Persisted across turns so that cumulative DWS chat logs don't re-emit
|
|
3056
|
-
// messages that were already streamed in a previous doStream() call.
|
|
3057
3055
|
persistedAgentEmitted = /* @__PURE__ */ new Map();
|
|
3058
3056
|
// Track all active stream clients so stopWorkflow() can stop them all.
|
|
3059
3057
|
activeClients = /* @__PURE__ */ new Set();
|
|
@@ -3115,6 +3113,11 @@ var GitLabWorkflowLanguageModel = class _GitLabWorkflowLanguageModel {
|
|
|
3115
3113
|
* Updated when the user chooses "always" in the approval prompt.
|
|
3116
3114
|
*/
|
|
3117
3115
|
sessionPreapprovedTools = [];
|
|
3116
|
+
/**
|
|
3117
|
+
* The opencode session ID. Set per-stream by the host to key per-session
|
|
3118
|
+
* DWS workflows. Different sessions get different DWS workflows.
|
|
3119
|
+
*/
|
|
3120
|
+
sessionID = "";
|
|
3118
3121
|
/**
|
|
3119
3122
|
* Set the approval handler callback.
|
|
3120
3123
|
* Called when DWS requires tool call approval. Host (e.g., opencode) wires this
|
|
@@ -3344,9 +3347,14 @@ var GitLabWorkflowLanguageModel = class _GitLabWorkflowLanguageModel {
|
|
|
3344
3347
|
* Reset the workflow state, forcing a new workflow to be created on the
|
|
3345
3348
|
* next doStream() call. Call this when starting a new conversation.
|
|
3346
3349
|
*/
|
|
3347
|
-
resetWorkflow() {
|
|
3348
|
-
|
|
3349
|
-
|
|
3350
|
+
resetWorkflow(sessionKey) {
|
|
3351
|
+
if (sessionKey) {
|
|
3352
|
+
this.sessionWorkflows.delete(sessionKey);
|
|
3353
|
+
} else {
|
|
3354
|
+
this.sessionWorkflows.clear();
|
|
3355
|
+
this.currentWorkflowId = null;
|
|
3356
|
+
this.persistedAgentEmitted.clear();
|
|
3357
|
+
}
|
|
3350
3358
|
}
|
|
3351
3359
|
/**
|
|
3352
3360
|
* Get the current workflow ID (if any).
|
|
@@ -3445,12 +3453,21 @@ var GitLabWorkflowLanguageModel = class _GitLabWorkflowLanguageModel {
|
|
|
3445
3453
|
);
|
|
3446
3454
|
const projectId = await this.resolveProjectId();
|
|
3447
3455
|
const effectiveDefinition = callFlowConfig ?? callWorkflowDefinition ?? DEFAULT_WORKFLOW_DEFINITION;
|
|
3448
|
-
|
|
3456
|
+
const sessionKey = this.sessionID;
|
|
3457
|
+
let sess = this.sessionWorkflows.get(sessionKey);
|
|
3458
|
+
if (sess && sess.workflowDefinition !== effectiveDefinition) {
|
|
3459
|
+
this.sessionWorkflows.delete(sessionKey);
|
|
3460
|
+
sess = void 0;
|
|
3461
|
+
}
|
|
3462
|
+
const useLegacy = sessionKey === "";
|
|
3463
|
+
if (useLegacy && this.currentWorkflowId && this.currentWorkflowDefinition !== effectiveDefinition) {
|
|
3449
3464
|
this.currentWorkflowId = null;
|
|
3450
3465
|
this.currentWorkflowDefinition = null;
|
|
3451
3466
|
}
|
|
3452
3467
|
let workflowId;
|
|
3453
|
-
if (
|
|
3468
|
+
if (sess) {
|
|
3469
|
+
workflowId = sess.workflowId;
|
|
3470
|
+
} else if (useLegacy && this.currentWorkflowId) {
|
|
3454
3471
|
workflowId = this.currentWorkflowId;
|
|
3455
3472
|
} else {
|
|
3456
3473
|
workflowId = await this.tokenClient.createWorkflow(goal, {
|
|
@@ -3460,8 +3477,17 @@ var GitLabWorkflowLanguageModel = class _GitLabWorkflowLanguageModel {
|
|
|
3460
3477
|
agentPrivileges: this.workflowOptions.agentPrivileges,
|
|
3461
3478
|
aiCatalogItemVersionId: callAiCatalogItemVersionId
|
|
3462
3479
|
});
|
|
3463
|
-
|
|
3464
|
-
|
|
3480
|
+
if (useLegacy) {
|
|
3481
|
+
this.currentWorkflowId = workflowId;
|
|
3482
|
+
this.currentWorkflowDefinition = effectiveDefinition;
|
|
3483
|
+
} else {
|
|
3484
|
+
this.sessionWorkflows.set(sessionKey, {
|
|
3485
|
+
workflowId,
|
|
3486
|
+
workflowDefinition: effectiveDefinition,
|
|
3487
|
+
agentEmitted: /* @__PURE__ */ new Map()
|
|
3488
|
+
});
|
|
3489
|
+
sess = this.sessionWorkflows.get(sessionKey);
|
|
3490
|
+
}
|
|
3465
3491
|
}
|
|
3466
3492
|
const wsClient = new GitLabWorkflowClient();
|
|
3467
3493
|
this.activeClients.add(wsClient);
|
|
@@ -3474,10 +3500,11 @@ var GitLabWorkflowLanguageModel = class _GitLabWorkflowLanguageModel {
|
|
|
3474
3500
|
approvalPending: false,
|
|
3475
3501
|
deferredClose: null,
|
|
3476
3502
|
activeTextBlockId: null,
|
|
3477
|
-
agentMessageEmitted: new Map(this.persistedAgentEmitted),
|
|
3503
|
+
agentMessageEmitted: new Map(sess?.agentEmitted ?? this.persistedAgentEmitted),
|
|
3478
3504
|
currentAgentMessageId: "",
|
|
3479
3505
|
activeClient: wsClient,
|
|
3480
|
-
processedRequestIDs: /* @__PURE__ */ new Set()
|
|
3506
|
+
processedRequestIDs: /* @__PURE__ */ new Set(),
|
|
3507
|
+
sessionKey
|
|
3481
3508
|
};
|
|
3482
3509
|
for (const msg of options.prompt) {
|
|
3483
3510
|
if (msg.role === "system") {
|
|
@@ -3588,7 +3615,13 @@ var GitLabWorkflowLanguageModel = class _GitLabWorkflowLanguageModel {
|
|
|
3588
3615
|
wsClient.close();
|
|
3589
3616
|
this.activeClients.delete(wsClient);
|
|
3590
3617
|
ss.activeClient = null;
|
|
3591
|
-
|
|
3618
|
+
if (!ss.streamClosed) {
|
|
3619
|
+
if (ss.sessionKey) {
|
|
3620
|
+
this.sessionWorkflows.delete(ss.sessionKey);
|
|
3621
|
+
} else {
|
|
3622
|
+
this.currentWorkflowId = null;
|
|
3623
|
+
}
|
|
3624
|
+
}
|
|
3592
3625
|
}
|
|
3593
3626
|
});
|
|
3594
3627
|
return {
|
|
@@ -3712,7 +3745,7 @@ var GitLabWorkflowLanguageModel = class _GitLabWorkflowLanguageModel {
|
|
|
3712
3745
|
toolExecutor,
|
|
3713
3746
|
nextTextId,
|
|
3714
3747
|
availableToolNames
|
|
3715
|
-
).catch(() => {
|
|
3748
|
+
).catch((_err) => {
|
|
3716
3749
|
ss.approvalPending = false;
|
|
3717
3750
|
if (ss.deferredClose) {
|
|
3718
3751
|
const close = ss.deferredClose;
|
|
@@ -3738,7 +3771,7 @@ var GitLabWorkflowLanguageModel = class _GitLabWorkflowLanguageModel {
|
|
|
3738
3771
|
});
|
|
3739
3772
|
ss.streamClosed = true;
|
|
3740
3773
|
controller.close();
|
|
3741
|
-
this.cleanupClient(ss);
|
|
3774
|
+
this.cleanupClient(ss, false);
|
|
3742
3775
|
};
|
|
3743
3776
|
if (ss.pendingToolCount > 0 || ss.approvalPending) {
|
|
3744
3777
|
ss.deferredClose = doCompleteClose;
|
|
@@ -3796,7 +3829,7 @@ var GitLabWorkflowLanguageModel = class _GitLabWorkflowLanguageModel {
|
|
|
3796
3829
|
});
|
|
3797
3830
|
ss.streamClosed = true;
|
|
3798
3831
|
controller.close();
|
|
3799
|
-
this.cleanupClient(ss);
|
|
3832
|
+
this.cleanupClient(ss, false);
|
|
3800
3833
|
}
|
|
3801
3834
|
};
|
|
3802
3835
|
if (ss.pendingToolCount > 0 || ss.approvalPending) {
|
|
@@ -3865,7 +3898,8 @@ var GitLabWorkflowLanguageModel = class _GitLabWorkflowLanguageModel {
|
|
|
3865
3898
|
});
|
|
3866
3899
|
ss.streamedOutputChars += delta.length;
|
|
3867
3900
|
ss.agentMessageEmitted.set(msgId, content.length);
|
|
3868
|
-
this.
|
|
3901
|
+
const target = this.sessionWorkflows.get(ss.sessionKey)?.agentEmitted ?? this.persistedAgentEmitted;
|
|
3902
|
+
target.set(msgId, content.length);
|
|
3869
3903
|
ss.currentAgentMessageId = msgId;
|
|
3870
3904
|
}
|
|
3871
3905
|
}
|
|
@@ -3971,8 +4005,12 @@ var GitLabWorkflowLanguageModel = class _GitLabWorkflowLanguageModel {
|
|
|
3971
4005
|
ss.activeClient = null;
|
|
3972
4006
|
}
|
|
3973
4007
|
if (clearWorkflow) {
|
|
3974
|
-
|
|
3975
|
-
|
|
4008
|
+
if (ss.sessionKey) {
|
|
4009
|
+
this.sessionWorkflows.delete(ss.sessionKey);
|
|
4010
|
+
} else {
|
|
4011
|
+
this.currentWorkflowId = null;
|
|
4012
|
+
this.persistedAgentEmitted.clear();
|
|
4013
|
+
}
|
|
3976
4014
|
}
|
|
3977
4015
|
}
|
|
3978
4016
|
async approveAndResume(ss, tools, startReq, controller, toolExecutor, nextTextId, availableToolNames) {
|
|
@@ -3995,9 +4033,14 @@ var GitLabWorkflowLanguageModel = class _GitLabWorkflowLanguageModel {
|
|
|
3995
4033
|
return;
|
|
3996
4034
|
}
|
|
3997
4035
|
ss.approvalPending = false;
|
|
4036
|
+
ss.deferredClose = null;
|
|
3998
4037
|
this.cleanupClient(ss, false);
|
|
3999
4038
|
const approval = decision.approved ? { approval: { tool_name: tools[0]?.name, tool_args_json: tools[0]?.args } } : { rejection: { message: decision.message ?? "User rejected" } };
|
|
4000
|
-
const newStartReq = {
|
|
4039
|
+
const newStartReq = {
|
|
4040
|
+
...startReq,
|
|
4041
|
+
approval,
|
|
4042
|
+
preapproved_tools: decision.approved ? [...startReq.preapproved_tools ?? [], ...tools.map((t) => t.name)] : startReq.preapproved_tools ?? []
|
|
4043
|
+
};
|
|
4001
4044
|
const newClient = new GitLabWorkflowClient();
|
|
4002
4045
|
this.activeClients.add(newClient);
|
|
4003
4046
|
ss.activeClient = newClient;
|