@geravant/sinain 1.14.0 → 1.15.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/.env.example +33 -29
- package/cli.js +38 -14
- package/config-shared.js +172 -30
- package/launcher.js +38 -21
- package/onboard.js +36 -20
- package/package.json +1 -1
- package/sinain-agent/run.sh +567 -126
- package/sinain-core/src/agents-loader.ts +254 -0
- package/sinain-core/src/config.ts +77 -15
- package/sinain-core/src/escalation/escalator.ts +178 -18
- package/sinain-core/src/index.ts +168 -12
- package/sinain-core/src/learning/local-curation.ts +81 -27
- package/sinain-core/src/overlay/commands.ts +25 -0
- package/sinain-core/src/overlay/ws-handler.ts +3 -0
- package/sinain-core/src/server.ts +101 -10
- package/sinain-core/src/types.ts +29 -3
package/onboard.js
CHANGED
|
@@ -8,7 +8,7 @@ import fs from "fs";
|
|
|
8
8
|
import path from "path";
|
|
9
9
|
import { execFileSync } from "child_process";
|
|
10
10
|
import {
|
|
11
|
-
c, guard, maskKey, readEnv, writeEnv, summarizeConfig, runHealthCheck,
|
|
11
|
+
c, guard, maskKey, readEnv, writeEnv, writeAgentsConfig, summarizeConfig, runHealthCheck,
|
|
12
12
|
stepApiKey, stepTranscription, stepGateway, stepPrivacy, stepModel,
|
|
13
13
|
HOME, SINAIN_DIR, ENV_PATH, PKG_DIR, IS_WINDOWS, IS_MAC,
|
|
14
14
|
} from "./config-shared.js";
|
|
@@ -143,6 +143,10 @@ export async function runOnboard(args = {}) {
|
|
|
143
143
|
// ── Collect vars ────────────────────────────────────────────────────────
|
|
144
144
|
|
|
145
145
|
const vars = { ...base };
|
|
146
|
+
// agents.json patch — accumulated from steps that touch the openclaw
|
|
147
|
+
// profile / escalation / default agent. Written once after all steps
|
|
148
|
+
// complete so we don't churn ~/.sinain/agents.json on every prompt.
|
|
149
|
+
let agentsPatch = {};
|
|
146
150
|
|
|
147
151
|
// Step 1: API key (both flows)
|
|
148
152
|
const apiKey = await stepApiKey(base, `[1/${totalSteps}] OpenRouter API key`);
|
|
@@ -150,23 +154,25 @@ export async function runOnboard(args = {}) {
|
|
|
150
154
|
p.log.success("API key saved.");
|
|
151
155
|
|
|
152
156
|
if (flow === "quickstart") {
|
|
153
|
-
// QuickStart: sensible defaults
|
|
157
|
+
// QuickStart: sensible defaults. Gateway is opt-in (skip by default);
|
|
158
|
+
// agent + escalation defaults go to agents.json.
|
|
154
159
|
vars.TRANSCRIPTION_BACKEND = base.TRANSCRIPTION_BACKEND || "openrouter";
|
|
155
160
|
vars.PRIVACY_MODE = base.PRIVACY_MODE || "standard";
|
|
156
161
|
vars.AGENT_MODEL = base.AGENT_MODEL || "google/gemini-2.5-flash-lite";
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
162
|
+
agentsPatch = {
|
|
163
|
+
default: base.SINAIN_AGENT || "claude",
|
|
164
|
+
escalationMode: "off",
|
|
165
|
+
// Don't touch openclawProfile in quickstart — keeps existing config
|
|
166
|
+
// intact for re-runs; first-time users get the "skip" state from
|
|
167
|
+
// agents.example.json bootstrap (no openclaw profile means no gateway).
|
|
168
|
+
};
|
|
163
169
|
|
|
164
170
|
p.note(
|
|
165
171
|
[
|
|
166
172
|
`Transcription: ${vars.TRANSCRIPTION_BACKEND}`,
|
|
167
173
|
`Privacy: ${vars.PRIVACY_MODE}`,
|
|
168
174
|
`Model: ${vars.AGENT_MODEL}`,
|
|
169
|
-
`Escalation:
|
|
175
|
+
`Escalation: off (pick a gateway agent in the overlay to enable)`,
|
|
170
176
|
"",
|
|
171
177
|
`Change later: sinain config`,
|
|
172
178
|
].join("\n"),
|
|
@@ -208,9 +214,12 @@ export async function runOnboard(args = {}) {
|
|
|
208
214
|
}
|
|
209
215
|
}
|
|
210
216
|
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
217
|
+
// stepGateway returns { envVars, agentsPatch }: tokens go to .env,
|
|
218
|
+
// URLs + session + escalation mode go to agents.json's openclaw profile.
|
|
219
|
+
const gatewayResult = await stepGateway(base, "[3/5] OpenClaw gateway");
|
|
220
|
+
Object.assign(vars, gatewayResult.envVars);
|
|
221
|
+
Object.assign(agentsPatch, gatewayResult.agentsPatch);
|
|
222
|
+
if (gatewayResult.agentsPatch.escalationMode === "off") {
|
|
214
223
|
p.log.info("Standalone mode (no gateway).");
|
|
215
224
|
} else {
|
|
216
225
|
p.log.success("Gateway configured.");
|
|
@@ -224,7 +233,9 @@ export async function runOnboard(args = {}) {
|
|
|
224
233
|
vars.AGENT_MODEL = model;
|
|
225
234
|
p.log.success(`Model: ${model}.`);
|
|
226
235
|
|
|
227
|
-
|
|
236
|
+
// Default agent goes into agents.json `default` field (was SINAIN_AGENT
|
|
237
|
+
// env var). Overlay's chip selector lets the user switch at runtime.
|
|
238
|
+
agentsPatch.default = base.SINAIN_AGENT || "claude";
|
|
228
239
|
}
|
|
229
240
|
|
|
230
241
|
// ── Common defaults ───────────────────────────────────────────────────
|
|
@@ -237,11 +248,16 @@ export async function runOnboard(args = {}) {
|
|
|
237
248
|
vars.PORT = vars.PORT || "9500";
|
|
238
249
|
|
|
239
250
|
// ── Write config ──────────────────────────────────────────────────────
|
|
251
|
+
// Two files: ~/.sinain/.env for secrets + infra, ~/.sinain/agents.json
|
|
252
|
+
// for agent + gateway config (the migrated keys).
|
|
240
253
|
|
|
241
254
|
const s = p.spinner();
|
|
242
255
|
s.start("Writing configuration...");
|
|
243
256
|
writeEnv(vars);
|
|
244
|
-
|
|
257
|
+
if (Object.keys(agentsPatch).length > 0) {
|
|
258
|
+
writeAgentsConfig(agentsPatch);
|
|
259
|
+
}
|
|
260
|
+
s.stop(c.green(`Config saved: ${c.dim(ENV_PATH)} + ~/.sinain/agents.json`));
|
|
245
261
|
|
|
246
262
|
// ── Overlay ───────────────────────────────────────────────────────────
|
|
247
263
|
|
|
@@ -312,20 +328,16 @@ if (flags.reset) {
|
|
|
312
328
|
}
|
|
313
329
|
|
|
314
330
|
if (flags.nonInteractive) {
|
|
331
|
+
// .env: secrets + infra. Agent + gateway config goes to agents.json.
|
|
315
332
|
const vars = {
|
|
316
333
|
OPENROUTER_API_KEY: flags.key || process.env.OPENROUTER_API_KEY || "",
|
|
317
334
|
TRANSCRIPTION_BACKEND: "openrouter",
|
|
318
335
|
PRIVACY_MODE: "standard",
|
|
319
336
|
AGENT_MODEL: "google/gemini-2.5-flash-lite",
|
|
320
|
-
ESCALATION_MODE: "off",
|
|
321
|
-
SINAIN_AGENT: "claude",
|
|
322
|
-
OPENCLAW_WS_URL: "",
|
|
323
|
-
OPENCLAW_HTTP_URL: "",
|
|
324
337
|
PORT: "9500",
|
|
325
338
|
AUDIO_CAPTURE_CMD: "screencapturekit",
|
|
326
339
|
AUDIO_AUTO_START: "true",
|
|
327
340
|
SINAIN_CORE_URL: "http://localhost:9500",
|
|
328
|
-
SINAIN_POLL_INTERVAL: "5",
|
|
329
341
|
SINAIN_HEARTBEAT_INTERVAL: "900",
|
|
330
342
|
};
|
|
331
343
|
|
|
@@ -335,7 +347,11 @@ if (flags.nonInteractive) {
|
|
|
335
347
|
}
|
|
336
348
|
|
|
337
349
|
writeEnv(vars);
|
|
338
|
-
|
|
350
|
+
// Default agent + escalation off (no gateway by default for non-interactive).
|
|
351
|
+
// openclaw profile is left as-is from the example template (or absent
|
|
352
|
+
// if first run) — gateway is opt-in via the wizard or `sinain config`.
|
|
353
|
+
writeAgentsConfig({ default: "claude", escalationMode: "off" });
|
|
354
|
+
console.log(c.green(` Config written to ${ENV_PATH} + ~/.sinain/agents.json`));
|
|
339
355
|
process.exit(0);
|
|
340
356
|
} else {
|
|
341
357
|
runOnboard(flags).catch((err) => {
|