@sjhmars/happy-bridge 0.1.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 +10 -10
- package/lib/index.js +22 -39
- package/lib/types/bridge.d.ts +3 -3
- package/package.json +2 -1
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
|
-
"
|
|
22
|
-
"
|
|
23
|
-
"header": "l9rBEq_header",
|
|
21
|
+
"row": "l9rBEq_row",
|
|
22
|
+
"chevron": "l9rBEq_chevron",
|
|
24
23
|
"body": "l9rBEq_body",
|
|
25
|
-
"
|
|
24
|
+
"button": "l9rBEq_button",
|
|
25
|
+
"qr": "l9rBEq_qr",
|
|
26
26
|
"status": "l9rBEq_status",
|
|
27
|
-
"
|
|
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
|
-
"
|
|
31
|
-
"
|
|
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 (`
|
|
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
|
|
3727
|
-
if (
|
|
3721
|
+
const controller = this.ctx.get("sessionController");
|
|
3722
|
+
if (controller === void 0) return;
|
|
3728
3723
|
this.hostSelectFromPhone += 1;
|
|
3729
3724
|
try {
|
|
3730
|
-
|
|
3731
|
-
|
|
3732
|
-
|
|
3733
|
-
|
|
3734
|
-
|
|
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
|
-
|
|
3756
|
-
|
|
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(
|
|
3767
|
-
const link = this.links.get(
|
|
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
|
|
3771
|
-
if (
|
|
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
|
package/lib/types/bridge.d.ts
CHANGED
|
@@ -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 (`
|
|
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
|
|
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.1
|
|
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",
|
|
@@ -56,6 +56,7 @@
|
|
|
56
56
|
"@deepseek-ai/schemastery": ">=0.1.0-rc.5",
|
|
57
57
|
"@deepseek-ai/dsh-agent": ">=0.1.0-rc.5",
|
|
58
58
|
"@deepseek-ai/dsh-attachment": ">=0.1.0-rc.5",
|
|
59
|
+
"@deepseek-ai/dsh-api-session-controller": ">=0.1.2-alpha.1",
|
|
59
60
|
"@deepseek-ai/dsh-client-connection": ">=0.1.0-rc.5",
|
|
60
61
|
"@deepseek-ai/dsh-client-locale": ">=0.1.0-rc.5",
|
|
61
62
|
"@deepseek-ai/dsh-client-runtime": ">=0.1.0-rc.5",
|