opencode-gitlab-duo-agentic 0.1.3 → 0.1.5
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.js +49 -51
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1179,6 +1179,20 @@ var TokenUsageEstimator = class {
|
|
|
1179
1179
|
}
|
|
1180
1180
|
};
|
|
1181
1181
|
|
|
1182
|
+
// src/provider/core/debug_log.ts
|
|
1183
|
+
import { appendFileSync, writeFileSync } from "fs";
|
|
1184
|
+
var LOG_PATH = "/tmp/duo-debug.log";
|
|
1185
|
+
function duoLog(...args) {
|
|
1186
|
+
const ts = (/* @__PURE__ */ new Date()).toISOString().slice(11, 23);
|
|
1187
|
+
const line = ts + " " + args.map(
|
|
1188
|
+
(a) => typeof a === "object" && a !== null ? JSON.stringify(a) : String(a)
|
|
1189
|
+
).join(" ");
|
|
1190
|
+
try {
|
|
1191
|
+
appendFileSync(LOG_PATH, line + "\n");
|
|
1192
|
+
} catch {
|
|
1193
|
+
}
|
|
1194
|
+
}
|
|
1195
|
+
|
|
1182
1196
|
// src/provider/application/model.ts
|
|
1183
1197
|
var GitLabDuoAgenticLanguageModel = class {
|
|
1184
1198
|
specificationVersion = "v2";
|
|
@@ -1225,14 +1239,7 @@ var GitLabDuoAgenticLanguageModel = class {
|
|
|
1225
1239
|
const workflowType = "chat";
|
|
1226
1240
|
const promptText = extractLastUserText(options.prompt);
|
|
1227
1241
|
const toolResults = extractToolResults(options.prompt);
|
|
1228
|
-
|
|
1229
|
-
promptText: promptText?.slice(0, 80),
|
|
1230
|
-
toolResultCount: toolResults.length,
|
|
1231
|
-
hasStarted: this.#runtime.hasStarted,
|
|
1232
|
-
lastSentPrompt: this.#lastSentPrompt?.slice(0, 80) ?? null,
|
|
1233
|
-
pendingToolRequests: this.#pendingToolRequests.size,
|
|
1234
|
-
sentToolCallIds: this.#sentToolCallIds.size
|
|
1235
|
-
});
|
|
1242
|
+
duoLog("--- doStream", "hasStarted=" + this.#runtime.hasStarted, "prompt=" + (promptText?.slice(0, 60) ?? "null"), "toolResults=" + toolResults.length);
|
|
1236
1243
|
this.#runtime.resetMapperState();
|
|
1237
1244
|
if (!this.#runtime.hasStarted) {
|
|
1238
1245
|
this.#sentToolCallIds.clear();
|
|
@@ -1242,18 +1249,15 @@ var GitLabDuoAgenticLanguageModel = class {
|
|
|
1242
1249
|
}
|
|
1243
1250
|
}
|
|
1244
1251
|
this.#lastSentPrompt = null;
|
|
1245
|
-
console.warn("[duo-debug] hasStarted=false => reset sentToolCallIds, lastSentPrompt=null");
|
|
1246
1252
|
}
|
|
1247
1253
|
const freshToolResults = toolResults.filter((r) => !this.#sentToolCallIds.has(r.toolCallId));
|
|
1248
|
-
console.warn("[duo-debug] freshToolResults:", freshToolResults.length);
|
|
1249
1254
|
const modelRef = this.modelId === GITLAB_DUO_DEFAULT_MODEL_ID ? void 0 : this.modelId;
|
|
1250
1255
|
this.#runtime.setSelectedModelIdentifier(modelRef);
|
|
1251
1256
|
await this.#runtime.ensureConnected(promptText || "", workflowType);
|
|
1252
|
-
console.warn("[duo-debug] ensureConnected returned OK");
|
|
1253
1257
|
const mcpTools = this.#options.enableMcp === false ? [] : buildMcpTools(options);
|
|
1254
1258
|
const toolContext = buildToolContext(mcpTools);
|
|
1255
1259
|
const isNewUserMessage = promptText != null && promptText !== this.#lastSentPrompt;
|
|
1256
|
-
|
|
1260
|
+
duoLog("gate", "isNewUserMessage=" + isNewUserMessage, "freshTools=" + freshToolResults.length, "lastSent=" + (this.#lastSentPrompt?.slice(0, 40) ?? "null"));
|
|
1257
1261
|
let sentToolResults = false;
|
|
1258
1262
|
if (freshToolResults.length > 0) {
|
|
1259
1263
|
for (const result of freshToolResults) {
|
|
@@ -1300,7 +1304,6 @@ var GitLabDuoAgenticLanguageModel = class {
|
|
|
1300
1304
|
this.#pendingToolRequests.delete(result.toolCallId);
|
|
1301
1305
|
}
|
|
1302
1306
|
}
|
|
1303
|
-
console.warn("[duo-debug] startRequest gate: !sentToolResults:", !sentToolResults, "isNewUserMessage:", isNewUserMessage, "=> will send:", !sentToolResults && isNewUserMessage);
|
|
1304
1307
|
if (!sentToolResults && isNewUserMessage) {
|
|
1305
1308
|
const extraContext = [];
|
|
1306
1309
|
if (toolContext) extraContext.push(toolContext);
|
|
@@ -1362,7 +1365,7 @@ var GitLabDuoAgenticLanguageModel = class {
|
|
|
1362
1365
|
}
|
|
1363
1366
|
});
|
|
1364
1367
|
}
|
|
1365
|
-
|
|
1368
|
+
duoLog("sendStartRequest", "hasStarted=" + this.#runtime.hasStarted);
|
|
1366
1369
|
this.#runtime.sendStartRequest(
|
|
1367
1370
|
promptText,
|
|
1368
1371
|
workflowType,
|
|
@@ -1371,15 +1374,13 @@ var GitLabDuoAgenticLanguageModel = class {
|
|
|
1371
1374
|
extraContext
|
|
1372
1375
|
);
|
|
1373
1376
|
this.#lastSentPrompt = promptText;
|
|
1374
|
-
console.warn("[duo-debug] >>> sendStartRequest completed, lastSentPrompt set");
|
|
1375
1377
|
this.#usageEstimator.addInputChars(promptText);
|
|
1376
1378
|
for (const ctx of extraContext) {
|
|
1377
1379
|
if (ctx.content) this.#usageEstimator.addInputChars(ctx.content);
|
|
1378
1380
|
}
|
|
1379
1381
|
} else {
|
|
1380
|
-
|
|
1382
|
+
duoLog("SKIP startRequest", "sentToolResults=" + sentToolResults, "isNewUserMessage=" + isNewUserMessage);
|
|
1381
1383
|
}
|
|
1382
|
-
console.warn("[duo-debug] creating event stream iterator");
|
|
1383
1384
|
const iterator = this.#mapEventsToStream(this.#runtime.getEventStream());
|
|
1384
1385
|
const stream = asyncIteratorToReadableStream(iterator);
|
|
1385
1386
|
return {
|
|
@@ -1393,12 +1394,11 @@ var GitLabDuoAgenticLanguageModel = class {
|
|
|
1393
1394
|
const state = { textStarted: false };
|
|
1394
1395
|
const estimator = this.#usageEstimator;
|
|
1395
1396
|
let eventCount = 0;
|
|
1396
|
-
console.warn("[duo-debug] #mapEventsToStream: starting iteration");
|
|
1397
1397
|
yield { type: "stream-start", warnings: [] };
|
|
1398
1398
|
try {
|
|
1399
1399
|
for await (const event of events) {
|
|
1400
1400
|
eventCount++;
|
|
1401
|
-
|
|
1401
|
+
duoLog("evt", event.type, eventCount);
|
|
1402
1402
|
if (event.type === "TEXT_CHUNK") {
|
|
1403
1403
|
if (event.content.length > 0) {
|
|
1404
1404
|
estimator.addOutputChars(event.content);
|
|
@@ -1444,11 +1444,11 @@ var GitLabDuoAgenticLanguageModel = class {
|
|
|
1444
1444
|
}
|
|
1445
1445
|
}
|
|
1446
1446
|
} catch (streamErr) {
|
|
1447
|
-
|
|
1447
|
+
duoLog("streamErr", streamErr instanceof Error ? streamErr.message : String(streamErr));
|
|
1448
1448
|
yield { type: "error", error: streamErr instanceof Error ? streamErr : new Error(String(streamErr)) };
|
|
1449
1449
|
return;
|
|
1450
1450
|
}
|
|
1451
|
-
|
|
1451
|
+
duoLog("finish", "events=" + eventCount);
|
|
1452
1452
|
yield { type: "finish", finishReason: "stop", usage: this.#currentUsage };
|
|
1453
1453
|
}
|
|
1454
1454
|
// ---------------------------------------------------------------------------
|
|
@@ -1873,6 +1873,7 @@ var GitLabAgenticRuntime = class {
|
|
|
1873
1873
|
#mapper = new WorkflowEventMapper();
|
|
1874
1874
|
#containerParams;
|
|
1875
1875
|
#startRequestSent = false;
|
|
1876
|
+
#connectingPromise;
|
|
1876
1877
|
constructor(options, dependencies) {
|
|
1877
1878
|
this.#options = options;
|
|
1878
1879
|
this.#dependencies = dependencies;
|
|
@@ -1895,26 +1896,32 @@ var GitLabAgenticRuntime = class {
|
|
|
1895
1896
|
// Connection lifecycle
|
|
1896
1897
|
// ---------------------------------------------------------------------------
|
|
1897
1898
|
async ensureConnected(goal, workflowType) {
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
});
|
|
1899
|
+
duoLog("ensureConnected", "stream=" + !!this.#stream, "wfId=" + !!this.#workflowId, "queue=" + !!this.#queue, "connecting=" + !!this.#connectingPromise);
|
|
1900
|
+
if (this.#connectingPromise) {
|
|
1901
|
+
duoLog("ensureConnected", "awaiting in-flight connection");
|
|
1902
|
+
await this.#connectingPromise;
|
|
1903
|
+
return;
|
|
1904
|
+
}
|
|
1905
1905
|
if (this.#stream && this.#workflowId && this.#queue) {
|
|
1906
|
-
|
|
1906
|
+
duoLog("ensureConnected", "skip (connected)");
|
|
1907
1907
|
return;
|
|
1908
1908
|
}
|
|
1909
|
+
this.#connectingPromise = this.#doConnect(goal, workflowType);
|
|
1910
|
+
try {
|
|
1911
|
+
await this.#connectingPromise;
|
|
1912
|
+
} finally {
|
|
1913
|
+
this.#connectingPromise = void 0;
|
|
1914
|
+
}
|
|
1915
|
+
}
|
|
1916
|
+
async #doConnect(goal, workflowType) {
|
|
1909
1917
|
if (!this.#containerParams) {
|
|
1910
1918
|
this.#containerParams = await this.#resolveContainerParams();
|
|
1911
1919
|
}
|
|
1912
1920
|
if (!this.#workflowId) {
|
|
1913
|
-
console.warn("[duo-debug] ensureConnected: creating new workflow");
|
|
1914
1921
|
this.#workflowId = await this.#createWorkflow(goal, workflowType);
|
|
1915
|
-
|
|
1922
|
+
duoLog("workflow created", this.#workflowId);
|
|
1916
1923
|
} else {
|
|
1917
|
-
|
|
1924
|
+
duoLog("workflow reuse", this.#workflowId);
|
|
1918
1925
|
}
|
|
1919
1926
|
const token = await this.#dependencies.workflowService.getWorkflowToken(
|
|
1920
1927
|
this.#options.instanceUrl,
|
|
@@ -1922,19 +1929,17 @@ var GitLabAgenticRuntime = class {
|
|
|
1922
1929
|
workflowType
|
|
1923
1930
|
);
|
|
1924
1931
|
this.#workflowToken = token;
|
|
1925
|
-
console.warn("[duo-debug] ensureConnected: got workflow token");
|
|
1926
1932
|
const MAX_LOCK_RETRIES = 3;
|
|
1927
1933
|
const LOCK_RETRY_DELAY_MS = 3e3;
|
|
1928
1934
|
for (let attempt = 1; attempt <= MAX_LOCK_RETRIES; attempt++) {
|
|
1929
1935
|
this.#queue = new AsyncQueue();
|
|
1930
1936
|
try {
|
|
1931
|
-
console.warn("[duo-debug] ensureConnected: connecting WebSocket (attempt", attempt, ")");
|
|
1932
1937
|
await this.#connectWebSocket();
|
|
1933
|
-
|
|
1938
|
+
duoLog("ws connected", "attempt=" + attempt);
|
|
1934
1939
|
return;
|
|
1935
1940
|
} catch (err2) {
|
|
1936
1941
|
const msg = err2 instanceof Error ? err2.message : String(err2);
|
|
1937
|
-
|
|
1942
|
+
duoLog("ws error", msg);
|
|
1938
1943
|
if ((msg.includes("1013") || msg.includes("lock")) && attempt < MAX_LOCK_RETRIES) {
|
|
1939
1944
|
this.#resetStreamState();
|
|
1940
1945
|
await this.#dependencies.clock.sleep(LOCK_RETRY_DELAY_MS);
|
|
@@ -1979,13 +1984,8 @@ var GitLabAgenticRuntime = class {
|
|
|
1979
1984
|
preapproved_tools: preapprovedTools
|
|
1980
1985
|
}
|
|
1981
1986
|
};
|
|
1982
|
-
|
|
1983
|
-
|
|
1984
|
-
goal: goal?.slice(0, 80),
|
|
1985
|
-
contextCount: additionalContext.length
|
|
1986
|
-
});
|
|
1987
|
-
const writeResult = this.#stream.write(startRequest);
|
|
1988
|
-
console.warn("[duo-debug] sendStartRequest: write() returned:", writeResult);
|
|
1987
|
+
const ok2 = this.#stream.write(startRequest);
|
|
1988
|
+
duoLog("startReq write=" + ok2, "wf=" + this.#workflowId);
|
|
1989
1989
|
this.#startRequestSent = true;
|
|
1990
1990
|
}
|
|
1991
1991
|
sendToolResponse(requestId, response, responseType) {
|
|
@@ -2074,14 +2074,14 @@ var GitLabAgenticRuntime = class {
|
|
|
2074
2074
|
#bindStream(stream, queue) {
|
|
2075
2075
|
const now = () => this.#dependencies.clock.now();
|
|
2076
2076
|
const closeWithError = (message) => {
|
|
2077
|
-
|
|
2077
|
+
duoLog("streamErr", message);
|
|
2078
2078
|
queue.push({ type: "ERROR", message, timestamp: now() });
|
|
2079
2079
|
queue.close();
|
|
2080
2080
|
this.#resetStreamState();
|
|
2081
2081
|
};
|
|
2082
2082
|
const handleAction = async (action) => {
|
|
2083
2083
|
if (action.newCheckpoint) {
|
|
2084
|
-
|
|
2084
|
+
duoLog("checkpoint", action.newCheckpoint.status);
|
|
2085
2085
|
const duoEvent = {
|
|
2086
2086
|
checkpoint: action.newCheckpoint.checkpoint,
|
|
2087
2087
|
errors: action.newCheckpoint.errors || [],
|
|
@@ -2089,7 +2089,7 @@ var GitLabAgenticRuntime = class {
|
|
|
2089
2089
|
workflowStatus: action.newCheckpoint.status
|
|
2090
2090
|
};
|
|
2091
2091
|
const events = await this.#mapper.mapWorkflowEvent(duoEvent);
|
|
2092
|
-
|
|
2092
|
+
duoLog("mapped", events.length, events.map((e) => e.type).join(","));
|
|
2093
2093
|
for (const event of events) {
|
|
2094
2094
|
queue.push(event);
|
|
2095
2095
|
}
|
|
@@ -2097,7 +2097,7 @@ var GitLabAgenticRuntime = class {
|
|
|
2097
2097
|
}
|
|
2098
2098
|
const toolRequest = mapWorkflowActionToToolRequest(action);
|
|
2099
2099
|
if (toolRequest) {
|
|
2100
|
-
|
|
2100
|
+
duoLog("toolReq", toolRequest.toolName);
|
|
2101
2101
|
queue.push({
|
|
2102
2102
|
type: "TOOL_REQUEST",
|
|
2103
2103
|
...toolRequest,
|
|
@@ -2105,7 +2105,6 @@ var GitLabAgenticRuntime = class {
|
|
|
2105
2105
|
});
|
|
2106
2106
|
return;
|
|
2107
2107
|
}
|
|
2108
|
-
console.warn("[duo-debug] stream data: unhandled action", Object.keys(action));
|
|
2109
2108
|
};
|
|
2110
2109
|
stream.on("data", (action) => {
|
|
2111
2110
|
void handleAction(action).catch((error) => {
|
|
@@ -2114,11 +2113,10 @@ var GitLabAgenticRuntime = class {
|
|
|
2114
2113
|
});
|
|
2115
2114
|
});
|
|
2116
2115
|
stream.on("error", (err2) => {
|
|
2117
|
-
console.warn("[duo-debug] stream error:", err2.message);
|
|
2118
2116
|
closeWithError(err2.message);
|
|
2119
2117
|
});
|
|
2120
2118
|
stream.on("end", () => {
|
|
2121
|
-
|
|
2119
|
+
duoLog("stream end");
|
|
2122
2120
|
queue.close();
|
|
2123
2121
|
this.#resetStreamState();
|
|
2124
2122
|
});
|
|
@@ -2140,7 +2138,7 @@ var GitLabAgenticRuntime = class {
|
|
|
2140
2138
|
this.#bindStream(stream, this.#queue);
|
|
2141
2139
|
}
|
|
2142
2140
|
#resetStreamState() {
|
|
2143
|
-
|
|
2141
|
+
duoLog("reset", "wf=" + this.#workflowId);
|
|
2144
2142
|
this.#stream = void 0;
|
|
2145
2143
|
this.#queue = void 0;
|
|
2146
2144
|
this.#startRequestSent = false;
|