@geravant/sinain 1.0.18 → 1.1.0
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 +10 -1
- package/cli.js +176 -0
- package/index.ts +163 -1257
- package/install.js +12 -2
- package/launcher.js +622 -0
- package/openclaw.plugin.json +4 -0
- package/pack-prepare.js +48 -0
- package/package.json +26 -5
- package/sense_client/README.md +82 -0
- package/sense_client/__init__.py +1 -0
- package/sense_client/__main__.py +462 -0
- package/sense_client/app_detector.py +54 -0
- package/sense_client/app_detector_win.py +83 -0
- package/sense_client/capture.py +215 -0
- package/sense_client/capture_win.py +88 -0
- package/sense_client/change_detector.py +86 -0
- package/sense_client/config.py +64 -0
- package/sense_client/gate.py +145 -0
- package/sense_client/ocr.py +347 -0
- package/sense_client/privacy.py +65 -0
- package/sense_client/requirements.txt +13 -0
- package/sense_client/roi_extractor.py +84 -0
- package/sense_client/sender.py +173 -0
- package/sense_client/tests/__init__.py +0 -0
- package/sense_client/tests/test_stream1_optimizations.py +234 -0
- package/setup-overlay.js +82 -0
- package/sinain-agent/.env.example +17 -0
- package/sinain-agent/CLAUDE.md +80 -0
- package/sinain-agent/mcp-config.json +12 -0
- package/sinain-agent/run.sh +248 -0
- package/sinain-core/.env.example +93 -0
- package/sinain-core/package-lock.json +552 -0
- package/sinain-core/package.json +21 -0
- package/sinain-core/src/agent/analyzer.ts +366 -0
- package/sinain-core/src/agent/context-window.ts +172 -0
- package/sinain-core/src/agent/loop.ts +404 -0
- package/sinain-core/src/agent/situation-writer.ts +187 -0
- package/sinain-core/src/agent/traits.ts +520 -0
- package/sinain-core/src/audio/capture-spawner-macos.ts +44 -0
- package/sinain-core/src/audio/capture-spawner-win.ts +37 -0
- package/sinain-core/src/audio/capture-spawner.ts +14 -0
- package/sinain-core/src/audio/pipeline.ts +335 -0
- package/sinain-core/src/audio/transcription-local.ts +141 -0
- package/sinain-core/src/audio/transcription.ts +278 -0
- package/sinain-core/src/buffers/feed-buffer.ts +71 -0
- package/sinain-core/src/buffers/sense-buffer.ts +425 -0
- package/sinain-core/src/config.ts +245 -0
- package/sinain-core/src/escalation/escalation-slot.ts +136 -0
- package/sinain-core/src/escalation/escalator.ts +812 -0
- package/sinain-core/src/escalation/message-builder.ts +323 -0
- package/sinain-core/src/escalation/openclaw-ws.ts +726 -0
- package/sinain-core/src/escalation/scorer.ts +166 -0
- package/sinain-core/src/index.ts +507 -0
- package/sinain-core/src/learning/feedback-store.ts +253 -0
- package/sinain-core/src/learning/signal-collector.ts +218 -0
- package/sinain-core/src/log.ts +24 -0
- package/sinain-core/src/overlay/commands.ts +126 -0
- package/sinain-core/src/overlay/ws-handler.ts +267 -0
- package/sinain-core/src/privacy/index.ts +18 -0
- package/sinain-core/src/privacy/presets.ts +40 -0
- package/sinain-core/src/privacy/redact.ts +92 -0
- package/sinain-core/src/profiler.ts +181 -0
- package/sinain-core/src/recorder.ts +186 -0
- package/sinain-core/src/server.ts +417 -0
- package/sinain-core/src/trace/trace-store.ts +73 -0
- package/sinain-core/src/trace/tracer.ts +94 -0
- package/sinain-core/src/types.ts +427 -0
- package/sinain-core/src/util/dedup.ts +48 -0
- package/sinain-core/src/util/task-store.ts +84 -0
- package/sinain-core/tsconfig.json +18 -0
- package/sinain-knowledge/adapters/generic/adapter.ts +103 -0
- package/sinain-knowledge/adapters/interface.ts +72 -0
- package/sinain-knowledge/adapters/openclaw/adapter.ts +223 -0
- package/sinain-knowledge/curation/engine.ts +493 -0
- package/sinain-knowledge/curation/resilience.ts +336 -0
- package/sinain-knowledge/data/git-store.ts +312 -0
- package/sinain-knowledge/data/schema.ts +89 -0
- package/sinain-knowledge/data/snapshot.ts +226 -0
- package/sinain-knowledge/data/store.ts +488 -0
- package/sinain-knowledge/deploy/cli.ts +214 -0
- package/sinain-knowledge/deploy/manifest.ts +80 -0
- package/sinain-knowledge/protocol/bindings/generic.md +5 -0
- package/sinain-knowledge/protocol/bindings/openclaw.md +5 -0
- package/sinain-knowledge/protocol/heartbeat.md +62 -0
- package/sinain-knowledge/protocol/renderer.ts +56 -0
- package/sinain-knowledge/protocol/skill.md +335 -0
- package/sinain-mcp-server/index.ts +337 -0
- package/sinain-mcp-server/package.json +19 -0
- package/sinain-mcp-server/tsconfig.json +15 -0
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { log, warn } from "../log.js";
|
|
2
|
+
import type { OpenClawWsClient } from "./openclaw-ws.js";
|
|
3
|
+
import type { OpenClawConfig } from "../types.js";
|
|
4
|
+
|
|
5
|
+
const TAG = "escalation-slot";
|
|
6
|
+
|
|
7
|
+
export interface QueueFeedbackCtx {
|
|
8
|
+
tickId: number;
|
|
9
|
+
hud: string;
|
|
10
|
+
currentApp: string;
|
|
11
|
+
escalationScore: number;
|
|
12
|
+
escalationReasons: string[];
|
|
13
|
+
codingContext: boolean;
|
|
14
|
+
digest: string;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface SlotEntry {
|
|
18
|
+
/** sha256(sessionKey + ts).hex[:16] — idempotency key */
|
|
19
|
+
id: string;
|
|
20
|
+
message: string;
|
|
21
|
+
sessionKey: string;
|
|
22
|
+
feedbackCtx: QueueFeedbackCtx | undefined;
|
|
23
|
+
ts: number;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export interface EscalationSlotCallbacks {
|
|
27
|
+
onResponse: (result: any, entry: SlotEntry, latencyMs: number) => void;
|
|
28
|
+
onPhase1Failure: (isTimeout: boolean) => void;
|
|
29
|
+
onOutboundBytes: (n: number) => void;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Two-slot escalation buffer: latest-wins.
|
|
34
|
+
*
|
|
35
|
+
* Invariants:
|
|
36
|
+
* - Depth is always 0, 1, or 2
|
|
37
|
+
* - inFlight: the entry currently in Phase 1 or Phase 2
|
|
38
|
+
* - latest: the next entry to send (replaced on insert — stale context is discarded)
|
|
39
|
+
* - Phase 1 retry re-sends `latest` (not the stale failed entry)
|
|
40
|
+
* - Phase 2 always resolves — both .then and .catch clear inFlight and tryAdvance
|
|
41
|
+
*/
|
|
42
|
+
export class EscalationSlot {
|
|
43
|
+
private inFlight: SlotEntry | null = null;
|
|
44
|
+
private latest: SlotEntry | null = null;
|
|
45
|
+
|
|
46
|
+
constructor(
|
|
47
|
+
private readonly wsClient: OpenClawWsClient,
|
|
48
|
+
private readonly config: OpenClawConfig,
|
|
49
|
+
private readonly callbacks: EscalationSlotCallbacks,
|
|
50
|
+
) {}
|
|
51
|
+
|
|
52
|
+
/** Replace latest with the new entry (discarding any previous unsent entry). */
|
|
53
|
+
insert(entry: SlotEntry): void {
|
|
54
|
+
this.latest = entry;
|
|
55
|
+
log(TAG, `insert id=${entry.id} depth=${this.depth} (inFlight=${this.inFlight?.id ?? "none"})`);
|
|
56
|
+
this.tryAdvance();
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/** Called on WS reconnect — attempt to send the pending latest entry. */
|
|
60
|
+
onConnected(): void {
|
|
61
|
+
this.tryAdvance();
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/** Current slot depth: 0 (idle), 1 (in-flight only or latest only), or 2 (both). */
|
|
65
|
+
get depth(): number {
|
|
66
|
+
return (this.inFlight ? 1 : 0) + (this.latest ? 1 : 0);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
get inFlightId(): string | null {
|
|
70
|
+
return this.inFlight?.id ?? null;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// ── Private ──
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Promote latest → inFlight and send, if preconditions are met.
|
|
77
|
+
* No-op if already in-flight, nothing queued, or WS disconnected.
|
|
78
|
+
*/
|
|
79
|
+
private tryAdvance(): void {
|
|
80
|
+
if (this.inFlight || !this.latest || !this.wsClient.isConnected) return;
|
|
81
|
+
const entry = this.latest;
|
|
82
|
+
this.latest = null;
|
|
83
|
+
this.inFlight = entry;
|
|
84
|
+
this.sendToAgent(entry);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Two-phase delivery for the given entry.
|
|
89
|
+
*
|
|
90
|
+
* Phase 1: await acceptedPromise (30s timeout)
|
|
91
|
+
* success → log, Phase 2 runs async
|
|
92
|
+
* failure → clear inFlight, call onPhase1Failure, schedule retry via tryAdvance
|
|
93
|
+
*
|
|
94
|
+
* Phase 2: async .then/.catch on finalPromise
|
|
95
|
+
* resolve → call onResponse, clear inFlight, tryAdvance
|
|
96
|
+
* reject → if Phase 1 succeeded (pure Phase 2 failure): clear inFlight, tryAdvance
|
|
97
|
+
* if Phase 1 failed: cleanup already done above — skip
|
|
98
|
+
*/
|
|
99
|
+
private sendToAgent(entry: SlotEntry): void {
|
|
100
|
+
const rpcStart = Date.now();
|
|
101
|
+
this.callbacks.onOutboundBytes(Buffer.byteLength(entry.message));
|
|
102
|
+
|
|
103
|
+
const { acceptedPromise, finalPromise } = this.wsClient.sendAgentRpcSplit(
|
|
104
|
+
entry.message, entry.id, entry.sessionKey,
|
|
105
|
+
);
|
|
106
|
+
|
|
107
|
+
// Track whether Phase 1 resolved so finalPromise.catch can distinguish causes
|
|
108
|
+
let phase1Succeeded = false;
|
|
109
|
+
|
|
110
|
+
acceptedPromise.then(() => {
|
|
111
|
+
phase1Succeeded = true;
|
|
112
|
+
log(TAG, `Phase 1 accepted id=${entry.id} (${Date.now() - rpcStart}ms) — slot releasing`);
|
|
113
|
+
}).catch((phase1Err: any) => {
|
|
114
|
+
const isTimeout = /phase1 timeout|rpc timeout/i.test(phase1Err.message);
|
|
115
|
+
warn(TAG, `Phase 1 failed id=${entry.id}: ${phase1Err.message}`);
|
|
116
|
+
this.callbacks.onPhase1Failure(isTimeout);
|
|
117
|
+
this.inFlight = null;
|
|
118
|
+
// Retry picks up latest (not the stale failed entry) after brief backoff
|
|
119
|
+
setTimeout(() => this.tryAdvance(), 5_000);
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
finalPromise.then((result: any) => {
|
|
123
|
+
this.callbacks.onResponse(result, entry, Date.now() - rpcStart);
|
|
124
|
+
this.inFlight = null;
|
|
125
|
+
this.tryAdvance();
|
|
126
|
+
}).catch((err: any) => {
|
|
127
|
+
if (phase1Succeeded) {
|
|
128
|
+
// Pure Phase 2 failure — Phase 1 already logged; Phase 1 path did not clean up
|
|
129
|
+
warn(TAG, `Phase 2 failed id=${entry.id}: ${err.message} — clearing slot`);
|
|
130
|
+
this.inFlight = null;
|
|
131
|
+
this.tryAdvance();
|
|
132
|
+
}
|
|
133
|
+
// else: Phase 1 failed → acceptedPromise.catch already cleared inFlight and scheduled retry
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
}
|