conductor-remote 1.96.1 → 1.96.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.
package/dist/index.html CHANGED
@@ -25,8 +25,8 @@
25
25
  <title>Conductor Remote</title>
26
26
  <!-- Runs before the module bundle so it can catch a stale shell that fails to boot. -->
27
27
  <script src="/self-heal.js"></script>
28
- <script type="module" crossorigin src="/assets/index-BtWcQBu6.js"></script>
29
- <link rel="stylesheet" crossorigin href="/assets/index-35kfVzU0.css">
28
+ <script type="module" crossorigin src="/assets/index-BtAuvfL4.js"></script>
29
+ <link rel="stylesheet" crossorigin href="/assets/index-7EOD11nV.css">
30
30
  <link rel="manifest" href="/manifest.webmanifest"></head>
31
31
  <body>
32
32
  <div id="root"></div>
package/dist/sw.js CHANGED
@@ -1 +1 @@
1
- if(!self.define){let e,s={};const i=(i,n)=>(i=new URL(i+".js",n).href,s[i]||new Promise(s=>{if("document"in self){const e=document.createElement("script");e.src=i,e.onload=s,document.head.appendChild(e)}else e=i,importScripts(i),s()}).then(()=>{let e=s[i];if(!e)throw new Error(`Module ${i} didn’t register its module`);return e}));self.define=(n,r)=>{const o=e||("document"in self?document.currentScript.src:"")||location.href;if(s[o])return;let c={};const l=e=>i(e,o),t={module:{uri:o},exports:c,require:l};s[o]=Promise.all(n.map(e=>t[e]||l(e))).then(e=>(r(...e),c))}}define(["./workbox-9c191d2f"],function(e){"use strict";importScripts("/push-sw.js"),self.addEventListener("message",e=>{e.data&&"SKIP_WAITING"===e.data.type&&self.skipWaiting()}),e.clientsClaim(),e.precacheAndRoute([{url:"self-heal.js",revision:"49bd63adb25a09341f8d2610e8bd3c76"},{url:"push-sw.js",revision:"e7ef44deca46c0539e6ff7bba5eb815e"},{url:"index.html",revision:"0d02566c58e13df99409e4cb0de1c43d"},{url:"assets/workbox-window.prod.es5-BBnX5xw4.js",revision:null},{url:"assets/index-BtWcQBu6.js",revision:null},{url:"assets/index-35kfVzU0.css",revision:null},{url:"apple-touch-icon.png",revision:"1127bb396b4648add53dce3f22c92aee"},{url:"icon-192.png",revision:"c5e01ac58768627e18ee7b8b6a9239ef"},{url:"icon-512.png",revision:"a40638c55e310312457a621c9a0002c8"},{url:"icon-maskable-512.png",revision:"a9b0d962686287452216492cd2247499"},{url:"icon.svg",revision:"c1aee186821798733dd477e69a0ef243"},{url:"manifest.webmanifest",revision:"cf88fbc5755108a7fe0616fa160a8a15"}],{}),e.cleanupOutdatedCaches(),e.registerRoute(new e.NavigationRoute(e.createHandlerBoundToURL("/index.html"),{denylist:[/^\/api\//]}))});
1
+ if(!self.define){let e,s={};const i=(i,n)=>(i=new URL(i+".js",n).href,s[i]||new Promise(s=>{if("document"in self){const e=document.createElement("script");e.src=i,e.onload=s,document.head.appendChild(e)}else e=i,importScripts(i),s()}).then(()=>{let e=s[i];if(!e)throw new Error(`Module ${i} didn’t register its module`);return e}));self.define=(n,r)=>{const o=e||("document"in self?document.currentScript.src:"")||location.href;if(s[o])return;let l={};const t=e=>i(e,o),c={module:{uri:o},exports:l,require:t};s[o]=Promise.all(n.map(e=>c[e]||t(e))).then(e=>(r(...e),l))}}define(["./workbox-9c191d2f"],function(e){"use strict";importScripts("/push-sw.js"),self.addEventListener("message",e=>{e.data&&"SKIP_WAITING"===e.data.type&&self.skipWaiting()}),e.clientsClaim(),e.precacheAndRoute([{url:"self-heal.js",revision:"49bd63adb25a09341f8d2610e8bd3c76"},{url:"push-sw.js",revision:"e7ef44deca46c0539e6ff7bba5eb815e"},{url:"index.html",revision:"679a9174a36942457a716182f6c1d863"},{url:"assets/workbox-window.prod.es5-BBnX5xw4.js",revision:null},{url:"assets/index-BtAuvfL4.js",revision:null},{url:"assets/index-7EOD11nV.css",revision:null},{url:"apple-touch-icon.png",revision:"1127bb396b4648add53dce3f22c92aee"},{url:"icon-192.png",revision:"c5e01ac58768627e18ee7b8b6a9239ef"},{url:"icon-512.png",revision:"a40638c55e310312457a621c9a0002c8"},{url:"icon-maskable-512.png",revision:"a9b0d962686287452216492cd2247499"},{url:"icon.svg",revision:"c1aee186821798733dd477e69a0ef243"},{url:"manifest.webmanifest",revision:"cf88fbc5755108a7fe0616fa160a8a15"}],{}),e.cleanupOutdatedCaches(),e.registerRoute(new e.NavigationRoute(e.createHandlerBoundToURL("/index.html"),{denylist:[/^\/api\//]}))});
@@ -0,0 +1,76 @@
1
+ import { modelAgentType, modelLabel, modelPickerLabel, shortModel } from "./shared.js";
2
+ function modelMatches(state, requested, allowPrefix = false) {
3
+ const label = modelPickerLabel(requested).trim();
4
+ const expectedAgentType = modelAgentType(label);
5
+ const actualLabel = modelPickerLabel(modelLabel(state.model, [label]));
6
+ const stored = shortModel(state.model).toLowerCase();
7
+ const wanted = label.toLowerCase();
8
+ const selected = actualLabel.toLowerCase() === wanted ||
9
+ stored === wanted ||
10
+ stored.endsWith(`:${wanted}`) ||
11
+ (allowPrefix && actualLabel.toLowerCase().startsWith(wanted));
12
+ return (!expectedAgentType || state.agentType === expectedAgentType) && selected;
13
+ }
14
+ function matches(state, patch) {
15
+ return ((!patch.model || modelMatches(state, patch.model, true)) &&
16
+ (!patch.effort || state.effort === patch.effort) &&
17
+ (patch.plan === undefined || state.plan === patch.plan) &&
18
+ (patch.fast === undefined || state.fast === patch.fast));
19
+ }
20
+ async function confirm(deps, predicate) {
21
+ const attempts = deps.confirmAttempts ?? 10;
22
+ for (let attempt = 0; attempt < attempts; attempt++) {
23
+ const current = deps.read();
24
+ if (current && predicate(current))
25
+ return current;
26
+ if (attempt + 1 < attempts)
27
+ await deps.wait();
28
+ }
29
+ return undefined;
30
+ }
31
+ function modelFailure(model) {
32
+ const agentType = modelAgentType(model);
33
+ const provider = agentType === 'claude' ? 'Claude' : agentType === 'codex' ? 'Codex' : agentType;
34
+ return provider
35
+ ? `Conductor did not record model ${model} on the expected ${provider} provider.`
36
+ : `Conductor did not record model ${model}.`;
37
+ }
38
+ /**
39
+ * Apply one desired role snapshot without holding stale AX references across a
40
+ * provider-changing rerender. The model gets its own UI pass and DB receipt;
41
+ * only then are the new provider's controls reacquired and changed by delta.
42
+ */
43
+ export async function applyAgentConfig(patch, deps) {
44
+ let current = deps.read();
45
+ if (!current)
46
+ return { ok: false, error: 'the chat is gone' };
47
+ if (patch.model && !modelMatches(current, patch.model)) {
48
+ const requestedModel = patch.model;
49
+ const selected = await deps.write({ model: requestedModel });
50
+ if (!selected.ok)
51
+ return selected;
52
+ // setModel accepts a unique picker prefix. It has already proved uniqueness
53
+ // before this receipt, so the stored full label may legitimately be longer.
54
+ current = await confirm(deps, state => modelMatches(state, requestedModel, true));
55
+ if (!current)
56
+ return { ok: false, error: modelFailure(requestedModel) };
57
+ }
58
+ const controls = {};
59
+ if (patch.effort && current.effort !== patch.effort)
60
+ controls.effort = patch.effort;
61
+ if (patch.plan !== undefined && current.plan !== patch.plan)
62
+ controls.plan = patch.plan;
63
+ if (patch.fast !== undefined && current.fast !== patch.fast)
64
+ controls.toggleFast = true;
65
+ if (Object.keys(controls).length) {
66
+ controls.agentType = current.agentType;
67
+ const applied = await deps.write(controls);
68
+ if (!applied.ok)
69
+ return applied;
70
+ }
71
+ const recorded = await confirm(deps, state => matches(state, patch));
72
+ if (!recorded) {
73
+ return { ok: false, error: 'Conductor did not record every requested agent setting.' };
74
+ }
75
+ return { ok: true };
76
+ }
@@ -1639,22 +1639,37 @@ end controlNamed
1639
1639
 
1640
1640
  on effortButton()
1641
1641
  -- The effort control is a button whose *label is its current value*, so it is
1642
- -- identified by that label rather than a stable name.
1643
- set levels to {"Low", "Medium", "High", "Extra high", "Max", "Ultracode"}
1642
+ -- identified by that label rather than a stable name. Claude calls its top
1643
+ -- level Ultracode while Codex calls the corresponding level Ultra. Codex's
1644
+ -- None state is the exception: its button has no accessible name at all, so
1645
+ -- accept one (and only one) unnamed button *after* the proven model picker.
1646
+ -- The main composer also contains unnamed attachment/stop buttons before that
1647
+ -- picker, and pressing one of those would be worse than failing.
1648
+ set levels to {"Light", "Low", "Medium", "High", "Extra high", "Max", "Ultracode", "Ultra"}
1649
+ set sawModel to false
1650
+ set unnamed to {}
1644
1651
  repeat with entry in my composerControls()
1645
1652
  set c to contents of entry
1646
- if my tabLabel(c) is in levels then return c
1653
+ if (my axRole(c)) is "AXPopUpButton" and (my axName(c)) contains "Change agent" then
1654
+ set sawModel to true
1655
+ else if sawModel and (my axRole(c)) is "AXButton" then
1656
+ set label to my axName(c)
1657
+ if label is in levels then return c
1658
+ if label is "" then set end of unnamed to c
1659
+ end if
1647
1660
  end repeat
1661
+ if (count of unnamed) is 1 then return item 1 of unnamed
1648
1662
  return missing value
1649
1663
  end effortButton
1650
1664
 
1651
1665
  on setEffort(wanted)
1652
- -- Pressing cycles Low Medium High Extra high Max → Ultracode → wrap,
1653
- -- so step around the ring at most one full turn and confirm the label landed.
1666
+ -- Claude owns a six-value ring ending in Ultracode; Codex adds None and ends
1667
+ -- in Ultra. Step around either ring once and confirm the label landed.
1654
1668
  set btn to my effortButton()
1655
1669
  if btn is missing value then error "couldn't find the effort control"
1656
- repeat 7 times
1657
- if my tabLabel(btn) is wanted then return
1670
+ repeat 8 times
1671
+ set currentLabel to my axName(btn)
1672
+ if currentLabel is wanted or (wanted is "__UNNAMED_EFFORT__" and currentLabel is "") then return
1658
1673
  tell application "System Events" to tell process "Conductor"
1659
1674
  perform action "AXPress" of btn
1660
1675
  end tell
@@ -1883,6 +1898,7 @@ on setModel(wanted)
1883
1898
  if (count of loose) > 1 then error "several models match " & wanted
1884
1899
  error "no model named " & wanted
1885
1900
  end if
1901
+ set chosenLabel to my firstLine(my tabLabel(chosen))
1886
1902
  tell application "System Events" to tell process "Conductor"
1887
1903
  perform action "AXPress" of chosen
1888
1904
  end tell
@@ -1893,7 +1909,7 @@ on setModel(wanted)
1893
1909
  if my tabLabel(c) contains "Change agent" then set popup to c
1894
1910
  end repeat
1895
1911
  if popup is missing value then error "the model picker vanished"
1896
- if not my pickerShowsModel(popup, wanted) then error "the model didn't switch to " & wanted
1912
+ if not my pickerShowsModel(popup, chosenLabel) then error "the model didn't switch to " & chosenLabel
1897
1913
  end setModel
1898
1914
 
1899
1915
  on listModels()