opencode-orchestrator 0.4.22 → 0.4.23

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.d.ts CHANGED
@@ -139,8 +139,7 @@ declare const OrchestratorPlugin: (input: PluginInput) => Promise<{
139
139
  output: string;
140
140
  metadata: any;
141
141
  }) => Promise<void>;
142
- "assistant.done": (assistantInput: any, assistantOutput: any) => Promise<void>;
143
- handler: ({ event }: {
142
+ event: (input: {
144
143
  event: {
145
144
  type: string;
146
145
  properties?: unknown;
package/dist/index.js CHANGED
@@ -15508,22 +15508,6 @@ var AGENT_EMOJI2 = {
15508
15508
  [AGENT_NAMES.RECORDER]: "\u{1F4BE}",
15509
15509
  [AGENT_NAMES.COMMANDER]: "\u{1F3AF}"
15510
15510
  };
15511
- var CONTINUE_INSTRUCTION = `<auto_continue>
15512
- <status>Mission not complete. Keep executing.</status>
15513
-
15514
- <rules>
15515
- 1. DO NOT stop - mission is incomplete
15516
- 2. DO NOT wait for user input
15517
- 3. If previous action failed, try different approach
15518
- 4. If agent returned nothing, proceed to next step
15519
- </rules>
15520
-
15521
- <next_step>
15522
- What is the current state?
15523
- What is the next action?
15524
- Execute it NOW.
15525
- </next_step>
15526
- </auto_continue>`;
15527
15511
  var OrchestratorPlugin = async (input) => {
15528
15512
  const { directory, client } = input;
15529
15513
  console.log(`[orchestrator] v${PLUGIN_VERSION} loaded`);
@@ -15764,107 +15748,17 @@ ${stateSession.graph.getTaskSummary()}`;
15764
15748
  \u23F1\uFE0F [${currentTime}] Step ${session.step}/${session.maxSteps} | This step: ${stepDuration} | Total: ${totalElapsed}`;
15765
15749
  },
15766
15750
  // -----------------------------------------------------------------
15767
- // assistant.done hook - runs when the LLM finishes responding
15768
- // This is the heart of the "relentless loop" - we keep pushing it
15769
- // to continue until we see MISSION COMPLETE or hit the limit
15751
+ // NOTE: assistant.done hook has been REMOVED
15752
+ // It was NOT in the official OpenCode plugin API and was causing
15753
+ // UI rendering issues. The "relentless loop" feature needs to be
15754
+ // reimplemented using supported hooks like tool.execute.after
15755
+ // or the event hook.
15770
15756
  // -----------------------------------------------------------------
15771
- "assistant.done": async (assistantInput, assistantOutput) => {
15772
- const sessionID = assistantInput.sessionID;
15773
- const session = sessions.get(sessionID);
15774
- if (!session?.active) return;
15775
- const parts = assistantOutput.parts;
15776
- const textContent = parts?.filter((p) => p.type === "text" || p.type === "reasoning").map((p) => p.text || "").join("\n") || "";
15777
- const stateSession = state.sessions.get(sessionID);
15778
- const sanityResult = checkOutputSanity(textContent);
15779
- if (!sanityResult.isHealthy && stateSession) {
15780
- stateSession.anomalyCount = (stateSession.anomalyCount || 0) + 1;
15781
- session.step++;
15782
- session.timestamp = Date.now();
15783
- const recoveryText = stateSession.anomalyCount >= 2 ? ESCALATION_PROMPT : RECOVERY_PROMPT;
15784
- try {
15785
- if (client?.session?.prompt) {
15786
- await client.session.prompt({
15787
- path: { id: sessionID },
15788
- body: {
15789
- parts: [{
15790
- type: "text",
15791
- text: `\u26A0\uFE0F ANOMALY #${stateSession.anomalyCount}: ${sanityResult.reason}
15792
-
15793
- ` + recoveryText + `
15794
-
15795
- [Recovery Step ${session.step}/${session.maxSteps}]`
15796
- }]
15797
- }
15798
- });
15799
- }
15800
- } catch {
15801
- session.active = false;
15802
- state.missionActive = false;
15803
- }
15804
- return;
15805
- }
15806
- if (stateSession && stateSession.anomalyCount > 0) {
15807
- stateSession.anomalyCount = 0;
15808
- }
15809
- if (textContent.includes("\u2705 MISSION COMPLETE") || textContent.includes("MISSION COMPLETE")) {
15810
- session.active = false;
15811
- state.missionActive = false;
15812
- sessions.delete(sessionID);
15813
- state.sessions.delete(sessionID);
15814
- return;
15815
- }
15816
- if (textContent.includes("/stop") || textContent.includes("/cancel")) {
15817
- session.active = false;
15818
- state.missionActive = false;
15819
- sessions.delete(sessionID);
15820
- state.sessions.delete(sessionID);
15821
- return;
15822
- }
15823
- const now = Date.now();
15824
- const stepDuration = formatElapsedTime(session.lastStepTime, now);
15825
- const totalElapsed = formatElapsedTime(session.startTime, now);
15826
- session.step++;
15827
- session.timestamp = now;
15828
- session.lastStepTime = now;
15829
- const currentTime = formatTimestamp();
15830
- if (session.step >= session.maxSteps) {
15831
- session.active = false;
15832
- state.missionActive = false;
15833
- return;
15834
- }
15835
- try {
15836
- if (client?.session?.prompt) {
15837
- await client.session.prompt({
15838
- path: { id: sessionID },
15839
- body: {
15840
- parts: [{
15841
- type: "text",
15842
- text: CONTINUE_INSTRUCTION + `
15843
-
15844
- \u23F1\uFE0F [${currentTime}] Step ${session.step}/${session.maxSteps} | This step: ${stepDuration} | Total: ${totalElapsed}`
15845
- }]
15846
- }
15847
- });
15848
- }
15849
- } catch {
15850
- try {
15851
- await new Promise((r) => setTimeout(r, 500));
15852
- if (client?.session?.prompt) {
15853
- await client.session.prompt({
15854
- path: { id: sessionID },
15855
- body: { parts: [{ type: "text", text: "continue" }] }
15856
- });
15857
- }
15858
- } catch {
15859
- session.active = false;
15860
- state.missionActive = false;
15861
- }
15862
- }
15863
- },
15864
15757
  // -----------------------------------------------------------------
15865
15758
  // Event handler - cleans up when sessions are deleted
15866
15759
  // -----------------------------------------------------------------
15867
- handler: async ({ event }) => {
15760
+ event: async (input2) => {
15761
+ const { event } = input2;
15868
15762
  if (event.type === "session.deleted") {
15869
15763
  const props = event.properties;
15870
15764
  if (props?.info?.id) {
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "opencode-orchestrator",
3
3
  "displayName": "OpenCode Orchestrator",
4
4
  "description": "Distributed Cognitive Architecture for OpenCode. Turns simple prompts into specialized multi-agent workflows (Planner, Coder, Reviewer).",
5
- "version": "0.4.22",
5
+ "version": "0.4.23",
6
6
  "author": "agnusdei1207",
7
7
  "license": "MIT",
8
8
  "repository": {
@@ -51,7 +51,8 @@
51
51
  "dev:status": "echo '=== Global Link Status ===' && shx ls -l $(npm root -g)/opencode-orchestrator || echo 'Not linked'",
52
52
  "dev:test": "node dist/scripts/postinstall.js && echo '---' && node dist/scripts/preuninstall.js",
53
53
  "delete": "brew uninstall opencode && rm -rf ~/.config/opencode && npm uninstall -g opencode-orchestrator",
54
- "setup": "brew install opencode && npm install -g opencode-orchestrator"
54
+ "setup": "brew install opencode && npm install -g opencode-orchestrator",
55
+ "set": "npm run delete && npm run setup"
55
56
  },
56
57
  "dependencies": {
57
58
  "@opencode-ai/plugin": "^1.1.1",