zenox 1.4.2 → 1.4.3

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.
@@ -5,4 +5,4 @@
5
5
  */
6
6
  export { BackgroundManager } from "./manager";
7
7
  export { createBackgroundTools, type BackgroundTools } from "./tools";
8
- export type { BackgroundTask, TaskStatus, LaunchInput, CompletionNotification, } from "./types";
8
+ export type { BackgroundTask, TaskStatus, LaunchInput, CompletionNotification, ParentModel, } from "./types";
@@ -3,6 +3,10 @@
3
3
  * Minimal interfaces for fire-and-forget parallel agent execution
4
4
  */
5
5
  export type TaskStatus = "running" | "completed" | "failed" | "cancelled";
6
+ export interface ParentModel {
7
+ providerID: string;
8
+ modelID: string;
9
+ }
6
10
  export interface BackgroundTask {
7
11
  id: string;
8
12
  sessionID: string;
@@ -14,6 +18,7 @@ export interface BackgroundTask {
14
18
  completedAt?: Date;
15
19
  error?: string;
16
20
  parentAgent?: string;
21
+ parentModel?: ParentModel;
17
22
  }
18
23
  export interface LaunchInput {
19
24
  agent: string;
@@ -21,6 +26,7 @@ export interface LaunchInput {
21
26
  description: string;
22
27
  parentSessionID: string;
23
28
  parentAgent?: string;
29
+ parentModel?: ParentModel;
24
30
  }
25
31
  export interface CompletionNotification {
26
32
  allComplete: boolean;
@@ -28,4 +34,5 @@ export interface CompletionNotification {
28
34
  completedTasks: BackgroundTask[];
29
35
  runningCount: number;
30
36
  parentAgent?: string;
37
+ parentModel?: ParentModel;
31
38
  }
package/dist/index.js CHANGED
@@ -835,18 +835,26 @@ function getOrchestrationPrompt(agent) {
835
835
  }
836
836
 
837
837
  // src/orchestration/session-agent-tracker.ts
838
- var sessionAgentMap = new Map;
839
- function setSessionAgent(sessionID, agent) {
840
- if (agent) {
841
- sessionAgentMap.set(sessionID, agent);
842
- }
838
+ var sessionContextMap = new Map;
839
+ function setSessionContext(sessionID, context) {
840
+ const existing = sessionContextMap.get(sessionID) ?? {};
841
+ sessionContextMap.set(sessionID, {
842
+ agent: context.agent ?? existing.agent,
843
+ model: context.model ?? existing.model
844
+ });
845
+ }
846
+ function getSessionContext(sessionID) {
847
+ return sessionContextMap.get(sessionID);
843
848
  }
844
849
  function getSessionAgent(sessionID) {
845
- return sessionAgentMap.get(sessionID);
850
+ return sessionContextMap.get(sessionID)?.agent;
851
+ }
852
+ function getSessionModel(sessionID) {
853
+ return sessionContextMap.get(sessionID)?.model;
846
854
  }
847
855
  function clearSessionAgent(sessionID) {
848
856
  if (sessionID) {
849
- sessionAgentMap.delete(sessionID);
857
+ sessionContextMap.delete(sessionID);
850
858
  }
851
859
  }
852
860
  function getOrchestrationAgentType(agent) {
@@ -4995,7 +5003,8 @@ class BackgroundManager {
4995
5003
  prompt: input.prompt,
4996
5004
  status: "running",
4997
5005
  startedAt: new Date,
4998
- parentAgent: input.parentAgent
5006
+ parentAgent: input.parentAgent,
5007
+ parentModel: input.parentModel
4999
5008
  };
5000
5009
  this.tasks.set(task.id, task);
5001
5010
  if (this.toastManager) {
@@ -5134,12 +5143,14 @@ ${runningTasks.length} task(s) still running. Continue working.
5134
5143
  </system-reminder>`;
5135
5144
  }
5136
5145
  const parentAgent = completedTasks[0]?.parentAgent;
5146
+ const parentModel = completedTasks[0]?.parentModel;
5137
5147
  return {
5138
5148
  allComplete,
5139
5149
  message,
5140
5150
  completedTasks,
5141
5151
  runningCount: runningTasks.length,
5142
- parentAgent
5152
+ parentAgent,
5153
+ parentModel
5143
5154
  };
5144
5155
  }
5145
5156
  listActiveTasks() {
@@ -17490,12 +17501,14 @@ Use for independent research tasks that benefit from parallelism.`,
17490
17501
  },
17491
17502
  async execute(args, context) {
17492
17503
  try {
17504
+ const parentModel = getSessionModel(context.sessionID);
17493
17505
  const task = await manager.launch(client, {
17494
17506
  agent: args.agent,
17495
17507
  description: args.description,
17496
17508
  prompt: args.prompt,
17497
17509
  parentSessionID: context.sessionID,
17498
- parentAgent: context.agent
17510
+ parentAgent: context.agent,
17511
+ parentModel
17499
17512
  });
17500
17513
  const activeTasks = manager.listActiveTasks();
17501
17514
  return `Background task launched successfully.
@@ -17930,12 +17943,15 @@ Current incomplete tasks:
17930
17943
  ${todoList}
17931
17944
 
17932
17945
  ${statusLine}`;
17933
- const sendPrompt = async (omitAgent = false) => {
17946
+ const sessionContext = getSessionContext(sessionID);
17947
+ const model = sessionContext?.model;
17948
+ const sendPrompt = async (omitContext = false) => {
17934
17949
  await ctx.client.session.prompt({
17935
17950
  path: { id: sessionID },
17936
17951
  body: {
17937
17952
  noReply: false,
17938
- ...omitAgent || !agent ? {} : { agent },
17953
+ ...omitContext || !agent ? {} : { agent },
17954
+ ...omitContext || !model ? {} : { model },
17939
17955
  parts: [{ type: "text", text: prompt }]
17940
17956
  }
17941
17957
  });
@@ -17944,7 +17960,7 @@ ${statusLine}`;
17944
17960
  await sendPrompt();
17945
17961
  } catch (err) {
17946
17962
  const errorMsg = err instanceof Error ? err.message : String(err);
17947
- if (errorMsg.includes("agent") || errorMsg.includes("undefined")) {
17963
+ if (errorMsg.includes("agent") || errorMsg.includes("model") || errorMsg.includes("undefined")) {
17948
17964
  try {
17949
17965
  await sendPrompt(true);
17950
17966
  } catch {
@@ -18349,7 +18365,7 @@ var ZenoxPlugin = async (ctx) => {
18349
18365
  ...codeIntelligenceTools
18350
18366
  },
18351
18367
  "chat.message": async (input, output) => {
18352
- setSessionAgent(input.sessionID, input.agent);
18368
+ setSessionContext(input.sessionID, { agent: input.agent, model: input.model });
18353
18369
  const message = output.message;
18354
18370
  if (firstMessageVariantGate.shouldOverride(input.sessionID)) {
18355
18371
  const variant = resolveAgentVariant(pluginConfig, input.agent);
@@ -18402,19 +18418,20 @@ var ZenoxPlugin = async (ctx) => {
18402
18418
  if (notification) {
18403
18419
  const mainSessionID = backgroundManager.getMainSession();
18404
18420
  if (mainSessionID) {
18405
- const sendNotification = async (omitAgent = false) => {
18421
+ const sendNotification = async (omitContext = false) => {
18406
18422
  try {
18407
18423
  await ctx.client.session.prompt({
18408
18424
  path: { id: mainSessionID },
18409
18425
  body: {
18410
18426
  noReply: !notification.allComplete,
18411
- ...omitAgent ? {} : { agent: notification.parentAgent },
18427
+ ...omitContext ? {} : { agent: notification.parentAgent },
18428
+ ...omitContext ? {} : { model: notification.parentModel },
18412
18429
  parts: [{ type: "text", text: notification.message }]
18413
18430
  }
18414
18431
  });
18415
18432
  } catch (err) {
18416
18433
  const errorMsg = err instanceof Error ? err.message : String(err);
18417
- if (!omitAgent && (errorMsg.includes("agent.name") || errorMsg.includes("undefined"))) {
18434
+ if (!omitContext && (errorMsg.includes("agent") || errorMsg.includes("model") || errorMsg.includes("undefined"))) {
18418
18435
  return sendNotification(true);
18419
18436
  }
18420
18437
  }
@@ -1,17 +1,39 @@
1
1
  /**
2
- * Session-Agent Tracker
2
+ * Session Context Tracker
3
3
  *
4
- * Tracks which agent is active for each session, allowing the system transform
5
- * hook to inject agent-specific prompts.
4
+ * Tracks agent and model context for each session, allowing:
5
+ * - System transform hook to inject agent-specific prompts
6
+ * - Todo enforcer and background tasks to preserve model context
6
7
  *
7
8
  * Flow:
8
- * 1. chat.message hook fires with { sessionID, agent }
9
- * 2. We store the mapping: sessionID -> agentName
9
+ * 1. chat.message hook fires with { sessionID, agent, model }
10
+ * 2. We store the mapping: sessionID -> { agent, model }
10
11
  * 3. experimental.chat.system.transform fires with { sessionID }
11
- * 4. We look up the agent and inject the appropriate prompt
12
+ * 4. We look up the context and inject the appropriate prompt
13
+ * 5. Todo enforcer / background tasks use model context when sending prompts
12
14
  */
15
+ export interface SessionModel {
16
+ providerID: string;
17
+ modelID: string;
18
+ }
19
+ export interface SessionContext {
20
+ agent?: string;
21
+ model?: SessionModel;
22
+ }
13
23
  /**
14
- * Record which agent is active for a session.
24
+ * Record context (agent + model) for a session.
25
+ * Called from chat.message hook.
26
+ */
27
+ export declare function setSessionContext(sessionID: string, context: {
28
+ agent?: string;
29
+ model?: SessionModel;
30
+ }): void;
31
+ /**
32
+ * Get the full context for a session.
33
+ */
34
+ export declare function getSessionContext(sessionID: string): SessionContext | undefined;
35
+ /**
36
+ * Record which agent is active for a session (legacy helper).
15
37
  * Called from chat.message hook.
16
38
  */
17
39
  export declare function setSessionAgent(sessionID: string, agent: string | undefined): void;
@@ -20,6 +42,10 @@ export declare function setSessionAgent(sessionID: string, agent: string | undef
20
42
  * Called from experimental.chat.system.transform hook.
21
43
  */
22
44
  export declare function getSessionAgent(sessionID: string): string | undefined;
45
+ /**
46
+ * Get the active model for a session.
47
+ */
48
+ export declare function getSessionModel(sessionID: string): SessionModel | undefined;
23
49
  /**
24
50
  * Clear tracking for a session (on deletion).
25
51
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zenox",
3
- "version": "1.4.2",
3
+ "version": "1.4.3",
4
4
  "description": "OpenCode plugin with specialized agents (explorer, librarian, oracle, ui-planner), background tasks for parallel execution, and smart orchestration",
5
5
  "author": "Ayush",
6
6
  "license": "MIT",