@cortexkit/opencode-magic-context 0.11.0 → 0.12.0

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 (29) hide show
  1. package/dist/config/schema/magic-context.d.ts +14 -0
  2. package/dist/config/schema/magic-context.d.ts.map +1 -1
  3. package/dist/features/magic-context/scheduler.d.ts +5 -1
  4. package/dist/features/magic-context/scheduler.d.ts.map +1 -1
  5. package/dist/hooks/magic-context/command-handler.d.ts +6 -0
  6. package/dist/hooks/magic-context/command-handler.d.ts.map +1 -1
  7. package/dist/hooks/magic-context/event-handler.d.ts +4 -0
  8. package/dist/hooks/magic-context/event-handler.d.ts.map +1 -1
  9. package/dist/hooks/magic-context/event-resolvers.d.ts +39 -1
  10. package/dist/hooks/magic-context/event-resolvers.d.ts.map +1 -1
  11. package/dist/hooks/magic-context/execute-status.d.ts +4 -1
  12. package/dist/hooks/magic-context/execute-status.d.ts.map +1 -1
  13. package/dist/hooks/magic-context/hook.d.ts +4 -0
  14. package/dist/hooks/magic-context/hook.d.ts.map +1 -1
  15. package/dist/hooks/magic-context/nudger.d.ts.map +1 -1
  16. package/dist/hooks/magic-context/transform.d.ts +4 -0
  17. package/dist/hooks/magic-context/transform.d.ts.map +1 -1
  18. package/dist/index.js +189 -39
  19. package/dist/plugin/hooks/create-session-hooks.d.ts.map +1 -1
  20. package/dist/plugin/rpc-handlers.d.ts.map +1 -1
  21. package/dist/shared/models-dev-cache.d.ts.map +1 -1
  22. package/dist/shared/rpc-types.d.ts +11 -0
  23. package/dist/shared/rpc-types.d.ts.map +1 -1
  24. package/dist/tui/data/context-db.d.ts.map +1 -1
  25. package/package.json +1 -1
  26. package/src/shared/models-dev-cache.test.ts +114 -1
  27. package/src/shared/models-dev-cache.ts +34 -14
  28. package/src/shared/rpc-types.ts +11 -0
  29. package/src/tui/data/context-db.ts +1 -0
@@ -177,6 +177,13 @@ export interface MagicContextConfig {
177
177
  default: number;
178
178
  [modelKey: string]: number;
179
179
  };
180
+ /** Absolute token thresholds per model. When set for a given model (or via `default`),
181
+ * this overrides `execute_threshold_percentage` for that model. Useful for hard caps
182
+ * matching provider input limits. Values above 80% × context_limit are clamped with a warning. */
183
+ execute_threshold_tokens?: {
184
+ default?: number;
185
+ [modelKey: string]: number | undefined;
186
+ };
180
187
  protected_tags: number;
181
188
  auto_drop_tool_age: number;
182
189
  drop_tool_structure: boolean;
@@ -333,6 +340,9 @@ export declare const MagicContextConfigSchema: z.ZodPipe<z.ZodObject<{
333
340
  execute_threshold_percentage: z.ZodDefault<z.ZodUnion<readonly [z.ZodNumber, z.ZodObject<{
334
341
  default: z.ZodNumber;
335
342
  }, z.core.$catchall<z.ZodNumber>>]>>;
343
+ execute_threshold_tokens: z.ZodOptional<z.ZodObject<{
344
+ default: z.ZodOptional<z.ZodNumber>;
345
+ }, z.core.$catchall<z.ZodNumber>>>;
336
346
  protected_tags: z.ZodOptional<z.ZodNumber>;
337
347
  auto_drop_tool_age: z.ZodDefault<z.ZodNumber>;
338
348
  drop_tool_structure: z.ZodDefault<z.ZodBoolean>;
@@ -543,6 +553,10 @@ export declare const MagicContextConfigSchema: z.ZodPipe<z.ZodObject<{
543
553
  variant?: string | undefined;
544
554
  fallback_models?: string | string[] | undefined;
545
555
  } | undefined;
556
+ execute_threshold_tokens?: {
557
+ [x: string]: number;
558
+ default?: number | undefined;
559
+ } | undefined;
546
560
  protected_tags?: number | undefined;
547
561
  sidekick?: {
548
562
  enabled: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"magic-context.d.ts","sourceRoot":"","sources":["../../../src/config/schema/magic-context.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"magic-context.d.ts","sourceRoot":"","sources":["../../../src/config/schema/magic-context.ts"],"names":[],"mappings":"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"}
@@ -1,12 +1,16 @@
1
1
  import type { ContextUsage, SchedulerDecision, SessionMeta } from "./types";
2
2
  export interface Scheduler {
3
- shouldExecute(sessionMeta: SessionMeta, contextUsage: ContextUsage, currentTime?: number, sessionId?: string, modelKey?: string): SchedulerDecision;
3
+ shouldExecute(sessionMeta: SessionMeta, contextUsage: ContextUsage, currentTime?: number, sessionId?: string, modelKey?: string, contextLimit?: number): SchedulerDecision;
4
4
  }
5
5
  interface SchedulerConfig {
6
6
  executeThresholdPercentage: number | {
7
7
  default: number;
8
8
  [modelKey: string]: number;
9
9
  };
10
+ executeThresholdTokens?: {
11
+ default?: number;
12
+ [modelKey: string]: number | undefined;
13
+ };
10
14
  }
11
15
  export declare function parseCacheTtl(ttl: string): number;
12
16
  export declare function createScheduler(config: SchedulerConfig): Scheduler;
@@ -1 +1 @@
1
- {"version":3,"file":"scheduler.d.ts","sourceRoot":"","sources":["../../../src/features/magic-context/scheduler.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAW5E,MAAM,WAAW,SAAS;IACtB,aAAa,CACT,WAAW,EAAE,WAAW,EACxB,YAAY,EAAE,YAAY,EAC1B,WAAW,CAAC,EAAE,MAAM,EACpB,SAAS,CAAC,EAAE,MAAM,EAClB,QAAQ,CAAC,EAAE,MAAM,GAClB,iBAAiB,CAAC;CACxB;AAED,UAAU,eAAe;IACrB,0BAA0B,EAAE,MAAM,GAAG;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAC;CACxF;AAED,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAiBjD;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,eAAe,GAAG,SAAS,CAkDlE"}
1
+ {"version":3,"file":"scheduler.d.ts","sourceRoot":"","sources":["../../../src/features/magic-context/scheduler.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAW5E,MAAM,WAAW,SAAS;IACtB,aAAa,CACT,WAAW,EAAE,WAAW,EACxB,YAAY,EAAE,YAAY,EAC1B,WAAW,CAAC,EAAE,MAAM,EACpB,SAAS,CAAC,EAAE,MAAM,EAClB,QAAQ,CAAC,EAAE,MAAM,EACjB,YAAY,CAAC,EAAE,MAAM,GACtB,iBAAiB,CAAC;CACxB;AAED,UAAU,eAAe;IACrB,0BAA0B,EAAE,MAAM,GAAG;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAC;IACrF,sBAAsB,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAA;KAAE,CAAC;CACzF;AAED,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAiBjD;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,eAAe,GAAG,SAAS,CAmElE"}
@@ -22,12 +22,18 @@ export declare function createMagicContextCommandHandler(deps: {
22
22
  default: number;
23
23
  [modelKey: string]: number;
24
24
  };
25
+ executeThresholdTokens?: {
26
+ default?: number;
27
+ [modelKey: string]: number | undefined;
28
+ };
25
29
  historyBudgetPercentage?: number;
26
30
  commitClusterTrigger?: {
27
31
  enabled: boolean;
28
32
  min_clusters: number;
29
33
  };
30
34
  getLiveModelKey?: (sessionId: string) => string | undefined;
35
+ /** Optional live context limit resolver — used for tokens-based threshold display. */
36
+ getContextLimit?: (sessionId: string) => number | undefined;
31
37
  onFlush?: (sessionId: string) => void;
32
38
  executeRecomp?: (sessionId: string) => Promise<string>;
33
39
  sendNotification: (sessionId: string, text: string, params: NotificationParams) => Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"command-handler.d.ts","sourceRoot":"","sources":["../../../src/hooks/magic-context/command-handler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AACvF,OAAO,EACH,KAAK,cAAc,EAGtB,MAAM,sCAAsC,CAAC;AAG9C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAKxD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AAOtE,MAAM,WAAW,mBAAmB;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,oBAAoB;IACjC,KAAK,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACjD;AA4KD,wBAAgB,gCAAgC,CAAC,IAAI,EAAE;IACnD,EAAE,EAAE,QAAQ,CAAC;IACb,aAAa,EAAE,MAAM,CAAC;IACtB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,0BAA0B,CAAC,EAAE,MAAM,GAAG;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAC;IACtF,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,oBAAoB,CAAC,EAAE;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,YAAY,EAAE,MAAM,CAAA;KAAE,CAAC;IAClE,eAAe,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC;IAC5D,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IACtC,aAAa,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IACvD,gBAAgB,EAAE,CACd,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,kBAAkB,KACzB,OAAO,CAAC,IAAI,CAAC,CAAC;IACnB,QAAQ,CAAC,EAAE;QACP,MAAM,EAAE,cAAc,CAAC;QACvB,WAAW,EAAE,MAAM,CAAC;QACpB,gBAAgB,CAAC,EAAE,MAAM,CAAC;QAC1B,MAAM,EAAE,aAAa,CAAC,QAAQ,CAAC,CAAC;KACnC,CAAC;IACF,OAAO,CAAC,EAAE;QACN,MAAM,EAAE,aAAa,CAAC;QACtB,WAAW,EAAE,MAAM,CAAC;QACpB,MAAM,EAAE,OAAO,CAAC;QAChB,SAAS,EAAE,MAAM,CAAC;QAClB,YAAY,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC;QACrE,wBAAwB,CAAC,EAAE;YAAE,OAAO,EAAE,OAAO,CAAC;YAAC,kBAAkB,EAAE,MAAM,CAAA;SAAE,CAAC;QAC5E,uBAAuB,CAAC,EAAE;YACtB,OAAO,EAAE,OAAO,CAAC;YACjB,YAAY,EAAE,MAAM,CAAC;YACrB,SAAS,EAAE,MAAM,CAAC;SACrB,CAAC;KACL,CAAC;CACL;sCASkB,mBAAmB,WACjB,oBAAoB,WACpB,kBAAkB,KAC5B,OAAO,CAAC,IAAI,CAAC;EA0GvB"}
1
+ {"version":3,"file":"command-handler.d.ts","sourceRoot":"","sources":["../../../src/hooks/magic-context/command-handler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AACvF,OAAO,EACH,KAAK,cAAc,EAGtB,MAAM,sCAAsC,CAAC;AAG9C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAKxD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AAOtE,MAAM,WAAW,mBAAmB;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,oBAAoB;IACjC,KAAK,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACjD;AA4KD,wBAAgB,gCAAgC,CAAC,IAAI,EAAE;IACnD,EAAE,EAAE,QAAQ,CAAC;IACb,aAAa,EAAE,MAAM,CAAC;IACtB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,0BAA0B,CAAC,EAAE,MAAM,GAAG;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAC;IACtF,sBAAsB,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAA;KAAE,CAAC;IACtF,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,oBAAoB,CAAC,EAAE;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,YAAY,EAAE,MAAM,CAAA;KAAE,CAAC;IAClE,eAAe,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC;IAC5D,sFAAsF;IACtF,eAAe,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC;IAC5D,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IACtC,aAAa,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IACvD,gBAAgB,EAAE,CACd,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,kBAAkB,KACzB,OAAO,CAAC,IAAI,CAAC,CAAC;IACnB,QAAQ,CAAC,EAAE;QACP,MAAM,EAAE,cAAc,CAAC;QACvB,WAAW,EAAE,MAAM,CAAC;QACpB,gBAAgB,CAAC,EAAE,MAAM,CAAC;QAC1B,MAAM,EAAE,aAAa,CAAC,QAAQ,CAAC,CAAC;KACnC,CAAC;IACF,OAAO,CAAC,EAAE;QACN,MAAM,EAAE,aAAa,CAAC;QACtB,WAAW,EAAE,MAAM,CAAC;QACpB,MAAM,EAAE,OAAO,CAAC;QAChB,SAAS,EAAE,MAAM,CAAC;QAClB,YAAY,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC;QACrE,wBAAwB,CAAC,EAAE;YAAE,OAAO,EAAE,OAAO,CAAC;YAAC,kBAAkB,EAAE,MAAM,CAAA;SAAE,CAAC;QAC5E,uBAAuB,CAAC,EAAE;YACtB,OAAO,EAAE,OAAO,CAAC;YACjB,YAAY,EAAE,MAAM,CAAC;YACrB,SAAS,EAAE,MAAM,CAAC;SACrB,CAAC;KACL,CAAC;CACL;sCASkB,mBAAmB,WACjB,oBAAoB,WACpB,kBAAkB,KAC5B,OAAO,CAAC,IAAI,CAAC;EA6GvB"}
@@ -22,6 +22,10 @@ export interface EventHandlerDeps {
22
22
  default: number;
23
23
  [modelKey: string]: number;
24
24
  };
25
+ execute_threshold_tokens?: {
26
+ default?: number;
27
+ [modelKey: string]: number | undefined;
28
+ };
25
29
  cache_ttl: CacheTtlConfig;
26
30
  commit_cluster_trigger?: {
27
31
  enabled: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"event-handler.d.ts","sourceRoot":"","sources":["../../../src/hooks/magic-context/event-handler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,yCAAyC,CAAC;AAqBvF,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qCAAqC,CAAC;AAClE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oCAAoC,CAAC;AAmBvE,OAAO,EAA2B,KAAK,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAKhF,KAAK,cAAc,GAAG,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAEtD,UAAU,iBAAiB;IACvB,KAAK,EAAE,YAAY,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;CACrB;AAOD,MAAM,WAAW,gBAAgB;IAC7B,eAAe,EAAE,GAAG,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;IAChD,iBAAiB,EAAE,UAAU,CAAC,OAAO,uBAAuB,CAAC,CAAC;IAC9D,eAAe,EAAE,mBAAmB,CAAC;IACrC,yBAAyB,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IACxD,gBAAgB,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/C,MAAM,EAAE;QACJ,cAAc,EAAE,MAAM,CAAC;QACvB,kBAAkB,CAAC,EAAE,MAAM,CAAC;QAC5B,mBAAmB,CAAC,EAAE,OAAO,CAAC;QAC9B,mBAAmB,CAAC,EAAE,MAAM,CAAC;QAC7B,4BAA4B,CAAC,EAAE,MAAM,GAAG;YAAE,OAAO,EAAE,MAAM,CAAC;YAAC,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAA;SAAE,CAAC;QACxF,SAAS,EAAE,cAAc,CAAC;QAC1B,sBAAsB,CAAC,EAAE;YAAE,OAAO,EAAE,OAAO,CAAC;YAAC,YAAY,EAAE,MAAM,CAAA;SAAE,CAAC;KACvE,CAAC;IACF,MAAM,EAAE,MAAM,CAAC;IACf,EAAE,EAAE,UAAU,CAAC,cAAc,sCAAsC,EAAE,YAAY,CAAC,CAAC;CACtF;AAqGD,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,gBAAgB,IACvC,OAAO;IAAE,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,OAAO,CAAA;KAAE,CAAA;CAAE,KAAG,OAAO,CAAC,IAAI,CAAC,CA6SzF"}
1
+ {"version":3,"file":"event-handler.d.ts","sourceRoot":"","sources":["../../../src/hooks/magic-context/event-handler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,yCAAyC,CAAC;AAqBvF,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qCAAqC,CAAC;AAClE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oCAAoC,CAAC;AAmBvE,OAAO,EAA2B,KAAK,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAKhF,KAAK,cAAc,GAAG,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAEtD,UAAU,iBAAiB;IACvB,KAAK,EAAE,YAAY,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;CACrB;AAOD,MAAM,WAAW,gBAAgB;IAC7B,eAAe,EAAE,GAAG,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;IAChD,iBAAiB,EAAE,UAAU,CAAC,OAAO,uBAAuB,CAAC,CAAC;IAC9D,eAAe,EAAE,mBAAmB,CAAC;IACrC,yBAAyB,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IACxD,gBAAgB,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/C,MAAM,EAAE;QACJ,cAAc,EAAE,MAAM,CAAC;QACvB,kBAAkB,CAAC,EAAE,MAAM,CAAC;QAC5B,mBAAmB,CAAC,EAAE,OAAO,CAAC;QAC9B,mBAAmB,CAAC,EAAE,MAAM,CAAC;QAC7B,4BAA4B,CAAC,EAAE,MAAM,GAAG;YAAE,OAAO,EAAE,MAAM,CAAC;YAAC,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAA;SAAE,CAAC;QACxF,wBAAwB,CAAC,EAAE;YAAE,OAAO,CAAC,EAAE,MAAM,CAAC;YAAC,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAA;SAAE,CAAC;QACxF,SAAS,EAAE,cAAc,CAAC;QAC1B,sBAAsB,CAAC,EAAE;YAAE,OAAO,EAAE,OAAO,CAAC;YAAC,YAAY,EAAE,MAAM,CAAA;SAAE,CAAC;KACvE,CAAC;IACF,MAAM,EAAE,MAAM,CAAC;IACf,EAAE,EAAE,UAAU,CAAC,cAAc,sCAAsC,EAAE,YAAY,CAAC,CAAC;CACtF;AAqGD,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,gBAAgB,IACvC,OAAO;IAAE,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,OAAO,CAAA;KAAE,CAAA;CAAE,KAAG,OAAO,CAAC,IAAI,CAAC,CAkTzF"}
@@ -5,7 +5,45 @@ type ExecuteThresholdConfig = number | {
5
5
  default: number;
6
6
  [modelKey: string]: number;
7
7
  };
8
- export declare function resolveExecuteThreshold(config: ExecuteThresholdConfig, modelKey: string | undefined, fallback: number): number;
8
+ type ExecuteThresholdTokensConfig = {
9
+ default?: number;
10
+ [modelKey: string]: number | undefined;
11
+ } | undefined;
12
+ export interface ExecuteThresholdOptions {
13
+ /** Optional tokens-based threshold config. When matched for the given modelKey,
14
+ * overrides the percentage-based threshold. */
15
+ tokensConfig?: ExecuteThresholdTokensConfig;
16
+ /** Required when `tokensConfig` is provided — used to convert tokens → percentage
17
+ * and to clamp values above 80% × context_limit. */
18
+ contextLimit?: number;
19
+ /** Session ID for warn logs when clamping. If absent, warns to global log. */
20
+ sessionId?: string;
21
+ }
22
+ export type ExecuteThresholdMode = "percentage" | "tokens";
23
+ export interface ExecuteThresholdDetail {
24
+ /** Effective execute threshold as a percentage (0–80). Downstream math keys off this. */
25
+ percentage: number;
26
+ /** Which source was authoritative: tokens config (when matched + valid context) or percentage. */
27
+ mode: ExecuteThresholdMode;
28
+ /** When mode is "tokens", the absolute token value after clamping (≤ 80% × contextLimit). */
29
+ absoluteTokens?: number;
30
+ /** The config key that matched, if any (for display/debugging). `"default"` when default fallback. */
31
+ matchedKey?: string;
32
+ }
33
+ /**
34
+ * Single source of truth for execute-threshold resolution. Returns the effective
35
+ * percentage plus which config source was authoritative. Callers that only need
36
+ * the percentage can use `resolveExecuteThreshold` (thin wrapper below); callers
37
+ * that surface the mode to users (`/ctx-status`, TUI, RPC) must use this directly
38
+ * to avoid the "progressive lookup drift" bug where two call sites disagree on
39
+ * whether tokens mode is active.
40
+ */
41
+ export declare function resolveExecuteThresholdDetail(config: ExecuteThresholdConfig, modelKey: string | undefined, fallback: number, options?: ExecuteThresholdOptions): ExecuteThresholdDetail;
42
+ /**
43
+ * Backward-compatible wrapper around `resolveExecuteThresholdDetail`.
44
+ * Use the detail version when you also need the mode or absolute token value.
45
+ */
46
+ export declare function resolveExecuteThreshold(config: ExecuteThresholdConfig, modelKey: string | undefined, fallback: number, options?: ExecuteThresholdOptions): number;
9
47
  export declare function resolveModelKey(providerID: string | undefined, modelID: string | undefined): string | undefined;
10
48
  export declare function resolveSessionId(properties: {
11
49
  info?: unknown;
@@ -1 +1 @@
1
- {"version":3,"file":"event-resolvers.d.ts","sourceRoot":"","sources":["../../../src/hooks/magic-context/event-resolvers.ts"],"names":[],"mappings":"AAIA,KAAK,cAAc,GAAG,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAEtD,wBAAgB,mBAAmB,CAC/B,UAAU,EAAE,MAAM,GAAG,SAAS,EAC9B,OAAO,EAAE,MAAM,GAAG,SAAS,GAC5B,MAAM,CAiBR;AAED,wBAAgB,eAAe,CAAC,QAAQ,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAiB9F;AAED,KAAK,sBAAsB,GAAG,MAAM,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAA;CAAE,CAAC;AAEvF,wBAAgB,uBAAuB,CACnC,MAAM,EAAE,sBAAsB,EAC9B,QAAQ,EAAE,MAAM,GAAG,SAAS,EAC5B,QAAQ,EAAE,MAAM,GACjB,MAAM,CAuBR;AAED,wBAAgB,eAAe,CAC3B,UAAU,EAAE,MAAM,GAAG,SAAS,EAC9B,OAAO,EAAE,MAAM,GAAG,SAAS,GAC5B,MAAM,GAAG,SAAS,CAMpB;AAED,wBAAgB,gBAAgB,CAC5B,UAAU,EAAE;IAAE,IAAI,CAAC,EAAE,OAAO,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,GAC/D,MAAM,GAAG,SAAS,CAmBpB"}
1
+ {"version":3,"file":"event-resolvers.d.ts","sourceRoot":"","sources":["../../../src/hooks/magic-context/event-resolvers.ts"],"names":[],"mappings":"AAMA,KAAK,cAAc,GAAG,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAEtD,wBAAgB,mBAAmB,CAC/B,UAAU,EAAE,MAAM,GAAG,SAAS,EAC9B,OAAO,EAAE,MAAM,GAAG,SAAS,GAC5B,MAAM,CAiBR;AAED,wBAAgB,eAAe,CAAC,QAAQ,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAiB9F;AAED,KAAK,sBAAsB,GAAG,MAAM,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAA;CAAE,CAAC;AACvF,KAAK,4BAA4B,GAC3B;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAA;CAAE,GAC5D,SAAS,CAAC;AAEhB,MAAM,WAAW,uBAAuB;IACpC;oDACgD;IAChD,YAAY,CAAC,EAAE,4BAA4B,CAAC;IAC5C;yDACqD;IACrD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,8EAA8E;IAC9E,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,MAAM,oBAAoB,GAAG,YAAY,GAAG,QAAQ,CAAC;AAE3D,MAAM,WAAW,sBAAsB;IACnC,yFAAyF;IACzF,UAAU,EAAE,MAAM,CAAC;IACnB,kGAAkG;IAClG,IAAI,EAAE,oBAAoB,CAAC;IAC3B,6FAA6F;IAC7F,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,sGAAsG;IACtG,UAAU,CAAC,EAAE,MAAM,CAAC;CACvB;AA8CD;;;;;;;GAOG;AACH,wBAAgB,6BAA6B,CACzC,MAAM,EAAE,sBAAsB,EAC9B,QAAQ,EAAE,MAAM,GAAG,SAAS,EAC5B,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,uBAAuB,GAClC,sBAAsB,CA+ExB;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CACnC,MAAM,EAAE,sBAAsB,EAC9B,QAAQ,EAAE,MAAM,GAAG,SAAS,EAC5B,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,uBAAuB,GAClC,MAAM,CAER;AA2BD,wBAAgB,eAAe,CAC3B,UAAU,EAAE,MAAM,GAAG,SAAS,EAC9B,OAAO,EAAE,MAAM,GAAG,SAAS,GAC5B,MAAM,GAAG,SAAS,CAMpB;AAED,wBAAgB,gBAAgB,CAC5B,UAAU,EAAE;IAAE,IAAI,CAAC,EAAE,OAAO,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,GAC/D,MAAM,GAAG,SAAS,CAmBpB"}
@@ -5,5 +5,8 @@ export declare function executeStatus(db: Database, sessionId: string, protected
5
5
  }, liveModelKey?: string, historyBudgetPercentage?: number, commitClusterTrigger?: {
6
6
  enabled: boolean;
7
7
  min_clusters: number;
8
- }): string;
8
+ }, executeThresholdTokens?: {
9
+ default?: number;
10
+ [modelKey: string]: number | undefined;
11
+ }, contextLimit?: number): string;
9
12
  //# sourceMappingURL=execute-status.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"execute-status.d.ts","sourceRoot":"","sources":["../../../src/hooks/magic-context/execute-status.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAyB3C,wBAAgB,aAAa,CACzB,EAAE,EAAE,QAAQ,EACZ,SAAS,EAAE,MAAM,EACjB,aAAa,EAAE,MAAM,EACrB,mBAAmB,GAAE,MAAsC,EAC3D,gCAAgC,GAC1B,MAAM,GACN;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAA;CAAyC,EAC5F,YAAY,CAAC,EAAE,MAAM,EACrB,uBAAuB,CAAC,EAAE,MAAM,EAChC,oBAAoB,CAAC,EAAE;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,GAClE,MAAM,CAiJR"}
1
+ {"version":3,"file":"execute-status.d.ts","sourceRoot":"","sources":["../../../src/hooks/magic-context/execute-status.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAyC3C,wBAAgB,aAAa,CACzB,EAAE,EAAE,QAAQ,EACZ,SAAS,EAAE,MAAM,EACjB,aAAa,EAAE,MAAM,EACrB,mBAAmB,GAAE,MAAsC,EAC3D,gCAAgC,GAC1B,MAAM,GACN;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAA;CAAyC,EAC5F,YAAY,CAAC,EAAE,MAAM,EACrB,uBAAuB,CAAC,EAAE,MAAM,EAChC,oBAAoB,CAAC,EAAE;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,EACjE,sBAAsB,CAAC,EAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAA;CAAE,EACrF,YAAY,CAAC,EAAE,MAAM,GACtB,MAAM,CA8JR"}
@@ -27,6 +27,10 @@ export interface MagicContextDeps {
27
27
  default: number;
28
28
  [modelKey: string]: number;
29
29
  };
30
+ execute_threshold_tokens?: {
31
+ default?: number;
32
+ [modelKey: string]: number | undefined;
33
+ };
30
34
  cache_ttl: string | Record<string, string>;
31
35
  historian?: z.infer<typeof AgentOverrideConfigSchema>;
32
36
  history_budget_percentage?: number;
@@ -1 +1 @@
1
- {"version":3,"file":"hook.d.ts","sourceRoot":"","sources":["../../../src/hooks/magic-context/hook.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAC7B,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,qCAAqC,CAAC;AACrF,OAAO,EAGH,KAAK,aAAa,EAClB,KAAK,cAAc,EACtB,MAAM,mCAAmC,CAAC;AAC3C,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,yCAAyC,CAAC;AAOvF,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wCAAwC,CAAC;AAMxE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qCAAqC,CAAC;AAElE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAYxD,YAAY,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAUnF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAQ7D,MAAM,WAAW,gBAAgB;IAC7B,MAAM,EAAE,aAAa,CAAC,QAAQ,CAAC,CAAC;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,SAAS,CAAC;IACrB,yBAAyB,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IACxD,iBAAiB,EAAE,UAAU,CAAC,OAAO,uBAAuB,CAAC,CAAC;IAC9D,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IACpC,MAAM,EAAE;QACJ,cAAc,EAAE,MAAM,CAAC;QACvB,kBAAkB,CAAC,EAAE,OAAO,CAAC;QAC7B,qBAAqB,CAAC,EAAE,MAAM,CAAC;QAC/B,kBAAkB,CAAC,EAAE,MAAM,CAAC;QAC5B,mBAAmB,CAAC,EAAE,OAAO,CAAC;QAC9B,mBAAmB,CAAC,EAAE,MAAM,CAAC;QAC7B,yBAAyB,CAAC,EAAE,MAAM,CAAC;QACnC,4BAA4B,CAAC,EAAE,MAAM,GAAG;YAAE,OAAO,EAAE,MAAM,CAAC;YAAC,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAA;SAAE,CAAC;QACxF,SAAS,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAE3C,SAAS,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAC;QACtD,yBAAyB,CAAC,EAAE,MAAM,CAAC;QACnC,oBAAoB,CAAC,EAAE,MAAM,CAAC;QAC9B,MAAM,CAAC,EAAE;YACL,OAAO,EAAE,OAAO,CAAC;YACjB,uBAAuB,EAAE,MAAM,CAAC;SACnC,CAAC;QACF,QAAQ,CAAC,EAAE,cAAc,CAAC;QAC1B,OAAO,CAAC,EAAE,aAAa,CAAC;QACxB,sBAAsB,CAAC,EAAE;YAAE,OAAO,EAAE,OAAO,CAAC;YAAC,YAAY,EAAE,MAAM,CAAA;SAAE,CAAC;QACpE,kBAAkB,CAAC,EAAE,OAAO,CAAC;QAC7B,YAAY,CAAC,EAAE;YACX,aAAa,CAAC,EAAE;gBAAE,OAAO,EAAE,OAAO,CAAC;gBAAC,mBAAmB,EAAE,MAAM,CAAA;aAAE,CAAC;YAClE,aAAa,CAAC,EAAE;gBAAE,OAAO,EAAE,OAAO,CAAC;gBAAC,YAAY,EAAE,MAAM,CAAC;gBAAC,SAAS,EAAE,MAAM,CAAA;aAAE,CAAC;SACjF,CAAC;KACL,CAAC;CACL;AAqCD,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,gBAAgB;;;;;iBA5CzB,CAAC;;;;;;;;;;;;iBAvBe,CAAC;eAC5C,CAAC;aAAe,CAAC;;mBAkWG;QAAE,KAAK,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,UAAU,CAAC,EAAE,OAAO,CAAA;SAAE,CAAA;KAAE;;;SAa7E"}
1
+ {"version":3,"file":"hook.d.ts","sourceRoot":"","sources":["../../../src/hooks/magic-context/hook.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"nudger.d.ts","sourceRoot":"","sources":["../../../src/hooks/magic-context/nudger.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,sBAAsB,EAGtB,aAAa,EAEhB,MAAM,sCAAsC,CAAC;AAC9C,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,oCAAoC,CAAC;AAY9F,KAAK,eAAe,GAAG,UAAU,CAAC,OAAO,sBAAsB,CAAC,CAAC,CAAC,CAAC,CAAC;AACpE,MAAM,MAAM,YAAY,GAAG;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAC/D,eAAO,MAAM,2BAA2B,QAAgB,CAAC;AA+BzD,wBAAgB,YAAY,CAAC,MAAM,EAAE;IACjC,cAAc,EAAE,MAAM,CAAC;IACvB,qBAAqB,EAAE,MAAM,CAAC;IAC9B,yBAAyB,EAAE,MAAM,CAAC;IAClC,4BAA4B,EAAE,MAAM,GAAG;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAC;IACvF,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB,qBAAqB,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC/C,IAIO,WAAW,MAAM,EACjB,cAAc,YAAY,EAC1B,IAAI,eAAe,EACnB,QAAQ,OAAO,aAAa,EAC5B,gBAAgB,QAAQ,EAAE,EAC1B,wBAAwB,MAAM,EAC9B,uBAAuB,WAAW,KACnC,YAAY,GAAG,IAAI,CAiIzB;AAyED,wBAAgB,0BAA0B,CACtC,EAAE,EAAE,eAAe,EACnB,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,YAAY,EAC1B,MAAM,EAAE;IAAE,cAAc,EAAE,MAAM,CAAA;CAAE,GACnC,MAAM,CA2BR"}
1
+ {"version":3,"file":"nudger.d.ts","sourceRoot":"","sources":["../../../src/hooks/magic-context/nudger.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,sBAAsB,EAGtB,aAAa,EAEhB,MAAM,sCAAsC,CAAC;AAC9C,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,oCAAoC,CAAC;AAY9F,KAAK,eAAe,GAAG,UAAU,CAAC,OAAO,sBAAsB,CAAC,CAAC,CAAC,CAAC,CAAC;AACpE,MAAM,MAAM,YAAY,GAAG;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAC/D,eAAO,MAAM,2BAA2B,QAAgB,CAAC;AA+BzD,wBAAgB,YAAY,CAAC,MAAM,EAAE;IACjC,cAAc,EAAE,MAAM,CAAC;IACvB,qBAAqB,EAAE,MAAM,CAAC;IAC9B,yBAAyB,EAAE,MAAM,CAAC;IAClC,4BAA4B,EAAE,MAAM,GAAG;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAC;IACvF,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB,qBAAqB,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC/C,IAIO,WAAW,MAAM,EACjB,cAAc,YAAY,EAC1B,IAAI,eAAe,EACnB,QAAQ,OAAO,aAAa,EAC5B,gBAAgB,QAAQ,EAAE,EAC1B,wBAAwB,MAAM,EAC9B,uBAAuB,WAAW,KACnC,YAAY,GAAG,IAAI,CAyIzB;AAyED,wBAAgB,0BAA0B,CACtC,EAAE,EAAE,eAAe,EACnB,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,YAAY,EAC1B,MAAM,EAAE;IAAE,cAAc,EAAE,MAAM,CAAA;CAAE,GACnC,MAAM,CA2BR"}
@@ -52,6 +52,10 @@ export interface TransformDeps {
52
52
  default: number;
53
53
  [modelKey: string]: number;
54
54
  };
55
+ executeThresholdTokens?: {
56
+ default?: number;
57
+ [modelKey: string]: number | undefined;
58
+ };
55
59
  historianTimeoutMs?: number;
56
60
  getNotificationParams?: (sessionId: string) => import("./send-session-notification").NotificationParams;
57
61
  getModelKey?: (sessionId: string) => string | undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"transform.d.ts","sourceRoot":"","sources":["../../../src/hooks/magic-context/transform.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"transform.d.ts","sourceRoot":"","sources":["../../../src/hooks/magic-context/transform.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -14148,9 +14148,12 @@ var init_magic_context = __esm(() => {
14148
14148
  cache_ttl: exports_external.union([exports_external.string(), exports_external.object({ default: exports_external.string() }).catchall(exports_external.string())]).default("5m"),
14149
14149
  nudge_interval_tokens: exports_external.number().min(1000).default(DEFAULT_NUDGE_INTERVAL_TOKENS),
14150
14150
  execute_threshold_percentage: exports_external.union([
14151
- exports_external.number().min(20).max(95),
14152
- exports_external.object({ default: exports_external.number().min(20).max(95) }).catchall(exports_external.number().min(20).max(95))
14151
+ exports_external.number().min(20).max(80),
14152
+ exports_external.object({ default: exports_external.number().min(20).max(80) }).catchall(exports_external.number().min(20).max(80))
14153
14153
  ]).default(DEFAULT_EXECUTE_THRESHOLD_PERCENTAGE),
14154
+ execute_threshold_tokens: exports_external.object({
14155
+ default: exports_external.number().min(5000).max(2000000).optional()
14156
+ }).catchall(exports_external.number().min(5000).max(2000000)).optional(),
14154
14157
  protected_tags: exports_external.number().min(1).max(100).optional(),
14155
14158
  auto_drop_tool_age: exports_external.number().min(10).default(100),
14156
14159
  drop_tool_structure: exports_external.boolean().default(true),
@@ -150985,6 +150988,15 @@ function getOpencodeConfigPath() {
150985
150988
  return json2;
150986
150989
  return null;
150987
150990
  }
150991
+ function resolveLimit(limit) {
150992
+ if (!limit)
150993
+ return;
150994
+ if (typeof limit.input === "number" && limit.input > 0)
150995
+ return limit.input;
150996
+ if (typeof limit.context === "number" && limit.context > 0)
150997
+ return limit.context;
150998
+ return;
150999
+ }
150988
151000
  function loadModelsDevLimitsFromFile() {
150989
151001
  const limits = new Map;
150990
151002
  const modelsJsonPath = getModelsJsonPath();
@@ -150998,13 +151010,13 @@ function loadModelsDevLimitsFromFile() {
150998
151010
  if (!provider2?.models || typeof provider2.models !== "object")
150999
151011
  continue;
151000
151012
  for (const [modelId, model] of Object.entries(provider2.models)) {
151001
- const context = model?.limit?.context;
151002
- if (typeof context === "number" && context > 0) {
151003
- limits.set(`${providerId}/${modelId}`, context);
151013
+ const effective = resolveLimit(model?.limit);
151014
+ if (typeof effective === "number" && effective > 0) {
151015
+ limits.set(`${providerId}/${modelId}`, effective);
151004
151016
  const modes = model?.experimental?.modes;
151005
151017
  if (modes && typeof modes === "object") {
151006
151018
  for (const mode of Object.keys(modes)) {
151007
- limits.set(`${providerId}/${modelId}-${mode}`, context);
151019
+ limits.set(`${providerId}/${modelId}-${mode}`, effective);
151008
151020
  }
151009
151021
  }
151010
151022
  }
@@ -151025,9 +151037,9 @@ function loadModelsDevLimitsFromFile() {
151025
151037
  if (!provider2?.models || typeof provider2.models !== "object")
151026
151038
  continue;
151027
151039
  for (const [modelId, model] of Object.entries(provider2.models)) {
151028
- const context = model?.limit?.context;
151029
- if (typeof context === "number" && context > 0) {
151030
- limits.set(`${providerId}/${modelId}`, context);
151040
+ const effective = resolveLimit(model?.limit);
151041
+ if (typeof effective === "number" && effective > 0) {
151042
+ limits.set(`${providerId}/${modelId}`, effective);
151031
151043
  }
151032
151044
  }
151033
151045
  }
@@ -151054,9 +151066,9 @@ async function refreshModelLimitsFromApi(client) {
151054
151066
  if (!p?.id || !p.models || typeof p.models !== "object")
151055
151067
  continue;
151056
151068
  for (const [modelId, model] of Object.entries(p.models)) {
151057
- const context = model?.limit?.context;
151058
- if (typeof context === "number" && context > 0) {
151059
- map2.set(`${p.id}/${modelId}`, context);
151069
+ const effective = resolveLimit(model?.limit);
151070
+ if (typeof effective === "number" && effective > 0) {
151071
+ map2.set(`${p.id}/${modelId}`, effective);
151060
151072
  }
151061
151073
  }
151062
151074
  }
@@ -163024,8 +163036,10 @@ function createCompactionHandler() {
163024
163036
  };
163025
163037
  }
163026
163038
  // src/hooks/magic-context/event-resolvers.ts
163039
+ init_logger();
163027
163040
  init_models_dev_cache();
163028
163041
  var DEFAULT_CONTEXT_LIMIT = 128000;
163042
+ var MAX_EXECUTE_THRESHOLD = 80;
163029
163043
  function resolveContextLimit(providerID, modelID) {
163030
163044
  if (!providerID) {
163031
163045
  return DEFAULT_CONTEXT_LIMIT;
@@ -163053,24 +163067,105 @@ function resolveCacheTtl(cacheTtl, modelKey) {
163053
163067
  }
163054
163068
  return cacheTtl.default ?? "5m";
163055
163069
  }
163056
- function resolveExecuteThreshold(config2, modelKey, fallback) {
163057
- const MAX_EXECUTE_THRESHOLD = 80;
163070
+ var clampWarnSeen = new Set;
163071
+ function isFinitePositive(v) {
163072
+ return typeof v === "number" && Number.isFinite(v) && v > 0;
163073
+ }
163074
+ function* modelKeyLookupOrder(modelKey) {
163075
+ const slash = modelKey.indexOf("/");
163076
+ const provider2 = slash >= 0 ? modelKey.slice(0, slash) : "";
163077
+ let modelId = slash >= 0 ? modelKey.slice(slash + 1) : modelKey;
163078
+ while (modelId.length > 0) {
163079
+ if (provider2)
163080
+ yield `${provider2}/${modelId}`;
163081
+ yield modelId;
163082
+ const lastDash = modelId.lastIndexOf("-");
163083
+ if (lastDash <= 0)
163084
+ break;
163085
+ modelId = modelId.slice(0, lastDash);
163086
+ }
163087
+ }
163088
+ function resolveExecuteThresholdDetail(config2, modelKey, fallback, options) {
163089
+ if (options?.tokensConfig && isFinitePositive(options.contextLimit)) {
163090
+ const contextLimit = options.contextLimit;
163091
+ const tokenMatch = resolveTokensMatchWithKey(options.tokensConfig, modelKey);
163092
+ if (tokenMatch && isFinitePositive(tokenMatch.value)) {
163093
+ const cap = contextLimit * (MAX_EXECUTE_THRESHOLD / 100);
163094
+ const effectiveTokens = Math.min(tokenMatch.value, cap);
163095
+ if (effectiveTokens < tokenMatch.value) {
163096
+ const dedupeKey = `${options.sessionId ?? "__global__"}|${modelKey ?? "__default__"}|${tokenMatch.value}|${cap}`;
163097
+ if (!clampWarnSeen.has(dedupeKey)) {
163098
+ clampWarnSeen.add(dedupeKey);
163099
+ const msg = `execute_threshold_tokens clamped: ${tokenMatch.value} \u2192 ${effectiveTokens} (80% of ${contextLimit}) for ${modelKey ?? "default"}`;
163100
+ if (options.sessionId) {
163101
+ sessionLog(options.sessionId, `WARN: ${msg}`);
163102
+ } else {
163103
+ log(`[magic-context] WARN: ${msg}`);
163104
+ }
163105
+ }
163106
+ }
163107
+ const percentage = effectiveTokens / contextLimit * 100;
163108
+ return {
163109
+ percentage: Math.min(percentage, MAX_EXECUTE_THRESHOLD),
163110
+ mode: "tokens",
163111
+ absoluteTokens: Math.floor(effectiveTokens),
163112
+ matchedKey: tokenMatch.matchedKey
163113
+ };
163114
+ }
163115
+ }
163058
163116
  let resolved;
163117
+ let matchedKey;
163059
163118
  if (typeof config2 === "number") {
163060
163119
  resolved = config2;
163061
- } else if (modelKey && typeof config2[modelKey] === "number") {
163062
- resolved = config2[modelKey];
163063
163120
  } else if (modelKey) {
163064
- const bareModelId = modelKey.split("/").slice(1).join("/");
163065
- if (bareModelId && typeof config2[bareModelId] === "number") {
163066
- resolved = config2[bareModelId];
163121
+ let matched;
163122
+ for (const candidate of modelKeyLookupOrder(modelKey)) {
163123
+ if (typeof config2[candidate] === "number") {
163124
+ matched = config2[candidate];
163125
+ matchedKey = candidate;
163126
+ break;
163127
+ }
163128
+ }
163129
+ if (matched === undefined && typeof config2.default === "number") {
163130
+ resolved = config2.default;
163131
+ matchedKey = "default";
163067
163132
  } else {
163068
- resolved = config2.default ?? fallback;
163133
+ resolved = matched ?? fallback;
163069
163134
  }
163135
+ } else if (typeof config2.default === "number") {
163136
+ resolved = config2.default;
163137
+ matchedKey = "default";
163070
163138
  } else {
163071
- resolved = config2.default ?? fallback;
163139
+ resolved = fallback;
163140
+ }
163141
+ if (!Number.isFinite(resolved) || resolved < 0) {
163142
+ resolved = fallback;
163072
163143
  }
163073
- return Math.min(resolved, MAX_EXECUTE_THRESHOLD);
163144
+ return {
163145
+ percentage: Math.min(resolved, MAX_EXECUTE_THRESHOLD),
163146
+ mode: "percentage",
163147
+ matchedKey
163148
+ };
163149
+ }
163150
+ function resolveExecuteThreshold(config2, modelKey, fallback, options) {
163151
+ return resolveExecuteThresholdDetail(config2, modelKey, fallback, options).percentage;
163152
+ }
163153
+ function resolveTokensMatchWithKey(tokensConfig, modelKey) {
163154
+ if (!tokensConfig) {
163155
+ return;
163156
+ }
163157
+ if (modelKey) {
163158
+ for (const candidate of modelKeyLookupOrder(modelKey)) {
163159
+ const value = tokensConfig[candidate];
163160
+ if (typeof value === "number") {
163161
+ return { value, matchedKey: candidate };
163162
+ }
163163
+ }
163164
+ }
163165
+ if (typeof tokensConfig.default === "number") {
163166
+ return { value: tokensConfig.default, matchedKey: "default" };
163167
+ }
163168
+ return;
163074
163169
  }
163075
163170
  function resolveModelKey(providerID, modelID) {
163076
163171
  if (!providerID || !modelID) {
@@ -163120,11 +163215,16 @@ function parseCacheTtl(ttl) {
163120
163215
  }
163121
163216
  function createScheduler(config2) {
163122
163217
  return {
163123
- shouldExecute(sessionMeta, contextUsage, currentTime = Date.now(), sessionId, modelKey) {
163218
+ shouldExecute(sessionMeta, contextUsage, currentTime = Date.now(), sessionId, modelKey, contextLimit) {
163124
163219
  if (contextUsage.percentage === 0 && sessionMeta.lastResponseTime === 0) {
163125
163220
  return "defer";
163126
163221
  }
163127
- const threshold = resolveExecuteThreshold(config2.executeThresholdPercentage, modelKey, 65);
163222
+ const effectiveContextLimit = contextLimit ?? (contextUsage.percentage > 0 && contextUsage.inputTokens > 0 ? contextUsage.inputTokens / (contextUsage.percentage / 100) : undefined);
163223
+ const threshold = resolveExecuteThreshold(config2.executeThresholdPercentage, modelKey, 65, {
163224
+ tokensConfig: config2.executeThresholdTokens,
163225
+ contextLimit: effectiveContextLimit,
163226
+ sessionId
163227
+ });
163128
163228
  if (contextUsage.percentage >= threshold) {
163129
163229
  return "execute";
163130
163230
  }
@@ -163513,8 +163613,25 @@ function getRollingNudgeIntervalTokens(baseIntervalTokens, band) {
163513
163613
 
163514
163614
  // src/hooks/magic-context/execute-status.ts
163515
163615
  init_read_session_formatting();
163516
- function executeStatus(db, sessionId, protectedTags, nudgeIntervalTokens = DEFAULT_NUDGE_INTERVAL_TOKENS, executeThresholdPercentageConfig = DEFAULT_EXECUTE_THRESHOLD_PERCENTAGE, liveModelKey, historyBudgetPercentage, commitClusterTrigger) {
163517
- const executeThresholdPercentage = resolveExecuteThreshold(executeThresholdPercentageConfig, liveModelKey, DEFAULT_EXECUTE_THRESHOLD_PERCENTAGE);
163616
+ function formatExecuteThreshold(thresholdPercentage, mode, contextLimit) {
163617
+ if (mode === "tokens" && contextLimit > 0) {
163618
+ const tokens = Math.floor(thresholdPercentage / 100 * contextLimit);
163619
+ return `${tokens.toLocaleString()} tokens (${thresholdPercentage.toFixed(1)}% of ${contextLimit.toLocaleString()}) [token-mode]`;
163620
+ }
163621
+ if (contextLimit > 0) {
163622
+ const tokens = Math.floor(thresholdPercentage / 100 * contextLimit);
163623
+ return `${thresholdPercentage}% (${tokens.toLocaleString()} of ${contextLimit.toLocaleString()})`;
163624
+ }
163625
+ return `${thresholdPercentage}%`;
163626
+ }
163627
+ function executeStatus(db, sessionId, protectedTags, nudgeIntervalTokens = DEFAULT_NUDGE_INTERVAL_TOKENS, executeThresholdPercentageConfig = DEFAULT_EXECUTE_THRESHOLD_PERCENTAGE, liveModelKey, historyBudgetPercentage, commitClusterTrigger, executeThresholdTokens, contextLimit) {
163628
+ const thresholdDetail = resolveExecuteThresholdDetail(executeThresholdPercentageConfig, liveModelKey, DEFAULT_EXECUTE_THRESHOLD_PERCENTAGE, {
163629
+ tokensConfig: executeThresholdTokens,
163630
+ contextLimit,
163631
+ sessionId
163632
+ });
163633
+ const executeThresholdPercentage = thresholdDetail.percentage;
163634
+ const thresholdMode = thresholdDetail.mode;
163518
163635
  try {
163519
163636
  const meta3 = getOrCreateSessionMeta(db, sessionId);
163520
163637
  const tags = getTagsBySession(db, sessionId);
@@ -163535,6 +163652,7 @@ function executeStatus(db, sessionId, protectedTags, nudgeIntervalTokens = DEFAU
163535
163652
  const currentBand = getRollingNudgeBand(meta3.lastContextPercentage, executeThresholdPercentage);
163536
163653
  const nudgeInterval = getRollingNudgeIntervalTokens(nudgeIntervalTokens, currentBand);
163537
163654
  const proactiveCompartmentTrigger = getProactiveCompartmentTriggerPercentage(executeThresholdPercentage);
163655
+ const displayContextLimit = contextLimit && contextLimit > 0 ? contextLimit : meta3.lastContextPercentage > 0 ? Math.round(meta3.lastInputTokens / (meta3.lastContextPercentage / 100)) : 0;
163538
163656
  const lines = [
163539
163657
  "## Magic Status",
163540
163658
  "",
@@ -163558,7 +163676,7 @@ function executeStatus(db, sessionId, protectedTags, nudgeIntervalTokens = DEFAU
163558
163676
  `- Queue will auto-execute: ${cacheExpired ? "yes (cache expired)" : `when TTL expires or context >= ${executeThresholdPercentage}%`}`,
163559
163677
  "",
163560
163678
  "### Rolling Nudges",
163561
- `- Execute threshold: ${executeThresholdPercentage}%`,
163679
+ `- Execute threshold: ${formatExecuteThreshold(executeThresholdPercentage, thresholdMode, displayContextLimit)}`,
163562
163680
  `- Rolling anchor: ${meta3.lastNudgeTokens.toLocaleString()} tokens`,
163563
163681
  `- Effective interval: ${nudgeInterval.toLocaleString()} tokens`,
163564
163682
  `- Next rolling nudge after: ${(meta3.lastNudgeTokens + nudgeInterval).toLocaleString()} tokens`,
@@ -163569,9 +163687,8 @@ function executeStatus(db, sessionId, protectedTags, nudgeIntervalTokens = DEFAU
163569
163687
  `**Protected tags:** ${protectedTags}`,
163570
163688
  `**Subagent session:** ${meta3.isSubagent}`
163571
163689
  ];
163572
- const contextLimit = meta3.lastContextPercentage > 0 ? Math.round(meta3.lastInputTokens / (meta3.lastContextPercentage / 100)) : 0;
163573
163690
  if (meta3.lastContextPercentage > 0 || meta3.lastInputTokens > 0) {
163574
- lines.push("", "### Context Usage", `- Last percentage: ${meta3.lastContextPercentage.toFixed(1)}%`, `- Last input tokens: ${meta3.lastInputTokens.toLocaleString()}`, `- Resolved context limit: ${contextLimit > 0 ? contextLimit.toLocaleString() : "unknown"}`, `- Proactive compartment evaluation: ${proactiveCompartmentTrigger}%`, `- Post-drop target for historian: ${(executeThresholdPercentage * POST_DROP_TARGET_RATIO).toFixed(0)}% (${executeThresholdPercentage}% * ${POST_DROP_TARGET_RATIO})`, `- Commit cluster trigger: ${commitClusterTrigger?.enabled !== false ? `enabled (min ${commitClusterTrigger?.min_clusters ?? 3} clusters)` : "disabled"}, tail-size trigger: > 3x compartment budget`);
163691
+ lines.push("", "### Context Usage", `- Last percentage: ${meta3.lastContextPercentage.toFixed(1)}%`, `- Last input tokens: ${meta3.lastInputTokens.toLocaleString()}`, `- Resolved context limit: ${displayContextLimit > 0 ? displayContextLimit.toLocaleString() : "unknown"}`, `- Proactive compartment evaluation: ${proactiveCompartmentTrigger}%`, `- Post-drop target for historian: ${(executeThresholdPercentage * POST_DROP_TARGET_RATIO).toFixed(0)}% (${executeThresholdPercentage}% * ${POST_DROP_TARGET_RATIO})`, `- Commit cluster trigger: ${commitClusterTrigger?.enabled !== false ? `enabled (min ${commitClusterTrigger?.min_clusters ?? 3} clusters)` : "disabled"}, tail-size trigger: > 3x compartment budget`);
163575
163692
  }
163576
163693
  const compartments = getCompartments(db, sessionId);
163577
163694
  const facts = getSessionFacts(db, sessionId);
@@ -163586,7 +163703,7 @@ ${c.content}
163586
163703
  historyBlockTokens += estimateTokens(`* ${f.content}
163587
163704
  `);
163588
163705
  }
163589
- const budgetTokens = historyBudgetPercentage && contextLimit > 0 ? Math.floor(contextLimit * (Math.min(executeThresholdPercentage, 80) / 100) * historyBudgetPercentage) : null;
163706
+ const budgetTokens = historyBudgetPercentage && displayContextLimit > 0 ? Math.floor(displayContextLimit * (Math.min(executeThresholdPercentage, 80) / 100) * historyBudgetPercentage) : null;
163590
163707
  const budgetUsage = budgetTokens ? (historyBlockTokens / budgetTokens * 100).toFixed(0) : null;
163591
163708
  lines.push("", "### History Compression", `- Compartments: ${compartments.length}`, `- Facts: ${facts.length}`, `- History block: ~${historyBlockTokens.toLocaleString()} tokens`, ...budgetTokens ? [
163592
163709
  `- Compression budget: ~${budgetTokens.toLocaleString()} tokens (${budgetUsage}% used)`,
@@ -163732,7 +163849,8 @@ function createMagicContextCommandHandler(deps) {
163732
163849
  throwSentinel(input.command);
163733
163850
  }
163734
163851
  const liveModelKey = deps.getLiveModelKey?.(sessionId);
163735
- const statusOutput = executeStatus(deps.db, sessionId, deps.protectedTags, deps.nudgeIntervalTokens, deps.executeThresholdPercentage, liveModelKey, deps.historyBudgetPercentage, deps.commitClusterTrigger);
163852
+ const liveContextLimit = deps.getContextLimit?.(sessionId);
163853
+ const statusOutput = executeStatus(deps.db, sessionId, deps.protectedTags, deps.nudgeIntervalTokens, deps.executeThresholdPercentage, liveModelKey, deps.historyBudgetPercentage, deps.commitClusterTrigger, deps.executeThresholdTokens, liveContextLimit);
163736
163854
  result += result ? `
163737
163855
 
163738
163856
  ${statusOutput}` : statusOutput;
@@ -166020,7 +166138,9 @@ function createTransform(deps) {
166020
166138
  const lastAssistantModel = findLastAssistantModel(messages);
166021
166139
  if (lastAssistantModel) {
166022
166140
  const knownModel = deps.liveModelBySession.get(sessionId);
166023
- if (knownModel && (knownModel.providerID !== lastAssistantModel.providerID || knownModel.modelID !== lastAssistantModel.modelID)) {
166141
+ if (!knownModel) {
166142
+ deps.liveModelBySession.set(sessionId, lastAssistantModel);
166143
+ } else if (knownModel.providerID !== lastAssistantModel.providerID || knownModel.modelID !== lastAssistantModel.modelID) {
166024
166144
  sessionLog(sessionId, `transform: model change detected (${knownModel.providerID}/${knownModel.modelID} -> ${lastAssistantModel.providerID}/${lastAssistantModel.modelID}), clearing stale context state`);
166025
166145
  deps.liveModelBySession.set(sessionId, lastAssistantModel);
166026
166146
  updateSessionMeta(db, sessionId, {
@@ -166051,7 +166171,7 @@ function createTransform(deps) {
166051
166171
  }
166052
166172
  }
166053
166173
  const contextUsageEarly = loadContextUsage(deps.contextUsageMap, db, sessionId);
166054
- const historyBudgetTokens = resolveHistoryBudgetTokens(deps.historyBudgetPercentage, contextUsageEarly, deps.executeThresholdPercentage, deps.getModelKey?.(sessionId));
166174
+ const historyBudgetTokens = resolveHistoryBudgetTokens(deps.historyBudgetPercentage, contextUsageEarly, deps.executeThresholdPercentage, deps.getModelKey?.(sessionId), deps.executeThresholdTokens);
166055
166175
  const schedulerDecisionEarly = resolveSchedulerDecision(deps.scheduler, sessionMeta, contextUsageEarly, sessionId, deps.getModelKey?.(sessionId));
166056
166176
  const isCacheBusting = deps.flushedSessions.has(sessionId);
166057
166177
  if (historianFailureState.failureCount === 0) {
@@ -166388,11 +166508,15 @@ function hasEligibleCompartmentHistory(db, sessionId) {
166388
166508
  return false;
166389
166509
  }
166390
166510
  }
166391
- function resolveHistoryBudgetTokens(historyBudgetPercentage, contextUsage, executeThresholdPercentage, modelKey) {
166511
+ function resolveHistoryBudgetTokens(historyBudgetPercentage, contextUsage, executeThresholdPercentage, modelKey, executeThresholdTokens) {
166392
166512
  if (!historyBudgetPercentage || contextUsage.percentage <= 0) {
166393
166513
  return;
166394
166514
  }
166395
- return Math.floor(contextUsage.inputTokens / (contextUsage.percentage / 100) * (resolveExecuteThreshold(executeThresholdPercentage ?? 65, modelKey, 65) / 100) * historyBudgetPercentage);
166515
+ const derivedContextLimit = contextUsage.inputTokens / (contextUsage.percentage / 100);
166516
+ return Math.floor(derivedContextLimit * (resolveExecuteThreshold(executeThresholdPercentage ?? 65, modelKey, 65, {
166517
+ tokensConfig: executeThresholdTokens,
166518
+ contextLimit: derivedContextLimit
166519
+ }) / 100) * historyBudgetPercentage);
166396
166520
  }
166397
166521
  function truncateHistorianEmergencyError(error48) {
166398
166522
  const normalized = (error48 ?? "unknown error").replace(/\s+/g, " ").trim();
@@ -166533,7 +166657,11 @@ function createEventHandler2(deps) {
166533
166657
  const sessionMeta = getOrCreateSessionMeta(deps.db, info.sessionID);
166534
166658
  const previousPercentage = sessionMeta.lastContextPercentage;
166535
166659
  if (!sessionMeta.isSubagent) {
166536
- const effectiveExecuteThreshold = resolveExecuteThreshold(deps.config.execute_threshold_percentage ?? 65, modelKey, 65);
166660
+ const effectiveExecuteThreshold = resolveExecuteThreshold(deps.config.execute_threshold_percentage ?? 65, modelKey, 65, {
166661
+ tokensConfig: deps.config.execute_threshold_tokens,
166662
+ contextLimit,
166663
+ sessionId: info.sessionID
166664
+ });
166537
166665
  const triggerBudget = deriveTriggerBudget(contextLimit, effectiveExecuteThreshold);
166538
166666
  const triggerResult = checkCompartmentTrigger(deps.db, info.sessionID, sessionMeta, { percentage, inputTokens: totalInputTokens }, previousPercentage, effectiveExecuteThreshold, triggerBudget, deps.config.auto_drop_tool_age ?? 100, deps.config.protected_tags, deps.config.clear_reasoning_age ?? 50, deps.config.drop_tool_structure ?? true, deps.config.commit_cluster_trigger);
166539
166667
  if (triggerResult.shouldFire) {
@@ -167479,6 +167607,7 @@ function createMagicContextHook(deps) {
167479
167607
  getHistorianChunkTokens,
167480
167608
  historyBudgetPercentage: deps.config.history_budget_percentage,
167481
167609
  executeThresholdPercentage: deps.config.execute_threshold_percentage,
167610
+ executeThresholdTokens: deps.config.execute_threshold_tokens,
167482
167611
  historianTimeoutMs: deps.config.historian_timeout_ms ?? DEFAULT_HISTORIAN_TIMEOUT_MS,
167483
167612
  getNotificationParams: (sessionId) => getLiveNotificationParams(sessionId, liveModelBySession, variantBySession, agentBySession),
167484
167613
  getModelKey: (sessionId) => {
@@ -167546,12 +167675,19 @@ function createMagicContextHook(deps) {
167546
167675
  protectedTags: deps.config.protected_tags,
167547
167676
  nudgeIntervalTokens: deps.config.nudge_interval_tokens ?? DEFAULT_NUDGE_INTERVAL_TOKENS,
167548
167677
  executeThresholdPercentage: deps.config.execute_threshold_percentage ?? 65,
167678
+ executeThresholdTokens: deps.config.execute_threshold_tokens,
167549
167679
  historyBudgetPercentage: deps.config.history_budget_percentage,
167550
167680
  commitClusterTrigger: deps.config.commit_cluster_trigger,
167551
167681
  getLiveModelKey: (sessionId) => {
167552
167682
  const model = liveModelBySession.get(sessionId);
167553
167683
  return model ? `${model.providerID}/${model.modelID}` : undefined;
167554
167684
  },
167685
+ getContextLimit: (sessionId) => {
167686
+ const model = liveModelBySession.get(sessionId);
167687
+ if (!model)
167688
+ return;
167689
+ return resolveContextLimit(model.providerID, model.modelID);
167690
+ },
167555
167691
  onFlush: (sessionId) => flushedSessions.add(sessionId),
167556
167692
  executeRecomp: async (sessionId) => executeContextRecomp({
167557
167693
  client: deps.client,
@@ -167662,7 +167798,8 @@ function createSessionHooks(args) {
167662
167798
  }
167663
167799
  const tagger = createTagger();
167664
167800
  const scheduler2 = createScheduler({
167665
- executeThresholdPercentage: pluginConfig.execute_threshold_percentage ?? DEFAULT_EXECUTE_THRESHOLD_PERCENTAGE
167801
+ executeThresholdPercentage: pluginConfig.execute_threshold_percentage ?? DEFAULT_EXECUTE_THRESHOLD_PERCENTAGE,
167802
+ executeThresholdTokens: pluginConfig.execute_threshold_tokens
167666
167803
  });
167667
167804
  const compactionHandler = createCompactionHandler();
167668
167805
  return {
@@ -167683,6 +167820,7 @@ function createSessionHooks(args) {
167683
167820
  clear_reasoning_age: pluginConfig.clear_reasoning_age,
167684
167821
  iteration_nudge_threshold: pluginConfig.iteration_nudge_threshold,
167685
167822
  execute_threshold_percentage: pluginConfig.execute_threshold_percentage ?? DEFAULT_EXECUTE_THRESHOLD_PERCENTAGE,
167823
+ execute_threshold_tokens: pluginConfig.execute_threshold_tokens,
167686
167824
  historian: pluginConfig.historian,
167687
167825
  history_budget_percentage: pluginConfig.history_budget_percentage,
167688
167826
  historian_timeout_ms: pluginConfig.historian_timeout_ms,
@@ -167944,6 +168082,7 @@ function buildStatusDetail(db, sessionId, directory, modelKey, config2) {
167944
168082
  cacheRemainingMs: 0,
167945
168083
  cacheExpired: false,
167946
168084
  executeThreshold: 65,
168085
+ executeThresholdMode: "percentage",
167947
168086
  protectedTagCount: 20,
167948
168087
  nudgeInterval: 20000,
167949
168088
  historyBudgetPercentage: 0.15,
@@ -167974,9 +168113,20 @@ function buildStatusDetail(db, sessionId, directory, modelKey, config2) {
167974
168113
  const ops = db.query("SELECT tag_id, operation FROM pending_ops WHERE session_id = ?").all(sessionId);
167975
168114
  detail.pendingOps = ops.map((o) => ({ tagId: o.tag_id, operation: o.operation }));
167976
168115
  } catch {}
168116
+ const contextLimitForTokens = base.usagePercentage > 0 ? Math.round(base.inputTokens / (base.usagePercentage / 100)) : 0;
167977
168117
  if (config2) {
167978
- const etp = resolveConfigValue(config2, "execute_threshold_percentage", modelKey, 65);
167979
- detail.executeThreshold = Math.min(etp, 80);
168118
+ const pctCfg = config2.execute_threshold_percentage;
168119
+ const tokensCfg = config2.execute_threshold_tokens;
168120
+ const thresholdDetail = resolveExecuteThresholdDetail(pctCfg ?? 65, modelKey, 65, {
168121
+ tokensConfig: tokensCfg,
168122
+ contextLimit: contextLimitForTokens || undefined,
168123
+ sessionId
168124
+ });
168125
+ detail.executeThreshold = thresholdDetail.percentage;
168126
+ detail.executeThresholdMode = thresholdDetail.mode;
168127
+ if (thresholdDetail.absoluteTokens !== undefined) {
168128
+ detail.executeThresholdTokens = thresholdDetail.absoluteTokens;
168129
+ }
167980
168130
  const ct = resolveConfigValue(config2, "cache_ttl", modelKey, "5m");
167981
168131
  detail.cacheTtl = ct;
167982
168132
  if (typeof config2.protected_tag_count === "number") {
@@ -1 +1 @@
1
- {"version":3,"file":"create-session-hooks.d.ts","sourceRoot":"","sources":["../../../src/plugin/hooks/create-session-hooks.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,cAAc,CAAC;AAU7D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,8CAA8C,CAAC;AACrF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAE9C,wBAAgB,kBAAkB,CAAC,IAAI,EAAE;IACrC,GAAG,EAAE,aAAa,CAAC;IACnB,YAAY,EAAE,wBAAwB,CAAC;IACvC,gBAAgB,EAAE,gBAAgB,CAAC;CACtC;;;;;;qBA8C8sB,CAAC;;;;;;;;;;;;qBAPhsB,CAAX;mBAAiB,CAAC;iBAAe,CAAC;;;;;0BAO60b,CAAC;;;;;;EADp3b"}
1
+ {"version":3,"file":"create-session-hooks.d.ts","sourceRoot":"","sources":["../../../src/plugin/hooks/create-session-hooks.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,cAAc,CAAC;AAU7D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,8CAA8C,CAAC;AACrF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAE9C,wBAAgB,kBAAkB,CAAC,IAAI,EAAE;IACrC,GAAG,EAAE,aAAa,CAAC;IACnB,YAAY,EAAE,wBAAwB,CAAC;IACvC,gBAAgB,EAAE,gBAAgB,CAAC;CACtC;;;;;;qBAgDsjB,CAAC;;;;;;;;;;;;qBAVngB,CAAC;mBAAiB,CAAC;iBACxD,CAAX;;;;;0BAS8rc,CAAC;;;;;;EADnsc"}
@@ -1 +1 @@
1
- {"version":3,"file":"rpc-handlers.d.ts","sourceRoot":"","sources":["../../src/plugin/rpc-handlers.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AAIzE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2CAA2C,CAAC;AAIlF,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAkblE;;GAEG;AACH,wBAAgB,mBAAmB,CAC/B,SAAS,EAAE,qBAAqB,EAChC,IAAI,EAAE;IACF,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,kBAAkB,CAAC;IAC3B,MAAM,EAAE,OAAO,CAAC;IAChB,gBAAgB,EAAE,gBAAgB,CAAC;CACtC,GACF,IAAI,CAqGN"}
1
+ {"version":3,"file":"rpc-handlers.d.ts","sourceRoot":"","sources":["../../src/plugin/rpc-handlers.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AAKzE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2CAA2C,CAAC;AAIlF,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAsclE;;GAEG;AACH,wBAAgB,mBAAmB,CAC/B,SAAS,EAAE,qBAAqB,EAChC,IAAI,EAAE;IACF,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,kBAAkB,CAAC;IAC3B,MAAM,EAAE,OAAO,CAAC;IAChB,gBAAgB,EAAE,gBAAgB,CAAC;CACtC,GACF,IAAI,CAqGN"}
@@ -1 +1 @@
1
- {"version":3,"file":"models-dev-cache.d.ts","sourceRoot":"","sources":["../../src/shared/models-dev-cache.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAMH,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAG7D,KAAK,cAAc,GAAG,UAAU,CAAC,OAAO,oBAAoB,CAAC,CAAC;AA2J9D;;;;;;;;;;GAUG;AACH,wBAAsB,yBAAyB,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAmCrF;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,wBAAwB,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAchG;AAED,4CAA4C;AAC5C,wBAAgB,mBAAmB,IAAI,IAAI,CAK1C;AAED,oDAAoD;AACpD,wBAAgB,sBAAsB,IAAI;IACtC,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACrB,CAOA"}
1
+ {"version":3,"file":"models-dev-cache.d.ts","sourceRoot":"","sources":["../../src/shared/models-dev-cache.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAMH,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAG7D,KAAK,cAAc,GAAG,UAAU,CAAC,OAAO,oBAAoB,CAAC,CAAC;AA+K9D;;;;;;;;;;GAUG;AACH,wBAAsB,yBAAyB,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAmCrF;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,wBAAwB,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAchG;AAED,4CAA4C;AAC5C,wBAAgB,mBAAmB,IAAI,IAAI,CAK1C;AAED,oDAAoD;AACpD,wBAAgB,sBAAsB,IAAI;IACtC,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACrB,CAOA"}
@@ -63,6 +63,17 @@ export interface StatusDetail extends SidebarSnapshot {
63
63
  cacheRemainingMs: number;
64
64
  cacheExpired: boolean;
65
65
  executeThreshold: number;
66
+ /**
67
+ * Which config source produced `executeThreshold`. "tokens" means
68
+ * execute_threshold_tokens matched for this session's model and was
69
+ * converted to a percentage. "percentage" means percentage config was used.
70
+ */
71
+ executeThresholdMode: "percentage" | "tokens";
72
+ /**
73
+ * When `executeThresholdMode === "tokens"`, the absolute clamped token value
74
+ * (≤ 80% × contextLimit) that will trigger execute. Undefined in percentage mode.
75
+ */
76
+ executeThresholdTokens?: number;
66
77
  protectedTagCount: number;
67
78
  nudgeInterval: number;
68
79
  historyBudgetPercentage: number;
@@ -1 +1 @@
1
- {"version":3,"file":"rpc-types.d.ts","sourceRoot":"","sources":["../../src/shared/rpc-types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,eAAe;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,gBAAgB,EAAE,MAAM,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,gBAAgB,EAAE,MAAM,CAAC;IACzB,eAAe,EAAE,MAAM,CAAC;IACxB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,qBAAqB,EAAE,OAAO,CAAC;IAC/B,gBAAgB,EAAE,MAAM,CAAC;IACzB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,kBAAkB,EAAE,MAAM,CAAC;IAC3B;;;;OAIG;IACH,cAAc,EAAE,MAAM,CAAC;IACvB;;;;;;OAMG;IACH,oBAAoB,EAAE,MAAM,CAAC;CAChC;AAED,MAAM,WAAW,YAAa,SAAQ,eAAe;IACjD,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,gBAAgB,EAAE,MAAM,CAAC;IACzB,eAAe,EAAE,MAAM,CAAC;IACxB,aAAa,EAAE,MAAM,CAAC;IACtB,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,UAAU,EAAE,OAAO,CAAC;IACpB,UAAU,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACxD,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,gBAAgB,EAAE,MAAM,CAAC;IACzB,YAAY,EAAE,OAAO,CAAC;IACtB,gBAAgB,EAAE,MAAM,CAAC;IACzB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,aAAa,EAAE,MAAM,CAAC;IACtB,uBAAuB,EAAE,MAAM,CAAC;IAChC,cAAc,EAAE,MAAM,CAAC;IACvB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;CACnC;AAED,MAAM,WAAW,sBAAsB;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB"}
1
+ {"version":3,"file":"rpc-types.d.ts","sourceRoot":"","sources":["../../src/shared/rpc-types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,eAAe;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,gBAAgB,EAAE,MAAM,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,gBAAgB,EAAE,MAAM,CAAC;IACzB,eAAe,EAAE,MAAM,CAAC;IACxB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,qBAAqB,EAAE,OAAO,CAAC;IAC/B,gBAAgB,EAAE,MAAM,CAAC;IACzB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,kBAAkB,EAAE,MAAM,CAAC;IAC3B;;;;OAIG;IACH,cAAc,EAAE,MAAM,CAAC;IACvB;;;;;;OAMG;IACH,oBAAoB,EAAE,MAAM,CAAC;CAChC;AAED,MAAM,WAAW,YAAa,SAAQ,eAAe;IACjD,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,gBAAgB,EAAE,MAAM,CAAC;IACzB,eAAe,EAAE,MAAM,CAAC;IACxB,aAAa,EAAE,MAAM,CAAC;IACtB,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,UAAU,EAAE,OAAO,CAAC;IACpB,UAAU,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACxD,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,gBAAgB,EAAE,MAAM,CAAC;IACzB,YAAY,EAAE,OAAO,CAAC;IACtB,gBAAgB,EAAE,MAAM,CAAC;IACzB;;;;OAIG;IACH,oBAAoB,EAAE,YAAY,GAAG,QAAQ,CAAC;IAC9C;;;OAGG;IACH,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,iBAAiB,EAAE,MAAM,CAAC;IAC1B,aAAa,EAAE,MAAM,CAAC;IACtB,uBAAuB,EAAE,MAAM,CAAC;IAChC,cAAc,EAAE,MAAM,CAAC;IACvB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;CACnC;AAED,MAAM,WAAW,sBAAsB;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB"}
@@ -1 +1 @@
1
- {"version":3,"file":"context-db.d.ts","sourceRoot":"","sources":["../../../src/tui/data/context-db.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAA0B,eAAe,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAEpG,YAAY,EAAE,eAAe,EAAE,YAAY,EAAE,CAAC;AAS9C,2DAA2D;AAC3D,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAGrD;AAED,+BAA+B;AAC/B,wBAAgB,QAAQ,IAAI,IAAI,CAG/B;AA2BD,sDAAsD;AACtD,wBAAsB,mBAAmB,CACrC,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,GAClB,OAAO,CAAC,eAAe,CAAC,CAc1B;AAED,wDAAwD;AACxD,wBAAsB,gBAAgB,CAClC,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,QAAQ,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,YAAY,CAAC,CA2CvB;AAED,qCAAqC;AACrC,wBAAsB,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAQ5E;AAED,6CAA6C;AAC7C,wBAAsB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAQvE;AAED,MAAM,WAAW,UAAU;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,yDAAyD;AACzD,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC,CAchE"}
1
+ {"version":3,"file":"context-db.d.ts","sourceRoot":"","sources":["../../../src/tui/data/context-db.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAA0B,eAAe,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAEpG,YAAY,EAAE,eAAe,EAAE,YAAY,EAAE,CAAC;AAS9C,2DAA2D;AAC3D,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAGrD;AAED,+BAA+B;AAC/B,wBAAgB,QAAQ,IAAI,IAAI,CAG/B;AA2BD,sDAAsD;AACtD,wBAAsB,mBAAmB,CACrC,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,GAClB,OAAO,CAAC,eAAe,CAAC,CAc1B;AAED,wDAAwD;AACxD,wBAAsB,gBAAgB,CAClC,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,QAAQ,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,YAAY,CAAC,CA4CvB;AAED,qCAAqC;AACrC,wBAAsB,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAQ5E;AAED,6CAA6C;AAC7C,wBAAsB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAQvE;AAED,MAAM,WAAW,UAAU;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,yDAAyD;AACzD,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC,CAchE"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cortexkit/opencode-magic-context",
3
- "version": "0.11.0",
3
+ "version": "0.12.0",
4
4
  "type": "module",
5
5
  "description": "OpenCode plugin for Magic Context — cross-session memory and context management",
6
6
  "main": "dist/index.js",
@@ -19,11 +19,17 @@ describe("models-dev-cache", () => {
19
19
  OPENCODE_MODELS_PATH: process.env.OPENCODE_MODELS_PATH,
20
20
  OPENCODE_MODELS_URL: process.env.OPENCODE_MODELS_URL,
21
21
  XDG_CACHE_HOME: process.env.XDG_CACHE_HOME,
22
+ OPENCODE_CONFIG_DIR: process.env.OPENCODE_CONFIG_DIR,
22
23
  };
23
- // Isolate from user environment.
24
+ // Isolate from user environment — including user's ~/.config/opencode/opencode.jsonc
25
+ // which may have custom provider limits that would override models.json entries.
24
26
  delete process.env.OPENCODE_MODELS_PATH;
25
27
  delete process.env.OPENCODE_MODELS_URL;
26
28
  process.env.XDG_CACHE_HOME = tempDir;
29
+ // Point at an empty directory so no opencode.json{c} is read unless the test writes one.
30
+ const emptyConfigDir = join(tempDir, "config", "opencode");
31
+ mkdirSync(emptyConfigDir, { recursive: true });
32
+ process.env.OPENCODE_CONFIG_DIR = emptyConfigDir;
27
33
  clearModelsDevCache();
28
34
  });
29
35
 
@@ -61,6 +67,113 @@ describe("models-dev-cache", () => {
61
67
  expect(getModelsDevContextLimit("unknown", "unknown")).toBeUndefined();
62
68
  });
63
69
 
70
+ test("prefers limit.input over limit.context when both are present", () => {
71
+ //#given — GitHub Copilot shape: input is max prompt, context is total window.
72
+ // Matches real-world github-copilot/gpt-5.3-codex which has
73
+ // limit.context = 400000 (total), limit.input = 272000 (max prompt).
74
+ // Our pressure math must use the input cap; sending a 400K prompt gets rejected.
75
+ // OpenCode's own session/overflow.ts follows the same rule.
76
+ const opencodeDir = join(tempDir, "opencode");
77
+ mkdirSync(opencodeDir, { recursive: true });
78
+ writeFileSync(
79
+ join(opencodeDir, "models.json"),
80
+ JSON.stringify({
81
+ "github-copilot": {
82
+ models: {
83
+ "gpt-5.3-codex": { limit: { context: 400000, input: 272000 } },
84
+ "claude-opus-4.6": { limit: { context: 144000, input: 128000 } },
85
+ // Context-only model (no input) falls back to context.
86
+ "legacy-only-context": { limit: { context: 100000 } },
87
+ },
88
+ },
89
+ }),
90
+ );
91
+
92
+ //#then
93
+ expect(getModelsDevContextLimit("github-copilot", "gpt-5.3-codex")).toBe(272000);
94
+ expect(getModelsDevContextLimit("github-copilot", "claude-opus-4.6")).toBe(128000);
95
+ expect(getModelsDevContextLimit("github-copilot", "legacy-only-context")).toBe(100000);
96
+ });
97
+
98
+ test("derived experimental.modes inherit the effective (input) limit", () => {
99
+ //#given — parent has input < context; derived modes should inherit input, not context
100
+ const opencodeDir = join(tempDir, "opencode");
101
+ mkdirSync(opencodeDir, { recursive: true });
102
+ writeFileSync(
103
+ join(opencodeDir, "models.json"),
104
+ JSON.stringify({
105
+ openai: {
106
+ models: {
107
+ "gpt-5.4": {
108
+ limit: { context: 1050000, input: 922000 },
109
+ experimental: { modes: { fast: {}, mini: {} } },
110
+ },
111
+ },
112
+ },
113
+ }),
114
+ );
115
+
116
+ //#then
117
+ expect(getModelsDevContextLimit("openai", "gpt-5.4")).toBe(922000);
118
+ expect(getModelsDevContextLimit("openai", "gpt-5.4-fast")).toBe(922000);
119
+ expect(getModelsDevContextLimit("openai", "gpt-5.4-mini")).toBe(922000);
120
+ });
121
+
122
+ test("custom opencode.json provider overlay uses limit.input preferentially", () => {
123
+ //#given — user defines a proxy provider in opencode.json with input < context
124
+ const opencodeDir = join(tempDir, "opencode");
125
+ mkdirSync(opencodeDir, { recursive: true });
126
+ const configDir = join(tempDir, "config", "opencode");
127
+ mkdirSync(configDir, { recursive: true });
128
+ writeFileSync(
129
+ join(configDir, "opencode.json"),
130
+ JSON.stringify({
131
+ provider: {
132
+ "my-proxy": {
133
+ models: {
134
+ "split-model": { limit: { context: 400000, input: 200000 } },
135
+ },
136
+ },
137
+ },
138
+ }),
139
+ );
140
+ process.env.OPENCODE_CONFIG_DIR = configDir;
141
+ clearModelsDevCache();
142
+
143
+ //#then
144
+ expect(getModelsDevContextLimit("my-proxy", "split-model")).toBe(200000);
145
+
146
+ // Cleanup: restore env (afterEach also handles this, but we added a new var)
147
+ delete process.env.OPENCODE_CONFIG_DIR;
148
+ });
149
+
150
+ test("API cache uses limit.input preferentially", async () => {
151
+ //#given — API response shape mirrors file layer
152
+ const mockClient = {
153
+ config: {
154
+ providers: async () => ({
155
+ data: {
156
+ providers: [
157
+ {
158
+ id: "github-copilot",
159
+ models: {
160
+ "gpt-5.3-codex": {
161
+ limit: { context: 400000, input: 272000 },
162
+ },
163
+ },
164
+ },
165
+ ],
166
+ },
167
+ }),
168
+ },
169
+ };
170
+ // @ts-expect-error mock narrow shape
171
+ await refreshModelLimitsFromApi(mockClient);
172
+
173
+ //#then
174
+ expect(getModelsDevContextLimit("github-copilot", "gpt-5.3-codex")).toBe(272000);
175
+ });
176
+
64
177
  test("expands experimental.modes into derived model IDs with parent context", () => {
65
178
  const opencodeDir = join(tempDir, "opencode");
66
179
  mkdirSync(opencodeDir, { recursive: true });
@@ -86,6 +86,24 @@ function getOpencodeConfigPath(): string | null {
86
86
  return null;
87
87
  }
88
88
 
89
+ /**
90
+ * Resolve the effective pressure limit for a model's `limit` object.
91
+ *
92
+ * Prefers `limit.input` (max prompt tokens the provider will accept) over
93
+ * `limit.context` (total window including output). For GitHub Copilot and
94
+ * several proxy providers, `context` is the marketing number (input + output
95
+ * combined), and sending a prompt sized against `context` gets rejected.
96
+ * OpenCode's own `session/overflow.ts` uses `input ?? context` for the same
97
+ * reason — the denominator that drives overflow/pressure must be the number
98
+ * the provider actually enforces on input.
99
+ */
100
+ function resolveLimit(limit: { context?: number; input?: number } | undefined): number | undefined {
101
+ if (!limit) return undefined;
102
+ if (typeof limit.input === "number" && limit.input > 0) return limit.input;
103
+ if (typeof limit.context === "number" && limit.context > 0) return limit.context;
104
+ return undefined;
105
+ }
106
+
89
107
  function loadModelsDevLimitsFromFile(): Map<string, number> {
90
108
  const limits = new Map<string, number>();
91
109
 
@@ -102,7 +120,7 @@ function loadModelsDevLimitsFromFile(): Map<string, number> {
102
120
  models?: Record<
103
121
  string,
104
122
  {
105
- limit?: { context?: number };
123
+ limit?: { context?: number; input?: number };
106
124
  experimental?: { modes?: Record<string, unknown> };
107
125
  }
108
126
  >;
@@ -112,15 +130,15 @@ function loadModelsDevLimitsFromFile(): Map<string, number> {
112
130
  for (const [providerId, provider] of Object.entries(data)) {
113
131
  if (!provider?.models || typeof provider.models !== "object") continue;
114
132
  for (const [modelId, model] of Object.entries(provider.models)) {
115
- const context = model?.limit?.context;
116
- if (typeof context === "number" && context > 0) {
117
- limits.set(`${providerId}/${modelId}`, context);
133
+ const effective = resolveLimit(model?.limit);
134
+ if (typeof effective === "number" && effective > 0) {
135
+ limits.set(`${providerId}/${modelId}`, effective);
118
136
  // OpenCode creates derived model IDs from experimental.modes
119
137
  // e.g. gpt-5.4 + modes.fast → gpt-5.4-fast (inherits parent limit).
120
138
  const modes = model?.experimental?.modes;
121
139
  if (modes && typeof modes === "object") {
122
140
  for (const mode of Object.keys(modes)) {
123
- limits.set(`${providerId}/${modelId}-${mode}`, context);
141
+ limits.set(`${providerId}/${modelId}-${mode}`, effective);
124
142
  }
125
143
  }
126
144
  }
@@ -136,7 +154,7 @@ function loadModelsDevLimitsFromFile(): Map<string, number> {
136
154
  }
137
155
 
138
156
  // 2. Overlay custom provider models from OpenCode config (higher priority).
139
- // Users define custom/proxy models via provider.<id>.models.<name>.limit.context
157
+ // Users define custom/proxy models via provider.<id>.models.<name>.limit.{input,context}
140
158
  // in opencode.json(c). These override models.dev entries for the same key.
141
159
  try {
142
160
  const configPath = getOpencodeConfigPath();
@@ -149,7 +167,9 @@ function loadModelsDevLimitsFromFile(): Map<string, number> {
149
167
  const config = JSON.parse(raw) as {
150
168
  provider?: Record<
151
169
  string,
152
- { models?: Record<string, { limit?: { context?: number } }> }
170
+ {
171
+ models?: Record<string, { limit?: { context?: number; input?: number } }>;
172
+ }
153
173
  >;
154
174
  };
155
175
 
@@ -157,9 +177,9 @@ function loadModelsDevLimitsFromFile(): Map<string, number> {
157
177
  for (const [providerId, provider] of Object.entries(config.provider)) {
158
178
  if (!provider?.models || typeof provider.models !== "object") continue;
159
179
  for (const [modelId, model] of Object.entries(provider.models)) {
160
- const context = model?.limit?.context;
161
- if (typeof context === "number" && context > 0) {
162
- limits.set(`${providerId}/${modelId}`, context);
180
+ const effective = resolveLimit(model?.limit);
181
+ if (typeof effective === "number" && effective > 0) {
182
+ limits.set(`${providerId}/${modelId}`, effective);
163
183
  }
164
184
  }
165
185
  }
@@ -206,13 +226,13 @@ export async function refreshModelLimitsFromApi(client: OpencodeClient): Promise
206
226
  for (const entry of providers) {
207
227
  const p = entry as {
208
228
  id?: string;
209
- models?: Record<string, { limit?: { context?: number } }>;
229
+ models?: Record<string, { limit?: { context?: number; input?: number } }>;
210
230
  };
211
231
  if (!p?.id || !p.models || typeof p.models !== "object") continue;
212
232
  for (const [modelId, model] of Object.entries(p.models)) {
213
- const context = model?.limit?.context;
214
- if (typeof context === "number" && context > 0) {
215
- map.set(`${p.id}/${modelId}`, context);
233
+ const effective = resolveLimit(model?.limit);
234
+ if (typeof effective === "number" && effective > 0) {
235
+ map.set(`${p.id}/${modelId}`, effective);
216
236
  }
217
237
  }
218
238
  }
@@ -62,6 +62,17 @@ export interface StatusDetail extends SidebarSnapshot {
62
62
  cacheRemainingMs: number;
63
63
  cacheExpired: boolean;
64
64
  executeThreshold: number;
65
+ /**
66
+ * Which config source produced `executeThreshold`. "tokens" means
67
+ * execute_threshold_tokens matched for this session's model and was
68
+ * converted to a percentage. "percentage" means percentage config was used.
69
+ */
70
+ executeThresholdMode: "percentage" | "tokens";
71
+ /**
72
+ * When `executeThresholdMode === "tokens"`, the absolute clamped token value
73
+ * (≤ 80% × contextLimit) that will trigger execute. Undefined in percentage mode.
74
+ */
75
+ executeThresholdTokens?: number;
65
76
  protectedTagCount: number;
66
77
  nudgeInterval: number;
67
78
  historyBudgetPercentage: number;
@@ -98,6 +98,7 @@ export async function loadStatusDetail(
98
98
  cacheRemainingMs: 0,
99
99
  cacheExpired: false,
100
100
  executeThreshold: 65,
101
+ executeThresholdMode: "percentage",
101
102
  protectedTagCount: 20,
102
103
  nudgeInterval: 20000,
103
104
  historyBudgetPercentage: 0.15,