@sjhmars/happy-bridge 0.2.0 → 0.2.1

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/lib/client.js CHANGED
@@ -18,20 +18,20 @@ window.__ModuleLoader__.load({
18
18
  }
19
19
  var HappyBridgeCard_module_css_default = {
20
20
  "error": "l9rBEq_error",
21
- "name": "l9rBEq_name",
22
- "qr": "l9rBEq_qr",
23
- "header": "l9rBEq_header",
21
+ "row": "l9rBEq_row",
22
+ "chevron": "l9rBEq_chevron",
24
23
  "body": "l9rBEq_body",
25
- "headText": "l9rBEq_headText",
24
+ "button": "l9rBEq_button",
25
+ "qr": "l9rBEq_qr",
26
26
  "status": "l9rBEq_status",
27
- "card": "l9rBEq_card",
27
+ "checkbox": "l9rBEq_checkbox",
28
+ "name": "l9rBEq_name",
29
+ "header": "l9rBEq_header",
30
+ "select": "l9rBEq_select",
28
31
  "description": "l9rBEq_description",
29
32
  "label": "l9rBEq_label",
30
- "select": "l9rBEq_select",
31
- "checkbox": "l9rBEq_checkbox",
32
- "row": "l9rBEq_row",
33
- "chevron": "l9rBEq_chevron",
34
- "button": "l9rBEq_button"
33
+ "headText": "l9rBEq_headText",
34
+ "card": "l9rBEq_card"
35
35
  };
36
36
  //#endregion
37
37
  //#region src/client/HappyBridgeCard.tsx
package/lib/index.js CHANGED
@@ -2847,6 +2847,10 @@ var HappyBridge = class {
2847
2847
  if (status === "idle") this.drainNewEvents(link, agent);
2848
2848
  }, { global: true });
2849
2849
  this.ctx.on("session/event", (session, event) => {
2850
+ if (event.type === "model/selection") {
2851
+ this.onHostModelSelected(String(session.header.id), event.data);
2852
+ return;
2853
+ }
2850
2854
  const link = this.links.get(session.header.id);
2851
2855
  if (link !== void 0) {
2852
2856
  this.onSessionEvent(link, event);
@@ -2857,15 +2861,6 @@ var HappyBridge = class {
2857
2861
  this.ensureMirror(session.header.id).catch((error) => this.log(`镜像会话失败:${String(error)}`));
2858
2862
  }, { global: true });
2859
2863
  this.ctx.on("approval/request", (req, next) => this.onApproval(req, next), { prepend: true });
2860
- this.ctx.inject(["apiProxy"], (inner) => {
2861
- const proxy = inner.get("apiProxy");
2862
- if (proxy === void 0) return;
2863
- const original = proxy.sessions.selectModel;
2864
- proxy.sessions.selectModel = (request) => this.afterHostSelect(request, original.call(proxy.sessions, request));
2865
- inner.effect(() => () => {
2866
- proxy.sessions.selectModel = original;
2867
- }, "happy-bridge: restore sessions.selectModel");
2868
- });
2869
2864
  this.ctx.inject(["userQuestions"], (inner) => {
2870
2865
  const questions = inner.userQuestions;
2871
2866
  const original = questions.ask;
@@ -3719,27 +3714,20 @@ var HappyBridge = class {
3719
3714
  this.syncHostSelection(agent, next);
3720
3715
  }
3721
3716
  /**
3722
- * Write the web picker's Host selection (`session.selectModel`) so the
3723
- * composer model seat reloads without a click on the computer.
3717
+ * Write the web picker's Host selection (`sessionController.selectModel`) so
3718
+ * the composer model seat reloads without a click on the computer.
3724
3719
  */
3725
3720
  async syncHostSelection(agent, next) {
3726
- const proxy = this.ctx.get("apiProxy");
3727
- if (proxy === void 0) return;
3721
+ const controller = this.ctx.get("sessionController");
3722
+ if (controller === void 0) return;
3728
3723
  this.hostSelectFromPhone += 1;
3729
3724
  try {
3730
- const response = await proxy.sessions.selectModel({
3731
- rpcId: `happy-model-${String(Date.now())}`,
3732
- payload: {
3733
- sessionId: agent.id,
3734
- provider: next.provider,
3735
- model: next.model,
3736
- ...next.reasoningEffort === void 0 ? {} : { reasoningEffort: next.reasoningEffort }
3737
- }
3725
+ await controller.selectModel({
3726
+ sessionId: agent.id,
3727
+ provider: next.provider,
3728
+ model: next.model,
3729
+ ...next.reasoningEffort === void 0 ? {} : { reasoningEffort: next.reasoningEffort }
3738
3730
  });
3739
- if (!response.result.ok) {
3740
- this.log(`电脑模型栏未同步:${response.result.error.message}`);
3741
- return;
3742
- }
3743
3731
  const link = this.links.get(agent.id);
3744
3732
  if (link !== void 0 && !link.parked) this.pushMetadata(link);
3745
3733
  } catch (error) {
@@ -3752,26 +3740,21 @@ var HappyBridge = class {
3752
3740
  * After the web picker (or any Host caller) lands a selection, publish it
3753
3741
  * to Happy. Phone-originated calls set {@link hostSelectFromPhone} and push themselves.
3754
3742
  */
3755
- async afterHostSelect(request, pending) {
3756
- const response = await pending;
3757
- if (this.hostSelectFromPhone) return response;
3758
- if (!response.result.ok) return response;
3759
- const { sessionId, provider, model, reasoningEffort } = request.payload;
3760
- const id = String(sessionId);
3743
+ onHostModelSelected(sessionId, selection) {
3744
+ if (this.hostSelectFromPhone) return;
3761
3745
  const next = {
3762
- provider,
3763
- model,
3764
- ...reasoningEffort === void 0 ? {} : { reasoningEffort: ReasoningEffortId(reasoningEffort) }
3746
+ provider: selection.provider,
3747
+ model: selection.model,
3748
+ ...selection.reasoningEffort === void 0 ? {} : { reasoningEffort: ReasoningEffortId(selection.reasoningEffort) }
3765
3749
  };
3766
- this.models.set(id, next);
3767
- const link = this.links.get(id);
3750
+ this.models.set(sessionId, next);
3751
+ const link = this.links.get(sessionId);
3768
3752
  const agent = link?.agent;
3769
3753
  if (agent !== void 0) {
3770
- const selection = this.selections.get(agent);
3771
- if (selection !== void 0) selection.current = next;
3754
+ const current = this.selections.get(agent);
3755
+ if (current !== void 0) current.current = next;
3772
3756
  }
3773
3757
  if (link !== void 0 && !link.parked) this.pushMetadata(link);
3774
- return response;
3775
3758
  }
3776
3759
  /**
3777
3760
  * Put a concrete reasoningEffort on a phone-spawned / phone-woken agent
@@ -169,15 +169,15 @@ export declare class HappyBridge {
169
169
  /** Keep the last Host pick so Happy metadata can echo the web composer. */
170
170
  private rememberModel;
171
171
  /**
172
- * Write the web picker's Host selection (`session.selectModel`) so the
173
- * composer model seat reloads without a click on the computer.
172
+ * Write the web picker's Host selection (`sessionController.selectModel`) so
173
+ * the composer model seat reloads without a click on the computer.
174
174
  */
175
175
  private syncHostSelection;
176
176
  /**
177
177
  * After the web picker (or any Host caller) lands a selection, publish it
178
178
  * to Happy. Phone-originated calls set {@link hostSelectFromPhone} and push themselves.
179
179
  */
180
- private afterHostSelect;
180
+ private onHostModelSelected;
181
181
  /**
182
182
  * Put a concrete reasoningEffort on a phone-spawned / phone-woken agent
183
183
  * before the first LLM request, matching the effort Happy metadata advertises.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sjhmars/happy-bridge",
3
- "version": "0.2.0",
3
+ "version": "0.2.1",
4
4
  "description": "Pair an already-running dsh web/desktop client with Happy App so the phone remote-controls the same harness sessions",
5
5
  "type": "module",
6
6
  "main": "lib/index.js",