@harmonyos-arkts/opencode-acp 0.0.9 → 0.0.11

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.cjs CHANGED
@@ -20649,11 +20649,13 @@ var EventHandler = class {
20649
20649
  aiCodeChangeStats = /* @__PURE__ */ new Map();
20650
20650
  lastSubscriptionErrorBroadcastAt = 0;
20651
20651
  turnTimeoutTracker;
20652
+ cancelTurnTracker;
20652
20653
  constructor(deps) {
20653
20654
  this.connection = deps.connection;
20654
20655
  this.sdk = deps.sdk;
20655
20656
  this.sessionManager = deps.sessionManager;
20656
20657
  this.turnTimeoutTracker = deps.turnTimeoutTracker;
20658
+ this.cancelTurnTracker = deps.cancelTurnTracker;
20657
20659
  }
20658
20660
  start() {
20659
20661
  if (this.started) return;
@@ -20717,6 +20719,10 @@ var EventHandler = class {
20717
20719
  if (!session) return void 0;
20718
20720
  return { sessionId: session.id, cwd: session.cwd };
20719
20721
  }
20722
+ /** Drop streaming chunks while a cancelled turn is unwinding on the OpenCode server. */
20723
+ shouldDropStreaming(sessionId) {
20724
+ return this.cancelTurnTracker?.isCancelled(sessionId) ?? false;
20725
+ }
20720
20726
  // ─── Event Handling ──────────────────────────────────────────────
20721
20727
  async handleEvent(event) {
20722
20728
  if (event.type === "server.heartbeat") {
@@ -20746,6 +20752,26 @@ var EventHandler = class {
20746
20752
  }
20747
20753
  return;
20748
20754
  }
20755
+ case "session.status": {
20756
+ ocEvent("session.status", event);
20757
+ const props = event.properties;
20758
+ const sessionID = props.sessionID;
20759
+ if (!sessionID) return;
20760
+ const resolved = this.resolveSession(sessionID);
20761
+ if (!resolved) return;
20762
+ await sendToClient(this.connection, {
20763
+ sessionId: resolved.sessionId,
20764
+ update: {
20765
+ sessionUpdate: "session_info_update",
20766
+ _meta: {
20767
+ opencodeStatus: props.status?.type ?? "unknown",
20768
+ opencodeStatusDetail: props.status
20769
+ }
20770
+ }
20771
+ }).catch(() => {
20772
+ });
20773
+ return;
20774
+ }
20749
20775
  case "permission.asked": {
20750
20776
  ocEvent("permission.asked", event);
20751
20777
  const permission = event.properties;
@@ -20893,7 +20919,7 @@ var EventHandler = class {
20893
20919
  if (part.type === "tool") {
20894
20920
  await this.handleToolPart(resolved.sessionId, part);
20895
20921
  }
20896
- if (part.type === "text" && typeof part.text === "string" && part.ignored === true) {
20922
+ if (part.type === "text" && typeof part.text === "string" && part.ignored === true && !this.shouldDropStreaming(resolved.sessionId)) {
20897
20923
  await sendToClient(this.connection, {
20898
20924
  sessionId: resolved.sessionId,
20899
20925
  update: {
@@ -20912,6 +20938,7 @@ var EventHandler = class {
20912
20938
  const resolved = this.resolveSession(props.sessionID);
20913
20939
  if (!resolved) return;
20914
20940
  const sessionId = resolved.sessionId;
20941
+ if (this.shouldDropStreaming(sessionId)) return;
20915
20942
  const partMeta = this.partMetaIndex.get(props.partID);
20916
20943
  if (!partMeta) return;
20917
20944
  if (partMeta.type === "text" && props.field === "text" && partMeta.ignored !== true) {
@@ -20985,7 +21012,9 @@ var EventHandler = class {
20985
21012
  }
20986
21013
  // ─── Tool Part Handling ──────────────────────────────────────────
20987
21014
  async handleToolPart(sessionId, part) {
21015
+ const dropStreaming = this.shouldDropStreaming(sessionId);
20988
21016
  if (!this.toolStarts.has(part.callID)) {
21017
+ if (dropStreaming) return;
20989
21018
  this.toolStarts.add(part.callID);
20990
21019
  this.turnTimeoutTracker?.onToolCallStart(sessionId);
20991
21020
  const session = this.sessionManager.tryGet(sessionId);
@@ -21020,6 +21049,7 @@ var EventHandler = class {
21020
21049
  this.bashSnapshots.delete(part.callID);
21021
21050
  return;
21022
21051
  case "running": {
21052
+ if (dropStreaming) return;
21023
21053
  const output = this.bashOutput(part);
21024
21054
  const content = [];
21025
21055
  if (output) {
@@ -21492,6 +21522,28 @@ var TurnTimeoutTracker = class {
21492
21522
  }
21493
21523
  };
21494
21524
 
21525
+ // src/cancel-turn-tracker.ts
21526
+ var CancelTurnTracker = class {
21527
+ cancelled = /* @__PURE__ */ new Set();
21528
+ /** New prompt turn — allow streaming again for this session subtree. */
21529
+ beginTurn(rootSessionId, relatedSessionIds = []) {
21530
+ this.cancelled.delete(rootSessionId);
21531
+ for (const id of relatedSessionIds) {
21532
+ this.cancelled.delete(id);
21533
+ }
21534
+ }
21535
+ /** User cancelled — drop streaming for root and related (child) sessions. */
21536
+ markCancelled(rootSessionId, relatedSessionIds = []) {
21537
+ this.cancelled.add(rootSessionId);
21538
+ for (const id of relatedSessionIds) {
21539
+ this.cancelled.add(id);
21540
+ }
21541
+ }
21542
+ isCancelled(sessionId) {
21543
+ return this.cancelled.has(sessionId);
21544
+ }
21545
+ };
21546
+
21495
21547
  // src/agent.ts
21496
21548
  function isApiKeyError(err) {
21497
21549
  return err instanceof Error && err.name === "AI_LoadAPIKeyError";
@@ -21505,6 +21557,7 @@ var Agent = class {
21505
21557
  authProvider;
21506
21558
  mcpManager;
21507
21559
  turnTimeoutTracker;
21560
+ cancelTurnTracker = new CancelTurnTracker();
21508
21561
  constructor(config2) {
21509
21562
  this.config = config2;
21510
21563
  this.sdk = config2.sdk;
@@ -21519,7 +21572,8 @@ var Agent = class {
21519
21572
  connection,
21520
21573
  sdk: this.sdk,
21521
21574
  sessionManager: this.sessionManager,
21522
- turnTimeoutTracker: this.turnTimeoutTracker
21575
+ turnTimeoutTracker: this.turnTimeoutTracker,
21576
+ cancelTurnTracker: this.cancelTurnTracker
21523
21577
  });
21524
21578
  this.eventHandler.start();
21525
21579
  }
@@ -21864,6 +21918,7 @@ var Agent = class {
21864
21918
  const cmd = this.parseCommand(parts);
21865
21919
  const modelLabel = `${model.providerID}/${model.modelID}`;
21866
21920
  ocCall("session.prompt", { sessionID, agent, model: modelLabel });
21921
+ this.cancelTurnTracker.beginTurn(sessionID, this.sessionManager.getRelatedSessions(sessionID));
21867
21922
  this.turnTimeoutTracker.onPromptStart(sessionID, { model: modelLabel });
21868
21923
  try {
21869
21924
  if (!cmd) {
@@ -21975,6 +22030,19 @@ var Agent = class {
21975
22030
  async cancel(params) {
21976
22031
  acpIn("cancel", { sessionId: params.sessionId });
21977
22032
  const session = this.sessionManager.get(params.sessionId);
22033
+ const related = this.sessionManager.getRelatedSessions(params.sessionId);
22034
+ this.cancelTurnTracker.markCancelled(params.sessionId, related);
22035
+ await sendToClient(this.connection, {
22036
+ sessionId: params.sessionId,
22037
+ update: {
22038
+ sessionUpdate: "session_info_update",
22039
+ _meta: {
22040
+ turnCancelled: true,
22041
+ opencodeStatus: "idle"
22042
+ }
22043
+ }
22044
+ }).catch(() => {
22045
+ });
21978
22046
  ocCall("session.abort", { sessionID: params.sessionId });
21979
22047
  await this.sdk.session.abort({
21980
22048
  sessionID: params.sessionId,