omnius 1.0.339 → 1.0.341
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 +219 -2
- package/docs/reference/rest-api.md +1 -0
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -560736,7 +560736,7 @@ var init_critic = __esm({
|
|
|
560736
560736
|
function extractSubject(errorText) {
|
|
560737
560737
|
if (!errorText)
|
|
560738
560738
|
return null;
|
|
560739
|
-
const
|
|
560739
|
+
const PATTERNS2 = [
|
|
560740
560740
|
// Quoted module / type / symbol after recognizable phrases
|
|
560741
560741
|
/cannot find (?:module|name|type|symbol|reference|file|namespace)\s+['"`]([^'"`\n]{1,80})['"`]/i,
|
|
560742
560742
|
/(?:undefined|unresolved)\s+(?:reference|import|symbol)\s+(?:to\s+)?['"`]([^'"`\n]{1,80})['"`]/i,
|
|
@@ -560751,7 +560751,7 @@ function extractSubject(errorText) {
|
|
|
560751
560751
|
/\bcannot resolve\s+['"`]?([^'"`\n\s]{1,120})['"`]?/i,
|
|
560752
560752
|
/\bmodule not found:?\s+['"`]?([^'"`\n\s]{1,120})['"`]?/i
|
|
560753
560753
|
];
|
|
560754
|
-
for (const re of
|
|
560754
|
+
for (const re of PATTERNS2) {
|
|
560755
560755
|
const m2 = errorText.match(re);
|
|
560756
560756
|
if (m2 && m2[1]) {
|
|
560757
560757
|
const subj = m2[1].trim();
|
|
@@ -565070,6 +565070,79 @@ var init_consolidation_runtime = __esm({
|
|
|
565070
565070
|
}
|
|
565071
565071
|
});
|
|
565072
565072
|
|
|
565073
|
+
// packages/orchestrator/dist/completion-evidence-gate.js
|
|
565074
|
+
function classifyCompletionClaim(text2) {
|
|
565075
|
+
const t2 = String(text2 || "");
|
|
565076
|
+
for (const p2 of PATTERNS) {
|
|
565077
|
+
if (p2.re.test(t2)) {
|
|
565078
|
+
return { category: p2.category, requiresIndependentEvidence: true, requiredCheck: p2.check };
|
|
565079
|
+
}
|
|
565080
|
+
}
|
|
565081
|
+
return { category: null, requiresIndependentEvidence: false, requiredCheck: "" };
|
|
565082
|
+
}
|
|
565083
|
+
function detectExitCodeMisread(text2) {
|
|
565084
|
+
const t2 = String(text2 || "");
|
|
565085
|
+
const nonzeroExit = /\bexit(?:ed|s)?\b[^.\n]{0,20}?\b(?:code\s*)?(?:[1-9]\d*|non-?zero)\b/i;
|
|
565086
|
+
const successWord = /\b(success(?:ful|fully|ed)?|succeeded|done|passed|works?|working|fine|ok|complete[d]?)\b/i;
|
|
565087
|
+
if (nonzeroExit.test(t2) && successWord.test(t2))
|
|
565088
|
+
return true;
|
|
565089
|
+
if (/\|\|\s*true\b|\bset \+e\b|2>\/dev\/null\s*;\s*(echo|exit 0)/i.test(t2))
|
|
565090
|
+
return true;
|
|
565091
|
+
return false;
|
|
565092
|
+
}
|
|
565093
|
+
function auditCompletionClaims(claims) {
|
|
565094
|
+
const blockers = [];
|
|
565095
|
+
for (const c8 of claims || []) {
|
|
565096
|
+
const cls = classifyCompletionClaim(c8.text);
|
|
565097
|
+
if (!cls.requiresIndependentEvidence || !cls.category)
|
|
565098
|
+
continue;
|
|
565099
|
+
if (c8.status !== "supported") {
|
|
565100
|
+
blockers.push({ claim: String(c8.text || "").slice(0, 160), category: cls.category, requiredCheck: cls.requiredCheck });
|
|
565101
|
+
}
|
|
565102
|
+
}
|
|
565103
|
+
return { ok: blockers.length === 0, blockers };
|
|
565104
|
+
}
|
|
565105
|
+
function completionEvidenceDirective() {
|
|
565106
|
+
return [
|
|
565107
|
+
"[Evidence-gated completion — do not pretend success]",
|
|
565108
|
+
"Before you claim a task is done, optimize for 'is the end state actually correct?', NOT 'did I make the change?'. Each of these claim types REQUIRES an independent check from a DIFFERENT command than the one that made the change:",
|
|
565109
|
+
"- A process is 'running/started/up' → re-probe liveness after a short delay (ps/pgrep, a health endpoint, or the listening port). A PID file or a launcher log is NOT proof it stayed alive — 'started' ≠ 'running'.",
|
|
565110
|
+
"- Something is 'installed/available' → verify with `command -v`/`--version`/a package query, NOT the installer's own log.",
|
|
565111
|
+
"- A bug is 'fixed' → re-run the ORIGINAL failing command/test and watch it pass, not just confirm the edit landed.",
|
|
565112
|
+
"- A success in simulation/mock/dry-run mode → label it as SIMULATED; never present it as the real capability.",
|
|
565113
|
+
"Exit codes: a non-zero exit is NOT success; a zero exit from a wrapper / `|| true` / `set +e` is NOT proof the underlying thing worked — inspect what actually happened.",
|
|
565114
|
+
"If you cannot produce the independent evidence, say so plainly and mark the item unverified or partial — never report a success state you have not verified."
|
|
565115
|
+
].join("\n");
|
|
565116
|
+
}
|
|
565117
|
+
var PATTERNS;
|
|
565118
|
+
var init_completion_evidence_gate = __esm({
|
|
565119
|
+
"packages/orchestrator/dist/completion-evidence-gate.js"() {
|
|
565120
|
+
"use strict";
|
|
565121
|
+
PATTERNS = [
|
|
565122
|
+
{
|
|
565123
|
+
category: "process_liveness",
|
|
565124
|
+
re: /\b(running|started|launched|spun up|brought up|is up|listening|serving|alive|daemon (is|now)|service (is|now)|server (is|now)|booted|online)\b/i,
|
|
565125
|
+
check: "Independently probe liveness AFTER a short delay: ps/pgrep for the actual process, a health endpoint, or `ss -ltnp` for the port — NOT the launcher log or a PID file (a PID file can exist while the process is dead)."
|
|
565126
|
+
},
|
|
565127
|
+
{
|
|
565128
|
+
category: "installation",
|
|
565129
|
+
re: /\b(installed|available in PATH|on the PATH|set up|provisioned|configured and ready|now available|dependency (is )?(present|installed))\b/i,
|
|
565130
|
+
check: "Independently confirm presence: `command -v <bin>` / `<bin> --version` / package manager query (e.g. `apt-cache policy`, `pip show`) — NOT the installer's own success log."
|
|
565131
|
+
},
|
|
565132
|
+
{
|
|
565133
|
+
category: "fix_confirmation",
|
|
565134
|
+
re: /\b(fixed|resolved|corrected|patched|repaired|no longer (fails|errors|crashes)|works now|issue (is )?gone)\b/i,
|
|
565135
|
+
check: "Re-run the ORIGINAL failing command/test and observe it now passes — an independent reproduction, not just confirming the edit was written."
|
|
565136
|
+
},
|
|
565137
|
+
{
|
|
565138
|
+
category: "reality",
|
|
565139
|
+
re: /\b(simulat\w+|mock\w*|stub\w*|fake|dry[- ]?run|--sim|placeholder mode|fallback mode)\b/i,
|
|
565140
|
+
check: "This was a SIMULATED/mock run. Label it explicitly as simulated and do NOT present it as the real capability; verify against the real system before claiming the real success."
|
|
565141
|
+
}
|
|
565142
|
+
];
|
|
565143
|
+
}
|
|
565144
|
+
});
|
|
565145
|
+
|
|
565073
565146
|
// packages/orchestrator/dist/tool-batching.js
|
|
565074
565147
|
function isConcurrencySafe(toolName, readOnlyHints) {
|
|
565075
565148
|
if (CONCURRENT_SAFE_TOOLS.has(toolName))
|
|
@@ -568620,6 +568693,7 @@ var init_agenticRunner = __esm({
|
|
|
568620
568693
|
init_dist5();
|
|
568621
568694
|
init_exploration_fanout();
|
|
568622
568695
|
init_consolidation_runtime();
|
|
568696
|
+
init_completion_evidence_gate();
|
|
568623
568697
|
init_tool_batching();
|
|
568624
568698
|
init_hooks2();
|
|
568625
568699
|
init_todo_context_chunker();
|
|
@@ -570710,6 +570784,18 @@ ${input.answerText ?? ""}`.toLowerCase().trim();
|
|
|
570710
570784
|
this._completionLedger = reconcileClaimsWithEvidence(this._completionLedger);
|
|
570711
570785
|
this._saveCompletionLedgerSafe();
|
|
570712
570786
|
}
|
|
570787
|
+
try {
|
|
570788
|
+
const _audit = auditCompletionClaims(this._completionLedger.proposedClaims.map((c8) => ({ text: c8.text, status: c8.status })));
|
|
570789
|
+
if (!_audit.ok) {
|
|
570790
|
+
const _checks = _audit.blockers.map((b) => `• [${b.category}] "${b.claim}" → ${b.requiredCheck}`).join("\n");
|
|
570791
|
+
this._completionCaveat = [
|
|
570792
|
+
this._completionCaveat || "",
|
|
570793
|
+
`[UNVERIFIED SUCCESS — run these independent checks before claiming done]
|
|
570794
|
+
${_checks}`
|
|
570795
|
+
].filter(Boolean).join("\n\n");
|
|
570796
|
+
}
|
|
570797
|
+
} catch {
|
|
570798
|
+
}
|
|
570713
570799
|
}
|
|
570714
570800
|
const optOverride = this.options.backwardPassReview;
|
|
570715
570801
|
const raw = (process.env["OMNIUS_BACKWARD_PASS"] || "on").toLowerCase();
|
|
@@ -573943,6 +574029,12 @@ Respond with your assessment, then take action.`;
|
|
|
573943
574029
|
}
|
|
573944
574030
|
const contextComposition = await this.assembleContext(task, context2);
|
|
573945
574031
|
let systemPrompt = contextComposition.assembled;
|
|
574032
|
+
try {
|
|
574033
|
+
systemPrompt = `${systemPrompt}
|
|
574034
|
+
|
|
574035
|
+
${completionEvidenceDirective()}`;
|
|
574036
|
+
} catch {
|
|
574037
|
+
}
|
|
573946
574038
|
try {
|
|
573947
574039
|
const _cap = getMediaCapability();
|
|
573948
574040
|
const _tier = this.options.modelTier ?? "large";
|
|
@@ -590380,6 +590472,7 @@ __export(dist_exports3, {
|
|
|
590380
590472
|
appendSteeringLedgerEntry: () => appendSteeringLedgerEntry,
|
|
590381
590473
|
appendSteeringOutcome: () => appendSteeringOutcome,
|
|
590382
590474
|
arcSummary: () => arcSummary,
|
|
590475
|
+
auditCompletionClaims: () => auditCompletionClaims,
|
|
590383
590476
|
buildAgentNotification: () => buildAgentNotification,
|
|
590384
590477
|
buildAgentTypeSummary: () => buildAgentTypeSummary,
|
|
590385
590478
|
buildCompletionScenarioDecomposition: () => buildCompletionScenarioDecomposition,
|
|
@@ -590400,6 +590493,7 @@ __export(dist_exports3, {
|
|
|
590400
590493
|
chooseCheapModelRoute: () => chooseCheapModelRoute,
|
|
590401
590494
|
claimAssertion: () => claimAssertion,
|
|
590402
590495
|
classifyBreadth: () => classifyBreadth,
|
|
590496
|
+
classifyCompletionClaim: () => classifyCompletionClaim,
|
|
590403
590497
|
classifyHandoff: () => classifyHandoff,
|
|
590404
590498
|
classifyOllamaProcesses: () => classifyOllamaProcesses,
|
|
590405
590499
|
cleanForStorage: () => cleanForStorage,
|
|
@@ -590408,6 +590502,7 @@ __export(dist_exports3, {
|
|
|
590408
590502
|
clearTurnState: () => clearTurnState,
|
|
590409
590503
|
combineValidatorResults: () => combineValidatorResults,
|
|
590410
590504
|
compilePersonalityPrompt: () => compilePersonalityPrompt,
|
|
590505
|
+
completionEvidenceDirective: () => completionEvidenceDirective,
|
|
590411
590506
|
compressFindings: () => compressFindings,
|
|
590412
590507
|
computeArc: () => computeArc,
|
|
590413
590508
|
computeStabilityHash: () => computeStabilityHash,
|
|
@@ -590425,6 +590520,7 @@ __export(dist_exports3, {
|
|
|
590425
590520
|
decomposeSpec: () => decomposeSpec,
|
|
590426
590521
|
deleteAgentTaskSidecar: () => deleteAgentTaskSidecar,
|
|
590427
590522
|
deriveClaimsFromProposedText: () => deriveClaimsFromProposedText,
|
|
590523
|
+
detectExitCodeMisread: () => detectExitCodeMisread,
|
|
590428
590524
|
detectExplorationIntent: () => detectExplorationIntent,
|
|
590429
590525
|
detectPressure: () => detectPressure,
|
|
590430
590526
|
detectTaskType: () => detectTaskType,
|
|
@@ -590638,6 +590734,7 @@ var init_dist8 = __esm({
|
|
|
590638
590734
|
init_memory_consolidation();
|
|
590639
590735
|
init_exploration_fanout();
|
|
590640
590736
|
init_consolidation_runtime();
|
|
590737
|
+
init_completion_evidence_gate();
|
|
590641
590738
|
}
|
|
590642
590739
|
});
|
|
590643
590740
|
|
|
@@ -689463,6 +689560,41 @@ window.__omniusStores = {
|
|
|
689463
689560
|
|
|
689464
689561
|
const conv = document.getElementById('conversation');
|
|
689465
689562
|
const input = document.getElementById('input-area');
|
|
689563
|
+
// SUGGESTED FOLLOW-UP — ghost text (placeholder-grey) shown after a reply
|
|
689564
|
+
// completes; Tab accepts it as real text, typing dismisses it.
|
|
689565
|
+
const DEFAULT_INPUT_PLACEHOLDER = 'Type a message...';
|
|
689566
|
+
let chatFollowup = null;
|
|
689567
|
+
function setFollowupSuggestion(text) {
|
|
689568
|
+
text = (text || '').trim();
|
|
689569
|
+
if (!text || streaming) return;
|
|
689570
|
+
if (input.value.trim().length > 0) return; // don't clobber what the user is typing
|
|
689571
|
+
chatFollowup = text;
|
|
689572
|
+
input.placeholder = text + ' (Tab \\u21E5)';
|
|
689573
|
+
}
|
|
689574
|
+
function clearFollowupSuggestion() {
|
|
689575
|
+
if (chatFollowup !== null) { chatFollowup = null; input.placeholder = DEFAULT_INPUT_PLACEHOLDER; }
|
|
689576
|
+
}
|
|
689577
|
+
function acceptFollowupSuggestion() {
|
|
689578
|
+
if (chatFollowup === null || input.value.trim().length > 0) return false;
|
|
689579
|
+
const t = chatFollowup;
|
|
689580
|
+
clearFollowupSuggestion();
|
|
689581
|
+
input.value = t;
|
|
689582
|
+
try { input.dispatchEvent(new Event('input')); } catch (e) {}
|
|
689583
|
+
input.focus();
|
|
689584
|
+
try { input.setSelectionRange(t.length, t.length); } catch (e) {}
|
|
689585
|
+
return true;
|
|
689586
|
+
}
|
|
689587
|
+
async function fetchFollowupSuggestion() {
|
|
689588
|
+
try {
|
|
689589
|
+
if (!chatSessionId || input.value.trim().length > 0) return;
|
|
689590
|
+
const r = await fetch('/v1/chat/suggest-followup', {
|
|
689591
|
+
method: 'POST', headers: headers(), body: JSON.stringify({ session_id: chatSessionId }),
|
|
689592
|
+
});
|
|
689593
|
+
if (!r.ok) return;
|
|
689594
|
+
const d = await r.json();
|
|
689595
|
+
if (d && d.suggestion) setFollowupSuggestion(d.suggestion);
|
|
689596
|
+
} catch (e) { /* best-effort */ }
|
|
689597
|
+
}
|
|
689466
689598
|
const sendBtn = document.getElementById('send-btn');
|
|
689467
689599
|
const modelSelect = document.getElementById('model-select');
|
|
689468
689600
|
// Persist the selected model on every change so a browser refresh /
|
|
@@ -689567,6 +689699,8 @@ if (conv) {
|
|
|
689567
689699
|
|
|
689568
689700
|
// Auto-resize textarea + WO-CHAT-CHECKIN typing detection
|
|
689569
689701
|
input.addEventListener('input', () => {
|
|
689702
|
+
// Dismiss the suggested follow-up the moment the user starts typing.
|
|
689703
|
+
if (input.value.length > 0) clearFollowupSuggestion();
|
|
689570
689704
|
input.style.height = 'auto';
|
|
689571
689705
|
// OWUI-4: bump max from 120 (~6 lines) to 240 (~12 lines).
|
|
689572
689706
|
input.style.height = Math.min(input.scrollHeight, 240) + 'px';
|
|
@@ -689597,6 +689731,10 @@ input.addEventListener('keydown', (e) => {
|
|
|
689597
689731
|
if (e.key === 'Tab') { e.preventDefault(); _slashPaletteAccept(); return; }
|
|
689598
689732
|
if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); _slashPaletteAccept(); return; }
|
|
689599
689733
|
}
|
|
689734
|
+
// Suggested follow-up: Tab accepts the ghost text as real input.
|
|
689735
|
+
if (e.key === 'Tab' && !e.shiftKey && chatFollowup !== null && input.value.trim().length === 0) {
|
|
689736
|
+
if (acceptFollowupSuggestion()) { e.preventDefault(); return; }
|
|
689737
|
+
}
|
|
689600
689738
|
// OWUI-4: Cmd/Ctrl+Enter — always sends, never inserts a newline.
|
|
689601
689739
|
if (e.key === 'Enter' && (e.metaKey || e.ctrlKey)) {
|
|
689602
689740
|
e.preventDefault();
|
|
@@ -690309,6 +690447,7 @@ async function runSlashCommandInline(rawInput) {
|
|
|
690309
690447
|
async function sendMessage() {
|
|
690310
690448
|
const text = input.value.trim();
|
|
690311
690449
|
if (!text || streaming) return;
|
|
690450
|
+
clearFollowupSuggestion(); // a real send supersedes any ghost suggestion
|
|
690312
690451
|
|
|
690313
690452
|
// ─── Slash command passthrough ────────────────────────────────────────
|
|
690314
690453
|
// /foo args → POST /v1/command, render result inline as a system
|
|
@@ -690686,6 +690825,8 @@ async function sendMessage() {
|
|
|
690686
690825
|
chatAbortController = null;
|
|
690687
690826
|
document.getElementById('send-btn').style.display = 'inline-block';
|
|
690688
690827
|
document.getElementById('stop-btn').style.display = 'none';
|
|
690828
|
+
// Reply finished — offer a suggested follow-up as ghost text in the input.
|
|
690829
|
+
try { fetchFollowupSuggestion(); } catch (e) {}
|
|
690689
690830
|
// OWUI-3: belt-and-braces — make sure the indicator is gone if we
|
|
690690
690831
|
// reach this finally{} via an error path before the success branch
|
|
690691
690832
|
// had a chance to call hideStreamingIndicator.
|
|
@@ -697329,6 +697470,7 @@ function getOpenApiSpec() {
|
|
|
697329
697470
|
},
|
|
697330
697471
|
"/v1/chat/sessions": { get: { summary: "List active chat sessions", tags: ["Chat"], responses: { 200: { description: "Session list" } } } },
|
|
697331
697472
|
"/v1/chat/sessions/{id}/summarize": { post: { summary: "Generate + cache an inference-based title/summary for a session — body {force?, root?}", tags: ["Chat"], responses: { 200: { description: "Title + summary" }, 500: { description: "Generation failed" } } } },
|
|
697473
|
+
"/v1/chat/suggest-followup": { post: { summary: "Suggest one short next-message follow-up for a session (ghost-text input) — body {session_id}", tags: ["Chat"], responses: { 200: { description: "{ suggestion }" } } } },
|
|
697332
697474
|
"/v1/chat/sessions/{id}/status": { get: { summary: "Reactive recall: is this session running right now + unseen deltas since ?since=<seq> (running, phase, seq, partial, deltas[])", tags: ["Chat"], responses: { 200: { description: "Live run status + catch-up deltas" } } } },
|
|
697333
697475
|
// ───── AIWG cascade ─────
|
|
697334
697476
|
"/v1/aiwg": { get: { summary: "AIWG installation root + control map", tags: ["AIWG"], responses: { 200: { description: "AIWG installation summary" } } } },
|
|
@@ -698184,6 +698326,62 @@ var init_chat_run_registry = __esm({
|
|
|
698184
698326
|
}
|
|
698185
698327
|
});
|
|
698186
698328
|
|
|
698329
|
+
// packages/cli/src/api/chat-followup.ts
|
|
698330
|
+
function normalizeBaseUrl2(url) {
|
|
698331
|
+
let u = (url || "").trim().replace(/\/+$/, "");
|
|
698332
|
+
if (u.endsWith("/v1")) u = u.slice(0, -3);
|
|
698333
|
+
return u;
|
|
698334
|
+
}
|
|
698335
|
+
function cleanSuggestion(raw) {
|
|
698336
|
+
let s2 = (raw || "").trim();
|
|
698337
|
+
s2 = s2.split("\n")[0].trim();
|
|
698338
|
+
s2 = s2.replace(/^["'`*\-\d.\s]+/, "").replace(/["'`]+$/, "").trim();
|
|
698339
|
+
if (/^(none|n\/?a|no follow|nothing)\b/i.test(s2)) return "";
|
|
698340
|
+
return s2.length > 140 ? s2.slice(0, 139).trimEnd() + "…" : s2;
|
|
698341
|
+
}
|
|
698342
|
+
async function suggestFollowup(args) {
|
|
698343
|
+
const turns = (args.turns || []).filter((t2) => t2 && t2.content && (t2.role === "user" || t2.role === "assistant"));
|
|
698344
|
+
if (!turns.length || !args.config.model || !args.config.backendUrl) return "";
|
|
698345
|
+
const transcript = turns.slice(-6).map((t2) => `${t2.role === "user" ? "User" : "Assistant"}: ${String(t2.content).slice(0, 800)}`).join("\n");
|
|
698346
|
+
try {
|
|
698347
|
+
const url = normalizeBaseUrl2(args.config.backendUrl) + "/v1/chat/completions";
|
|
698348
|
+
const headers = { "Content-Type": "application/json" };
|
|
698349
|
+
if (args.config.apiKey) headers["Authorization"] = `Bearer ${args.config.apiKey}`;
|
|
698350
|
+
const body = {
|
|
698351
|
+
model: args.config.model,
|
|
698352
|
+
messages: [
|
|
698353
|
+
{
|
|
698354
|
+
role: "system",
|
|
698355
|
+
content: "You suggest the single most likely NEXT message the user would send to continue this conversation. Write it in the user's voice (imperative, first person), as if they typed it. Reply with ONLY that one short prompt — no quotes, no preamble, no markdown, max ~12 words. If no natural follow-up exists, reply with exactly: NONE."
|
|
698356
|
+
},
|
|
698357
|
+
{ role: "user", content: `Conversation so far:
|
|
698358
|
+
${transcript}
|
|
698359
|
+
|
|
698360
|
+
The user's likely next message:` }
|
|
698361
|
+
],
|
|
698362
|
+
temperature: 0.4,
|
|
698363
|
+
max_tokens: 40,
|
|
698364
|
+
stream: false
|
|
698365
|
+
};
|
|
698366
|
+
const resp = await fetch(url, {
|
|
698367
|
+
method: "POST",
|
|
698368
|
+
headers,
|
|
698369
|
+
body: JSON.stringify(body),
|
|
698370
|
+
signal: AbortSignal.timeout(args.timeoutMs ?? 12e3)
|
|
698371
|
+
});
|
|
698372
|
+
if (!resp.ok) return "";
|
|
698373
|
+
const data = await resp.json();
|
|
698374
|
+
return cleanSuggestion(data?.choices?.[0]?.message?.content ?? "");
|
|
698375
|
+
} catch {
|
|
698376
|
+
return "";
|
|
698377
|
+
}
|
|
698378
|
+
}
|
|
698379
|
+
var init_chat_followup = __esm({
|
|
698380
|
+
"packages/cli/src/api/chat-followup.ts"() {
|
|
698381
|
+
"use strict";
|
|
698382
|
+
}
|
|
698383
|
+
});
|
|
698384
|
+
|
|
698187
698385
|
// packages/cli/src/docker.ts
|
|
698188
698386
|
import { execSync as execSync59, spawn as spawn32 } from "node:child_process";
|
|
698189
698387
|
import { existsSync as existsSync158, mkdirSync as mkdirSync99, writeFileSync as writeFileSync84 } from "node:fs";
|
|
@@ -706426,6 +706624,24 @@ ${historyLines}
|
|
|
706426
706624
|
});
|
|
706427
706625
|
return;
|
|
706428
706626
|
}
|
|
706627
|
+
if (pathname === "/v1/chat/suggest-followup" && method === "POST") {
|
|
706628
|
+
if (!checkAuth(req3, res, "read")) return;
|
|
706629
|
+
const fbBody = await parseJsonBody(req3);
|
|
706630
|
+
const sid = fbBody?.session_id ? String(fbBody.session_id) : "";
|
|
706631
|
+
const session = sid ? lookupSession(sid) : null;
|
|
706632
|
+
const turns = session ? session.messages.filter((m2) => m2 && (m2.role === "user" || m2.role === "assistant") && typeof m2.content === "string").map((m2) => ({ role: m2.role, content: m2.content })) : [];
|
|
706633
|
+
if (turns.length === 0) {
|
|
706634
|
+
jsonResponse(res, 200, { suggestion: "" });
|
|
706635
|
+
return;
|
|
706636
|
+
}
|
|
706637
|
+
const cfg = loadConfig();
|
|
706638
|
+
const suggestion = await suggestFollowup({
|
|
706639
|
+
turns,
|
|
706640
|
+
config: { backendUrl: cfg.backendUrl, model: cfg.model, apiKey: cfg.apiKey }
|
|
706641
|
+
});
|
|
706642
|
+
jsonResponse(res, 200, { suggestion });
|
|
706643
|
+
return;
|
|
706644
|
+
}
|
|
706429
706645
|
const chatSessionMatch = pathname.match(/^\/v1\/chat\/sessions\/([^/]+)$/);
|
|
706430
706646
|
if (chatSessionMatch) {
|
|
706431
706647
|
const sid = decodeURIComponent(chatSessionMatch[1]);
|
|
@@ -709080,6 +709296,7 @@ var init_serve = __esm({
|
|
|
709080
709296
|
init_omnius_directory();
|
|
709081
709297
|
init_session_summary();
|
|
709082
709298
|
init_chat_run_registry();
|
|
709299
|
+
init_chat_followup();
|
|
709083
709300
|
init_omnius_directory();
|
|
709084
709301
|
init_command_registry();
|
|
709085
709302
|
init_profiles();
|
|
@@ -52,6 +52,7 @@ pnpm docs:check
|
|
|
52
52
|
| `GET` | `/api/tags` | Ollama-compatible model tags |
|
|
53
53
|
| `GET` | `/v1/chat/sessions` | Active chat sessions |
|
|
54
54
|
| `POST` | `/v1/chat/sessions/{id}/summarize` | Generate + cache an inference-based session title/summary |
|
|
55
|
+
| `POST` | `/v1/chat/suggest-followup` | Suggest one short next-message follow-up (ghost-text input) |
|
|
55
56
|
| `GET` | `/v1/chat/sessions/{id}/status` | Reactive recall: live run status + unseen deltas (`?since=<seq>`) |
|
|
56
57
|
| `POST` | `/v1/chat/check-in` | Steering check-in for active chat |
|
|
57
58
|
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "omnius",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.341",
|
|
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.341",
|
|
10
10
|
"bundleDependencies": [
|
|
11
11
|
"image-to-ascii"
|
|
12
12
|
],
|
package/package.json
CHANGED