omnius 1.0.728 → 1.0.730
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/index.js +2 -2
- package/dist/update-worker.js +91 -66
- package/docs/DISCOVERY.json +24 -5
- package/docs/DISCOVERY.md +1 -1
- package/docs/rest/endpoints/chat.md +5 -2
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
[diffend] Oversized file quarantined before diffing.
|
|
2
2
|
name: package/dist/index.js
|
|
3
|
-
size:
|
|
4
|
-
sha256:
|
|
3
|
+
size: 38141493 bytes
|
|
4
|
+
sha256: 129ae1a628f2ee04d633a2a2829eb8b968652fd68b8d93fadf28e3fc72eb1284
|
package/dist/update-worker.js
CHANGED
|
@@ -296100,21 +296100,32 @@ async function repairManagedDaemonUnit(port, preferredEntrypoint) {
|
|
|
296100
296100
|
return false;
|
|
296101
296101
|
}
|
|
296102
296102
|
}
|
|
296103
|
-
|
|
296103
|
+
function daemonListenerLsofArgs(port) {
|
|
296104
|
+
return ["-nP", "-t", "-a", `-iTCP:${port}`, "-sTCP:LISTEN"];
|
|
296105
|
+
}
|
|
296106
|
+
function parsePidList(output) {
|
|
296107
|
+
return output.split(/[\s\n]+/).map((value) => parseInt(value, 10)).filter((pid) => Number.isInteger(pid) && pid > 0 && pid !== process.pid);
|
|
296108
|
+
}
|
|
296109
|
+
function parseSsListenerPids(output) {
|
|
296110
|
+
return [...output.matchAll(/\bpid=(\d+)\b/g)].map((match2) => parseInt(match2[1], 10)).filter((pid) => Number.isInteger(pid) && pid > 0 && pid !== process.pid);
|
|
296111
|
+
}
|
|
296112
|
+
async function daemonListenerPids(port, dependencies = { run: runUtilityCommand }) {
|
|
296104
296113
|
try {
|
|
296105
|
-
const lsof = await
|
|
296106
|
-
|
|
296107
|
-
|
|
296108
|
-
const fuser = await runUtilityCommand("fuser", [`${port}/tcp`], 3e3);
|
|
296109
|
-
output = `${fuser.stdout}
|
|
296110
|
-
${fuser.stderr}`;
|
|
296111
|
-
if (!lsof.available && !fuser.available) return null;
|
|
296114
|
+
const lsof = await dependencies.run("lsof", daemonListenerLsofArgs(port), 3e3);
|
|
296115
|
+
if (lsof.available && (lsof.code === 0 || lsof.code === 1)) {
|
|
296116
|
+
return [...new Set(parsePidList(lsof.stdout))];
|
|
296112
296117
|
}
|
|
296113
|
-
|
|
296118
|
+
const ss = await dependencies.run("ss", ["-H", "-ltnp", `sport = :${port}`], 3e3);
|
|
296119
|
+
if (!ss.available || ss.code !== 0) return null;
|
|
296120
|
+
const pids = [...new Set(parseSsListenerPids(ss.stdout))];
|
|
296121
|
+
return ss.stdout.trim() && pids.length === 0 ? null : pids;
|
|
296114
296122
|
} catch {
|
|
296115
296123
|
return null;
|
|
296116
296124
|
}
|
|
296117
296125
|
}
|
|
296126
|
+
async function portHolderPids(port) {
|
|
296127
|
+
return daemonListenerPids(port);
|
|
296128
|
+
}
|
|
296118
296129
|
async function daemonPortIsFree(port) {
|
|
296119
296130
|
return new Promise((resolve10) => {
|
|
296120
296131
|
const probe = createNetServer();
|
|
@@ -296135,8 +296146,7 @@ async function daemonPortIsFree(port) {
|
|
|
296135
296146
|
async function waitForDaemonStopped(port, attempts = DAEMON_GRACEFUL_STOP_ATTEMPTS) {
|
|
296136
296147
|
for (let attempt = 0; attempt < attempts; attempt++) {
|
|
296137
296148
|
const healthy = await isDaemonRunning(port);
|
|
296138
|
-
const
|
|
296139
|
-
const portFree = holders === null ? await daemonPortIsFree(port) : holders.length === 0;
|
|
296149
|
+
const portFree = await daemonPortIsFree(port);
|
|
296140
296150
|
if (!healthy && portFree) return true;
|
|
296141
296151
|
await delay(500);
|
|
296142
296152
|
}
|
|
@@ -296152,42 +296162,44 @@ var DEFAULT_RECLAIM_DEPENDENCIES = {
|
|
|
296152
296162
|
}),
|
|
296153
296163
|
waitForFree: (port) => waitForDaemonStopped(port)
|
|
296154
296164
|
};
|
|
296155
|
-
|
|
296165
|
+
function removeDaemonLockIfUnchanged(port, expected) {
|
|
296156
296166
|
const lockFile = daemonLockFile(port);
|
|
296157
|
-
const
|
|
296158
|
-
if (!
|
|
296159
|
-
if (
|
|
296160
|
-
|
|
296161
|
-
|
|
296162
|
-
if (current2?.pid === record.pid && current2.token === record.token) {
|
|
296163
|
-
try {
|
|
296164
|
-
unlinkSync2(lockFile);
|
|
296165
|
-
} catch {
|
|
296166
|
-
}
|
|
296167
|
-
}
|
|
296167
|
+
const current = readDaemonLock(lockFile);
|
|
296168
|
+
if (!current) return true;
|
|
296169
|
+
if (current.pid !== expected.pid || current.token !== expected.token) return false;
|
|
296170
|
+
try {
|
|
296171
|
+
unlinkSync2(lockFile);
|
|
296168
296172
|
return true;
|
|
296173
|
+
} catch (error) {
|
|
296174
|
+
return error.code === "ENOENT";
|
|
296169
296175
|
}
|
|
296170
|
-
|
|
296176
|
+
}
|
|
296177
|
+
var DEFAULT_CLAIM_RECLAIM_DEPENDENCIES = {
|
|
296178
|
+
readLock: (port) => readDaemonLock(daemonLockFile(port)),
|
|
296179
|
+
portIsFree: (port) => daemonPortIsFree(port),
|
|
296180
|
+
processIsAlive: (pid) => processIsAlive(pid),
|
|
296181
|
+
leases: () => listProcessLeases({ includeInactive: false }),
|
|
296182
|
+
stopLease: (leaseId, port) => stopProcessLease(leaseId, {
|
|
296183
|
+
reason: `stale daemon endpoint claim on port ${port}`,
|
|
296184
|
+
termGraceMs: 1e3
|
|
296185
|
+
}),
|
|
296186
|
+
removeLockIfUnchanged: (port, expected) => removeDaemonLockIfUnchanged(port, expected)
|
|
296187
|
+
};
|
|
296188
|
+
async function reclaimStaleDaemonEndpointClaim(port, verifiedStoppedPids = /* @__PURE__ */ new Set(), dependencies = DEFAULT_CLAIM_RECLAIM_DEPENDENCIES) {
|
|
296189
|
+
const record = dependencies.readLock(port);
|
|
296190
|
+
if (!record) return dependencies.portIsFree(port);
|
|
296191
|
+
if (!await dependencies.portIsFree(port)) return false;
|
|
296192
|
+
const clearExactClaim = async () => dependencies.removeLockIfUnchanged(port, record) && dependencies.portIsFree(port);
|
|
296193
|
+
if (verifiedStoppedPids.has(record.pid) || !dependencies.processIsAlive(record.pid)) {
|
|
296194
|
+
return clearExactClaim();
|
|
296195
|
+
}
|
|
296196
|
+
const lease = dependencies.leases().find(
|
|
296171
296197
|
(item) => item.status === "active" && item.pid === record.pid && item.ownerKind === "daemon" && item.ownerId === `daemon:${port}`
|
|
296172
296198
|
);
|
|
296173
296199
|
if (!lease) return false;
|
|
296174
|
-
const stopped = await
|
|
296175
|
-
reason: `stale daemon endpoint claim on port ${port}`,
|
|
296176
|
-
termGraceMs: 1e3
|
|
296177
|
-
});
|
|
296200
|
+
const stopped = await dependencies.stopLease(lease.leaseId, port);
|
|
296178
296201
|
if (stopped.action !== "killed" && stopped.action !== "dead") return false;
|
|
296179
|
-
|
|
296180
|
-
await delay(100);
|
|
296181
|
-
}
|
|
296182
|
-
if (processIsAlive(record.pid)) return false;
|
|
296183
|
-
const current = readDaemonLock(lockFile);
|
|
296184
|
-
if (current?.pid === record.pid && current.token === record.token) {
|
|
296185
|
-
try {
|
|
296186
|
-
unlinkSync2(lockFile);
|
|
296187
|
-
} catch {
|
|
296188
|
-
}
|
|
296189
|
-
}
|
|
296190
|
-
return daemonPortIsFree(port);
|
|
296202
|
+
return clearExactClaim();
|
|
296191
296203
|
}
|
|
296192
296204
|
async function reclaimOwnedDaemonListener(port = getDaemonPort(), dependencies = DEFAULT_RECLAIM_DEPENDENCIES) {
|
|
296193
296205
|
const holders = await dependencies.holderPids(port);
|
|
@@ -296269,9 +296281,9 @@ async function restartDaemon(port, expectedVersion, preferredEntrypoint) {
|
|
|
296269
296281
|
const managed = await managedDaemonServiceMatchesPort(p);
|
|
296270
296282
|
if (managed) {
|
|
296271
296283
|
if (!await managedDaemonServiceOwnsPort(p)) {
|
|
296272
|
-
const
|
|
296273
|
-
if (!
|
|
296274
|
-
await reclaimStaleDaemonEndpointClaim(p);
|
|
296284
|
+
const reclaimed2 = await reclaimOwnedDaemonListener(p);
|
|
296285
|
+
if (!reclaimed2.ok) return false;
|
|
296286
|
+
await reclaimStaleDaemonEndpointClaim(p, new Set(reclaimed2.clearedPids));
|
|
296275
296287
|
}
|
|
296276
296288
|
await runUserSystemctl(["reset-failed", "omnius-daemon.service"]);
|
|
296277
296289
|
const restarted = await runUserSystemctl(["restart", "omnius-daemon.service"]);
|
|
@@ -296286,15 +296298,13 @@ async function restartDaemon(port, expectedVersion, preferredEntrypoint) {
|
|
|
296286
296298
|
}
|
|
296287
296299
|
await runUserSystemctl(["stop", "omnius-daemon.service"]);
|
|
296288
296300
|
if (!await waitForDaemonStopped(p)) {
|
|
296289
|
-
const
|
|
296290
|
-
if (!
|
|
296301
|
+
const reclaimed2 = await reclaimOwnedDaemonListener(p);
|
|
296302
|
+
if (!reclaimed2.ok) return false;
|
|
296291
296303
|
}
|
|
296292
296304
|
}
|
|
296293
|
-
|
|
296294
|
-
|
|
296295
|
-
|
|
296296
|
-
}
|
|
296297
|
-
if (!await reclaimStaleDaemonEndpointClaim(p)) return false;
|
|
296305
|
+
const reclaimed = await reclaimOwnedDaemonListener(p);
|
|
296306
|
+
if (!reclaimed.ok) return false;
|
|
296307
|
+
if (!await reclaimStaleDaemonEndpointClaim(p, new Set(reclaimed.clearedPids))) return false;
|
|
296298
296308
|
const pid = await startDaemon(p, preferredEntrypoint);
|
|
296299
296309
|
if (!pid) return false;
|
|
296300
296310
|
return (await waitForDaemonReady(p, expectedVersion)).ok;
|
|
@@ -296404,25 +296414,27 @@ async function startDaemon(port = getDaemonPort(), preferredEntrypoint) {
|
|
|
296404
296414
|
}
|
|
296405
296415
|
}
|
|
296406
296416
|
}
|
|
296407
|
-
|
|
296408
|
-
|
|
296409
|
-
|
|
296410
|
-
|
|
296417
|
+
var DEFAULT_DAEMON_STOP_DEPENDENCIES = {
|
|
296418
|
+
managedServiceMatchesPort: (port) => managedDaemonServiceMatchesPort(port),
|
|
296419
|
+
stopManagedService: async () => (await runUserSystemctl(["stop", "omnius-daemon.service"])).ok,
|
|
296420
|
+
waitForStopped: (port) => waitForDaemonStopped(port),
|
|
296421
|
+
reclaimListener: (port) => reclaimOwnedDaemonListener(port),
|
|
296422
|
+
reclaimClaim: (port, verifiedStoppedPids) => reclaimStaleDaemonEndpointClaim(port, verifiedStoppedPids)
|
|
296423
|
+
};
|
|
296424
|
+
async function stopDaemonAtPort(port = getDaemonPort(), dependencies = DEFAULT_DAEMON_STOP_DEPENDENCIES) {
|
|
296425
|
+
if (await dependencies.managedServiceMatchesPort(port)) {
|
|
296426
|
+
const stopped = await dependencies.stopManagedService();
|
|
296427
|
+
if (stopped && await dependencies.waitForStopped(port)) return true;
|
|
296411
296428
|
}
|
|
296412
|
-
const
|
|
296413
|
-
const reclaimed = await reclaimOwnedDaemonListener(port);
|
|
296429
|
+
const reclaimed = await dependencies.reclaimListener(port);
|
|
296414
296430
|
if (!reclaimed.ok) return false;
|
|
296415
|
-
const claimCleared = await
|
|
296416
|
-
|
|
296431
|
+
const claimCleared = await dependencies.reclaimClaim(
|
|
296432
|
+
port,
|
|
296433
|
+
new Set(reclaimed.clearedPids)
|
|
296434
|
+
);
|
|
296435
|
+
return claimCleared && dependencies.waitForStopped(port);
|
|
296417
296436
|
}
|
|
296418
296437
|
async function quiesceDaemonForUpdate(port = getDaemonPort()) {
|
|
296419
|
-
if (await managedDaemonServiceMatchesPort(port)) {
|
|
296420
|
-
const stopped = await runUserSystemctl(["stop", "omnius-daemon.service"]);
|
|
296421
|
-
if (stopped.ok && await waitForDaemonStopped(port)) return true;
|
|
296422
|
-
}
|
|
296423
|
-
if (!await isDaemonRunning(port)) {
|
|
296424
|
-
return daemonPortIsFree(port);
|
|
296425
|
-
}
|
|
296426
296438
|
return stopDaemonAtPort(port);
|
|
296427
296439
|
}
|
|
296428
296440
|
|
|
@@ -296662,6 +296674,19 @@ function transition(current, patch, paths) {
|
|
|
296662
296674
|
function permissionRemediation(evidence) {
|
|
296663
296675
|
return /EACCES|EPERM|permission denied/i.test(evidence) ? "The discovered npm global prefix is not writable. Configure a user-owned npm prefix or rerun the explicit update from a privileged terminal; Omnius never silently elevates." : void 0;
|
|
296664
296676
|
}
|
|
296677
|
+
async function quiesceDaemonWithRetry(quiesce, attempts = 3, pauseMs = 250) {
|
|
296678
|
+
const boundedAttempts = Math.max(1, Math.min(5, Math.floor(attempts)));
|
|
296679
|
+
for (let attempt = 1; attempt <= boundedAttempts; attempt++) {
|
|
296680
|
+
try {
|
|
296681
|
+
if (await quiesce()) return true;
|
|
296682
|
+
} catch {
|
|
296683
|
+
}
|
|
296684
|
+
if (attempt < boundedAttempts && pauseMs > 0) {
|
|
296685
|
+
await new Promise((resolve10) => setTimeout(resolve10, pauseMs));
|
|
296686
|
+
}
|
|
296687
|
+
}
|
|
296688
|
+
return false;
|
|
296689
|
+
}
|
|
296665
296690
|
function installGlobalPackageStreaming(input) {
|
|
296666
296691
|
return new Promise((resolve10) => {
|
|
296667
296692
|
const stderrTail = [];
|
|
@@ -296740,7 +296765,7 @@ async function runVerifiedUpdateTransaction(initial, dependencies, paths = resol
|
|
|
296740
296765
|
try {
|
|
296741
296766
|
if (dependencies.quiesceDaemon) {
|
|
296742
296767
|
state = transition(state, { phase: "daemon_quiescing" }, paths);
|
|
296743
|
-
if (!await dependencies.quiesceDaemon
|
|
296768
|
+
if (!await quiesceDaemonWithRetry(dependencies.quiesceDaemon)) {
|
|
296744
296769
|
throw new Error(
|
|
296745
296770
|
`Could not safely stop the daemon at ${state.daemon_endpoint ?? "the configured endpoint"} before updating`
|
|
296746
296771
|
);
|
package/docs/DISCOVERY.json
CHANGED
|
@@ -5680,7 +5680,7 @@
|
|
|
5680
5680
|
"id": "api.v1-chat",
|
|
5681
5681
|
"kind": "api",
|
|
5682
5682
|
"title": "/v1/chat",
|
|
5683
|
-
"summary": "Stateful chat
|
|
5683
|
+
"summary": "Stateful direct chat with explicit autonomous-agent opt-in",
|
|
5684
5684
|
"aliases": [
|
|
5685
5685
|
"/v1/chat"
|
|
5686
5686
|
],
|
|
@@ -5729,8 +5729,8 @@
|
|
|
5729
5729
|
],
|
|
5730
5730
|
"operations": {
|
|
5731
5731
|
"post": {
|
|
5732
|
-
"summary": "Stateful chat
|
|
5733
|
-
"description": "Drop-in replacement for OpenAI /v1/chat/completions and Ollama /api/chat.
|
|
5732
|
+
"summary": "Stateful direct chat with explicit autonomous-agent opt-in",
|
|
5733
|
+
"description": "Drop-in replacement for OpenAI /v1/chat/completions and Ollama /api/chat. Requests use direct backend inference by default. Set tools=true or use_tools=true to explicitly run the full Omnius autonomous-agent stack. Explicit agent runs have a daemon-enforced whole-run deadline and duplicate-work suppression.",
|
|
5734
5734
|
"tags": [
|
|
5735
5735
|
"Chat"
|
|
5736
5736
|
],
|
|
@@ -5781,8 +5781,27 @@
|
|
|
5781
5781
|
},
|
|
5782
5782
|
"tools": {
|
|
5783
5783
|
"type": "boolean",
|
|
5784
|
-
"default":
|
|
5785
|
-
"description": "true
|
|
5784
|
+
"default": false,
|
|
5785
|
+
"description": "Set true to explicitly launch the full autonomous agent. Omitted or false uses direct backend chat."
|
|
5786
|
+
},
|
|
5787
|
+
"use_tools": {
|
|
5788
|
+
"type": "boolean",
|
|
5789
|
+
"default": false,
|
|
5790
|
+
"description": "Omnius-native alias for tools=true; the built-in web UI uses this explicit opt-in."
|
|
5791
|
+
},
|
|
5792
|
+
"timeout_s": {
|
|
5793
|
+
"type": "number",
|
|
5794
|
+
"minimum": 0,
|
|
5795
|
+
"maximum": 3600,
|
|
5796
|
+
"default": 180,
|
|
5797
|
+
"description": "Per-backend-request liveness timeout passed to the agent CLI."
|
|
5798
|
+
},
|
|
5799
|
+
"agent_timeout_s": {
|
|
5800
|
+
"type": "number",
|
|
5801
|
+
"minimum": 0.05,
|
|
5802
|
+
"maximum": 3600,
|
|
5803
|
+
"default": 180,
|
|
5804
|
+
"description": "Daemon-enforced whole-agent wall-clock deadline. Distinct from timeout_s."
|
|
5786
5805
|
}
|
|
5787
5806
|
}
|
|
5788
5807
|
}
|
package/docs/DISCOVERY.md
CHANGED
|
@@ -115,7 +115,7 @@ Daemon equivalents are `GET /v1/discovery/bootstrap`, `GET /v1/discovery?q=<inte
|
|
|
115
115
|
| `api.v1-audio-speech` | /v1/audio/speech | OpenAI-compatible alias of /v1/voice/tts (input/voice/response_format names) |
|
|
116
116
|
| `api.v1-audio-transcriptions` | /v1/audio/transcriptions | OpenAI-compatible alias of /v1/asr/transcriptions |
|
|
117
117
|
| `api.v1-audit` | /v1/audit | Query audit log |
|
|
118
|
-
| `api.v1-chat` | /v1/chat | Stateful chat
|
|
118
|
+
| `api.v1-chat` | /v1/chat | Stateful direct chat with explicit autonomous-agent opt-in |
|
|
119
119
|
| `api.v1-chat-attachments` | /v1/chat/attachments | Upload an attachment for a stateful chat |
|
|
120
120
|
| `api.v1-chat-check-in` | /v1/chat/check-in | Send a steering check-in to the active chat session — returns model inference + queued steering_packet |
|
|
121
121
|
| `api.v1-chat-completions` | /v1/chat/completions | OpenAI-compatible chat completion (with optional server-side agent loop) |
|
|
@@ -71,7 +71,7 @@ Realtime example:
|
|
|
71
71
|
|
|
72
72
|
## `/v1/chat`
|
|
73
73
|
|
|
74
|
-
This is the Omnius stateful chat endpoint.
|
|
74
|
+
This is the Omnius stateful chat endpoint. It uses direct backend inference by default. Set `tools: true` or `use_tools: true` to explicitly launch the full Omnius agent stack with tools, memory, skills, and multi-agent context. `realtime: true` always uses the direct backend path. Explicit agent runs default to a 180-second daemon-owned wall-clock deadline and reject equivalent concurrent work even when callers omit `session_id`.
|
|
75
75
|
|
|
76
76
|
Body fields:
|
|
77
77
|
|
|
@@ -81,7 +81,10 @@ Body fields:
|
|
|
81
81
|
| `model` | string | Optional model override |
|
|
82
82
|
| `session_id` | string | Reuse or name a session |
|
|
83
83
|
| `stream` | boolean | Stream when supported |
|
|
84
|
-
| `tools` | boolean |
|
|
84
|
+
| `tools` | boolean | Set true to explicitly launch the full agent stack |
|
|
85
|
+
| `use_tools` | boolean | Omnius-native alias for `tools: true` |
|
|
86
|
+
| `timeout_s` | number | Per-backend-request liveness timeout |
|
|
87
|
+
| `agent_timeout_s` | number | Whole-agent daemon deadline, default 180 seconds and maximum 3600 |
|
|
85
88
|
| `realtime` | boolean | Short ASR/TTS conversation mode |
|
|
86
89
|
| `realtime_options` | object | Realtime settings |
|
|
87
90
|
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "omnius",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.730",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "omnius",
|
|
9
|
-
"version": "1.0.
|
|
9
|
+
"version": "1.0.730",
|
|
10
10
|
"bundleDependencies": [
|
|
11
11
|
"image-to-ascii"
|
|
12
12
|
],
|
package/package.json
CHANGED