opencode-orchestrator 1.0.28 → 1.0.30

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 +105 -43
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -947,17 +947,20 @@ var PHASE_0_SCOUT_SWARM = `**Mandatory Parallel Initialization**: DO NOT run dis
947
947
  3. **ONE-PASS INGESTION**: Once all scouts show DONE, use \`${TOOL_NAMES.GET_TASK_RESULT}\` for ALL scouts in a single turn to consolidate findings into \`${PATHS.CONTEXT}\`.
948
948
 
949
949
  [CRITICAL]: Sequential execution (running tools yourself) is a mission failure. Launch the swarm NOW.`;
950
- var PHASE_1_THINK_ANALYSIS = `### 1.1 MISSION SCOPE
951
- - What is the FULL scope? What are the success criteria?
952
- - What does the user REALLY want?
950
+ var PHASE_1_THINK_ANALYSIS = `### 1.1 ANALYZE & SCOPE (INPUT)
951
+ - **Review consolidated ${PATHS.CONTEXT} from Phase 0.**
952
+ - Map discovered files to the user's request.
953
+ - **Define Scope:** What is the FULL scope? What does the user REALLY want?
953
954
 
954
- ### 1.2 DECOMPOSITION
955
- - Break into INDEPENDENT sub-tasks.
956
- - Identify sequential dependencies vs parallel opportunities.
955
+ ### 1.2 STRATEGIC DECOMPOSITION (THINKING)
956
+ - **Mental Model:** How do identified files interact?
957
+ - **Breakdown:** Break into INDEPENDENT sub-tasks (sequential vs parallel).
958
+ - **Plan Structure:** How should ${AGENT_NAMES.PLANNER} structure the ${PATHS.TODO}?
957
959
 
958
- ### 1.3 DELEGATION
959
- - Choose best agent for each task (${AGENT_NAMES.PLANNER}/${AGENT_NAMES.WORKER}/${AGENT_NAMES.REVIEWER}).
960
- - Provide focused context for each.
960
+ ### 1.3 DELEGATION & DIRECTIVES (OUTPUT)
961
+ - **Synthesize Instructions:** Create clear directives for ${AGENT_NAMES.PLANNER}.
962
+ - **Pass Context:** Ensure specific file paths and tech stack details are passed.
963
+ - **Assign Roles:** Verify correct agent assignment (${AGENT_NAMES.WORKER}/${AGENT_NAMES.REVIEWER}).
961
964
 
962
965
  ### 1.4 RISK ASSESSMENT
963
966
  - Identify high-risk parts and fallback plans.
@@ -20386,7 +20389,91 @@ function cleanupSession2(sessionID) {
20386
20389
  }
20387
20390
 
20388
20391
  // src/core/context/context-window-monitor.ts
20392
+ var CONTEXT_THRESHOLDS = {
20393
+ /** Info level - remind agent there's still room */
20394
+ INFO: 0.7,
20395
+ /** Warning level - consider compaction soon */
20396
+ WARNING: 0.85,
20397
+ /** Critical level - immediate action needed */
20398
+ CRITICAL: 0.95
20399
+ };
20400
+ var CONTEXT_MONITOR_CONFIG = {
20401
+ /** Default max tokens for most models */
20402
+ DEFAULT_MAX_TOKENS: 2e5,
20403
+ /** Check interval in milliseconds */
20404
+ CHECK_INTERVAL_MS: 3e4,
20405
+ /** Minimum time between alerts (ms) */
20406
+ ALERT_COOLDOWN_MS: 6e4
20407
+ };
20389
20408
  var sessionStates3 = /* @__PURE__ */ new Map();
20409
+ function getState4(sessionID) {
20410
+ let state2 = sessionStates3.get(sessionID);
20411
+ if (!state2) {
20412
+ state2 = {
20413
+ lastAlertTime: 0,
20414
+ lastAlertLevel: null,
20415
+ isMonitoring: false
20416
+ };
20417
+ sessionStates3.set(sessionID, state2);
20418
+ }
20419
+ return state2;
20420
+ }
20421
+ function calculateUsage(usedTokens, maxTokens) {
20422
+ if (maxTokens <= 0) return 0;
20423
+ return usedTokens / maxTokens;
20424
+ }
20425
+ function getAlertLevel(usage) {
20426
+ if (usage >= CONTEXT_THRESHOLDS.CRITICAL) return "critical";
20427
+ if (usage >= CONTEXT_THRESHOLDS.WARNING) return "warning";
20428
+ if (usage >= CONTEXT_THRESHOLDS.INFO) return "info";
20429
+ return null;
20430
+ }
20431
+ function formatUsage(usage, usedTokens, maxTokens) {
20432
+ const percentage = Math.round(usage * 100);
20433
+ const usedK = Math.round(usedTokens / 1e3);
20434
+ const maxK = Math.round(maxTokens / 1e3);
20435
+ return `${percentage}% (${usedK}k/${maxK}k tokens)`;
20436
+ }
20437
+ function getAlertMessage(level, usage, usedTokens, maxTokens) {
20438
+ const usageStr = formatUsage(usage, usedTokens, maxTokens);
20439
+ switch (level) {
20440
+ case "info":
20441
+ return {
20442
+ title: "\u{1F4CA} Context Window Status",
20443
+ message: `${usageStr} - Still plenty of headroom. Continue without rushing.`,
20444
+ variant: "info"
20445
+ };
20446
+ case "warning":
20447
+ return {
20448
+ title: "\u26A0\uFE0F Context Window Alert",
20449
+ message: `${usageStr} - Consider wrapping up current task or requesting compaction.`,
20450
+ variant: "warning"
20451
+ };
20452
+ case "critical":
20453
+ return {
20454
+ title: "\u{1F6A8} Context Window Critical",
20455
+ message: `${usageStr} - Compaction recommended. Context may be truncated soon.`,
20456
+ variant: "warning"
20457
+ };
20458
+ }
20459
+ }
20460
+ function checkContextWindow(sessionID, usedTokens, maxTokens = CONTEXT_MONITOR_CONFIG.DEFAULT_MAX_TOKENS) {
20461
+ const usage = calculateUsage(usedTokens, maxTokens);
20462
+ const level = getAlertLevel(usage);
20463
+ if (!level) return;
20464
+ const state2 = getState4(sessionID);
20465
+ const now = Date.now();
20466
+ if (now - state2.lastAlertTime < CONTEXT_MONITOR_CONFIG.ALERT_COOLDOWN_MS) {
20467
+ if (state2.lastAlertLevel === level) return;
20468
+ if (state2.lastAlertLevel === "critical") return;
20469
+ if (state2.lastAlertLevel === "warning" && level === "info") return;
20470
+ }
20471
+ const alert = getAlertMessage(level, usage, usedTokens, maxTokens);
20472
+ show({ title: alert.title, message: alert.message, variant: alert.variant });
20473
+ state2.lastAlertTime = now;
20474
+ state2.lastAlertLevel = level;
20475
+ log("[context-window-monitor] Alert shown", { sessionID, level, usage: Math.round(usage * 100) });
20476
+ }
20390
20477
  function cleanupSession3(sessionID) {
20391
20478
  const state2 = sessionStates3.get(sessionID);
20392
20479
  if (state2?.intervalId) {
@@ -20455,9 +20542,16 @@ function createEventHandler(ctx) {
20455
20542
  presets.taskFailed("session", String(error45).slice(0, 50));
20456
20543
  }
20457
20544
  if (event.type === MESSAGE_EVENTS.UPDATED) {
20458
- const messageInfo = event.properties?.info;
20545
+ const messageProperties = event.properties;
20546
+ const messageInfo = messageProperties?.info;
20459
20547
  const sessionID = messageInfo?.sessionID;
20460
20548
  const role = messageInfo?.role;
20549
+ if (sessionID && messageProperties?.usage) {
20550
+ const totalTokens = messageProperties.usage.totalTokens ?? (messageProperties.usage.inputTokens ?? 0) + (messageProperties.usage.outputTokens ?? 0);
20551
+ if (totalTokens > 0) {
20552
+ checkContextWindow(sessionID, totalTokens);
20553
+ }
20554
+ }
20461
20555
  if (sessionID && role === MESSAGE_ROLES.ASSISTANT) {
20462
20556
  markRecoveryComplete(sessionID);
20463
20557
  }
@@ -20663,41 +20757,9 @@ function createChatMessageHandler(ctx) {
20663
20757
  if (sessionID) {
20664
20758
  handleUserMessage(sessionID);
20665
20759
  }
20666
- if (agentName === AGENT_NAMES.COMMANDER.toLowerCase()) {
20667
- if (!sessions.has(sessionID)) {
20668
- const now = Date.now();
20669
- sessions.set(sessionID, {
20670
- active: true,
20671
- step: 0,
20672
- timestamp: now,
20673
- startTime: now,
20674
- lastStepTime: now
20675
- });
20676
- state.missionActive = true;
20677
- state.sessions.set(sessionID, {
20678
- enabled: true,
20679
- iterations: 0,
20680
- taskRetries: /* @__PURE__ */ new Map(),
20681
- currentTask: "",
20682
- anomalyCount: 0
20683
- });
20684
- startSession(sessionID);
20685
- presets.taskStarted(sessionID, AGENT_NAMES.COMMANDER);
20686
- }
20687
- if (!parsed || parsed.command !== COMMAND_NAMES.TASK) {
20688
- const taskTemplate = COMMANDS[COMMAND_NAMES.TASK].template;
20689
- const userMessage = parsed?.args || originalText;
20690
- parts[textPartIndex].text = taskTemplate.replace(
20691
- /\$ARGUMENTS/g,
20692
- userMessage || PROMPTS.CONTINUE
20693
- );
20694
- startMissionLoop(directory, sessionID, userMessage || originalText);
20695
- log("[chat-message-handler] Auto-applied mission mode + started loop", { originalLength: originalText.length });
20696
- }
20697
- }
20698
20760
  if (parsed) {
20699
20761
  const command = COMMANDS[parsed.command];
20700
- if (command && agentName !== AGENT_NAMES.COMMANDER.toLowerCase()) {
20762
+ if (command) {
20701
20763
  parts[textPartIndex].text = command.template.replace(
20702
20764
  /\$ARGUMENTS/g,
20703
20765
  parsed.args || PROMPTS.CONTINUE
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": "1.0.28",
5
+ "version": "1.0.30",
6
6
  "author": "agnusdei1207",
7
7
  "license": "MIT",
8
8
  "repository": {