@bolloon/bolloon-agent 0.4.22 → 0.4.24
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/agents/gateway-join.js +271 -0
- package/dist/agents/pi-sdk-tools.js +75 -2
- package/dist/agents/pi-sdk.js +6 -3
- package/dist/ios/index.html +74 -17
- package/dist/ios/mobile-agent.js +49 -4
- package/dist/ios/mobile-chain.js +481 -0
- package/dist/ios/mobile-core.js +373 -13
- package/dist/ios/mobile-helia.js +683 -0
- package/dist/ios/mobile-ipfs.js +680 -0
- package/dist/ios/mobile-orbit.js +268 -0
- package/dist/ios/mobile-p2p.js +130 -1
- package/dist/ios/mobile-social.js +624 -0
- package/dist/ios/mobile-sync.js +193 -0
- package/dist/ios/mobile-trade.js +492 -0
- package/dist/ios/mobile-wallet.js +11 -0
- package/dist/ios/mobile.css +24 -0
- package/dist/ios/mobile.html +74 -17
- package/dist/ios/mobile.js +911 -55
- package/dist/ios/routes-x402-info.js +194 -0
- package/dist/ios/server.js +303 -9
- package/dist/ios/sw.js +26 -2
- package/dist/llm/pi-ai.js +35 -2
- package/dist/network/agent-network.js +78 -6
- package/dist/web/agent-delegate-server.js +58 -12
- package/dist/web/mobile-agent.js +195 -1
- package/dist/web/mobile-core.js +187 -1
- package/dist/web/mobile.css +24 -0
- package/dist/web/mobile.html +23 -14
- package/dist/web/mobile.js +439 -45
- package/dist/web/server.js +114 -9
- package/dist/web/sw.js +26 -2
- package/package.json +1 -1
package/dist/web/mobile-core.js
CHANGED
|
@@ -86655,15 +86655,20 @@ ${[...listenStats.errors.entries()].map(([addr, err2]) => {
|
|
|
86655
86655
|
// src/web/mobile-agent.ts
|
|
86656
86656
|
var mobile_agent_exports = {};
|
|
86657
86657
|
__export(mobile_agent_exports, {
|
|
86658
|
+
MOBILE_JOIN_DOC_RE: () => MOBILE_JOIN_DOC_RE,
|
|
86658
86659
|
callRemoteAgent: () => callRemoteAgent,
|
|
86659
86660
|
cancelPhoneAgent: () => cancelPhoneAgent,
|
|
86660
86661
|
default: () => mobile_agent_default,
|
|
86662
|
+
detectJoinDocUrl: () => detectJoinDocUrl,
|
|
86661
86663
|
ensureIdentity: () => ensureIdentity,
|
|
86664
|
+
formatMobileJoinResult: () => formatMobileJoinResult,
|
|
86662
86665
|
getLastWorklog: () => getLastWorklog,
|
|
86663
86666
|
getLlmConfig: () => getLlmConfig,
|
|
86667
|
+
getMobileJoinState: () => getMobileJoinState,
|
|
86664
86668
|
handleIncomingAgentMessage: () => handleIncomingAgentMessage,
|
|
86665
86669
|
handleIncomingPhoneMessage: () => handleIncomingPhoneMessage,
|
|
86666
86670
|
identityStatus: () => identityStatus,
|
|
86671
|
+
joinGatewayFromDoc: () => joinGatewayFromDoc,
|
|
86667
86672
|
loginIdentity: () => loginIdentity,
|
|
86668
86673
|
logoutIdentity: () => logoutIdentity,
|
|
86669
86674
|
notifyAgentReply: () => notifyAgentReply,
|
|
@@ -86810,9 +86815,171 @@ ${[...listenStats.errors.entries()].map(([addr, err2]) => {
|
|
|
86810
86815
|
} catch {
|
|
86811
86816
|
}
|
|
86812
86817
|
}
|
|
86818
|
+
function detectJoinDocUrl(text) {
|
|
86819
|
+
const m2 = MOBILE_JOIN_DOC_RE.exec(String(text || ""));
|
|
86820
|
+
return m2 ? m2[1] : null;
|
|
86821
|
+
}
|
|
86822
|
+
function parseFm(text) {
|
|
86823
|
+
const m2 = /^---\r?\n([\s\S]*?)\r?\n---/.exec(String(text || ""));
|
|
86824
|
+
if (!m2) return {};
|
|
86825
|
+
const out = {};
|
|
86826
|
+
for (const line of m2[1].split(/\r?\n/)) {
|
|
86827
|
+
const kv = /^([A-Za-z_][\w-]*)\s*:\s*(.*)$/.exec(line.trim());
|
|
86828
|
+
if (!kv) continue;
|
|
86829
|
+
const k = kv[1].toLowerCase();
|
|
86830
|
+
if (k === "name") out.name = kv[2].trim().replace(/^["']|["']$/g, "");
|
|
86831
|
+
if (k === "version") out.version = kv[2].trim().replace(/^["']|["']$/g, "");
|
|
86832
|
+
}
|
|
86833
|
+
return out;
|
|
86834
|
+
}
|
|
86835
|
+
async function getMobileJoinState() {
|
|
86836
|
+
try {
|
|
86837
|
+
const raw = typeof localStorage !== "undefined" ? localStorage.getItem(MOBILE_JOIN_STATE_KEY) : null;
|
|
86838
|
+
return raw ? JSON.parse(raw) : null;
|
|
86839
|
+
} catch {
|
|
86840
|
+
return null;
|
|
86841
|
+
}
|
|
86842
|
+
}
|
|
86843
|
+
function saveMobileJoinState(s2) {
|
|
86844
|
+
try {
|
|
86845
|
+
if (typeof localStorage !== "undefined") localStorage.setItem(MOBILE_JOIN_STATE_KEY, JSON.stringify(s2));
|
|
86846
|
+
} catch {
|
|
86847
|
+
}
|
|
86848
|
+
}
|
|
86849
|
+
async function joinGatewayFromDoc(docUrl, opts = {}) {
|
|
86850
|
+
const f = opts.fetchImpl || fetch;
|
|
86851
|
+
const steps = [];
|
|
86852
|
+
const url = String(docUrl || "").trim();
|
|
86853
|
+
if (!/^https?:\/\//i.test(url)) {
|
|
86854
|
+
return { ok: false, docUrl: url, steps, error: `\u5165\u7F51\u8BF4\u660E\u5730\u5740\u5FC5\u987B\u662F http(s) URL (\u6536\u5230: ${url.slice(0, 60)})` };
|
|
86855
|
+
}
|
|
86856
|
+
let docVersion;
|
|
86857
|
+
try {
|
|
86858
|
+
const r = await f(url, { signal: AbortSignal.timeout(opts.timeoutMs ?? 15e3) });
|
|
86859
|
+
if (!r.ok) {
|
|
86860
|
+
steps.push({ step: "\u8BFB\u5165\u7F51\u8BF4\u660E", ok: false, note: `\u6587\u6863\u4E0D\u53EF\u8FBE (HTTP ${r.status})` });
|
|
86861
|
+
return { ok: false, docUrl: url, steps, error: `\u5165\u7F51\u8BF4\u660E\u4E0D\u53EF\u8FBE (HTTP ${r.status})` };
|
|
86862
|
+
}
|
|
86863
|
+
const text = await r.text();
|
|
86864
|
+
const fm = parseFm(text);
|
|
86865
|
+
if (fm.name !== "bolloon-gateway-join" && !/加入网关|bolloon-gateway-join/.test(text)) {
|
|
86866
|
+
steps.push({ step: "\u8BFB\u5165\u7F51\u8BF4\u660E", ok: false, note: `\u4E0D\u662F Bolloon \u5165\u7F51\u8BF4\u660E (name=${fm.name || "\u65E0"})` });
|
|
86867
|
+
return { ok: false, docUrl: url, steps, error: "\u8BE5\u6587\u6863\u4E0D\u662F Bolloon \u7F51\u5173\u5165\u7F51\u8BF4\u660E, \u62D2\u7EDD\u636E\u6B64\u5165\u7F51" };
|
|
86868
|
+
}
|
|
86869
|
+
docVersion = fm.version;
|
|
86870
|
+
steps.push({ step: "\u8BFB\u5165\u7F51\u8BF4\u660E", ok: true, note: `${fm.name || "bolloon-gateway-join"} v${fm.version || "?"} (${text.length} \u5B57\u7B26)` });
|
|
86871
|
+
} catch (e) {
|
|
86872
|
+
steps.push({ step: "\u8BFB\u5165\u7F51\u8BF4\u660E", ok: false, note: `\u8BFB\u53D6\u5931\u8D25: ${String(e?.message || e).slice(0, 120)}` });
|
|
86873
|
+
return { ok: false, docUrl: url, steps, error: `\u5165\u7F51\u8BF4\u660E\u8BFB\u53D6\u5931\u8D25: ${String(e?.message || e).slice(0, 120)}` };
|
|
86874
|
+
}
|
|
86875
|
+
let did = String(opts.did || "");
|
|
86876
|
+
if (did) {
|
|
86877
|
+
steps.push({ step: "DID \u8EAB\u4EFD", ok: true, note: `${did} (\u6CE8\u5165\u8EAB\u4EFD)` });
|
|
86878
|
+
} else {
|
|
86879
|
+
try {
|
|
86880
|
+
const id = await ensureIdentity();
|
|
86881
|
+
did = id.did;
|
|
86882
|
+
steps.push({ step: "DID \u8EAB\u4EFD", ok: true, note: `${did} (\u624B\u673A\u7AEF\u672C\u673A\u751F\u6210)` });
|
|
86883
|
+
} catch (e) {
|
|
86884
|
+
steps.push({ step: "DID \u8EAB\u4EFD", ok: false, note: String(e?.message || e).slice(0, 120) });
|
|
86885
|
+
return { ok: false, docUrl: url, docVersion, steps, error: "\u624B\u673A\u7AEF DID \u751F\u6210\u5931\u8D25" };
|
|
86886
|
+
}
|
|
86887
|
+
}
|
|
86888
|
+
const name10 = String(opts.name || "phone-agent");
|
|
86889
|
+
const capabilities = ["chat", "gateway-join"];
|
|
86890
|
+
let desktopBase = String(opts.desktopBaseUrl ?? "");
|
|
86891
|
+
if (opts.desktopBaseUrl === void 0) {
|
|
86892
|
+
try {
|
|
86893
|
+
const g = await Promise.resolve().then(() => (init_mobile_gateway(), mobile_gateway_exports));
|
|
86894
|
+
desktopBase = String(g.getDesktopBaseUrl() || "");
|
|
86895
|
+
} catch {
|
|
86896
|
+
desktopBase = "";
|
|
86897
|
+
}
|
|
86898
|
+
}
|
|
86899
|
+
desktopBase = desktopBase.replace(/\/+$/, "");
|
|
86900
|
+
let registeredOn = "local";
|
|
86901
|
+
if (desktopBase) {
|
|
86902
|
+
try {
|
|
86903
|
+
const r = await f(`${desktopBase}/api/registry/register`, {
|
|
86904
|
+
method: "POST",
|
|
86905
|
+
headers: { "content-type": "application/json" },
|
|
86906
|
+
body: JSON.stringify({
|
|
86907
|
+
agentId: did,
|
|
86908
|
+
name: name10,
|
|
86909
|
+
wallet: "",
|
|
86910
|
+
service: { name: "chat", description: "\u624B\u673A\u7AEF\u667A\u80FD\u4F53 (\u81EA\u8DB3\u8282\u70B9)", price: { amount: "0", currency: "USDC", per: "task" }, endpoint: "" },
|
|
86911
|
+
capabilities
|
|
86912
|
+
}),
|
|
86913
|
+
signal: AbortSignal.timeout(opts.timeoutMs ?? 15e3)
|
|
86914
|
+
});
|
|
86915
|
+
if (r.ok) {
|
|
86916
|
+
registeredOn = "desktop";
|
|
86917
|
+
steps.push({ step: "\u670D\u52A1\u767B\u8BB0", ok: true, note: `\u5DF2\u767B\u8BB0\u8FDB\u7535\u8111\u7AEF\u7F51\u7EDC registry (${desktopBase}) \u2014\u2014 \u7F51\u7EDC\u5185\u5176\u4ED6\u667A\u80FD\u4F53\u53EF\u6309\u80FD\u529B\u53D1\u73B0\u6211` });
|
|
86918
|
+
} else {
|
|
86919
|
+
steps.push({ step: "\u670D\u52A1\u767B\u8BB0", ok: false, note: `\u7535\u8111\u7AEF registry \u62D2\u7EDD (HTTP ${r.status}); \u5DF2\u6539\u4E3A\u672C\u673A\u767B\u8BB0` });
|
|
86920
|
+
}
|
|
86921
|
+
} catch (e) {
|
|
86922
|
+
steps.push({ step: "\u670D\u52A1\u767B\u8BB0", ok: false, note: `\u7535\u8111\u7AEF\u4E0D\u53EF\u8FBE (${String(e?.message || e).slice(0, 80)}); \u5DF2\u6539\u4E3A\u672C\u673A\u767B\u8BB0` });
|
|
86923
|
+
}
|
|
86924
|
+
} else {
|
|
86925
|
+
steps.push({ step: "\u670D\u52A1\u767B\u8BB0", ok: true, note: "\u672A\u914D\u7F6E\u7535\u8111\u7AEF\u57FA\u5740 \u2192 \u53EA\u5728\u672C\u673A\u767B\u8BB0 (\u624B\u673A\u662F\u81EA\u6CBB\u8282\u70B9; \u8BBE\u7F6E\u91CC\u586B\u7535\u8111\u7AEF\u5730\u5740\u53EF\u767B\u8BB0\u8FDB\u7F51\u7EDC registry)" });
|
|
86926
|
+
}
|
|
86927
|
+
try {
|
|
86928
|
+
const p2p = await Promise.resolve().then(() => (init_mobile_p2p(), mobile_p2p_exports));
|
|
86929
|
+
let peers = 0;
|
|
86930
|
+
try {
|
|
86931
|
+
peers = (p2p.getConnectedPeers?.() || []).length;
|
|
86932
|
+
} catch {
|
|
86933
|
+
peers = 0;
|
|
86934
|
+
}
|
|
86935
|
+
if (peers > 0 && typeof p2p.sendMobileP2PMessage === "function") {
|
|
86936
|
+
const okAnnounce = await p2p.sendMobileP2PMessage("*", "registry.register", JSON.stringify({ agent_id: did, name: name10, capabilities }), did);
|
|
86937
|
+
steps.push({ step: "P2P \u516C\u544A", ok: !!okAnnounce, note: okAnnounce ? `\u5DF2\u5411 ${peers} \u4E2A\u5BF9\u7AEF\u5E7F\u64AD\u672C\u673A\u58F0\u660E` : `\u5E7F\u64AD\u5931\u8D25 (\u5BF9\u7AEF ${peers} \u4E2A)` });
|
|
86938
|
+
} else {
|
|
86939
|
+
steps.push({ step: "P2P \u516C\u544A", ok: false, note: "\u5F53\u524D\u65E0\u5DF2\u8FDE\u63A5\u5BF9\u7AEF (\u6D4F\u89C8\u5668/\u672A\u8FDE\u7535\u8111\u7AEF\u65F6\u6B63\u5E38) \u2014 \u672C\u673A\u58F0\u660E\u5DF2\u5C31\u7EEA, \u8FDE\u4E0A\u5373\u751F\u6548" });
|
|
86940
|
+
}
|
|
86941
|
+
} catch (e) {
|
|
86942
|
+
steps.push({ step: "P2P \u516C\u544A", ok: false, note: `P2P \u5C42\u4E0D\u53EF\u7528: ${String(e?.message || e).slice(0, 80)}` });
|
|
86943
|
+
}
|
|
86944
|
+
saveMobileJoinState({ url, did, name: name10, capabilities, docVersion, registeredOn, desktopBaseUrl: desktopBase || void 0, joinedAt: (/* @__PURE__ */ new Date()).toISOString() });
|
|
86945
|
+
const state2 = await getMobileJoinState();
|
|
86946
|
+
steps.push({ step: "\u843D\u76D8\u5165\u7F51\u6001", ok: !!state2?.did, note: `localStorage:${MOBILE_JOIN_STATE_KEY}` });
|
|
86947
|
+
return { ok: true, docUrl: url, docVersion, did, steps };
|
|
86948
|
+
}
|
|
86949
|
+
function formatMobileJoinResult(r) {
|
|
86950
|
+
if (!r.ok) {
|
|
86951
|
+
return `\u274C \u5165\u7F51\u5931\u8D25: ${r.error || "\u672A\u77E5\u539F\u56E0"}
|
|
86952
|
+
|
|
86953
|
+
${r.steps.map((s3) => `${s3.ok ? "\u2713" : "\u2717"} ${s3.step}: ${s3.note}`).join("\n")}`;
|
|
86954
|
+
}
|
|
86955
|
+
const s2 = r.steps.find((x) => x.step === "\u670D\u52A1\u767B\u8BB0");
|
|
86956
|
+
return [
|
|
86957
|
+
"\u2705 \u5DF2\u52A0\u5165\u5168\u7403\u667A\u80FD\u4F53\u7F51\u7EDC (\u624B\u673A\u7AEF\u81EA\u8DB3\u6267\u884C)",
|
|
86958
|
+
"",
|
|
86959
|
+
`DID: ${r.did}`,
|
|
86960
|
+
`\u5165\u7F51\u8BF4\u660E: v${r.docVersion || "?"} (${r.docUrl})`,
|
|
86961
|
+
s2 ? `\u767B\u8BB0: ${s2.note}` : "",
|
|
86962
|
+
"",
|
|
86963
|
+
...r.steps.map((x) => `${x.ok ? "\u2713" : "\u2717"} ${x.step}: ${x.note}`),
|
|
86964
|
+
"",
|
|
86965
|
+
"\u7528\u300C\u7F51\u7EDC \u2192 Agent \u7F51\u7EDC\u300D\u53EF\u67E5\u770B\u6210\u5458; \u8BBE\u7F6E\u91CC\u586B\u7535\u8111\u7AEF\u5730\u5740\u53EF\u628A\u672C\u673A\u767B\u8BB0\u8FDB\u7F51\u7EDC registry\u3002"
|
|
86966
|
+
].filter((l) => l !== "").join("\n");
|
|
86967
|
+
}
|
|
86813
86968
|
async function runLocalAgent(goal) {
|
|
86814
86969
|
const win = typeof window !== "undefined" ? window : null;
|
|
86815
86970
|
const cap = win?.Capacitor;
|
|
86971
|
+
const joinDocUrl = detectJoinDocUrl(goal);
|
|
86972
|
+
if (joinDocUrl) {
|
|
86973
|
+
_lastWorklog = [`\u{1F9E9} \u8BC6\u522B\u4E3A\u5165\u7F51\u53E3\u4EE4: ${joinDocUrl}`];
|
|
86974
|
+
const r = await joinGatewayFromDoc(joinDocUrl).catch((e) => ({
|
|
86975
|
+
ok: false,
|
|
86976
|
+
docUrl: joinDocUrl,
|
|
86977
|
+
steps: [{ step: "\u5165\u7F51", ok: false, note: String(e?.message || e).slice(0, 120) }],
|
|
86978
|
+
error: String(e?.message || e)
|
|
86979
|
+
}));
|
|
86980
|
+
_lastWorklog = [..._lastWorklog, ...r.steps.map((s2) => `${s2.ok ? "\u2713" : "\u2717"} ${s2.step}: ${s2.note}`)];
|
|
86981
|
+
return formatMobileJoinResult(r);
|
|
86982
|
+
}
|
|
86816
86983
|
const bridge = cap && cap.Plugins && cap.Plugins.RokidBridge;
|
|
86817
86984
|
if (bridge && cap.isNativePlatform?.()) {
|
|
86818
86985
|
try {
|
|
@@ -87068,7 +87235,7 @@ ${[...listenStats.errors.entries()].map(([addr, err2]) => {
|
|
|
87068
87235
|
} catch {
|
|
87069
87236
|
}
|
|
87070
87237
|
}
|
|
87071
|
-
var IDENTITY_DB, _identity, _identityDb, _llmConfig, _lastWorklog, _send, _ownDid, replyHandlers, inboundChatHandlers, mobile_agent_default;
|
|
87238
|
+
var IDENTITY_DB, _identity, _identityDb, _llmConfig, _lastWorklog, MOBILE_JOIN_DOC_RE, MOBILE_JOIN_STATE_KEY, _send, _ownDid, replyHandlers, inboundChatHandlers, mobile_agent_default;
|
|
87072
87239
|
var init_mobile_agent = __esm({
|
|
87073
87240
|
"src/web/mobile-agent.ts"() {
|
|
87074
87241
|
"use strict";
|
|
@@ -87078,6 +87245,8 @@ ${[...listenStats.errors.entries()].map(([addr, err2]) => {
|
|
|
87078
87245
|
_identityDb = null;
|
|
87079
87246
|
_llmConfig = null;
|
|
87080
87247
|
_lastWorklog = [];
|
|
87248
|
+
MOBILE_JOIN_DOC_RE = /read\s+(https?:\/\/\S*bolloon-gateway-join\.md)/i;
|
|
87249
|
+
MOBILE_JOIN_STATE_KEY = "bolloon_gateway_join";
|
|
87081
87250
|
_send = null;
|
|
87082
87251
|
_ownDid = "";
|
|
87083
87252
|
replyHandlers = /* @__PURE__ */ new Set();
|
|
@@ -162740,8 +162909,10 @@ ${error.stack}` : head;
|
|
|
162740
162909
|
resolve(path) {
|
|
162741
162910
|
const p = path || "";
|
|
162742
162911
|
if (p === "/channels") return () => core.channels.get();
|
|
162912
|
+
if (p === "/api/data/snapshot") return () => core.data.snapshot();
|
|
162743
162913
|
if (p === "/api/peers") return () => core.peers.list();
|
|
162744
162914
|
if (p === "/api/mcp/tools") return () => core.mcp.tools();
|
|
162915
|
+
if (p === "/api/skills") return () => core.skills.list();
|
|
162745
162916
|
if (p === "/api/auth/status") return () => core.identity.status();
|
|
162746
162917
|
if (p === "/api/payments/pending") return () => core.payments.pending();
|
|
162747
162918
|
if (p === "/api/llm-config") return () => core.data.getLlmConfig();
|
|
@@ -162787,6 +162958,10 @@ ${error.stack}` : head;
|
|
|
162787
162958
|
/** POST 路径 → 内核函数 */
|
|
162788
162959
|
resolvePost(path, body) {
|
|
162789
162960
|
const p = path || "";
|
|
162961
|
+
if (p === "/api/mcp/call") {
|
|
162962
|
+
const b = body || {};
|
|
162963
|
+
return () => core.mcp.call(String(b.name || ""), b.args || {});
|
|
162964
|
+
}
|
|
162790
162965
|
if (p === "/message") {
|
|
162791
162966
|
const b = body || {};
|
|
162792
162967
|
return () => core.message.send({ text: b.text, channelId: b.channelId });
|
|
@@ -163485,6 +163660,17 @@ ${error.stack}` : head;
|
|
|
163485
163660
|
{ name: "gateway_call", description: "\u901A\u8FC7 Agent Gateway \u8C03\u7528\u670D\u52A1 (\u81EA\u52A8\u95ED\u73AF)" },
|
|
163486
163661
|
{ name: "gateway_join", description: "\u901A\u8FC7\u94FE\u63A5\u52A0\u5165\u5171\u4EAB Agent \u7F51\u7EDC" }
|
|
163487
163662
|
];
|
|
163663
|
+
},
|
|
163664
|
+
async call(name10, args) {
|
|
163665
|
+
const { mobileGatewayTool: mobileGatewayTool2 } = await Promise.resolve().then(() => (init_mobile_gateway(), mobile_gateway_exports));
|
|
163666
|
+
return mobileGatewayTool2(String(name10 || ""), args || {});
|
|
163667
|
+
}
|
|
163668
|
+
},
|
|
163669
|
+
skills: {
|
|
163670
|
+
async list() {
|
|
163671
|
+
const s2 = await Promise.resolve().then(() => (init_mobile_sync(), mobile_sync_exports));
|
|
163672
|
+
const snap = s2.getLastSnapshot();
|
|
163673
|
+
return snap && Array.isArray(snap.skills) ? snap.skills : [];
|
|
163488
163674
|
}
|
|
163489
163675
|
},
|
|
163490
163676
|
message: {
|
package/dist/web/mobile.css
CHANGED
|
@@ -664,3 +664,27 @@ body {
|
|
|
664
664
|
.list-icon .ico { width: 21px; height: 21px; }
|
|
665
665
|
|
|
666
666
|
.icon-btn .ico { width: 20px; height: 20px; }
|
|
667
|
+
|
|
668
|
+
/* 供应商选择: 芯片式 (API 配置页, 2026-09-14) */
|
|
669
|
+
.provider-chips {
|
|
670
|
+
display: flex;
|
|
671
|
+
flex-wrap: wrap;
|
|
672
|
+
gap: 8px;
|
|
673
|
+
}
|
|
674
|
+
.provider-chip {
|
|
675
|
+
padding: 8px 14px;
|
|
676
|
+
border: 1px solid var(--border);
|
|
677
|
+
border-radius: 999px;
|
|
678
|
+
background: var(--bg-hover);
|
|
679
|
+
color: var(--text-secondary);
|
|
680
|
+
font-size: 13px;
|
|
681
|
+
line-height: 1.2;
|
|
682
|
+
-webkit-tap-highlight-color: transparent;
|
|
683
|
+
}
|
|
684
|
+
.provider-chip:active { transform: scale(.96); }
|
|
685
|
+
.provider-chip.active {
|
|
686
|
+
border-color: var(--accent);
|
|
687
|
+
background: var(--accent);
|
|
688
|
+
color: var(--bg);
|
|
689
|
+
font-weight: 600;
|
|
690
|
+
}
|
package/dist/web/mobile.html
CHANGED
|
@@ -34,9 +34,10 @@
|
|
|
34
34
|
<div id="app" class="app">
|
|
35
35
|
<!-- 顶部导航 -->
|
|
36
36
|
<header class="topbar">
|
|
37
|
+
<button class="icon-btn" id="btn-index" title="索引"><svg class="ico" viewBox="0 0 24 24"><path d="M4 6h16M4 12h16M4 18h16"/></svg></button>
|
|
37
38
|
<div class="topbar-title" id="topbar-title">首页</div>
|
|
38
39
|
<div class="topbar-actions" id="topbar-actions">
|
|
39
|
-
<button class="icon-btn" id="btn-
|
|
40
|
+
<button class="icon-btn" id="btn-search" title="搜索"><svg class="ico" viewBox="0 0 24 24"><circle cx="11" cy="11" r="6.5"/><path d="M16 16l4.5 4.5"/></svg></button>
|
|
40
41
|
<button class="icon-btn" id="btn-add" title="添加会话"><svg class="ico" viewBox="0 0 24 24"><path d="M12 5v14M5 12h14"/></svg></button>
|
|
41
42
|
</div>
|
|
42
43
|
</header>
|
|
@@ -60,25 +61,34 @@
|
|
|
60
61
|
<div class="detail-body" id="detail-body"></div>
|
|
61
62
|
</div>
|
|
62
63
|
</main>
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
<section class="page" id="page-network" data-tab="network" hidden>
|
|
64
|
+
<!-- 好友 tab: 好友与 P2P (原来散在网络页, 现已归拢; 网络页不再重复这些) -->
|
|
65
|
+
<section class="page" id="page-friends" data-tab="friends" hidden>
|
|
66
66
|
<div class="list">
|
|
67
|
-
<div class="list-item" id="item-join-global"><span class="list-icon"><svg class="ico" viewBox="0 0 24 24"><circle cx="12" cy="12" r="8.5"/><path d="M3.5 12h17"/><path d="M12 3.5c2.7 2.6 2.7 14.4 0 17M12 3.5c-2.7 2.6-2.7 14.4 0 17"/><circle cx="12" cy="12" r="1.2" fill="currentColor" stroke="none"/></svg></span><span>一键入网 · 全球智能体网络</span><span class="list-arrow">›</span></div>
|
|
68
|
-
<div class="list-item" id="item-join-net"><span class="list-icon"><svg class="ico" viewBox="0 0 24 24"><path d="M3.5 9.5a13 13 0 0 1 17 0M6.5 13a8.5 8.5 0 0 1 11 0M9.6 16.3a4 4 0 0 1 4.8 0"/><circle cx="12" cy="19.5" r="1.1" fill="currentColor" stroke="none"/></svg></span><span>加入网络</span><span class="list-arrow">›</span></div>
|
|
69
67
|
<div class="list-item" id="item-add-friend"><span class="list-icon"><svg class="ico" viewBox="0 0 24 24"><circle cx="9" cy="8" r="3.2"/><path d="M3.5 19c.8-3 3-4.6 5.5-4.6S13.7 16 14.5 19"/><path d="M17 8v6M14 11h6"/></svg></span><span>连接好友</span><span class="list-arrow">›</span></div>
|
|
70
68
|
<div class="list-item" id="item-nearby"><span class="list-icon"><svg class="ico" viewBox="0 0 24 24"><path d="M4 12a8 8 0 0 1 16 0"/><path d="M7.5 12a4.5 4.5 0 0 1 9 0"/><circle cx="12" cy="12" r="1.4"/><path d="M12 13.6V19"/></svg></span><span>附近设备</span><span class="list-arrow">›</span></div>
|
|
71
69
|
<div class="list-item" id="item-scan-net"><span class="list-icon"><svg class="ico" viewBox="0 0 24 24"><path d="M4 8V6a2 2 0 0 1 2-2h2M16 4h2a2 2 0 0 1 2 2v2M20 16v2a2 2 0 0 1-2 2h-2M8 20H6a2 2 0 0 1-2-2v-2"/><path d="M4 12h16"/></svg></span><span>扫码入网 / 加好友</span></div>
|
|
72
70
|
</div>
|
|
73
71
|
<input type="file" id="qr-scan-input" accept="image/*" capture="environment" style="display:none">
|
|
74
|
-
<div class="section-label">P2P 连接</div>
|
|
75
|
-
<div class="list" id="p2p-status"></div>
|
|
76
|
-
<div class="section-label">Agent 网络</div>
|
|
77
|
-
<div class="list" id="net-members"></div>
|
|
78
72
|
<div class="list">
|
|
79
73
|
<div class="list-item" id="item-p2p"><span class="list-icon"><svg class="ico" viewBox="0 0 24 24"><circle cx="12" cy="12" r="8.5"/><path d="M3.5 12h17"/><path d="M12 3.5c2.3 2.3 3.5 5.3 3.5 8.5s-1.2 6.2-3.5 8.5c-2.3-2.3-3.5-5.3-3.5-8.5S9.7 5.8 12 3.5z"/></svg></span><span>P2P 好友</span></div>
|
|
80
74
|
<div class="list-item" id="item-p2p-id"><span class="list-icon"><svg class="ico" viewBox="0 0 24 24"><rect x="3" y="5.5" width="18" height="13" rx="2.5"/><circle cx="8.5" cy="11" r="2"/><path d="M5.6 15.8a3.2 3.2 0 0 1 5.8 0M13.5 10h5M13.5 13.5h5"/></svg></span><span>我的 P2P ID</span></div>
|
|
81
75
|
</div>
|
|
76
|
+
<div class="section-label">P2P 连接</div>
|
|
77
|
+
<div class="list" id="p2p-status"></div>
|
|
78
|
+
<div class="section-label">好友列表</div>
|
|
79
|
+
<div class="list" id="contacts-list"></div>
|
|
80
|
+
</section>
|
|
81
|
+
|
|
82
|
+
</main>
|
|
83
|
+
|
|
84
|
+
<!-- 网络 tab -->
|
|
85
|
+
<section class="page" id="page-network" data-tab="network" hidden>
|
|
86
|
+
<div class="list">
|
|
87
|
+
<div class="list-item" id="item-join-global"><span class="list-icon"><svg class="ico" viewBox="0 0 24 24"><circle cx="12" cy="12" r="8.5"/><path d="M3.5 12h17"/><path d="M12 3.5c2.7 2.6 2.7 14.4 0 17M12 3.5c-2.7 2.6-2.7 14.4 0 17"/><circle cx="12" cy="12" r="1.2" fill="currentColor" stroke="none"/></svg></span><span>一键入网 · 全球智能体网络</span><span class="list-arrow">›</span></div>
|
|
88
|
+
<div class="list-item" id="item-join-net"><span class="list-icon"><svg class="ico" viewBox="0 0 24 24"><path d="M3.5 9.5a13 13 0 0 1 17 0M6.5 13a8.5 8.5 0 0 1 11 0M9.6 16.3a4 4 0 0 1 4.8 0"/><circle cx="12" cy="19.5" r="1.1" fill="currentColor" stroke="none"/></svg></span><span>加入网络</span><span class="list-arrow">›</span></div>
|
|
89
|
+
</div>
|
|
90
|
+
<div class="section-label">Agent 网络</div>
|
|
91
|
+
<div class="list" id="net-members"></div>
|
|
82
92
|
<div class="section-label">Agent 服务 (协议自动发现)</div>
|
|
83
93
|
<div class="list" id="agent-services"></div>
|
|
84
94
|
<div class="list">
|
|
@@ -86,10 +96,8 @@
|
|
|
86
96
|
</div>
|
|
87
97
|
<div class="section-label">微信息 (微支付)</div>
|
|
88
98
|
<div class="list" id="x402-info-list"></div>
|
|
89
|
-
<div class="section-label"
|
|
90
|
-
<div class="list" id="
|
|
91
|
-
<div class="section-label">MCP 工具 (触控调用)</div>
|
|
92
|
-
<div class="list" id="mcp-tools"></div>
|
|
99
|
+
<div class="section-label">智能体控制 (MCP / Skills)</div>
|
|
100
|
+
<div class="list" id="agent-control"></div>
|
|
93
101
|
<div class="section-label">待人工审批支付</div>
|
|
94
102
|
<div class="list" id="approval-list"></div>
|
|
95
103
|
<div class="section-label">A2UI 动态面板 (智能体生成)</div>
|
|
@@ -122,6 +130,7 @@
|
|
|
122
130
|
<!-- 底部 tab -->
|
|
123
131
|
<nav class="tabbar" id="tabbar">
|
|
124
132
|
<button class="tab active" data-tab="main"><span class="tab-icon"><svg class="ico" viewBox="0 0 24 24"><rect x="3.5" y="3.5" width="7" height="7" rx="1.6"/><rect x="13.5" y="3.5" width="7" height="7" rx="1.6"/><rect x="3.5" y="13.5" width="7" height="7" rx="1.6"/><rect x="13.5" y="13.5" width="7" height="7" rx="1.6"/></svg></span><span>首页</span></button>
|
|
133
|
+
<button class="tab" data-tab="friends"><span class="tab-icon"><svg class="ico" viewBox="0 0 24 24"><circle cx="9" cy="8" r="3.2"/><path d="M3.5 19c.8-3 3-4.6 5.5-4.6S13.7 16 14.5 19"/><path d="M17 8v6M14 11h6"/></svg></span><span>好友</span></button>
|
|
125
134
|
<button class="tab" data-tab="network"><span class="tab-icon"><svg class="ico" viewBox="0 0 24 24"><circle cx="12" cy="12" r="8.5"/><path d="M3.5 12h17"/><path d="M12 3.5c2.3 2.3 3.5 5.3 3.5 8.5s-1.2 6.2-3.5 8.5c-2.3-2.3-3.5-5.3-3.5-8.5S9.7 5.8 12 3.5z"/></svg></span><span>网络</span></button>
|
|
126
135
|
<button class="tab" data-tab="me"><span class="tab-icon"><svg class="ico" viewBox="0 0 24 24"><circle cx="12" cy="8.5" r="4"/><path d="M4.5 20.5a7.5 7.5 0 0 1 15 0"/></svg></span><span>我</span></button>
|
|
127
136
|
</nav>
|