opensyn 0.1.3 → 0.1.5
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/README.md +18 -1
- package/README.zh-CN.md +18 -1
- package/index.ts +840 -82
- package/openclaw.plugin.json +1 -1
- package/package.json +1 -1
- package/runtime/opensyn-cli +7 -0
- package/runtime/opensyn-daemon +7 -0
- package/runtime/opensyn-host-distiller.mjs +24 -138
- package/runtime/postinstall.mjs +1 -9
package/openclaw.plugin.json
CHANGED
package/package.json
CHANGED
package/runtime/opensyn-cli
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
set -euo pipefail
|
|
3
3
|
|
|
4
4
|
script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
5
|
+
script_path="$(cd "$script_dir" && pwd)/$(basename "${BASH_SOURCE[0]}")"
|
|
5
6
|
|
|
6
7
|
platform="$(uname -s | tr '[:upper:]' '[:lower:]')"
|
|
7
8
|
arch_raw="$(uname -m)"
|
|
@@ -30,6 +31,12 @@ candidates+=(
|
|
|
30
31
|
)
|
|
31
32
|
|
|
32
33
|
for candidate in "${candidates[@]}"; do
|
|
34
|
+
if [[ -n "$candidate" ]]; then
|
|
35
|
+
candidate_real="$(realpath -m "$candidate" 2>/dev/null || printf '%s' "$candidate")"
|
|
36
|
+
if [[ "$candidate_real" == "$script_path" ]]; then
|
|
37
|
+
continue
|
|
38
|
+
fi
|
|
39
|
+
fi
|
|
33
40
|
if [[ -n "$candidate" && -x "$candidate" ]]; then
|
|
34
41
|
exec "$candidate" "$@"
|
|
35
42
|
fi
|
package/runtime/opensyn-daemon
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
set -euo pipefail
|
|
3
3
|
|
|
4
4
|
script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
5
|
+
script_path="$(cd "$script_dir" && pwd)/$(basename "${BASH_SOURCE[0]}")"
|
|
5
6
|
|
|
6
7
|
platform="$(uname -s | tr '[:upper:]' '[:lower:]')"
|
|
7
8
|
arch_raw="$(uname -m)"
|
|
@@ -30,6 +31,12 @@ candidates+=(
|
|
|
30
31
|
)
|
|
31
32
|
|
|
32
33
|
for candidate in "${candidates[@]}"; do
|
|
34
|
+
if [[ -n "$candidate" ]]; then
|
|
35
|
+
candidate_real="$(realpath -m "$candidate" 2>/dev/null || printf '%s' "$candidate")"
|
|
36
|
+
if [[ "$candidate_real" == "$script_path" ]]; then
|
|
37
|
+
continue
|
|
38
|
+
fi
|
|
39
|
+
fi
|
|
33
40
|
if [[ -n "$candidate" && -x "$candidate" ]]; then
|
|
34
41
|
exec "$candidate" "$@"
|
|
35
42
|
fi
|
|
@@ -1,38 +1,17 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
import { spawnSync } from "node:child_process";
|
|
4
3
|
import fs from "node:fs";
|
|
5
4
|
import path from "node:path";
|
|
6
5
|
|
|
7
6
|
function parseArgs(argv) {
|
|
8
7
|
const options = {
|
|
9
|
-
openclawBin: "openclaw",
|
|
10
|
-
agentId: "main",
|
|
11
|
-
intervalSecs: 60,
|
|
12
|
-
timeoutSecs: 120,
|
|
13
|
-
projectRoot: process.cwd(),
|
|
14
8
|
statePath: "",
|
|
15
9
|
};
|
|
16
10
|
|
|
17
11
|
for (let i = 0; i < argv.length; i += 1) {
|
|
18
12
|
const arg = argv[i];
|
|
19
13
|
const next = argv[i + 1];
|
|
20
|
-
if (arg === "--
|
|
21
|
-
options.openclawBin = next;
|
|
22
|
-
i += 1;
|
|
23
|
-
} else if (arg === "--agent-id" && next) {
|
|
24
|
-
options.agentId = next;
|
|
25
|
-
i += 1;
|
|
26
|
-
} else if (arg === "--interval-secs" && next) {
|
|
27
|
-
options.intervalSecs = Number.parseInt(next, 10) || options.intervalSecs;
|
|
28
|
-
i += 1;
|
|
29
|
-
} else if (arg === "--timeout-secs" && next) {
|
|
30
|
-
options.timeoutSecs = Number.parseInt(next, 10) || options.timeoutSecs;
|
|
31
|
-
i += 1;
|
|
32
|
-
} else if (arg === "--project-root" && next) {
|
|
33
|
-
options.projectRoot = next;
|
|
34
|
-
i += 1;
|
|
35
|
-
} else if (arg === "--state-path" && next) {
|
|
14
|
+
if (arg === "--state-path" && next) {
|
|
36
15
|
options.statePath = next;
|
|
37
16
|
i += 1;
|
|
38
17
|
}
|
|
@@ -41,14 +20,11 @@ function parseArgs(argv) {
|
|
|
41
20
|
return options;
|
|
42
21
|
}
|
|
43
22
|
|
|
44
|
-
function sleep(ms) {
|
|
45
|
-
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
46
|
-
}
|
|
47
|
-
|
|
48
23
|
function updateState(statePath, payload) {
|
|
49
24
|
if (!statePath) {
|
|
50
25
|
return;
|
|
51
26
|
}
|
|
27
|
+
|
|
52
28
|
let previous = {};
|
|
53
29
|
if (fs.existsSync(statePath)) {
|
|
54
30
|
try {
|
|
@@ -57,122 +33,32 @@ function updateState(statePath, payload) {
|
|
|
57
33
|
previous = {};
|
|
58
34
|
}
|
|
59
35
|
}
|
|
36
|
+
|
|
60
37
|
fs.mkdirSync(path.dirname(statePath), { recursive: true });
|
|
61
38
|
fs.writeFileSync(
|
|
62
39
|
statePath,
|
|
63
|
-
`${JSON.stringify(
|
|
64
|
-
"utf8",
|
|
65
|
-
);
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
function buildPrompt(projectRoot) {
|
|
69
|
-
return [
|
|
70
|
-
`Run exactly one OpenSyn autonomous distillation cycle for project ${projectRoot}.`,
|
|
71
|
-
"Rules:",
|
|
72
|
-
"- Use only the OpenClaw-configured host model already available to this local runtime.",
|
|
73
|
-
"- Do not browse, do not call external network tools, and do not use any model outside OpenClaw.",
|
|
74
|
-
"- First call opensyn_autonomous_tick with no arguments.",
|
|
75
|
-
"- If automation_state is idle_waiting_for_activity, stop immediately.",
|
|
76
|
-
"- If automation_state is distillation_work_ready, follow cycle_plan.primary_steps in order.",
|
|
77
|
-
"- If the primary path cannot complete safely, follow cycle_plan.fallback_steps.",
|
|
78
|
-
"- Always execute cycle_plan.resume_steps before ending when they are available.",
|
|
79
|
-
"- Complete at most one queued work packet in this run.",
|
|
80
|
-
"- End with one short sentence describing the outcome.",
|
|
81
|
-
].join("\n");
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
async function main() {
|
|
85
|
-
const options = parseArgs(process.argv.slice(2));
|
|
86
|
-
const prompt = buildPrompt(options.projectRoot);
|
|
87
|
-
const usesNodeShim =
|
|
88
|
-
options.openclawBin.endsWith(".mjs") || options.openclawBin.endsWith(".js");
|
|
89
|
-
let stopped = false;
|
|
90
|
-
|
|
91
|
-
process.on("SIGTERM", () => {
|
|
92
|
-
stopped = true;
|
|
93
|
-
});
|
|
94
|
-
process.on("SIGINT", () => {
|
|
95
|
-
stopped = true;
|
|
96
|
-
});
|
|
97
|
-
|
|
98
|
-
while (!stopped) {
|
|
99
|
-
const startedAt = new Date().toISOString();
|
|
100
|
-
const command = usesNodeShim ? process.execPath : options.openclawBin;
|
|
101
|
-
const commandArgs = usesNodeShim
|
|
102
|
-
? [
|
|
103
|
-
options.openclawBin,
|
|
104
|
-
"agent",
|
|
105
|
-
"--local",
|
|
106
|
-
"--agent",
|
|
107
|
-
options.agentId,
|
|
108
|
-
"--thinking",
|
|
109
|
-
"minimal",
|
|
110
|
-
"--timeout",
|
|
111
|
-
String(options.timeoutSecs),
|
|
112
|
-
"--message",
|
|
113
|
-
prompt,
|
|
114
|
-
"--json",
|
|
115
|
-
]
|
|
116
|
-
: [
|
|
117
|
-
"agent",
|
|
118
|
-
"--local",
|
|
119
|
-
"--agent",
|
|
120
|
-
options.agentId,
|
|
121
|
-
"--thinking",
|
|
122
|
-
"minimal",
|
|
123
|
-
"--timeout",
|
|
124
|
-
String(options.timeoutSecs),
|
|
125
|
-
"--message",
|
|
126
|
-
prompt,
|
|
127
|
-
"--json",
|
|
128
|
-
];
|
|
129
|
-
const result = spawnSync(
|
|
130
|
-
command,
|
|
131
|
-
commandArgs,
|
|
40
|
+
`${JSON.stringify(
|
|
132
41
|
{
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
42
|
+
...previous,
|
|
43
|
+
runtime: "deprecated_external_worker",
|
|
44
|
+
running: false,
|
|
45
|
+
last_error:
|
|
46
|
+
"Deprecated external OpenSyn distillation worker invoked. OpenSyn now manages host-model distillation through the OpenClaw plugin service.",
|
|
47
|
+
last_finished_at: new Date().toISOString(),
|
|
136
48
|
},
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
finished_at: finishedAt,
|
|
143
|
-
command,
|
|
144
|
-
command_args: commandArgs,
|
|
145
|
-
exit_code: result.status,
|
|
146
|
-
signal: result.signal,
|
|
147
|
-
error: result.error ? String(result.error.message || result.error) : "",
|
|
148
|
-
stdout: result.stdout?.trim() || "",
|
|
149
|
-
stderr: result.stderr?.trim() || "",
|
|
150
|
-
};
|
|
151
|
-
const computedLastError =
|
|
152
|
-
result.status && result.status !== 0
|
|
153
|
-
? payload.error || payload.stderr || ""
|
|
154
|
-
: payload.error || "";
|
|
155
|
-
updateState(options.statePath, {
|
|
156
|
-
last_started_at: startedAt,
|
|
157
|
-
last_finished_at: finishedAt,
|
|
158
|
-
last_exit_code: result.status,
|
|
159
|
-
last_signal: result.signal,
|
|
160
|
-
last_error: computedLastError,
|
|
161
|
-
last_stderr: payload.stderr,
|
|
162
|
-
last_stdout: payload.stdout,
|
|
163
|
-
last_command: payload.command,
|
|
164
|
-
last_command_args: payload.command_args,
|
|
165
|
-
});
|
|
166
|
-
process.stdout.write(`${JSON.stringify(payload)}\n`);
|
|
167
|
-
|
|
168
|
-
if (stopped) {
|
|
169
|
-
break;
|
|
170
|
-
}
|
|
171
|
-
await sleep(Math.max(5, options.intervalSecs) * 1000);
|
|
172
|
-
}
|
|
49
|
+
null,
|
|
50
|
+
2,
|
|
51
|
+
)}\n`,
|
|
52
|
+
"utf8",
|
|
53
|
+
);
|
|
173
54
|
}
|
|
174
55
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
56
|
+
const options = parseArgs(process.argv.slice(2));
|
|
57
|
+
updateState(options.statePath, {});
|
|
58
|
+
process.stdout.write(
|
|
59
|
+
`${JSON.stringify({
|
|
60
|
+
deprecated: true,
|
|
61
|
+
message:
|
|
62
|
+
"OpenSyn host-model distillation is now managed by the OpenClaw plugin service. No external worker was started.",
|
|
63
|
+
})}\n`,
|
|
64
|
+
);
|
package/runtime/postinstall.mjs
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
2
|
import os from "node:os";
|
|
3
3
|
import path from "node:path";
|
|
4
|
-
import { spawnSync } from "node:child_process";
|
|
5
4
|
|
|
6
5
|
const pluginId = "opensyn";
|
|
7
6
|
const cwd = process.cwd();
|
|
@@ -65,8 +64,7 @@ config.plugins = {
|
|
|
65
64
|
daemonBin: path.join(runtimeDir, "opensyn-daemon"),
|
|
66
65
|
helperPath: path.join(runtimeDir, "opensyn-ingest-command"),
|
|
67
66
|
runnerPath: path.join(runtimeDir, "opensyn-run"),
|
|
68
|
-
defaultShell:
|
|
69
|
-
path.basename(process.env.SHELL || "bash") || "bash",
|
|
67
|
+
defaultShell: "bash",
|
|
70
68
|
projectionBundleRoot: path.join(home, ".openclaw", "workspace"),
|
|
71
69
|
projectionHost: "openclaw",
|
|
72
70
|
projectionAutoApplyApproved: true,
|
|
@@ -77,9 +75,3 @@ config.plugins = {
|
|
|
77
75
|
|
|
78
76
|
fs.mkdirSync(path.dirname(configPath), { recursive: true });
|
|
79
77
|
fs.writeFileSync(configPath, `${JSON.stringify(config, null, 2)}\n`, "utf8");
|
|
80
|
-
|
|
81
|
-
if (fs.existsSync(cliBin)) {
|
|
82
|
-
spawnSync(cliBin, ["init-db", "--db", path.join(runtimeRoot, "opensyn.db")], {
|
|
83
|
-
stdio: "ignore",
|
|
84
|
-
});
|
|
85
|
-
}
|