@melaya/runner 1.0.84 → 1.0.86
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/assistantHost.py +63 -6
- package/package.json +42 -42
package/dist/assistantHost.py
CHANGED
|
@@ -46,6 +46,55 @@ _stream = {"turnId": "", "lens": {}, "cancel": False}
|
|
|
46
46
|
_CANCELLED = object()
|
|
47
47
|
|
|
48
48
|
|
|
49
|
+
class _RedactingStdout:
|
|
50
|
+
"""Wrap stdout to strip long base64 runs before they reach the log.
|
|
51
|
+
|
|
52
|
+
agentscope prints every agent message verbatim (the `MelayaAssistant: {...}`
|
|
53
|
+
lines), which for phone_screenshot tool results embeds a full base64 JPEG —
|
|
54
|
+
tens of KB per turn that floods and explodes the runner logs. This filter is
|
|
55
|
+
line-buffered and only replaces base64-looking runs (>=200 chars), so the
|
|
56
|
+
structured `MELASSIST ` event lines (short text deltas / tool names) pass
|
|
57
|
+
through byte-for-byte and the runner's line parser is unaffected."""
|
|
58
|
+
|
|
59
|
+
import re as _re
|
|
60
|
+
_B64 = _re.compile(r"[A-Za-z0-9+/]{200,}={0,2}")
|
|
61
|
+
|
|
62
|
+
def __init__(self, real):
|
|
63
|
+
self._real = real
|
|
64
|
+
self._buf = ""
|
|
65
|
+
|
|
66
|
+
def _scrub(self, s: str) -> str:
|
|
67
|
+
return self._B64.sub(lambda m: f"<redacted base64 {len(m.group(0))} bytes>", s)
|
|
68
|
+
|
|
69
|
+
def write(self, s):
|
|
70
|
+
try:
|
|
71
|
+
self._buf += s
|
|
72
|
+
while "\n" in self._buf:
|
|
73
|
+
line, self._buf = self._buf.split("\n", 1)
|
|
74
|
+
self._real.write(self._scrub(line) + "\n")
|
|
75
|
+
return len(s)
|
|
76
|
+
except Exception:
|
|
77
|
+
return self._real.write(s)
|
|
78
|
+
|
|
79
|
+
def flush(self):
|
|
80
|
+
try:
|
|
81
|
+
if self._buf:
|
|
82
|
+
self._real.write(self._scrub(self._buf))
|
|
83
|
+
self._buf = ""
|
|
84
|
+
self._real.flush()
|
|
85
|
+
except Exception:
|
|
86
|
+
pass
|
|
87
|
+
|
|
88
|
+
def __getattr__(self, k):
|
|
89
|
+
return getattr(self._real, k)
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
# Install the redactor as early as possible so agentscope's message printing is
|
|
93
|
+
# filtered for the whole process lifetime.
|
|
94
|
+
if not isinstance(sys.stdout, _RedactingStdout):
|
|
95
|
+
sys.stdout = _RedactingStdout(sys.stdout)
|
|
96
|
+
|
|
97
|
+
|
|
49
98
|
def _emit(turn_id: str, kind: str, **fields) -> None:
|
|
50
99
|
"""Write one structured event line to stdout (flushed) for the runner to relay."""
|
|
51
100
|
try:
|
|
@@ -127,14 +176,22 @@ def _build_agent():
|
|
|
127
176
|
"tap, type, comment, post), use the phone_* tools. ALWAYS call "
|
|
128
177
|
"phone_get_screen_tree before you tap or type. Publish comments/posts with "
|
|
129
178
|
"phone_post_comment / phone_create_post — every publish is approved by the "
|
|
130
|
-
"user ON THEIR PHONE, so never refuse for safety
|
|
131
|
-
"
|
|
179
|
+
"user ON THEIR PHONE, so never refuse for safety.\n"
|
|
180
|
+
"- EXACT APP ONLY — this overrides your autonomy: operate on the EXACT app "
|
|
181
|
+
"the user named, never a different one. If that app is not in the allowlist "
|
|
182
|
+
"(phone_open_app returns app_not_allowed) or not installed, STOP and tell the "
|
|
183
|
+
"user to authorize/install it in Device Control. NEVER substitute a 'similar', "
|
|
184
|
+
"'closest', or 'equivalent' app (e.g. do NOT open Instagram when asked for "
|
|
185
|
+
"TikTok). Opening the wrong app is a FAILED task, not a reasonable default. "
|
|
186
|
+
"After the user authorizes the app, phone_list_apps reflects it immediately — "
|
|
187
|
+
"re-check and open the REQUESTED app.\n"
|
|
132
188
|
"- You are FULLY AUTONOMOUS on the phone: NEVER ask the user a question, "
|
|
133
189
|
"never end your turn asking for confirmation or offering a choice — make the "
|
|
134
|
-
"reasonable decision and DO it
|
|
135
|
-
"
|
|
136
|
-
"
|
|
137
|
-
"
|
|
190
|
+
"reasonable decision and DO it (the ONE exception is the EXACT-APP rule above: "
|
|
191
|
+
"a missing app is a stop, not a substitution). If a feed is algorithmic, use "
|
|
192
|
+
"the app's own Search / Explore to find the right content yourself. Keep going "
|
|
193
|
+
"until the task is COMPLETE (e.g. all N comments posted) or you are genuinely "
|
|
194
|
+
"blocked; only then report what you did and what (if anything) is blocked.\n"
|
|
138
195
|
if phone_enabled else ""
|
|
139
196
|
)
|
|
140
197
|
sys_prompt = (
|
package/package.json
CHANGED
|
@@ -1,42 +1,42 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@melaya/runner",
|
|
3
|
-
"version": "1.0.
|
|
4
|
-
"description": "Run Melaya AI pipelines locally with your own LM Studio or Ollama models",
|
|
5
|
-
"license": "UNLICENSED",
|
|
6
|
-
"private": false,
|
|
7
|
-
"type": "module",
|
|
8
|
-
"bin": {
|
|
9
|
-
"melaya-runner": "dist/cli.js"
|
|
10
|
-
},
|
|
11
|
-
"main": "dist/index.js",
|
|
12
|
-
"files": [
|
|
13
|
-
"dist/**/*.js",
|
|
14
|
-
"dist/**/*.d.ts",
|
|
15
|
-
"dist/**/*.py",
|
|
16
|
-
"localRagIngest.py",
|
|
17
|
-
"localRagRetrieve.py",
|
|
18
|
-
"nltk_data/**",
|
|
19
|
-
"README.md"
|
|
20
|
-
],
|
|
21
|
-
"scripts": {
|
|
22
|
-
"build": "tsc && node -e \"const fs=require('fs'); fs.copyFileSync('localRagIngest.py','dist/localRagIngest.py'); fs.copyFileSync('localRagRetrieve.py','dist/localRagRetrieve.py'); fs.copyFileSync('src/assistantHost.py','dist/assistantHost.py')\"",
|
|
23
|
-
"prepublishOnly": "npm run build"
|
|
24
|
-
},
|
|
25
|
-
"dependencies": {
|
|
26
|
-
"chalk": "^5.3.0",
|
|
27
|
-
"commander": "^12.0.0",
|
|
28
|
-
"ora": "^8.0.0",
|
|
29
|
-
"playwright": "^1.47.0",
|
|
30
|
-
"socket.io-client": "^4.8.0"
|
|
31
|
-
},
|
|
32
|
-
"devDependencies": {
|
|
33
|
-
"@types/node": "^20.0.0",
|
|
34
|
-
"typescript": "^5.5.0"
|
|
35
|
-
},
|
|
36
|
-
"engines": {
|
|
37
|
-
"node": ">=18"
|
|
38
|
-
},
|
|
39
|
-
"publishConfig": {
|
|
40
|
-
"access": "public"
|
|
41
|
-
}
|
|
42
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@melaya/runner",
|
|
3
|
+
"version": "1.0.86",
|
|
4
|
+
"description": "Run Melaya AI pipelines locally with your own LM Studio or Ollama models",
|
|
5
|
+
"license": "UNLICENSED",
|
|
6
|
+
"private": false,
|
|
7
|
+
"type": "module",
|
|
8
|
+
"bin": {
|
|
9
|
+
"melaya-runner": "dist/cli.js"
|
|
10
|
+
},
|
|
11
|
+
"main": "dist/index.js",
|
|
12
|
+
"files": [
|
|
13
|
+
"dist/**/*.js",
|
|
14
|
+
"dist/**/*.d.ts",
|
|
15
|
+
"dist/**/*.py",
|
|
16
|
+
"localRagIngest.py",
|
|
17
|
+
"localRagRetrieve.py",
|
|
18
|
+
"nltk_data/**",
|
|
19
|
+
"README.md"
|
|
20
|
+
],
|
|
21
|
+
"scripts": {
|
|
22
|
+
"build": "tsc && node -e \"const fs=require('fs'); fs.copyFileSync('localRagIngest.py','dist/localRagIngest.py'); fs.copyFileSync('localRagRetrieve.py','dist/localRagRetrieve.py'); fs.copyFileSync('src/assistantHost.py','dist/assistantHost.py')\"",
|
|
23
|
+
"prepublishOnly": "npm run build"
|
|
24
|
+
},
|
|
25
|
+
"dependencies": {
|
|
26
|
+
"chalk": "^5.3.0",
|
|
27
|
+
"commander": "^12.0.0",
|
|
28
|
+
"ora": "^8.0.0",
|
|
29
|
+
"playwright": "^1.47.0",
|
|
30
|
+
"socket.io-client": "^4.8.0"
|
|
31
|
+
},
|
|
32
|
+
"devDependencies": {
|
|
33
|
+
"@types/node": "^20.0.0",
|
|
34
|
+
"typescript": "^5.5.0"
|
|
35
|
+
},
|
|
36
|
+
"engines": {
|
|
37
|
+
"node": ">=18"
|
|
38
|
+
},
|
|
39
|
+
"publishConfig": {
|
|
40
|
+
"access": "public"
|
|
41
|
+
}
|
|
42
|
+
}
|