opencode-gitlab-duo-agentic 0.1.3 → 0.1.4

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.
Files changed (2) hide show
  1. package/dist/index.js +42 -51
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1179,6 +1179,26 @@ 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
+ function duoLogReset() {
1196
+ try {
1197
+ writeFileSync(LOG_PATH, "");
1198
+ } catch {
1199
+ }
1200
+ }
1201
+
1182
1202
  // src/provider/application/model.ts
1183
1203
  var GitLabDuoAgenticLanguageModel = class {
1184
1204
  specificationVersion = "v2";
@@ -1225,14 +1245,8 @@ var GitLabDuoAgenticLanguageModel = class {
1225
1245
  const workflowType = "chat";
1226
1246
  const promptText = extractLastUserText(options.prompt);
1227
1247
  const toolResults = extractToolResults(options.prompt);
1228
- console.warn("[duo-debug] doStream called", {
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
- });
1248
+ duoLogReset();
1249
+ duoLog("doStream", "hasStarted=" + this.#runtime.hasStarted, "prompt=" + (promptText?.slice(0, 60) ?? "null"), "toolResults=" + toolResults.length);
1236
1250
  this.#runtime.resetMapperState();
1237
1251
  if (!this.#runtime.hasStarted) {
1238
1252
  this.#sentToolCallIds.clear();
@@ -1242,18 +1256,15 @@ var GitLabDuoAgenticLanguageModel = class {
1242
1256
  }
1243
1257
  }
1244
1258
  this.#lastSentPrompt = null;
1245
- console.warn("[duo-debug] hasStarted=false => reset sentToolCallIds, lastSentPrompt=null");
1246
1259
  }
1247
1260
  const freshToolResults = toolResults.filter((r) => !this.#sentToolCallIds.has(r.toolCallId));
1248
- console.warn("[duo-debug] freshToolResults:", freshToolResults.length);
1249
1261
  const modelRef = this.modelId === GITLAB_DUO_DEFAULT_MODEL_ID ? void 0 : this.modelId;
1250
1262
  this.#runtime.setSelectedModelIdentifier(modelRef);
1251
1263
  await this.#runtime.ensureConnected(promptText || "", workflowType);
1252
- console.warn("[duo-debug] ensureConnected returned OK");
1253
1264
  const mcpTools = this.#options.enableMcp === false ? [] : buildMcpTools(options);
1254
1265
  const toolContext = buildToolContext(mcpTools);
1255
1266
  const isNewUserMessage = promptText != null && promptText !== this.#lastSentPrompt;
1256
- console.warn("[duo-debug] isNewUserMessage:", isNewUserMessage, "promptText != null:", promptText != null, "promptText !== lastSentPrompt:", promptText !== this.#lastSentPrompt);
1267
+ duoLog("gate", "isNewUserMessage=" + isNewUserMessage, "freshTools=" + freshToolResults.length, "lastSent=" + (this.#lastSentPrompt?.slice(0, 40) ?? "null"));
1257
1268
  let sentToolResults = false;
1258
1269
  if (freshToolResults.length > 0) {
1259
1270
  for (const result of freshToolResults) {
@@ -1300,7 +1311,6 @@ var GitLabDuoAgenticLanguageModel = class {
1300
1311
  this.#pendingToolRequests.delete(result.toolCallId);
1301
1312
  }
1302
1313
  }
1303
- console.warn("[duo-debug] startRequest gate: !sentToolResults:", !sentToolResults, "isNewUserMessage:", isNewUserMessage, "=> will send:", !sentToolResults && isNewUserMessage);
1304
1314
  if (!sentToolResults && isNewUserMessage) {
1305
1315
  const extraContext = [];
1306
1316
  if (toolContext) extraContext.push(toolContext);
@@ -1362,7 +1372,7 @@ var GitLabDuoAgenticLanguageModel = class {
1362
1372
  }
1363
1373
  });
1364
1374
  }
1365
- console.warn("[duo-debug] >>> calling sendStartRequest", { goal: promptText?.slice(0, 80), hasStarted: this.#runtime.hasStarted, extraContextCount: extraContext.length });
1375
+ duoLog("sendStartRequest", "hasStarted=" + this.#runtime.hasStarted);
1366
1376
  this.#runtime.sendStartRequest(
1367
1377
  promptText,
1368
1378
  workflowType,
@@ -1371,15 +1381,13 @@ var GitLabDuoAgenticLanguageModel = class {
1371
1381
  extraContext
1372
1382
  );
1373
1383
  this.#lastSentPrompt = promptText;
1374
- console.warn("[duo-debug] >>> sendStartRequest completed, lastSentPrompt set");
1375
1384
  this.#usageEstimator.addInputChars(promptText);
1376
1385
  for (const ctx of extraContext) {
1377
1386
  if (ctx.content) this.#usageEstimator.addInputChars(ctx.content);
1378
1387
  }
1379
1388
  } else {
1380
- console.warn("[duo-debug] SKIPPED sendStartRequest (sentToolResults:", sentToolResults, "isNewUserMessage:", isNewUserMessage, ")");
1389
+ duoLog("SKIP startRequest", "sentToolResults=" + sentToolResults, "isNewUserMessage=" + isNewUserMessage);
1381
1390
  }
1382
- console.warn("[duo-debug] creating event stream iterator");
1383
1391
  const iterator = this.#mapEventsToStream(this.#runtime.getEventStream());
1384
1392
  const stream = asyncIteratorToReadableStream(iterator);
1385
1393
  return {
@@ -1393,12 +1401,11 @@ var GitLabDuoAgenticLanguageModel = class {
1393
1401
  const state = { textStarted: false };
1394
1402
  const estimator = this.#usageEstimator;
1395
1403
  let eventCount = 0;
1396
- console.warn("[duo-debug] #mapEventsToStream: starting iteration");
1397
1404
  yield { type: "stream-start", warnings: [] };
1398
1405
  try {
1399
1406
  for await (const event of events) {
1400
1407
  eventCount++;
1401
- console.warn("[duo-debug] #mapEventsToStream event #" + eventCount + ":", event.type, event.type === "TEXT_CHUNK" ? "(len=" + event.content.length + ")" : "");
1408
+ duoLog("evt", event.type, eventCount);
1402
1409
  if (event.type === "TEXT_CHUNK") {
1403
1410
  if (event.content.length > 0) {
1404
1411
  estimator.addOutputChars(event.content);
@@ -1444,11 +1451,11 @@ var GitLabDuoAgenticLanguageModel = class {
1444
1451
  }
1445
1452
  }
1446
1453
  } catch (streamErr) {
1447
- console.warn("[duo-debug] #mapEventsToStream: caught error after", eventCount, "events:", streamErr instanceof Error ? streamErr.message : String(streamErr));
1454
+ duoLog("streamErr", streamErr instanceof Error ? streamErr.message : String(streamErr));
1448
1455
  yield { type: "error", error: streamErr instanceof Error ? streamErr : new Error(String(streamErr)) };
1449
1456
  return;
1450
1457
  }
1451
- console.warn("[duo-debug] #mapEventsToStream: loop ended normally after", eventCount, "events => yielding finish:stop");
1458
+ duoLog("finish", "events=" + eventCount);
1452
1459
  yield { type: "finish", finishReason: "stop", usage: this.#currentUsage };
1453
1460
  }
1454
1461
  // ---------------------------------------------------------------------------
@@ -1895,26 +1902,19 @@ var GitLabAgenticRuntime = class {
1895
1902
  // Connection lifecycle
1896
1903
  // ---------------------------------------------------------------------------
1897
1904
  async ensureConnected(goal, workflowType) {
1898
- console.warn("[duo-debug] ensureConnected called", {
1899
- hasStream: !!this.#stream,
1900
- hasWorkflowId: !!this.#workflowId,
1901
- workflowId: this.#workflowId?.slice(0, 12),
1902
- hasQueue: !!this.#queue,
1903
- startRequestSent: this.#startRequestSent
1904
- });
1905
+ duoLog("ensureConnected", "stream=" + !!this.#stream, "wfId=" + !!this.#workflowId, "queue=" + !!this.#queue);
1905
1906
  if (this.#stream && this.#workflowId && this.#queue) {
1906
- console.warn("[duo-debug] ensureConnected: short-circuit (already connected)");
1907
+ duoLog("ensureConnected", "skip (connected)");
1907
1908
  return;
1908
1909
  }
1909
1910
  if (!this.#containerParams) {
1910
1911
  this.#containerParams = await this.#resolveContainerParams();
1911
1912
  }
1912
1913
  if (!this.#workflowId) {
1913
- console.warn("[duo-debug] ensureConnected: creating new workflow");
1914
1914
  this.#workflowId = await this.#createWorkflow(goal, workflowType);
1915
- console.warn("[duo-debug] ensureConnected: workflow created:", this.#workflowId?.slice(0, 12));
1915
+ duoLog("workflow created", this.#workflowId);
1916
1916
  } else {
1917
- console.warn("[duo-debug] ensureConnected: reusing existing workflowId:", this.#workflowId?.slice(0, 12));
1917
+ duoLog("workflow reuse", this.#workflowId);
1918
1918
  }
1919
1919
  const token = await this.#dependencies.workflowService.getWorkflowToken(
1920
1920
  this.#options.instanceUrl,
@@ -1922,19 +1922,17 @@ var GitLabAgenticRuntime = class {
1922
1922
  workflowType
1923
1923
  );
1924
1924
  this.#workflowToken = token;
1925
- console.warn("[duo-debug] ensureConnected: got workflow token");
1926
1925
  const MAX_LOCK_RETRIES = 3;
1927
1926
  const LOCK_RETRY_DELAY_MS = 3e3;
1928
1927
  for (let attempt = 1; attempt <= MAX_LOCK_RETRIES; attempt++) {
1929
1928
  this.#queue = new AsyncQueue();
1930
1929
  try {
1931
- console.warn("[duo-debug] ensureConnected: connecting WebSocket (attempt", attempt, ")");
1932
1930
  await this.#connectWebSocket();
1933
- console.warn("[duo-debug] ensureConnected: WebSocket connected OK");
1931
+ duoLog("ws connected", "attempt=" + attempt);
1934
1932
  return;
1935
1933
  } catch (err2) {
1936
1934
  const msg = err2 instanceof Error ? err2.message : String(err2);
1937
- console.warn("[duo-debug] ensureConnected: WebSocket error:", msg);
1935
+ duoLog("ws error", msg);
1938
1936
  if ((msg.includes("1013") || msg.includes("lock")) && attempt < MAX_LOCK_RETRIES) {
1939
1937
  this.#resetStreamState();
1940
1938
  await this.#dependencies.clock.sleep(LOCK_RETRY_DELAY_MS);
@@ -1979,13 +1977,8 @@ var GitLabAgenticRuntime = class {
1979
1977
  preapproved_tools: preapprovedTools
1980
1978
  }
1981
1979
  };
1982
- console.warn("[duo-debug] sendStartRequest: writing to stream", {
1983
- workflowId: this.#workflowId?.slice(0, 12),
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);
1980
+ const ok2 = this.#stream.write(startRequest);
1981
+ duoLog("startReq write=" + ok2, "wf=" + this.#workflowId);
1989
1982
  this.#startRequestSent = true;
1990
1983
  }
1991
1984
  sendToolResponse(requestId, response, responseType) {
@@ -2074,14 +2067,14 @@ var GitLabAgenticRuntime = class {
2074
2067
  #bindStream(stream, queue) {
2075
2068
  const now = () => this.#dependencies.clock.now();
2076
2069
  const closeWithError = (message) => {
2077
- console.warn("[duo-debug] stream closeWithError:", message);
2070
+ duoLog("streamErr", message);
2078
2071
  queue.push({ type: "ERROR", message, timestamp: now() });
2079
2072
  queue.close();
2080
2073
  this.#resetStreamState();
2081
2074
  };
2082
2075
  const handleAction = async (action) => {
2083
2076
  if (action.newCheckpoint) {
2084
- console.warn("[duo-debug] stream data: newCheckpoint status=", action.newCheckpoint.status, "goal=", action.newCheckpoint.goal?.slice(0, 40));
2077
+ duoLog("checkpoint", action.newCheckpoint.status);
2085
2078
  const duoEvent = {
2086
2079
  checkpoint: action.newCheckpoint.checkpoint,
2087
2080
  errors: action.newCheckpoint.errors || [],
@@ -2089,7 +2082,7 @@ var GitLabAgenticRuntime = class {
2089
2082
  workflowStatus: action.newCheckpoint.status
2090
2083
  };
2091
2084
  const events = await this.#mapper.mapWorkflowEvent(duoEvent);
2092
- console.warn("[duo-debug] mapper produced", events.length, "events:", events.map((e) => e.type));
2085
+ duoLog("mapped", events.length, events.map((e) => e.type).join(","));
2093
2086
  for (const event of events) {
2094
2087
  queue.push(event);
2095
2088
  }
@@ -2097,7 +2090,7 @@ var GitLabAgenticRuntime = class {
2097
2090
  }
2098
2091
  const toolRequest = mapWorkflowActionToToolRequest(action);
2099
2092
  if (toolRequest) {
2100
- console.warn("[duo-debug] stream data: toolRequest", toolRequest.toolName);
2093
+ duoLog("toolReq", toolRequest.toolName);
2101
2094
  queue.push({
2102
2095
  type: "TOOL_REQUEST",
2103
2096
  ...toolRequest,
@@ -2105,7 +2098,6 @@ var GitLabAgenticRuntime = class {
2105
2098
  });
2106
2099
  return;
2107
2100
  }
2108
- console.warn("[duo-debug] stream data: unhandled action", Object.keys(action));
2109
2101
  };
2110
2102
  stream.on("data", (action) => {
2111
2103
  void handleAction(action).catch((error) => {
@@ -2114,11 +2106,10 @@ var GitLabAgenticRuntime = class {
2114
2106
  });
2115
2107
  });
2116
2108
  stream.on("error", (err2) => {
2117
- console.warn("[duo-debug] stream error:", err2.message);
2118
2109
  closeWithError(err2.message);
2119
2110
  });
2120
2111
  stream.on("end", () => {
2121
- console.warn("[duo-debug] stream end => closing queue + resetStreamState");
2112
+ duoLog("stream end");
2122
2113
  queue.close();
2123
2114
  this.#resetStreamState();
2124
2115
  });
@@ -2140,7 +2131,7 @@ var GitLabAgenticRuntime = class {
2140
2131
  this.#bindStream(stream, this.#queue);
2141
2132
  }
2142
2133
  #resetStreamState() {
2143
- console.warn("[duo-debug] #resetStreamState called", { hadStream: !!this.#stream, hadQueue: !!this.#queue, workflowId: this.#workflowId?.slice(0, 12) });
2134
+ duoLog("reset", "wf=" + this.#workflowId);
2144
2135
  this.#stream = void 0;
2145
2136
  this.#queue = void 0;
2146
2137
  this.#startRequestSent = false;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-gitlab-duo-agentic",
3
- "version": "0.1.3",
3
+ "version": "0.1.4",
4
4
  "description": "OpenCode plugin and provider for GitLab Duo Agentic workflows",
5
5
  "license": "MIT",
6
6
  "type": "module",