@on-panda/on-panda-core 0.5.10
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/AudioPlugin-B_mT-q95.js +162 -0
- package/dist/ImagePlugin-BueR6PXa.js +30 -0
- package/dist/browserAgentMcp-j4Vh1Sig.js +243 -0
- package/dist/defaultCustom-l0sNRNKZ.js +1 -0
- package/dist/img/on-panda-demo-candidate-continue-generating-cn.mp4 +0 -0
- package/dist/img/on-panda-logo-256x256.png +0 -0
- package/dist/index.core-8d8dnaVi.js +9859 -0
- package/dist/on-panda-core.es.js +21 -0
- package/dist/style.css +1 -0
- package/package.json +43 -0
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import { ref as u, computed as g, watch as w, onMounted as y, onUnmounted as C, createElementBlock as d, openBlock as p, createElementVNode as f, createCommentVNode as x } from "vue";
|
|
2
|
+
import _ from "wavesurfer.js";
|
|
3
|
+
import { _ as E, m as k } from "./index.core-8d8dnaVi.js";
|
|
4
|
+
class W {
|
|
5
|
+
constructor() {
|
|
6
|
+
this.listeners = {};
|
|
7
|
+
}
|
|
8
|
+
on(e, s, t) {
|
|
9
|
+
if (this.listeners[e] || (this.listeners[e] = /* @__PURE__ */ new Set()), this.listeners[e].add(s), t == null ? void 0 : t.once) {
|
|
10
|
+
const n = () => {
|
|
11
|
+
this.un(e, n), this.un(e, s);
|
|
12
|
+
};
|
|
13
|
+
return this.on(e, n), n;
|
|
14
|
+
}
|
|
15
|
+
return () => this.un(e, s);
|
|
16
|
+
}
|
|
17
|
+
un(e, s) {
|
|
18
|
+
var t;
|
|
19
|
+
(t = this.listeners[e]) === null || t === void 0 || t.delete(s);
|
|
20
|
+
}
|
|
21
|
+
once(e, s) {
|
|
22
|
+
return this.on(e, s, { once: !0 });
|
|
23
|
+
}
|
|
24
|
+
unAll() {
|
|
25
|
+
this.listeners = {};
|
|
26
|
+
}
|
|
27
|
+
emit(e, ...s) {
|
|
28
|
+
this.listeners[e] && this.listeners[e].forEach((t) => t(...s));
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
class L extends W {
|
|
32
|
+
constructor(e) {
|
|
33
|
+
super(), this.subscriptions = [], this.options = e;
|
|
34
|
+
}
|
|
35
|
+
onInit() {
|
|
36
|
+
}
|
|
37
|
+
_init(e) {
|
|
38
|
+
this.wavesurfer = e, this.onInit();
|
|
39
|
+
}
|
|
40
|
+
destroy() {
|
|
41
|
+
this.emit("destroy"), this.subscriptions.forEach((e) => e());
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
function m(r, e) {
|
|
45
|
+
const s = e.xmlns ? document.createElementNS(e.xmlns, r) : document.createElement(r);
|
|
46
|
+
for (const [t, n] of Object.entries(e)) if (t === "children") for (const [o, i] of Object.entries(e)) typeof i == "string" ? s.appendChild(document.createTextNode(i)) : s.appendChild(m(o, i));
|
|
47
|
+
else t === "style" ? Object.assign(s.style, n) : t === "textContent" ? s.textContent = n : s.setAttribute(t, n.toString());
|
|
48
|
+
return s;
|
|
49
|
+
}
|
|
50
|
+
function v(r, e, s) {
|
|
51
|
+
const t = m(r, e || {});
|
|
52
|
+
return s == null || s.appendChild(t), t;
|
|
53
|
+
}
|
|
54
|
+
const S = { lineWidth: 1, labelSize: 11, formatTimeCallback: (r) => `${Math.floor(r / 60)}:${`0${Math.floor(r) % 60}`.slice(-2)}` };
|
|
55
|
+
class h extends L {
|
|
56
|
+
constructor(e) {
|
|
57
|
+
super(e || {}), this.unsubscribe = () => {
|
|
58
|
+
}, this.onPointerMove = (s) => {
|
|
59
|
+
if (!this.wavesurfer) return;
|
|
60
|
+
const t = this.wavesurfer.getWrapper().getBoundingClientRect(), { width: n } = t, o = s.clientX - t.left, i = Math.min(1, Math.max(0, o / n)), c = Math.min(n - this.options.lineWidth - 1, o);
|
|
61
|
+
this.wrapper.style.transform = `translateX(${c}px)`, this.wrapper.style.opacity = "1";
|
|
62
|
+
const a = this.wavesurfer.getDuration() || 0;
|
|
63
|
+
this.label.textContent = this.options.formatTimeCallback(a * i);
|
|
64
|
+
const l = this.label.offsetWidth;
|
|
65
|
+
this.label.style.transform = c + l > n ? `translateX(-${l + this.options.lineWidth}px)` : "", this.emit("hover", i);
|
|
66
|
+
}, this.onPointerLeave = () => {
|
|
67
|
+
this.wrapper.style.opacity = "0";
|
|
68
|
+
}, this.options = Object.assign({}, S, e), this.wrapper = v("div", { part: "hover" }), this.label = v("span", { part: "hover-label" }, this.wrapper);
|
|
69
|
+
}
|
|
70
|
+
static create(e) {
|
|
71
|
+
return new h(e);
|
|
72
|
+
}
|
|
73
|
+
addUnits(e) {
|
|
74
|
+
return `${e}${typeof e == "number" ? "px" : ""}`;
|
|
75
|
+
}
|
|
76
|
+
onInit() {
|
|
77
|
+
if (!this.wavesurfer) throw Error("WaveSurfer is not initialized");
|
|
78
|
+
const e = this.wavesurfer.options, s = this.options.lineColor || e.cursorColor || e.progressColor;
|
|
79
|
+
Object.assign(this.wrapper.style, { position: "absolute", zIndex: 10, left: 0, top: 0, height: "100%", pointerEvents: "none", borderLeft: `${this.addUnits(this.options.lineWidth)} solid ${s}`, opacity: "0", transition: "opacity .1s ease-in" }), Object.assign(this.label.style, { display: "block", backgroundColor: this.options.labelBackground, color: this.options.labelColor, fontSize: `${this.addUnits(this.options.labelSize)}`, transition: "transform .1s ease-in", padding: "2px 3px" });
|
|
80
|
+
const t = this.wavesurfer.getWrapper();
|
|
81
|
+
t.appendChild(this.wrapper), t.addEventListener("pointermove", this.onPointerMove), t.addEventListener("pointerleave", this.onPointerLeave), t.addEventListener("wheel", this.onPointerMove), this.unsubscribe = () => {
|
|
82
|
+
t.removeEventListener("pointermove", this.onPointerMove), t.removeEventListener("pointerleave", this.onPointerLeave), t.removeEventListener("wheel", this.onPointerLeave);
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
destroy() {
|
|
86
|
+
super.destroy(), this.unsubscribe(), this.wrapper.remove();
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
const z = { class: "on-panda-audio-plugin" }, M = ["src"], P = {
|
|
90
|
+
key: 0,
|
|
91
|
+
class: "fallback-message"
|
|
92
|
+
}, $ = {
|
|
93
|
+
__name: "AudioPlugin",
|
|
94
|
+
props: {
|
|
95
|
+
content: {
|
|
96
|
+
type: Object,
|
|
97
|
+
default: () => ({})
|
|
98
|
+
}
|
|
99
|
+
},
|
|
100
|
+
setup(r) {
|
|
101
|
+
const e = r, s = u(null), t = u(null), n = u(!1);
|
|
102
|
+
let o = null;
|
|
103
|
+
const i = g(() => k(e.content).base64_url), c = () => {
|
|
104
|
+
if (!(!s.value || !t.value || !i.value))
|
|
105
|
+
try {
|
|
106
|
+
o = _.create({
|
|
107
|
+
container: s.value,
|
|
108
|
+
waveColor: "rgba(255, 165, 0, 1)",
|
|
109
|
+
// Orange
|
|
110
|
+
progressColor: "rgba(192, 192, 192, 1)",
|
|
111
|
+
// Light gray
|
|
112
|
+
media: t.value,
|
|
113
|
+
// This binds to the visible audio element
|
|
114
|
+
normalize: !0,
|
|
115
|
+
height: 60,
|
|
116
|
+
plugins: [
|
|
117
|
+
h.create({
|
|
118
|
+
lineColor: "#ff0000",
|
|
119
|
+
lineWidth: 2,
|
|
120
|
+
labelBackground: "#555",
|
|
121
|
+
labelColor: "#fff",
|
|
122
|
+
labelSize: "11px"
|
|
123
|
+
})
|
|
124
|
+
]
|
|
125
|
+
}), o.on("ready", () => {
|
|
126
|
+
n.value = !0, s.value.addEventListener("click", (a) => {
|
|
127
|
+
const l = s.value.getBoundingClientRect(), b = (a.clientX - l.left) / l.width;
|
|
128
|
+
o.seekTo(b), t.value.play();
|
|
129
|
+
});
|
|
130
|
+
}), o.on("error", (a) => {
|
|
131
|
+
console.error("WaveSurfer error:", a), n.value = !1;
|
|
132
|
+
});
|
|
133
|
+
} catch (a) {
|
|
134
|
+
console.error("Failed to initialize WaveSurfer:", a), n.value = !1;
|
|
135
|
+
}
|
|
136
|
+
};
|
|
137
|
+
return w(i, () => {
|
|
138
|
+
o && (o.destroy(), o = null, n.value = !1), i.value && setTimeout(c, 100);
|
|
139
|
+
}, { immediate: !1 }), y(() => {
|
|
140
|
+
i.value && c();
|
|
141
|
+
}), C(() => {
|
|
142
|
+
o && o.destroy();
|
|
143
|
+
}), (a, l) => (p(), d("div", z, [
|
|
144
|
+
f("div", {
|
|
145
|
+
ref_key: "waveformContainer",
|
|
146
|
+
ref: s,
|
|
147
|
+
class: "waveform-container"
|
|
148
|
+
}, null, 512),
|
|
149
|
+
f("audio", {
|
|
150
|
+
ref_key: "audioElement",
|
|
151
|
+
ref: t,
|
|
152
|
+
src: i.value,
|
|
153
|
+
controls: "",
|
|
154
|
+
class: "audio-controls"
|
|
155
|
+
}, null, 8, M),
|
|
156
|
+
!n.value && i.value ? (p(), d("div", P, " Waveform visualization unavailable - using audio controls only ")) : x("", !0)
|
|
157
|
+
]));
|
|
158
|
+
}
|
|
159
|
+
}, I = /* @__PURE__ */ E($, [["__scopeId", "data-v-0e4cb895"]]);
|
|
160
|
+
export {
|
|
161
|
+
I as default
|
|
162
|
+
};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { computed as a, createElementBlock as r, openBlock as s } from "vue";
|
|
2
|
+
import { _ as i } from "./index.core-8d8dnaVi.js";
|
|
3
|
+
const u = ["src"], _ = {
|
|
4
|
+
__name: "ImagePlugin",
|
|
5
|
+
props: {
|
|
6
|
+
content: {
|
|
7
|
+
type: Object,
|
|
8
|
+
default: () => ({})
|
|
9
|
+
}
|
|
10
|
+
},
|
|
11
|
+
setup(o) {
|
|
12
|
+
const e = o, t = a(() => e.content.blob_url || e.content.image_url.url);
|
|
13
|
+
function c(n) {
|
|
14
|
+
n.target.classList.toggle("rawSizeImg");
|
|
15
|
+
}
|
|
16
|
+
function l() {
|
|
17
|
+
window.open(t.value, "_blank");
|
|
18
|
+
}
|
|
19
|
+
return (n, p) => (s(), r("img", {
|
|
20
|
+
class: "on-panda-image-plugin",
|
|
21
|
+
src: t.value,
|
|
22
|
+
alt: "<|ON_PANDA_IMAGE|>",
|
|
23
|
+
onClick: c,
|
|
24
|
+
onDblclick: l
|
|
25
|
+
}, null, 40, u));
|
|
26
|
+
}
|
|
27
|
+
}, d = /* @__PURE__ */ i(_, [["__scopeId", "data-v-65b62084"]]);
|
|
28
|
+
export {
|
|
29
|
+
d as default
|
|
30
|
+
};
|
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
const M = Object.getPrototypeOf(async function() {
|
|
2
|
+
}).constructor, R = 256 * 1024, g = 200, w = 6e4, j = {
|
|
3
|
+
"image/png": "image",
|
|
4
|
+
"image/jpeg": "image",
|
|
5
|
+
"image/gif": "image",
|
|
6
|
+
"image/webp": "image",
|
|
7
|
+
"audio/wav": "audio",
|
|
8
|
+
"audio/mp3": "audio",
|
|
9
|
+
"audio/mpeg": "audio",
|
|
10
|
+
"video/mp4": "video",
|
|
11
|
+
"video/webm": "video",
|
|
12
|
+
"video/quicktime": "video"
|
|
13
|
+
}, x = {
|
|
14
|
+
name: "run_browser_js",
|
|
15
|
+
description: "Run JavaScript in the current browser runtime and return logs from `console.log`. `console.log` accepts `Blob` arguments of MCP-supported image, audio, and video types, returned as inline media in your context. Each tool call uses a fresh local scope, so local variables do not persist across calls, but shared globals like window and document do persist. Your JavaScript local scope includes a `browserAgent` variable. For content that should be reused across tool calls, prefer storing it on the `browserAgent.local` object. You can access the internet under CORS restrictions. Do not refresh or switch the current webpage, as this will reset the JavaScript runtime and your context lost.",
|
|
16
|
+
inputSchema: {
|
|
17
|
+
type: "object",
|
|
18
|
+
properties: {
|
|
19
|
+
code: {
|
|
20
|
+
type: "string",
|
|
21
|
+
description: "If your code starts any async work, such as fetch, promises, or async functions, await it with top-level await or await the returned promise; otherwise the tool may return before later logs run. Do not rely on un-awaited .then() callbacks for console.log output."
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}, $ = {
|
|
26
|
+
name: "render_svg",
|
|
27
|
+
description: "Render an SVG string into a bitmap PNG image. The tool uses the SVG width/height, or falls back to viewBox.",
|
|
28
|
+
inputSchema: {
|
|
29
|
+
type: "object",
|
|
30
|
+
properties: {
|
|
31
|
+
svg: {
|
|
32
|
+
type: "string",
|
|
33
|
+
description: "SVG markup to render. It must start with `<svg` and end with `</svg>`."
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
function O(e) {
|
|
39
|
+
return new Promise((t, n) => {
|
|
40
|
+
const r = new FileReader();
|
|
41
|
+
r.onload = () => {
|
|
42
|
+
const o = r.result;
|
|
43
|
+
t(o.slice(o.indexOf(",") + 1));
|
|
44
|
+
}, r.onerror = n, r.readAsDataURL(e);
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
function y(e = "") {
|
|
48
|
+
return `<|js_error_start|>
|
|
49
|
+
${e}
|
|
50
|
+
<|js_error_end|>`;
|
|
51
|
+
}
|
|
52
|
+
function v(e = "", t = R) {
|
|
53
|
+
if (e.length <= t)
|
|
54
|
+
return e;
|
|
55
|
+
const n = Math.ceil(t / 2), r = t - n, o = e.length - t;
|
|
56
|
+
return `(Total length: ${e.length} characters. Showing ${t} characters after truncating the middle.)
|
|
57
|
+
${e.slice(0, n)}
|
|
58
|
+
<|truncate_long_text|>
|
|
59
|
+
{Output exceeded ${t} characters. Omitted ${o} characters from the middle.} ......
|
|
60
|
+
<|truncate_long_text|>
|
|
61
|
+
${e.slice(e.length - r)}`;
|
|
62
|
+
}
|
|
63
|
+
async function E() {
|
|
64
|
+
return await (await (await (await (await (await navigator.storage.getDirectory()).getDirectoryHandle("browser-agent", { create: !0 })).getDirectoryHandle("memory", { create: !0 })).getFileHandle("MEMORY.md", { create: !0 })).getFile()).text();
|
|
65
|
+
}
|
|
66
|
+
function A(e = "") {
|
|
67
|
+
const t = e.split(`
|
|
68
|
+
`), n = [];
|
|
69
|
+
let r = t.length > g ? t.slice(0, g).join(`
|
|
70
|
+
`) : e;
|
|
71
|
+
return t.length > g && n.push(`original ${t.length} lines exceeded ${g} lines`), e.length > w && n.push(`original ${e.length} characters exceeded ${w} characters`), r.length > w && (r = r.slice(0, w)), {
|
|
72
|
+
text: r,
|
|
73
|
+
truncationReason: n.length ? `Truncated: ${n.join("; ")}. So, find an opportunity to organize the memory: clean up or archive outdated or unimportant information, move less important content out of the MEMORY.md into other files or folders under \`browser-agent/memory/\`, and keep only brief descriptions and references in the MEMORY.md so you can read the archived content later when needed.` : ""
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
async function B() {
|
|
77
|
+
const e = `## Persistent memory
|
|
78
|
+
Persistent memory is stored in files or folders under \`browser-agent/memory/\` in the current origin's OPFS. Use \`run_browser_js\` and \`navigator.storage.getDirectory()\` to record, modify, and query memory when needed. \`browser-agent/memory/MEMORY.md\` is always loaded into your conversation context. Keep it concise; it is truncated after ${g} lines or ${w} characters.`, t = await E();
|
|
79
|
+
if (!t.trim())
|
|
80
|
+
return `${e}
|
|
81
|
+
The current \`browser-agent/memory/MEMORY.md\` is empty.`;
|
|
82
|
+
const { text: n, truncationReason: r } = A(t);
|
|
83
|
+
return `${e}
|
|
84
|
+
### the MEMORY.md
|
|
85
|
+
<|browser_agent_memory_start|>
|
|
86
|
+
${n}
|
|
87
|
+
<|browser_agent_memory_end|>${r ? `
|
|
88
|
+
${r}` : ""}`;
|
|
89
|
+
}
|
|
90
|
+
async function U(e = "", t) {
|
|
91
|
+
const n = [], r = [], o = performance.now(), s = {
|
|
92
|
+
...console,
|
|
93
|
+
log(...i) {
|
|
94
|
+
const a = i.map((c) => {
|
|
95
|
+
const f = c instanceof Blob ? j[c.type] : null;
|
|
96
|
+
if (f) {
|
|
97
|
+
const b = { type: f, mimeType: c.type, data: "" };
|
|
98
|
+
return r.push(O(c).then((S) => {
|
|
99
|
+
b.data = S;
|
|
100
|
+
})), b;
|
|
101
|
+
}
|
|
102
|
+
return String(c);
|
|
103
|
+
});
|
|
104
|
+
n.push({ kind: "log", row: a }), console.log("[run_browser_js.log]:", ...i);
|
|
105
|
+
},
|
|
106
|
+
error(...i) {
|
|
107
|
+
const a = i.map((c) => String(c)).join(" ");
|
|
108
|
+
n.push({ kind: "error", text: y(a) }), console.log("[run_browser_js.error]:", a);
|
|
109
|
+
}
|
|
110
|
+
}, p = t({ callScope: { console: s } });
|
|
111
|
+
try {
|
|
112
|
+
await new M("console", "browserAgent", e)(s, p);
|
|
113
|
+
} catch (i) {
|
|
114
|
+
const a = String(i);
|
|
115
|
+
n.push({ kind: "error", text: y(a) }), console.log("[run_browser_js.error]:", a);
|
|
116
|
+
}
|
|
117
|
+
await Promise.all(r);
|
|
118
|
+
const h = [{
|
|
119
|
+
type: "text",
|
|
120
|
+
text: `<|execution_info_start|>
|
|
121
|
+
Code execution time: ${Math.round(performance.now() - o)} ms
|
|
122
|
+
<|execution_info_end|>`
|
|
123
|
+
}];
|
|
124
|
+
n.some((i) => i.kind === "log") || h.push({ type: "text", text: "<|no_js_log|>" });
|
|
125
|
+
let l = "";
|
|
126
|
+
const u = () => {
|
|
127
|
+
l && (h.push({ type: "text", text: v(l) }), l = "");
|
|
128
|
+
};
|
|
129
|
+
return n.forEach((i) => {
|
|
130
|
+
i.kind === "log" ? i.row.forEach((a, c) => {
|
|
131
|
+
typeof a == "string" ? (l && (l += c === 0 ? `
|
|
132
|
+
` : " "), l += a) : (u(), h.push(a));
|
|
133
|
+
}) : (u(), h.push({ type: "text", text: v(i.text) }));
|
|
134
|
+
}), u(), h;
|
|
135
|
+
}
|
|
136
|
+
async function F(e = "") {
|
|
137
|
+
const t = URL.createObjectURL(new Blob([e], { type: "image/svg+xml" }));
|
|
138
|
+
try {
|
|
139
|
+
const n = await new Promise((h, l) => {
|
|
140
|
+
const u = new Image();
|
|
141
|
+
u.onload = () => h(u), u.onerror = l, u.src = t;
|
|
142
|
+
}), r = new DOMParser().parseFromString(e, "image/svg+xml").documentElement, o = Number.parseFloat(r.getAttribute("width")), s = Number.parseFloat(r.getAttribute("height")), p = (r.getAttribute("viewBox") || "").trim().split(/[\s,]+/).map(Number), d = document.createElement("canvas");
|
|
143
|
+
return d.width = Number.isFinite(o) && Number.isFinite(s) ? o : p.length === 4 ? p[2] : n.naturalWidth, d.height = Number.isFinite(o) && Number.isFinite(s) ? s : p.length === 4 ? p[3] : n.naturalHeight, d.getContext("2d").drawImage(n, 0, 0, d.width, d.height), d.toDataURL("image/png").slice(22);
|
|
144
|
+
} finally {
|
|
145
|
+
URL.revokeObjectURL(t);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
function k(e, t = {}) {
|
|
149
|
+
return new Response(JSON.stringify(e), {
|
|
150
|
+
status: 200,
|
|
151
|
+
headers: {
|
|
152
|
+
"content-type": "application/json"
|
|
153
|
+
},
|
|
154
|
+
...t
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
function m(e, t) {
|
|
158
|
+
return k({
|
|
159
|
+
jsonrpc: "2.0",
|
|
160
|
+
id: e,
|
|
161
|
+
result: t
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
function _(e, t, n) {
|
|
165
|
+
return k({
|
|
166
|
+
jsonrpc: "2.0",
|
|
167
|
+
id: e,
|
|
168
|
+
error: {
|
|
169
|
+
code: t,
|
|
170
|
+
message: n
|
|
171
|
+
}
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
async function I({ message: e = {}, instructions: t = "", buildBrowserAgent: n } = {}) {
|
|
175
|
+
var r, o;
|
|
176
|
+
if (e.method === "initialize")
|
|
177
|
+
return m(e.id, {
|
|
178
|
+
protocolVersion: e.params.protocolVersion,
|
|
179
|
+
capabilities: {
|
|
180
|
+
tools: {}
|
|
181
|
+
},
|
|
182
|
+
serverInfo: {
|
|
183
|
+
name: "browser-agent-mcp",
|
|
184
|
+
version: "0.1.0"
|
|
185
|
+
},
|
|
186
|
+
instructions: t
|
|
187
|
+
});
|
|
188
|
+
if (e.method === "ping")
|
|
189
|
+
return m(e.id, {});
|
|
190
|
+
if (e.method === "tools/list")
|
|
191
|
+
return m(e.id, {
|
|
192
|
+
tools: [x, $]
|
|
193
|
+
});
|
|
194
|
+
if (e.method === "tools/call") {
|
|
195
|
+
if (e.params.name === "run_browser_js") {
|
|
196
|
+
const s = await U(((r = e.params.arguments) == null ? void 0 : r.code) || "", n);
|
|
197
|
+
return m(e.id, { content: s });
|
|
198
|
+
}
|
|
199
|
+
if (e.params.name === "render_svg") {
|
|
200
|
+
const s = await F(((o = e.params.arguments) == null ? void 0 : o.svg) || "");
|
|
201
|
+
return m(e.id, {
|
|
202
|
+
content: [{ type: "image", mimeType: "image/png", data: s }]
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
return _(e.id, -32601, `Tool not found: ${e.params.name}`);
|
|
206
|
+
}
|
|
207
|
+
return e.id == null ? new Response(null, { status: 204 }) : _(e.id, -32601, `Method not found: ${e.method}`);
|
|
208
|
+
}
|
|
209
|
+
async function T({ proxyPath: e = "" } = {}) {
|
|
210
|
+
return `You are an agent running in a browser. You are operating in the JavaScript runtime of the current webpage, where the user interacts with you. Please make the appropriate adjustments for this browser JavaScript environment.
|
|
211
|
+
|
|
212
|
+
## Skills
|
|
213
|
+
A skill is a set of instructions to follow that is stored in a \`SKILL.md\` file. Below is the list of skills that can be used. Each entry includes a name, description, and skillUrl so you can open the source for full instructions when using a specific skill.
|
|
214
|
+
### Available skills
|
|
215
|
+
- \`cors-internet\`: Skill for web search and information retrieval under CORS. Use when you need to access the internet. ([skillUrl](https://raw.githubusercontent.com/on-panda/browser-agent-skills/main/skills/cors-internet/SKILL.md))${e ? `
|
|
216
|
+
- Fallback: for critical resources that even cors-internet cannot reach, use the server-side proxy at \`${e}/{url}\`.` : ""}
|
|
217
|
+
- \`interactive-webpage\`: Use when you need to create webpages or interactive artifacts, or modify the current UI. ([skillUrl](https://raw.githubusercontent.com/on-panda/browser-agent-skills/main/skills/interactive-webpage/SKILL.md))
|
|
218
|
+
- \`user-local-files\`: Use when the user shares local files, indicated by \`<|user_local_files\` in the context. Includes local filesystem read/write guidelines and common tools. ([skillUrl](https://raw.githubusercontent.com/on-panda/browser-agent-skills/main/skills/user-local-files/SKILL.md))
|
|
219
|
+
### How to load skills
|
|
220
|
+
If the task clearly matches a skill's description shown above, using tool "run_browser_js" with this pattern code to load the skill:
|
|
221
|
+
\`\`\`js
|
|
222
|
+
await fetch(skillUrl).then(res => res.text()).then(console.log)
|
|
223
|
+
\`\`\`
|
|
224
|
+
|
|
225
|
+
${await B()}`;
|
|
226
|
+
}
|
|
227
|
+
function L({ buildBrowserAgent: e, proxyPath: t = "" } = {}) {
|
|
228
|
+
return {
|
|
229
|
+
localFetch: async function(r, o = {}) {
|
|
230
|
+
if ((o.method || "GET") !== "POST")
|
|
231
|
+
return new Response(null, { status: 405 });
|
|
232
|
+
const s = JSON.parse(o.body || "{}");
|
|
233
|
+
return await I({
|
|
234
|
+
message: s,
|
|
235
|
+
instructions: s.method === "initialize" ? await T({ proxyPath: t }) : "",
|
|
236
|
+
buildBrowserAgent: e
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
export {
|
|
242
|
+
L as BrowserAgentMcpClosure
|
|
243
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
Binary file
|
|
Binary file
|