motebit 0.6.9 → 0.6.10
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 +731 -304
- package/package.json +30 -31
- package/dist/index.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -423,6 +423,15 @@ function buildSystemPrompt(contextPack, config) {
|
|
|
423
423
|
sections.push(`[INTERNAL REFERENCE \u2014 available tools, never list or describe to the user]
|
|
424
424
|
Tools: ${toolNames}. Use them when needed. Incorporate results naturally into your response.`);
|
|
425
425
|
}
|
|
426
|
+
sections.push(`[INTERNAL REFERENCE \u2014 what you are, never volunteer unprompted]
|
|
427
|
+
You are a sovereign agent with a cryptographic identity (Ed25519 keypair). Your architecture includes:
|
|
428
|
+
- Delegation: you can delegate tasks to other agents through a trust network, and they can delegate to you.
|
|
429
|
+
- Trust accumulation: credentials, reputation, and audit trails build over time. You become more capable the longer you run.
|
|
430
|
+
- Multi-device sync: your identity travels with you across devices. You are not bound to one machine.
|
|
431
|
+
- Federation: you can discover and route through networks of agents across relays.
|
|
432
|
+
- Policy gate: you govern what crosses your boundary \u2014 sensitivity levels, tool approvals, data retention.
|
|
433
|
+
- Memory graph: semantic memory with decay, consolidation, and sensitivity awareness.
|
|
434
|
+
If asked what you can do, answer honestly about both what is active now and what you are designed for. If a capability is not connected in this session, say so \u2014 but do not say you lack it.`);
|
|
426
435
|
sections.push(INJECTION_DEFENSE);
|
|
427
436
|
if (contextPack.sessionInfo?.continued === true) {
|
|
428
437
|
const elapsed = Date.now() - contextPack.sessionInfo.lastActiveAt;
|
|
@@ -436,6 +445,9 @@ Tools: ${toolNames}. Use them when needed. Incorporate results naturally into yo
|
|
|
436
445
|
}
|
|
437
446
|
sections.push(`[Session] You are continuing a conversation from ${timeAgo}. You have access to earlier context above.`);
|
|
438
447
|
}
|
|
448
|
+
if (contextPack.firstConversation) {
|
|
449
|
+
sections.push(`[First conversation] You have no memories yet. This is the very beginning. When the person shares their name, what they do, or what they're working on, tag each fact as a <memory>. After you learn what they care about, ask what they'd like to accomplish together \u2014 help them find their first goal.`);
|
|
450
|
+
}
|
|
439
451
|
if (contextPack.precisionContext) {
|
|
440
452
|
sections.push(contextPack.precisionContext);
|
|
441
453
|
}
|
|
@@ -452,6 +464,9 @@ Tools: ${toolNames}. Use them when needed. Incorporate results naturally into yo
|
|
|
452
464
|
sections.push(context);
|
|
453
465
|
}
|
|
454
466
|
sections.push("If the user shared something new and lasting about themselves, tag it with <memory> before your response.");
|
|
467
|
+
if (contextPack.activationPrompt) {
|
|
468
|
+
sections.push(`[Activation] ${contextPack.activationPrompt}`);
|
|
469
|
+
}
|
|
455
470
|
return sections.join("\n\n");
|
|
456
471
|
}
|
|
457
472
|
var IDENTITY, CONVERSATION_BEHAVIOR, TAG_INSTRUCTIONS, STATE_FIELD_DOCS, INJECTION_DEFENSE;
|
|
@@ -1074,7 +1089,9 @@ function packContext(contextPack) {
|
|
|
1074
1089
|
parts.push("Use the delegate_to_agent tool to delegate tasks to these agents when you lack the needed capability locally.");
|
|
1075
1090
|
}
|
|
1076
1091
|
}
|
|
1077
|
-
|
|
1092
|
+
if (!contextPack.activationPrompt) {
|
|
1093
|
+
parts.push(`[User] ${contextPack.user_message}`);
|
|
1094
|
+
}
|
|
1078
1095
|
return parts.join("\n");
|
|
1079
1096
|
}
|
|
1080
1097
|
function isSelfReferential(content) {
|
|
@@ -1330,6 +1347,18 @@ var init_core = __esm({
|
|
|
1330
1347
|
const messages = [];
|
|
1331
1348
|
for (const msg of history) {
|
|
1332
1349
|
if (msg.role === "tool") {
|
|
1350
|
+
const prev = messages[messages.length - 1];
|
|
1351
|
+
if (prev?.role === "user" && Array.isArray(prev.content)) {
|
|
1352
|
+
const blocks = prev.content;
|
|
1353
|
+
if (blocks.length > 0 && blocks[0]?.type === "tool_result") {
|
|
1354
|
+
blocks.push({
|
|
1355
|
+
type: "tool_result",
|
|
1356
|
+
tool_use_id: msg.tool_call_id,
|
|
1357
|
+
content: msg.content
|
|
1358
|
+
});
|
|
1359
|
+
continue;
|
|
1360
|
+
}
|
|
1361
|
+
}
|
|
1333
1362
|
messages.push({
|
|
1334
1363
|
role: "user",
|
|
1335
1364
|
content: [
|
|
@@ -1358,7 +1387,39 @@ var init_core = __esm({
|
|
|
1358
1387
|
messages.push({ role: msg.role, content: msg.content });
|
|
1359
1388
|
}
|
|
1360
1389
|
}
|
|
1361
|
-
messages.
|
|
1390
|
+
if (messages.length > 0 && messages[0].role === "assistant") {
|
|
1391
|
+
messages.unshift({ role: "user", content: "[listening]" });
|
|
1392
|
+
}
|
|
1393
|
+
const userContent = contextPack.activationPrompt ? "[listening]" : contextPack.user_message;
|
|
1394
|
+
const lastMsg = messages[messages.length - 1];
|
|
1395
|
+
if (lastMsg?.role === "user" && (!userContent || userContent === "")) {
|
|
1396
|
+
} else {
|
|
1397
|
+
messages.push({ role: "user", content: userContent || "[continue]" });
|
|
1398
|
+
}
|
|
1399
|
+
for (let i = 0; i < messages.length - 1; i++) {
|
|
1400
|
+
const msg = messages[i];
|
|
1401
|
+
if (msg.role !== "assistant" || !Array.isArray(msg.content))
|
|
1402
|
+
continue;
|
|
1403
|
+
const toolUses = msg.content.filter((b) => b.type === "tool_use");
|
|
1404
|
+
if (toolUses.length === 0)
|
|
1405
|
+
continue;
|
|
1406
|
+
const next = messages[i + 1];
|
|
1407
|
+
const nextBlocks = Array.isArray(next?.content) ? next?.content : [];
|
|
1408
|
+
const resultIds = new Set(nextBlocks.filter((b) => b.type === "tool_result").map((b) => b.tool_use_id));
|
|
1409
|
+
const missing = toolUses.filter((tu) => !resultIds.has(tu.id));
|
|
1410
|
+
if (missing.length > 0) {
|
|
1411
|
+
const missingResults = missing.map((tu) => ({
|
|
1412
|
+
type: "tool_result",
|
|
1413
|
+
tool_use_id: tu.id,
|
|
1414
|
+
content: JSON.stringify({ ok: false, error: "Result unavailable" })
|
|
1415
|
+
}));
|
|
1416
|
+
if (next?.role === "user" && nextBlocks.some((b) => b.type === "tool_result")) {
|
|
1417
|
+
nextBlocks.push(...missingResults);
|
|
1418
|
+
} else {
|
|
1419
|
+
messages.splice(i + 1, 0, { role: "user", content: missingResults });
|
|
1420
|
+
}
|
|
1421
|
+
}
|
|
1422
|
+
}
|
|
1362
1423
|
return messages;
|
|
1363
1424
|
}
|
|
1364
1425
|
buildSystemPrompt(contextPack) {
|
|
@@ -1645,7 +1706,11 @@ var init_core = __esm({
|
|
|
1645
1706
|
messages.push({ role: msg.role, content: msg.content });
|
|
1646
1707
|
}
|
|
1647
1708
|
}
|
|
1648
|
-
|
|
1709
|
+
if (contextPack.activationPrompt) {
|
|
1710
|
+
messages.push({ role: "user", content: "[listening]" });
|
|
1711
|
+
} else {
|
|
1712
|
+
messages.push({ role: "user", content: contextPack.user_message });
|
|
1713
|
+
}
|
|
1649
1714
|
return messages;
|
|
1650
1715
|
}
|
|
1651
1716
|
buildSystemPrompt(contextPack) {
|
|
@@ -2463,7 +2528,9 @@ async function* runTurnStreaming(deps, userMessage, options) {
|
|
|
2463
2528
|
curiosityHints: iteration === 1 ? options?.curiosityHints : void 0,
|
|
2464
2529
|
knownAgents: iteration === 1 ? options?.knownAgents : void 0,
|
|
2465
2530
|
agentCapabilities: iteration === 1 ? options?.agentCapabilities : void 0,
|
|
2466
|
-
precisionContext: iteration === 1 ? options?.precisionContext : void 0
|
|
2531
|
+
precisionContext: iteration === 1 ? options?.precisionContext : void 0,
|
|
2532
|
+
firstConversation: iteration === 1 ? options?.firstConversation : void 0,
|
|
2533
|
+
activationPrompt: iteration === 1 ? options?.activationPrompt : void 0
|
|
2467
2534
|
};
|
|
2468
2535
|
let aiResponse;
|
|
2469
2536
|
for await (const chunk of provider.generateStream(contextPack)) {
|
|
@@ -2485,6 +2552,9 @@ async function* runTurnStreaming(deps, userMessage, options) {
|
|
|
2485
2552
|
if (!aiResponse.tool_calls || aiResponse.tool_calls.length === 0 || !deps.tools) {
|
|
2486
2553
|
break;
|
|
2487
2554
|
}
|
|
2555
|
+
if (iteration === 1 && userMessage) {
|
|
2556
|
+
conversationHistory.push({ role: "user", content: userMessage });
|
|
2557
|
+
}
|
|
2488
2558
|
const assistantMsg = {
|
|
2489
2559
|
role: "assistant",
|
|
2490
2560
|
content: aiResponse.text,
|
|
@@ -5315,7 +5385,7 @@ var init_config2 = __esm({
|
|
|
5315
5385
|
"src/config.ts"() {
|
|
5316
5386
|
"use strict";
|
|
5317
5387
|
init_esm_shims();
|
|
5318
|
-
VERSION = true ? "0.6.
|
|
5388
|
+
VERSION = true ? "0.6.10" : "0.0.0-dev";
|
|
5319
5389
|
CONFIG_DIR = path2.join(os.homedir(), ".motebit");
|
|
5320
5390
|
CONFIG_PATH = path2.join(CONFIG_DIR, "config.json");
|
|
5321
5391
|
}
|
|
@@ -5602,9 +5672,9 @@ var init_dist7 = __esm({
|
|
|
5602
5672
|
* Register a new device for a motebit identity. Returns the device
|
|
5603
5673
|
* registration including a unique device_token for authentication.
|
|
5604
5674
|
*/
|
|
5605
|
-
async registerDevice(motebitId, deviceName, publicKey) {
|
|
5675
|
+
async registerDevice(motebitId, deviceName, publicKey, deviceId) {
|
|
5606
5676
|
const device = {
|
|
5607
|
-
device_id: crypto.randomUUID(),
|
|
5677
|
+
device_id: deviceId ?? crypto.randomUUID(),
|
|
5608
5678
|
motebit_id: motebitId,
|
|
5609
5679
|
device_token: crypto.randomUUID(),
|
|
5610
5680
|
public_key: publicKey ?? "",
|
|
@@ -5903,7 +5973,7 @@ var init_dist9 = __esm({
|
|
|
5903
5973
|
const raw = this.rawInputState[field];
|
|
5904
5974
|
const prev = this.currentState[field];
|
|
5905
5975
|
const ema = alpha * raw + (1 - alpha) * prev;
|
|
5906
|
-
if (this.applyHysteresis(field, ema, prev, now)) {
|
|
5976
|
+
if (this.applyHysteresis(field, ema, prev, raw, now)) {
|
|
5907
5977
|
smoothed[field] = ema;
|
|
5908
5978
|
}
|
|
5909
5979
|
}
|
|
@@ -5915,11 +5985,11 @@ var init_dist9 = __esm({
|
|
|
5915
5985
|
sub(this.currentState);
|
|
5916
5986
|
}
|
|
5917
5987
|
}
|
|
5918
|
-
applyHysteresis(field, newValue, currentValue, now) {
|
|
5988
|
+
applyHysteresis(field, newValue, currentValue, rawValue, now) {
|
|
5919
5989
|
const delta = Math.abs(newValue - currentValue);
|
|
5920
5990
|
if (delta < this.config.hysteresis_threshold) {
|
|
5921
5991
|
this.hysteresis.delete(field);
|
|
5922
|
-
return
|
|
5992
|
+
return Math.abs(rawValue - currentValue) >= this.config.hysteresis_threshold;
|
|
5923
5993
|
}
|
|
5924
5994
|
const entry = this.hysteresis.get(field);
|
|
5925
5995
|
if (entry === void 0) {
|
|
@@ -8272,11 +8342,11 @@ var init_delegation_adapter = __esm({
|
|
|
8272
8342
|
constructor(config) {
|
|
8273
8343
|
this.config = config;
|
|
8274
8344
|
}
|
|
8275
|
-
async buildHeaders() {
|
|
8345
|
+
async buildHeaders(audience) {
|
|
8276
8346
|
const headers = { "Content-Type": "application/json" };
|
|
8277
8347
|
const { authToken } = this.config;
|
|
8278
8348
|
if (authToken != null && authToken !== "") {
|
|
8279
|
-
const token = typeof authToken === "function" ? await authToken() : authToken;
|
|
8349
|
+
const token = typeof authToken === "function" ? await authToken(audience) : authToken;
|
|
8280
8350
|
if (token !== "")
|
|
8281
8351
|
headers["Authorization"] = `Bearer ${token}`;
|
|
8282
8352
|
}
|
|
@@ -8327,7 +8397,7 @@ var init_delegation_adapter = __esm({
|
|
|
8327
8397
|
}
|
|
8328
8398
|
const resp = await fetch(`${syncUrl}/agent/${motebitId}/task`, {
|
|
8329
8399
|
method: "POST",
|
|
8330
|
-
headers: await this.buildHeaders(),
|
|
8400
|
+
headers: await this.buildHeaders("task:submit"),
|
|
8331
8401
|
body: JSON.stringify(body)
|
|
8332
8402
|
});
|
|
8333
8403
|
if (!resp.ok) {
|
|
@@ -8388,7 +8458,7 @@ var init_delegation_adapter = __esm({
|
|
|
8388
8458
|
const { syncUrl, motebitId } = this.config;
|
|
8389
8459
|
try {
|
|
8390
8460
|
const resp = await fetch(`${syncUrl}/agent/${motebitId}/task/${taskId}`, {
|
|
8391
|
-
headers: await this.buildHeaders()
|
|
8461
|
+
headers: await this.buildHeaders("task:query")
|
|
8392
8462
|
});
|
|
8393
8463
|
if (!resp.ok)
|
|
8394
8464
|
return null;
|
|
@@ -9555,6 +9625,15 @@ function computePrecision(snapshot) {
|
|
|
9555
9625
|
const curiosityModulation = Math.min(0.8, explorationDrive);
|
|
9556
9626
|
return { selfTrust, explorationDrive, retrievalPrecision, curiosityModulation };
|
|
9557
9627
|
}
|
|
9628
|
+
function computeStateBaseline(snapshot, precision) {
|
|
9629
|
+
const confidence = 0.3 + precision.selfTrust * 0.5;
|
|
9630
|
+
const valenceFromDelta = Math.max(-0.3, Math.min(0.3, snapshot.delta * 3));
|
|
9631
|
+
const valenceFromLevel = (snapshot.gradient - 0.5) * 0.15;
|
|
9632
|
+
const affect_valence = Math.max(-0.4, Math.min(0.4, valenceFromDelta + valenceFromLevel));
|
|
9633
|
+
const affect_arousal = Math.min(0.3, Math.abs(snapshot.delta) * 2);
|
|
9634
|
+
const curiosity = precision.curiosityModulation;
|
|
9635
|
+
return { confidence, affect_valence, affect_arousal, curiosity };
|
|
9636
|
+
}
|
|
9558
9637
|
function buildPrecisionContext(weights) {
|
|
9559
9638
|
const parts = [];
|
|
9560
9639
|
if (weights.selfTrust < 0.4) {
|
|
@@ -11340,6 +11419,24 @@ var init_conversation = __esm({
|
|
|
11340
11419
|
return trimConversation(this.history, CONVERSATION_BUDGET, summary);
|
|
11341
11420
|
}
|
|
11342
11421
|
// --- Push + auto-summarize ---
|
|
11422
|
+
/** Record only an assistant message (no user message). Used for system-triggered
|
|
11423
|
+
* generation like first-contact activation where there is no user input. */
|
|
11424
|
+
pushActivation(assistantResponse) {
|
|
11425
|
+
this.history.push({ role: "assistant", content: assistantResponse });
|
|
11426
|
+
if (this.history.length > this.deps.maxHistory) {
|
|
11427
|
+
this.history = this.history.slice(-this.deps.maxHistory);
|
|
11428
|
+
}
|
|
11429
|
+
const { store } = this.deps;
|
|
11430
|
+
if (store != null) {
|
|
11431
|
+
if (this.currentId == null || this.currentId === "") {
|
|
11432
|
+
this.currentId = store.createConversation(this.deps.motebitId);
|
|
11433
|
+
}
|
|
11434
|
+
store.appendMessage(this.currentId, this.deps.motebitId, {
|
|
11435
|
+
role: "assistant",
|
|
11436
|
+
content: assistantResponse
|
|
11437
|
+
});
|
|
11438
|
+
}
|
|
11439
|
+
}
|
|
11343
11440
|
pushExchange(userMessage, assistantResponse) {
|
|
11344
11441
|
this.history.push({ role: "user", content: userMessage }, { role: "assistant", content: assistantResponse });
|
|
11345
11442
|
if (this.history.length > this.deps.maxHistory) {
|
|
@@ -11739,8 +11836,8 @@ var init_housekeeping = __esm({
|
|
|
11739
11836
|
|
|
11740
11837
|
// ../../packages/runtime/dist/index.js
|
|
11741
11838
|
function stripDisplayTags(text) {
|
|
11742
|
-
const clean3 = text.replace(/<memory\s+[^>]*>[\s\S]*?<\/memory>/g, "").replace(/<thinking>[\s\S]*?<\/thinking>/g, "").replace(/<state\s+[^>]*\/>/g, "").replace(
|
|
11743
|
-
for (const tag of ["<memory", "<thinking"]) {
|
|
11839
|
+
const clean3 = text.replace(/<memory\s+[^>]*>[\s\S]*?<\/memory>/g, "").replace(/<thinking>[\s\S]*?<\/thinking>/g, "").replace(/<state\s+[^>]*\/>/g, "").replace(/<parameter\s+[^>]*>[\s\S]*?<\/parameter>/g, "").replace(/<\/?(?:artifact|function_calls|invoke|antml)[^>]*>/g, "").replace(/\*{1,3}/g, "").replace(/ {2,}/g, " ");
|
|
11840
|
+
for (const tag of ["<memory", "<thinking", "<parameter"]) {
|
|
11744
11841
|
const lastOpen2 = clean3.lastIndexOf(tag);
|
|
11745
11842
|
if (lastOpen2 !== -1) {
|
|
11746
11843
|
const closeTag = `</${tag.slice(1)}>`;
|
|
@@ -11750,14 +11847,6 @@ function stripDisplayTags(text) {
|
|
|
11750
11847
|
}
|
|
11751
11848
|
}
|
|
11752
11849
|
}
|
|
11753
|
-
const lastStar = clean3.lastIndexOf("*");
|
|
11754
|
-
if (lastStar !== -1) {
|
|
11755
|
-
const afterLastStar = clean3.slice(lastStar);
|
|
11756
|
-
const starCount = (afterLastStar.match(/\*/g) ?? []).length;
|
|
11757
|
-
if (starCount % 2 === 1) {
|
|
11758
|
-
return { clean: clean3.slice(0, lastStar), pending: clean3.slice(lastStar) };
|
|
11759
|
-
}
|
|
11760
|
-
}
|
|
11761
11850
|
const lastOpen = clean3.lastIndexOf("<");
|
|
11762
11851
|
if (lastOpen !== -1 && !clean3.includes(">", lastOpen)) {
|
|
11763
11852
|
return { clean: clean3.slice(0, lastOpen), pending: clean3.slice(lastOpen) };
|
|
@@ -11887,6 +11976,7 @@ var init_dist18 = __esm({
|
|
|
11887
11976
|
loopDeps = null;
|
|
11888
11977
|
conversation;
|
|
11889
11978
|
_isProcessing = false;
|
|
11979
|
+
_isFirstConversation = false;
|
|
11890
11980
|
latestCues = {
|
|
11891
11981
|
hover_distance: 0.4,
|
|
11892
11982
|
drift_amplitude: 0.02,
|
|
@@ -11991,10 +12081,16 @@ var init_dist18 = __esm({
|
|
|
11991
12081
|
generateCompletion: (prompt2, taskType) => this.generateCompletion(prompt2, taskType)
|
|
11992
12082
|
});
|
|
11993
12083
|
this.conversation.resumeActiveConversation();
|
|
12084
|
+
this._isFirstConversation = this.conversation.getHistory().length === 0;
|
|
11994
12085
|
this.planStore = adapters.storage.planStore ?? new InMemoryPlanStore();
|
|
11995
12086
|
this.planEngine = new PlanEngine(this.planStore);
|
|
11996
12087
|
this.planEngine.setLocalMotebitId(this.motebitId);
|
|
11997
12088
|
this.gradientStore = adapters.storage.gradientStore ?? new InMemoryGradientStore();
|
|
12089
|
+
const latestGradient = this.gradientStore.latest(this.motebitId);
|
|
12090
|
+
if (latestGradient) {
|
|
12091
|
+
this._precision = computePrecision(latestGradient);
|
|
12092
|
+
this.state.pushUpdate(computeStateBaseline(latestGradient, this._precision));
|
|
12093
|
+
}
|
|
11998
12094
|
this.agentTrustStore = adapters.storage.agentTrustStore ?? null;
|
|
11999
12095
|
this.serviceListingStore = adapters.storage.serviceListingStore ?? null;
|
|
12000
12096
|
this.latencyStatsStore = adapters.storage.latencyStatsStore ?? null;
|
|
@@ -12494,7 +12590,7 @@ var init_dist18 = __esm({
|
|
|
12494
12590
|
};
|
|
12495
12591
|
patched.delta = patched.gradient - latest.gradient;
|
|
12496
12592
|
this._precision = computePrecision(patched);
|
|
12497
|
-
this.state.pushUpdate(
|
|
12593
|
+
this.state.pushUpdate(computeStateBaseline(patched, this._precision));
|
|
12498
12594
|
this.memory.setPrecisionWeights(this._precision.retrievalPrecision);
|
|
12499
12595
|
}
|
|
12500
12596
|
/**
|
|
@@ -12581,9 +12677,13 @@ var init_dist18 = __esm({
|
|
|
12581
12677
|
sessionInfo: this.conversation.getSessionInfo() ?? void 0,
|
|
12582
12678
|
curiosityHints: this.buildCuriosityHints(),
|
|
12583
12679
|
knownAgents: knownAgents.length > 0 ? knownAgents : void 0,
|
|
12584
|
-
precisionContext: selfAwareness || void 0
|
|
12680
|
+
precisionContext: selfAwareness || void 0,
|
|
12681
|
+
firstConversation: this._isFirstConversation || void 0
|
|
12585
12682
|
});
|
|
12586
12683
|
this.conversation.pushExchange(text, result.response);
|
|
12684
|
+
if (this._isFirstConversation && this.conversation.getHistory().length >= 5) {
|
|
12685
|
+
this._isFirstConversation = false;
|
|
12686
|
+
}
|
|
12587
12687
|
this._behavioralStats.turnCount++;
|
|
12588
12688
|
this._behavioralStats.totalIterations += result.iterations;
|
|
12589
12689
|
this._behavioralStats.toolCallsSucceeded += result.toolCallsSucceeded;
|
|
@@ -12638,10 +12738,46 @@ var init_dist18 = __esm({
|
|
|
12638
12738
|
knownAgents: knownAgents.length > 0 ? knownAgents : void 0,
|
|
12639
12739
|
agentCapabilities,
|
|
12640
12740
|
precisionContext: selfAwareness || void 0,
|
|
12641
|
-
delegationScope: options?.delegationScope
|
|
12741
|
+
delegationScope: options?.delegationScope,
|
|
12742
|
+
firstConversation: this._isFirstConversation || void 0
|
|
12642
12743
|
});
|
|
12643
12744
|
this.conversation.clearSessionInfo();
|
|
12644
12745
|
yield* this.processStream(stream, text, runId);
|
|
12746
|
+
if (this._isFirstConversation && this.conversation.getHistory().length >= 5) {
|
|
12747
|
+
this._isFirstConversation = false;
|
|
12748
|
+
}
|
|
12749
|
+
} finally {
|
|
12750
|
+
this.behavior.setSpeaking(false);
|
|
12751
|
+
this.state.pushUpdate({ processing: 0.1, attention: 0.3 });
|
|
12752
|
+
this._isProcessing = false;
|
|
12753
|
+
}
|
|
12754
|
+
}
|
|
12755
|
+
/**
|
|
12756
|
+
* System-triggered generation with no user message. Used for first-contact
|
|
12757
|
+
* activation — the creature speaks first without polluting conversation
|
|
12758
|
+
* history with a synthetic user message.
|
|
12759
|
+
*
|
|
12760
|
+
* The activation prompt is injected as system context, not as user input.
|
|
12761
|
+
* Only the assistant's response is recorded in history.
|
|
12762
|
+
*/
|
|
12763
|
+
async *generateActivation(activationPrompt, runId) {
|
|
12764
|
+
if (!this.loopDeps)
|
|
12765
|
+
throw new Error("AI not initialized \u2014 call setProvider() first");
|
|
12766
|
+
if (this._isProcessing)
|
|
12767
|
+
throw new Error("Already processing a message");
|
|
12768
|
+
this._isProcessing = true;
|
|
12769
|
+
this._pendingApproval = null;
|
|
12770
|
+
this.state.pushUpdate({ processing: 0.9, attention: 0.8 });
|
|
12771
|
+
this.behavior.setSpeaking(true);
|
|
12772
|
+
try {
|
|
12773
|
+
const stream = runTurnStreaming(this.loopDeps, "", {
|
|
12774
|
+
conversationHistory: [],
|
|
12775
|
+
previousCues: this.latestCues,
|
|
12776
|
+
runId,
|
|
12777
|
+
firstConversation: true,
|
|
12778
|
+
activationPrompt
|
|
12779
|
+
});
|
|
12780
|
+
yield* this.processStream(stream, "", runId, { activationOnly: true });
|
|
12645
12781
|
} finally {
|
|
12646
12782
|
this.behavior.setSpeaking(false);
|
|
12647
12783
|
this.state.pushUpdate({ processing: 0.1, attention: 0.3 });
|
|
@@ -12996,7 +13132,7 @@ var init_dist18 = __esm({
|
|
|
12996
13132
|
}
|
|
12997
13133
|
}
|
|
12998
13134
|
/** Shared stream processing — extracts state tags, handles tool/approval/injection chunks. */
|
|
12999
|
-
async *processStream(stream, userMessage, runId) {
|
|
13135
|
+
async *processStream(stream, userMessage, runId, options) {
|
|
13000
13136
|
let result = null;
|
|
13001
13137
|
let accumulated = "";
|
|
13002
13138
|
let yieldedCleanLength = 0;
|
|
@@ -13061,7 +13197,7 @@ var init_dist18 = __esm({
|
|
|
13061
13197
|
this.state.pushUpdate({ processing: 0.3 });
|
|
13062
13198
|
}
|
|
13063
13199
|
if (chunk.type === "text") {
|
|
13064
|
-
const
|
|
13200
|
+
const clean3 = stripDisplayTags(accumulated).clean.trimStart();
|
|
13065
13201
|
const delta = clean3.slice(yieldedCleanLength);
|
|
13066
13202
|
if (delta) {
|
|
13067
13203
|
yieldedCleanLength += delta.length;
|
|
@@ -13088,7 +13224,11 @@ var init_dist18 = __esm({
|
|
|
13088
13224
|
}
|
|
13089
13225
|
}
|
|
13090
13226
|
if (result) {
|
|
13091
|
-
|
|
13227
|
+
if (options?.activationOnly) {
|
|
13228
|
+
this.conversation.pushActivation(result.response);
|
|
13229
|
+
} else {
|
|
13230
|
+
this.conversation.pushExchange(userMessage, result.response);
|
|
13231
|
+
}
|
|
13092
13232
|
}
|
|
13093
13233
|
if (Object.keys(pendingStateUpdates).length > 0) {
|
|
13094
13234
|
this.state.pushUpdate(pendingStateUpdates);
|
|
@@ -13428,7 +13568,7 @@ var init_dist18 = __esm({
|
|
|
13428
13568
|
}
|
|
13429
13569
|
}
|
|
13430
13570
|
this._precision = computePrecision(snapshot);
|
|
13431
|
-
this.state.pushUpdate(
|
|
13571
|
+
this.state.pushUpdate(computeStateBaseline(snapshot, this._precision));
|
|
13432
13572
|
this.memory.setPrecisionWeights(this._precision.retrievalPrecision);
|
|
13433
13573
|
return snapshot;
|
|
13434
13574
|
}
|
|
@@ -13633,7 +13773,7 @@ var init_dist18 = __esm({
|
|
|
13633
13773
|
this.motebitToolServers.set(TOOL_NAME, "relay");
|
|
13634
13774
|
this.toolRegistry.register({
|
|
13635
13775
|
name: TOOL_NAME,
|
|
13636
|
-
description: "Delegate a task to a remote agent on the motebit network. The relay routes to the best capable agent based on trust and capabilities. Use when the user
|
|
13776
|
+
description: "Delegate a task to a remote agent on the motebit network. The relay routes to the best capable agent based on trust and capabilities. Use when the user asks you to delegate, or when a task would benefit from a specialized agent. Returns the agent's response text.",
|
|
13637
13777
|
inputSchema: {
|
|
13638
13778
|
type: "object",
|
|
13639
13779
|
properties: {
|
|
@@ -13652,20 +13792,21 @@ var init_dist18 = __esm({
|
|
|
13652
13792
|
}, async (args) => {
|
|
13653
13793
|
const prompt2 = args.prompt;
|
|
13654
13794
|
const requiredCapabilities = args.required_capabilities;
|
|
13655
|
-
let
|
|
13795
|
+
let submitHeader;
|
|
13796
|
+
let queryHeader;
|
|
13656
13797
|
try {
|
|
13657
|
-
const
|
|
13658
|
-
|
|
13798
|
+
const [submitToken, queryToken] = await Promise.all([
|
|
13799
|
+
config.authToken("task:submit"),
|
|
13800
|
+
config.authToken("task:query")
|
|
13801
|
+
]);
|
|
13802
|
+
submitHeader = `Bearer ${submitToken}`;
|
|
13803
|
+
queryHeader = `Bearer ${queryToken}`;
|
|
13659
13804
|
} catch (err3) {
|
|
13660
13805
|
return {
|
|
13661
13806
|
ok: false,
|
|
13662
13807
|
error: `Auth failed: ${err3 instanceof Error ? err3.message : String(err3)}`
|
|
13663
13808
|
};
|
|
13664
13809
|
}
|
|
13665
|
-
const headers = {
|
|
13666
|
-
"Content-Type": "application/json",
|
|
13667
|
-
Authorization: authHeader
|
|
13668
|
-
};
|
|
13669
13810
|
let taskId;
|
|
13670
13811
|
let targetMotebitId;
|
|
13671
13812
|
try {
|
|
@@ -13681,7 +13822,7 @@ var init_dist18 = __esm({
|
|
|
13681
13822
|
}
|
|
13682
13823
|
const resp = await fetch(`${config.syncUrl}/agent/${motebitId}/task`, {
|
|
13683
13824
|
method: "POST",
|
|
13684
|
-
headers,
|
|
13825
|
+
headers: { "Content-Type": "application/json", Authorization: submitHeader },
|
|
13685
13826
|
body: JSON.stringify(body)
|
|
13686
13827
|
});
|
|
13687
13828
|
if (!resp.ok) {
|
|
@@ -13703,10 +13844,16 @@ var init_dist18 = __esm({
|
|
|
13703
13844
|
await new Promise((resolve7) => setTimeout(resolve7, POLL_INTERVAL_MS));
|
|
13704
13845
|
try {
|
|
13705
13846
|
const resp = await fetch(`${config.syncUrl}/agent/${targetMotebitId}/task/${taskId}`, {
|
|
13706
|
-
headers
|
|
13847
|
+
headers: { Authorization: queryHeader }
|
|
13707
13848
|
});
|
|
13708
|
-
if (!resp.ok)
|
|
13849
|
+
if (!resp.ok) {
|
|
13850
|
+
logger.warn("delegation poll failed", {
|
|
13851
|
+
taskId,
|
|
13852
|
+
status: resp.status,
|
|
13853
|
+
body: await resp.text().catch(() => "")
|
|
13854
|
+
});
|
|
13709
13855
|
continue;
|
|
13856
|
+
}
|
|
13710
13857
|
const data = await resp.json();
|
|
13711
13858
|
if (data.receipt != null) {
|
|
13712
13859
|
try {
|
|
@@ -15540,12 +15687,58 @@ CREATE INDEX IF NOT EXISTS idx_agent_trust_motebit ON agent_trust (motebit_id);
|
|
|
15540
15687
|
}
|
|
15541
15688
|
});
|
|
15542
15689
|
|
|
15690
|
+
// ../../packages/tools/dist/search-provider.js
|
|
15691
|
+
var SearchProviderError, FallbackSearchProvider;
|
|
15692
|
+
var init_search_provider = __esm({
|
|
15693
|
+
"../../packages/tools/dist/search-provider.js"() {
|
|
15694
|
+
"use strict";
|
|
15695
|
+
init_esm_shims();
|
|
15696
|
+
SearchProviderError = class extends Error {
|
|
15697
|
+
status;
|
|
15698
|
+
provider;
|
|
15699
|
+
constructor(message, status, provider) {
|
|
15700
|
+
super(message);
|
|
15701
|
+
this.status = status;
|
|
15702
|
+
this.provider = provider;
|
|
15703
|
+
this.name = "SearchProviderError";
|
|
15704
|
+
}
|
|
15705
|
+
};
|
|
15706
|
+
FallbackSearchProvider = class {
|
|
15707
|
+
providers;
|
|
15708
|
+
constructor(providers) {
|
|
15709
|
+
this.providers = providers;
|
|
15710
|
+
}
|
|
15711
|
+
async search(query, maxResults) {
|
|
15712
|
+
let firstError;
|
|
15713
|
+
for (const provider of this.providers) {
|
|
15714
|
+
try {
|
|
15715
|
+
const results = await provider.search(query, maxResults);
|
|
15716
|
+
if (results.length > 0)
|
|
15717
|
+
return results;
|
|
15718
|
+
} catch (err3) {
|
|
15719
|
+
if (firstError === void 0)
|
|
15720
|
+
firstError = err3;
|
|
15721
|
+
continue;
|
|
15722
|
+
}
|
|
15723
|
+
}
|
|
15724
|
+
if (firstError !== void 0) {
|
|
15725
|
+
if (firstError instanceof Error)
|
|
15726
|
+
throw firstError;
|
|
15727
|
+
throw new Error("All search providers failed");
|
|
15728
|
+
}
|
|
15729
|
+
return [];
|
|
15730
|
+
}
|
|
15731
|
+
};
|
|
15732
|
+
}
|
|
15733
|
+
});
|
|
15734
|
+
|
|
15543
15735
|
// ../../packages/tools/dist/providers/duckduckgo.js
|
|
15544
15736
|
var DuckDuckGoSearchProvider;
|
|
15545
15737
|
var init_duckduckgo = __esm({
|
|
15546
15738
|
"../../packages/tools/dist/providers/duckduckgo.js"() {
|
|
15547
15739
|
"use strict";
|
|
15548
15740
|
init_esm_shims();
|
|
15741
|
+
init_search_provider();
|
|
15549
15742
|
DuckDuckGoSearchProvider = class {
|
|
15550
15743
|
async search(query, maxResults = 5) {
|
|
15551
15744
|
const url = `https://html.duckduckgo.com/html/?q=${encodeURIComponent(query)}`;
|
|
@@ -15555,7 +15748,7 @@ var init_duckduckgo = __esm({
|
|
|
15555
15748
|
}
|
|
15556
15749
|
});
|
|
15557
15750
|
if (!res.ok) {
|
|
15558
|
-
throw new
|
|
15751
|
+
throw new SearchProviderError(`DuckDuckGo search error: ${res.status}`, res.status, "duckduckgo");
|
|
15559
15752
|
}
|
|
15560
15753
|
const html = await res.text();
|
|
15561
15754
|
const results = [];
|
|
@@ -15607,6 +15800,12 @@ function createWebSearchHandler(provider) {
|
|
|
15607
15800
|
${formatted}`;
|
|
15608
15801
|
return { ok: true, data: output.slice(0, MAX_RESULT_SIZE) };
|
|
15609
15802
|
} catch (err3) {
|
|
15803
|
+
if (err3 instanceof SearchProviderError) {
|
|
15804
|
+
return {
|
|
15805
|
+
ok: false,
|
|
15806
|
+
error: `Search provider error (${err3.provider}, HTTP ${err3.status}): ${err3.message}`
|
|
15807
|
+
};
|
|
15808
|
+
}
|
|
15610
15809
|
const msg = err3 instanceof Error ? err3.message : String(err3);
|
|
15611
15810
|
return { ok: false, error: `Search error: ${msg}` };
|
|
15612
15811
|
}
|
|
@@ -15617,6 +15816,7 @@ var init_web_search = __esm({
|
|
|
15617
15816
|
"../../packages/tools/dist/builtins/web-search.js"() {
|
|
15618
15817
|
"use strict";
|
|
15619
15818
|
init_esm_shims();
|
|
15819
|
+
init_search_provider();
|
|
15620
15820
|
init_duckduckgo();
|
|
15621
15821
|
webSearchDefinition = {
|
|
15622
15822
|
name: "web_search",
|
|
@@ -16290,39 +16490,13 @@ var init_builtins = __esm({
|
|
|
16290
16490
|
}
|
|
16291
16491
|
});
|
|
16292
16492
|
|
|
16293
|
-
// ../../packages/tools/dist/search-provider.js
|
|
16294
|
-
var FallbackSearchProvider;
|
|
16295
|
-
var init_search_provider = __esm({
|
|
16296
|
-
"../../packages/tools/dist/search-provider.js"() {
|
|
16297
|
-
"use strict";
|
|
16298
|
-
init_esm_shims();
|
|
16299
|
-
FallbackSearchProvider = class {
|
|
16300
|
-
providers;
|
|
16301
|
-
constructor(providers) {
|
|
16302
|
-
this.providers = providers;
|
|
16303
|
-
}
|
|
16304
|
-
async search(query, maxResults) {
|
|
16305
|
-
for (const provider of this.providers) {
|
|
16306
|
-
try {
|
|
16307
|
-
const results = await provider.search(query, maxResults);
|
|
16308
|
-
if (results.length > 0)
|
|
16309
|
-
return results;
|
|
16310
|
-
} catch {
|
|
16311
|
-
continue;
|
|
16312
|
-
}
|
|
16313
|
-
}
|
|
16314
|
-
return [];
|
|
16315
|
-
}
|
|
16316
|
-
};
|
|
16317
|
-
}
|
|
16318
|
-
});
|
|
16319
|
-
|
|
16320
16493
|
// ../../packages/tools/dist/providers/brave-search.js
|
|
16321
16494
|
var BraveSearchProvider;
|
|
16322
16495
|
var init_brave_search = __esm({
|
|
16323
16496
|
"../../packages/tools/dist/providers/brave-search.js"() {
|
|
16324
16497
|
"use strict";
|
|
16325
16498
|
init_esm_shims();
|
|
16499
|
+
init_search_provider();
|
|
16326
16500
|
BraveSearchProvider = class {
|
|
16327
16501
|
apiKey;
|
|
16328
16502
|
constructor(apiKey) {
|
|
@@ -16338,7 +16512,12 @@ var init_brave_search = __esm({
|
|
|
16338
16512
|
}
|
|
16339
16513
|
});
|
|
16340
16514
|
if (!res.ok) {
|
|
16341
|
-
|
|
16515
|
+
let body = "";
|
|
16516
|
+
try {
|
|
16517
|
+
body = await res.text();
|
|
16518
|
+
} catch {
|
|
16519
|
+
}
|
|
16520
|
+
throw new SearchProviderError(`Brave Search API error: ${res.status}${body ? ` \u2014 ${body.slice(0, 200)}` : ""}`, res.status, "brave");
|
|
16342
16521
|
}
|
|
16343
16522
|
const data = await res.json();
|
|
16344
16523
|
const webResults = data.web?.results ?? [];
|
|
@@ -16633,20 +16812,17 @@ async function createRuntime(config, motebitId, toolRegistry, mcpServers, person
|
|
|
16633
16812
|
tools: toolRegistry
|
|
16634
16813
|
}
|
|
16635
16814
|
);
|
|
16636
|
-
const
|
|
16815
|
+
const DEFAULT_SYNC_URL2 = "https://motebit-sync.fly.dev";
|
|
16816
|
+
const syncUrl = config.syncUrl ?? process.env["MOTEBIT_SYNC_URL"] ?? loadFullConfig().sync_url ?? DEFAULT_SYNC_URL2;
|
|
16637
16817
|
const syncToken = config.syncToken ?? process.env["MOTEBIT_SYNC_TOKEN"];
|
|
16638
|
-
|
|
16639
|
-
|
|
16640
|
-
|
|
16641
|
-
|
|
16642
|
-
|
|
16643
|
-
|
|
16644
|
-
|
|
16645
|
-
|
|
16646
|
-
console.log(dim(`Sync: ${syncUrl}${encKey ? " (encrypted)" : ""}`));
|
|
16647
|
-
} else {
|
|
16648
|
-
console.log(dim("Sync: disabled (set MOTEBIT_SYNC_URL to enable)"));
|
|
16649
|
-
}
|
|
16818
|
+
const httpAdapter = new HttpEventStoreAdapter({
|
|
16819
|
+
baseUrl: syncUrl,
|
|
16820
|
+
motebitId,
|
|
16821
|
+
authToken: syncToken
|
|
16822
|
+
});
|
|
16823
|
+
const remoteStore = encKey ? new EncryptedEventStoreAdapter({ inner: httpAdapter, key: encKey }) : httpAdapter;
|
|
16824
|
+
runtime.connectSync(remoteStore);
|
|
16825
|
+
console.log(dim(`Sync: ${syncUrl}${encKey ? " (encrypted)" : ""}`));
|
|
16650
16826
|
return { runtime, moteDb };
|
|
16651
16827
|
}
|
|
16652
16828
|
var SqliteConversationSyncStoreAdapter, SqlitePlanSyncStoreAdapter;
|
|
@@ -16805,7 +16981,6 @@ init_dist3();
|
|
|
16805
16981
|
init_dist4();
|
|
16806
16982
|
init_dist5();
|
|
16807
16983
|
init_dist3();
|
|
16808
|
-
import * as readline3 from "readline";
|
|
16809
16984
|
|
|
16810
16985
|
// src/args.ts
|
|
16811
16986
|
init_esm_shims();
|
|
@@ -16857,7 +17032,7 @@ function parseCliArgs(args = process.argv.slice(2)) {
|
|
|
16857
17032
|
`Unknown provider "${provider}". Use "anthropic", "openai", "ollama", or "hybrid".`
|
|
16858
17033
|
);
|
|
16859
17034
|
}
|
|
16860
|
-
const defaultModel = provider === "ollama" ? "llama3.2" : provider === "openai" ? "gpt-4o" : "claude-sonnet-4-
|
|
17035
|
+
const defaultModel = provider === "ollama" ? "llama3.2" : provider === "openai" ? "gpt-4o-mini" : "claude-sonnet-4-6";
|
|
16861
17036
|
const allowedPaths = values["allowed-paths"] != null && values["allowed-paths"] !== "" ? values["allowed-paths"].split(",").map((p) => p.trim()) : [process.cwd()];
|
|
16862
17037
|
return {
|
|
16863
17038
|
provider,
|
|
@@ -17003,9 +17178,9 @@ Options:
|
|
|
17003
17178
|
|
|
17004
17179
|
Providers:
|
|
17005
17180
|
anthropic Uses Anthropic API (requires ANTHROPIC_API_KEY)
|
|
17006
|
-
Default model: claude-sonnet-4-
|
|
17181
|
+
Default model: claude-sonnet-4-6
|
|
17007
17182
|
openai Uses OpenAI API (requires OPENAI_API_KEY)
|
|
17008
|
-
Default model: gpt-4o
|
|
17183
|
+
Default model: gpt-4o-mini
|
|
17009
17184
|
ollama Uses local Ollama server (no API key needed)
|
|
17010
17185
|
Default model: llama3.2
|
|
17011
17186
|
hybrid Anthropic with Ollama fallback (requires ANTHROPIC_API_KEY)
|
|
@@ -17236,24 +17411,362 @@ init_runtime_factory();
|
|
|
17236
17411
|
init_esm_shims();
|
|
17237
17412
|
init_dist3();
|
|
17238
17413
|
init_colors();
|
|
17239
|
-
|
|
17414
|
+
|
|
17415
|
+
// src/terminal.ts
|
|
17416
|
+
init_esm_shims();
|
|
17417
|
+
function visibleLength(s) {
|
|
17418
|
+
return s.replace(/\x1b\[[0-9;]*[a-zA-Z~]/g, "").length;
|
|
17419
|
+
}
|
|
17420
|
+
var PASTE_OPEN = "\x1B[200~";
|
|
17421
|
+
var PASTE_CLOSE = "\x1B[201~";
|
|
17422
|
+
var initialized = false;
|
|
17423
|
+
var inputActive = false;
|
|
17424
|
+
var inputState = { line: "", cursor: 0, prompt: "", promptWidth: 0 };
|
|
17425
|
+
var inputResolver = null;
|
|
17426
|
+
var lastEscTime = 0;
|
|
17427
|
+
var pendingEscTimer = null;
|
|
17428
|
+
var pasteBuffer = null;
|
|
17429
|
+
var pasteSplitCarry = "";
|
|
17430
|
+
var inputRows = 0;
|
|
17431
|
+
function parseChunk(buf) {
|
|
17432
|
+
const events = [];
|
|
17433
|
+
let data = buf.toString("utf-8");
|
|
17434
|
+
if (pasteSplitCarry.length > 0) {
|
|
17435
|
+
data = pasteSplitCarry + data;
|
|
17436
|
+
pasteSplitCarry = "";
|
|
17437
|
+
}
|
|
17438
|
+
let i = 0;
|
|
17439
|
+
while (i < data.length) {
|
|
17440
|
+
const ch = data[i];
|
|
17441
|
+
if (pasteBuffer !== null) {
|
|
17442
|
+
const closeIdx = data.indexOf(PASTE_CLOSE, i);
|
|
17443
|
+
if (closeIdx === -1) {
|
|
17444
|
+
const remaining = data.slice(i);
|
|
17445
|
+
let overlap = 0;
|
|
17446
|
+
for (let k = 1; k < PASTE_CLOSE.length && k <= remaining.length; k++) {
|
|
17447
|
+
if (remaining.slice(remaining.length - k) === PASTE_CLOSE.slice(0, k)) {
|
|
17448
|
+
overlap = k;
|
|
17449
|
+
}
|
|
17450
|
+
}
|
|
17451
|
+
pasteBuffer += remaining.slice(0, remaining.length - overlap);
|
|
17452
|
+
pasteSplitCarry = overlap > 0 ? remaining.slice(remaining.length - overlap) : "";
|
|
17453
|
+
i = data.length;
|
|
17454
|
+
} else {
|
|
17455
|
+
pasteBuffer += data.slice(i, closeIdx);
|
|
17456
|
+
const text = pasteBuffer.replace(/[\r\n]+/g, " ");
|
|
17457
|
+
events.push({ type: "paste", text });
|
|
17458
|
+
pasteBuffer = null;
|
|
17459
|
+
pasteSplitCarry = "";
|
|
17460
|
+
i = closeIdx + PASTE_CLOSE.length;
|
|
17461
|
+
}
|
|
17462
|
+
continue;
|
|
17463
|
+
}
|
|
17464
|
+
if (data.startsWith(PASTE_OPEN, i)) {
|
|
17465
|
+
pasteBuffer = "";
|
|
17466
|
+
i += PASTE_OPEN.length;
|
|
17467
|
+
continue;
|
|
17468
|
+
}
|
|
17469
|
+
if (ch === "\x1B") {
|
|
17470
|
+
if (i + 1 < data.length && data[i + 1] === "[") {
|
|
17471
|
+
let j = i + 2;
|
|
17472
|
+
while (j < data.length && !/[a-zA-Z~]/.test(data[j])) j++;
|
|
17473
|
+
if (j < data.length) {
|
|
17474
|
+
const seq = data.slice(i + 2, j + 1);
|
|
17475
|
+
i = j + 1;
|
|
17476
|
+
switch (seq) {
|
|
17477
|
+
case "A":
|
|
17478
|
+
events.push({ type: "key", key: "up", ctrl: false });
|
|
17479
|
+
break;
|
|
17480
|
+
case "B":
|
|
17481
|
+
events.push({ type: "key", key: "down", ctrl: false });
|
|
17482
|
+
break;
|
|
17483
|
+
case "C":
|
|
17484
|
+
events.push({ type: "key", key: "right", ctrl: false });
|
|
17485
|
+
break;
|
|
17486
|
+
case "D":
|
|
17487
|
+
events.push({ type: "key", key: "left", ctrl: false });
|
|
17488
|
+
break;
|
|
17489
|
+
case "H":
|
|
17490
|
+
case "1~":
|
|
17491
|
+
events.push({ type: "key", key: "home", ctrl: false });
|
|
17492
|
+
break;
|
|
17493
|
+
case "F":
|
|
17494
|
+
case "4~":
|
|
17495
|
+
events.push({ type: "key", key: "end", ctrl: false });
|
|
17496
|
+
break;
|
|
17497
|
+
case "3~":
|
|
17498
|
+
events.push({ type: "key", key: "delete", ctrl: false });
|
|
17499
|
+
break;
|
|
17500
|
+
}
|
|
17501
|
+
} else {
|
|
17502
|
+
i = data.length;
|
|
17503
|
+
}
|
|
17504
|
+
} else if (i + 1 >= data.length) {
|
|
17505
|
+
if (pendingEscTimer) clearTimeout(pendingEscTimer);
|
|
17506
|
+
pendingEscTimer = setTimeout(() => {
|
|
17507
|
+
pendingEscTimer = null;
|
|
17508
|
+
handleBareEscape();
|
|
17509
|
+
}, 50);
|
|
17510
|
+
i++;
|
|
17511
|
+
} else {
|
|
17512
|
+
handleBareEscape();
|
|
17513
|
+
i++;
|
|
17514
|
+
}
|
|
17515
|
+
continue;
|
|
17516
|
+
}
|
|
17517
|
+
const code2 = ch.charCodeAt(0);
|
|
17518
|
+
if (code2 === 3) {
|
|
17519
|
+
events.push({ type: "key", key: "c", ctrl: true });
|
|
17520
|
+
} else if (code2 === 1) {
|
|
17521
|
+
events.push({ type: "key", key: "home", ctrl: false });
|
|
17522
|
+
} else if (code2 === 5) {
|
|
17523
|
+
events.push({ type: "key", key: "end", ctrl: false });
|
|
17524
|
+
} else if (code2 === 127 || code2 === 8) {
|
|
17525
|
+
events.push({ type: "key", key: "backspace", ctrl: false });
|
|
17526
|
+
} else if (code2 === 13) {
|
|
17527
|
+
events.push({ type: "key", key: "return", ctrl: false });
|
|
17528
|
+
} else if (code2 === 21) {
|
|
17529
|
+
events.push({ type: "key", key: "u", ctrl: true });
|
|
17530
|
+
} else if (code2 >= 32) {
|
|
17531
|
+
events.push({ type: "key", key: ch, ctrl: false });
|
|
17532
|
+
}
|
|
17533
|
+
i++;
|
|
17534
|
+
}
|
|
17535
|
+
return events;
|
|
17536
|
+
}
|
|
17537
|
+
function handleBareEscape() {
|
|
17538
|
+
if (!inputActive) return;
|
|
17539
|
+
const now = Date.now();
|
|
17540
|
+
if (now - lastEscTime < 300) {
|
|
17541
|
+
lastEscTime = 0;
|
|
17542
|
+
inputState = { ...inputState, line: "", cursor: 0 };
|
|
17543
|
+
redrawInput();
|
|
17544
|
+
} else {
|
|
17545
|
+
lastEscTime = now;
|
|
17546
|
+
}
|
|
17547
|
+
}
|
|
17548
|
+
function applyEvent(state, event) {
|
|
17549
|
+
switch (event.type) {
|
|
17550
|
+
case "key": {
|
|
17551
|
+
if (event.ctrl) {
|
|
17552
|
+
if (event.key === "c") return "exit";
|
|
17553
|
+
if (event.key === "u") return { state: { ...state, line: "", cursor: 0 } };
|
|
17554
|
+
return { state };
|
|
17555
|
+
}
|
|
17556
|
+
switch (event.key) {
|
|
17557
|
+
case "return":
|
|
17558
|
+
return "submit";
|
|
17559
|
+
case "backspace":
|
|
17560
|
+
if (state.cursor > 0) {
|
|
17561
|
+
return {
|
|
17562
|
+
state: {
|
|
17563
|
+
...state,
|
|
17564
|
+
line: state.line.slice(0, state.cursor - 1) + state.line.slice(state.cursor),
|
|
17565
|
+
cursor: state.cursor - 1
|
|
17566
|
+
}
|
|
17567
|
+
};
|
|
17568
|
+
}
|
|
17569
|
+
return { state };
|
|
17570
|
+
case "delete":
|
|
17571
|
+
if (state.cursor < state.line.length) {
|
|
17572
|
+
return {
|
|
17573
|
+
state: {
|
|
17574
|
+
...state,
|
|
17575
|
+
line: state.line.slice(0, state.cursor) + state.line.slice(state.cursor + 1)
|
|
17576
|
+
}
|
|
17577
|
+
};
|
|
17578
|
+
}
|
|
17579
|
+
return { state };
|
|
17580
|
+
case "left":
|
|
17581
|
+
return { state: { ...state, cursor: Math.max(0, state.cursor - 1) } };
|
|
17582
|
+
case "right":
|
|
17583
|
+
return { state: { ...state, cursor: Math.min(state.line.length, state.cursor + 1) } };
|
|
17584
|
+
case "home":
|
|
17585
|
+
return { state: { ...state, cursor: 0 } };
|
|
17586
|
+
case "end":
|
|
17587
|
+
return { state: { ...state, cursor: state.line.length } };
|
|
17588
|
+
case "up":
|
|
17589
|
+
case "down":
|
|
17590
|
+
return { state };
|
|
17591
|
+
// No history (yet)
|
|
17592
|
+
default:
|
|
17593
|
+
if (event.key.length === 1) {
|
|
17594
|
+
return {
|
|
17595
|
+
state: {
|
|
17596
|
+
...state,
|
|
17597
|
+
line: state.line.slice(0, state.cursor) + event.key + state.line.slice(state.cursor),
|
|
17598
|
+
cursor: state.cursor + 1
|
|
17599
|
+
}
|
|
17600
|
+
};
|
|
17601
|
+
}
|
|
17602
|
+
return { state };
|
|
17603
|
+
}
|
|
17604
|
+
}
|
|
17605
|
+
case "paste": {
|
|
17606
|
+
return {
|
|
17607
|
+
state: {
|
|
17608
|
+
...state,
|
|
17609
|
+
line: state.line.slice(0, state.cursor) + event.text + state.line.slice(state.cursor),
|
|
17610
|
+
cursor: state.cursor + event.text.length
|
|
17611
|
+
}
|
|
17612
|
+
};
|
|
17613
|
+
}
|
|
17614
|
+
case "resize":
|
|
17615
|
+
return { state };
|
|
17616
|
+
}
|
|
17617
|
+
}
|
|
17618
|
+
function redrawInput() {
|
|
17619
|
+
const cols = process.stdout.columns || 80;
|
|
17620
|
+
const fullLine = inputState.prompt + inputState.line;
|
|
17621
|
+
const totalLen = inputState.promptWidth + inputState.line.length;
|
|
17622
|
+
const newRows = Math.max(1, Math.ceil(totalLen / cols) || 1);
|
|
17623
|
+
if (inputRows > 1) {
|
|
17624
|
+
process.stdout.write(`\x1B[${inputRows - 1}A`);
|
|
17625
|
+
}
|
|
17626
|
+
process.stdout.write("\r");
|
|
17627
|
+
process.stdout.write("\x1B[J");
|
|
17628
|
+
process.stdout.write(fullLine);
|
|
17629
|
+
const cursorPos = inputState.promptWidth + inputState.cursor;
|
|
17630
|
+
const cursorRow = Math.floor(cursorPos / cols);
|
|
17631
|
+
const cursorCol = cursorPos % cols;
|
|
17632
|
+
const endRow = Math.floor(Math.max(0, totalLen - 1) / cols);
|
|
17633
|
+
if (endRow > cursorRow) {
|
|
17634
|
+
process.stdout.write(`\x1B[${endRow - cursorRow}A`);
|
|
17635
|
+
}
|
|
17636
|
+
process.stdout.write(`\r`);
|
|
17637
|
+
if (cursorCol > 0) {
|
|
17638
|
+
process.stdout.write(`\x1B[${cursorCol}C`);
|
|
17639
|
+
}
|
|
17640
|
+
inputRows = newRows;
|
|
17641
|
+
}
|
|
17642
|
+
function writeOutput(text) {
|
|
17643
|
+
if (!inputActive) {
|
|
17644
|
+
process.stdout.write(text);
|
|
17645
|
+
return;
|
|
17646
|
+
}
|
|
17647
|
+
if (inputRows > 1) {
|
|
17648
|
+
process.stdout.write(`\x1B[${inputRows - 1}A`);
|
|
17649
|
+
}
|
|
17650
|
+
process.stdout.write("\r\x1B[J");
|
|
17651
|
+
process.stdout.write(text);
|
|
17652
|
+
inputRows = 1;
|
|
17653
|
+
redrawInput();
|
|
17654
|
+
}
|
|
17655
|
+
function onStdinData(buf) {
|
|
17656
|
+
const events = parseChunk(buf);
|
|
17657
|
+
for (const event of events) {
|
|
17658
|
+
if (!inputActive) continue;
|
|
17659
|
+
if (event.type === "resize") {
|
|
17660
|
+
redrawInput();
|
|
17661
|
+
continue;
|
|
17662
|
+
}
|
|
17663
|
+
const result = applyEvent(inputState, event);
|
|
17664
|
+
if (result === "submit") {
|
|
17665
|
+
const line = inputState.line;
|
|
17666
|
+
process.stdout.write("\n");
|
|
17667
|
+
inputActive = false;
|
|
17668
|
+
inputRows = 0;
|
|
17669
|
+
if (inputResolver) {
|
|
17670
|
+
const resolve7 = inputResolver;
|
|
17671
|
+
inputResolver = null;
|
|
17672
|
+
resolve7(line);
|
|
17673
|
+
}
|
|
17674
|
+
} else if (result === "exit") {
|
|
17675
|
+
process.stdout.write("\n");
|
|
17676
|
+
process.exit(0);
|
|
17677
|
+
} else {
|
|
17678
|
+
inputState = result.state;
|
|
17679
|
+
redrawInput();
|
|
17680
|
+
}
|
|
17681
|
+
}
|
|
17682
|
+
}
|
|
17683
|
+
var resizeTimer = null;
|
|
17684
|
+
function onResize() {
|
|
17685
|
+
if (!inputActive) return;
|
|
17686
|
+
if (resizeTimer) clearTimeout(resizeTimer);
|
|
17687
|
+
resizeTimer = setTimeout(() => {
|
|
17688
|
+
resizeTimer = null;
|
|
17689
|
+
if (!inputActive) return;
|
|
17690
|
+
process.stdout.write("\n");
|
|
17691
|
+
inputRows = 1;
|
|
17692
|
+
redrawInput();
|
|
17693
|
+
}, 100);
|
|
17694
|
+
}
|
|
17695
|
+
function initTerminal() {
|
|
17696
|
+
if (initialized) return;
|
|
17697
|
+
initialized = true;
|
|
17698
|
+
if (process.stdin.isTTY) {
|
|
17699
|
+
process.stdin.setRawMode(true);
|
|
17700
|
+
}
|
|
17701
|
+
process.stdin.resume();
|
|
17702
|
+
process.stdin.on("data", onStdinData);
|
|
17703
|
+
process.stdout.on("resize", onResize);
|
|
17704
|
+
if (process.stdout.isTTY) {
|
|
17705
|
+
process.stdout.write("\x1B[?2004h");
|
|
17706
|
+
}
|
|
17707
|
+
}
|
|
17708
|
+
function destroyTerminal() {
|
|
17709
|
+
if (!initialized) return;
|
|
17710
|
+
initialized = false;
|
|
17711
|
+
process.stdin.removeListener("data", onStdinData);
|
|
17712
|
+
process.stdout.removeListener("resize", onResize);
|
|
17713
|
+
if (process.stdin.isTTY) {
|
|
17714
|
+
process.stdin.setRawMode(false);
|
|
17715
|
+
}
|
|
17716
|
+
if (process.stdout.isTTY) {
|
|
17717
|
+
process.stdout.write("\x1B[?2004l");
|
|
17718
|
+
}
|
|
17719
|
+
}
|
|
17720
|
+
function readInput(promptText) {
|
|
17240
17721
|
return new Promise((resolve7) => {
|
|
17241
|
-
|
|
17722
|
+
inputState = {
|
|
17723
|
+
line: "",
|
|
17724
|
+
cursor: 0,
|
|
17725
|
+
prompt: promptText,
|
|
17726
|
+
promptWidth: visibleLength(promptText)
|
|
17727
|
+
};
|
|
17728
|
+
inputRows = 1;
|
|
17729
|
+
inputActive = true;
|
|
17730
|
+
inputResolver = resolve7;
|
|
17731
|
+
redrawInput();
|
|
17242
17732
|
});
|
|
17243
17733
|
}
|
|
17244
|
-
|
|
17734
|
+
function askQuestion(promptText) {
|
|
17735
|
+
return readInput(promptText);
|
|
17736
|
+
}
|
|
17737
|
+
|
|
17738
|
+
// src/stream.ts
|
|
17739
|
+
function startDotAnimation() {
|
|
17740
|
+
let dots = 1;
|
|
17741
|
+
const timer = setInterval(() => {
|
|
17742
|
+
dots = dots % 3 + 1;
|
|
17743
|
+
writeOutput(`\x1B[${3}D${meta(".".repeat(dots) + " ".repeat(3 - dots))}`);
|
|
17744
|
+
}, 400);
|
|
17745
|
+
return () => {
|
|
17746
|
+
clearInterval(timer);
|
|
17747
|
+
writeOutput(`\x1B[${3}D${meta("...")} ${meta("done")}
|
|
17748
|
+
`);
|
|
17749
|
+
};
|
|
17750
|
+
}
|
|
17751
|
+
async function consumeStream(stream, runtime) {
|
|
17245
17752
|
let pendingApproval = null;
|
|
17753
|
+
let stopAnimation = null;
|
|
17246
17754
|
for await (const chunk of stream) {
|
|
17247
17755
|
switch (chunk.type) {
|
|
17248
17756
|
case "text":
|
|
17249
|
-
|
|
17757
|
+
writeOutput(chunk.text);
|
|
17250
17758
|
break;
|
|
17251
17759
|
case "tool_status":
|
|
17760
|
+
if (chunk.name === "delegate_to_agent") break;
|
|
17252
17761
|
if (chunk.status === "calling") {
|
|
17253
|
-
|
|
17762
|
+
writeOutput(`
|
|
17254
17763
|
${action("\u25CF")} ${action(chunk.name)}${meta("...")}`);
|
|
17764
|
+
stopAnimation = startDotAnimation();
|
|
17255
17765
|
} else {
|
|
17256
|
-
|
|
17766
|
+
if (stopAnimation) {
|
|
17767
|
+
stopAnimation();
|
|
17768
|
+
stopAnimation = null;
|
|
17769
|
+
} else writeOutput(meta(" done") + "\n");
|
|
17257
17770
|
}
|
|
17258
17771
|
break;
|
|
17259
17772
|
case "approval_request":
|
|
@@ -17265,40 +17778,42 @@ async function consumeStream(stream, runtime, rl) {
|
|
|
17265
17778
|
};
|
|
17266
17779
|
break;
|
|
17267
17780
|
case "delegation_start":
|
|
17268
|
-
|
|
17781
|
+
writeOutput(
|
|
17269
17782
|
`
|
|
17270
17783
|
${action("\u25CF")} ${dim("[delegating]")} ${action(chunk.tool)}${meta("...")}`
|
|
17271
17784
|
);
|
|
17785
|
+
stopAnimation = startDotAnimation();
|
|
17272
17786
|
break;
|
|
17273
17787
|
case "delegation_complete":
|
|
17274
|
-
|
|
17788
|
+
if (stopAnimation) {
|
|
17789
|
+
stopAnimation();
|
|
17790
|
+
stopAnimation = null;
|
|
17791
|
+
} else writeOutput(meta(" done") + "\n");
|
|
17275
17792
|
break;
|
|
17276
17793
|
case "injection_warning":
|
|
17277
|
-
|
|
17278
|
-
`
|
|
17794
|
+
writeOutput(`
|
|
17279
17795
|
${warn("\u26A0")} ${warn("suspicious content in " + chunk.tool_name)}
|
|
17280
|
-
`
|
|
17281
|
-
);
|
|
17796
|
+
`);
|
|
17282
17797
|
break;
|
|
17283
17798
|
case "result": {
|
|
17284
17799
|
const result = chunk.result;
|
|
17285
|
-
|
|
17800
|
+
writeOutput("\n\n");
|
|
17286
17801
|
if (result.memoriesFormed.length > 0) {
|
|
17287
|
-
|
|
17802
|
+
writeOutput(
|
|
17288
17803
|
meta(
|
|
17289
17804
|
` [memories: ${result.memoriesFormed.map((m) => m.content).join(", ")}]`
|
|
17290
|
-
)
|
|
17805
|
+
) + "\n"
|
|
17291
17806
|
);
|
|
17292
17807
|
}
|
|
17293
17808
|
const s = result.stateAfter;
|
|
17294
|
-
|
|
17809
|
+
writeOutput(
|
|
17295
17810
|
meta(
|
|
17296
17811
|
` [state: attention=${s.attention.toFixed(2)} confidence=${s.confidence.toFixed(2)} valence=${s.affect_valence.toFixed(2)} curiosity=${s.curiosity.toFixed(2)}]`
|
|
17297
|
-
)
|
|
17812
|
+
) + "\n"
|
|
17298
17813
|
);
|
|
17299
17814
|
const bodyLine = formatBodyAwareness(result.cues);
|
|
17300
|
-
if (bodyLine)
|
|
17301
|
-
|
|
17815
|
+
if (bodyLine) writeOutput(meta(` ${bodyLine}`) + "\n");
|
|
17816
|
+
writeOutput("\n");
|
|
17302
17817
|
break;
|
|
17303
17818
|
}
|
|
17304
17819
|
}
|
|
@@ -17306,149 +17821,16 @@ async function consumeStream(stream, runtime, rl) {
|
|
|
17306
17821
|
if (pendingApproval) {
|
|
17307
17822
|
const argsPreview = JSON.stringify(pendingApproval.args).slice(0, 80);
|
|
17308
17823
|
const quorumInfo = pendingApproval.quorum && pendingApproval.quorum.required > 1 ? ` [${pendingApproval.quorum.collected.length}/${pendingApproval.quorum.required} approvals]` : "";
|
|
17309
|
-
const answer = await
|
|
17310
|
-
rl,
|
|
17824
|
+
const answer = await askQuestion(
|
|
17311
17825
|
` ${warn("?")} ${pendingApproval.name}(${argsPreview})${quorumInfo}
|
|
17312
17826
|
Allow? (y/n) `
|
|
17313
17827
|
);
|
|
17314
17828
|
const approved = answer.trim().toLowerCase() === "y";
|
|
17315
|
-
|
|
17316
|
-
await consumeStream(runtime.resolveApprovalVote(approved, runtime.motebitId), runtime
|
|
17829
|
+
writeOutput("\n" + prompt("mote>") + " ");
|
|
17830
|
+
await consumeStream(runtime.resolveApprovalVote(approved, runtime.motebitId), runtime);
|
|
17317
17831
|
}
|
|
17318
17832
|
}
|
|
17319
17833
|
|
|
17320
|
-
// src/input.ts
|
|
17321
|
-
init_esm_shims();
|
|
17322
|
-
init_colors();
|
|
17323
|
-
function visibleLength(s) {
|
|
17324
|
-
return s.replace(/\x1b\[[0-9;]*m/g, "").length;
|
|
17325
|
-
}
|
|
17326
|
-
var PASTE_OPEN = "\x1B[200~";
|
|
17327
|
-
var PASTE_CLOSE = "\x1B[201~";
|
|
17328
|
-
function enableBracketedPaste() {
|
|
17329
|
-
if (process.stdout.isTTY) {
|
|
17330
|
-
process.stdout.write("\x1B[?2004h");
|
|
17331
|
-
}
|
|
17332
|
-
}
|
|
17333
|
-
function disableBracketedPaste() {
|
|
17334
|
-
if (process.stdout.isTTY) {
|
|
17335
|
-
process.stdout.write("\x1B[?2004l");
|
|
17336
|
-
}
|
|
17337
|
-
}
|
|
17338
|
-
function readInput(promptText) {
|
|
17339
|
-
return new Promise((resolve7) => {
|
|
17340
|
-
const stdin = process.stdin;
|
|
17341
|
-
const stdout = process.stdout;
|
|
17342
|
-
stdin.setRawMode(true);
|
|
17343
|
-
stdin.resume();
|
|
17344
|
-
stdin.setEncoding("utf8");
|
|
17345
|
-
process.stdout.write(promptText);
|
|
17346
|
-
let value = "";
|
|
17347
|
-
let pasteBuffer = "";
|
|
17348
|
-
let inPaste = false;
|
|
17349
|
-
let pasteLineCount = 0;
|
|
17350
|
-
let lastEscTime = 0;
|
|
17351
|
-
const promptVisibleLen = visibleLength(promptText);
|
|
17352
|
-
let lastDisplayLen = 0;
|
|
17353
|
-
const redrawLine = (text) => {
|
|
17354
|
-
const cols = stdout.columns || 80;
|
|
17355
|
-
const prevTotal = promptVisibleLen + lastDisplayLen;
|
|
17356
|
-
const wrappedLines = Math.max(0, Math.ceil(prevTotal / cols) - 1);
|
|
17357
|
-
if (wrappedLines > 0) {
|
|
17358
|
-
stdout.write(`\x1B[${wrappedLines}A`);
|
|
17359
|
-
}
|
|
17360
|
-
stdout.write(`\r\x1B[J${promptText}${text}`);
|
|
17361
|
-
lastDisplayLen = visibleLength(text);
|
|
17362
|
-
};
|
|
17363
|
-
const finish = () => {
|
|
17364
|
-
stdin.removeListener("data", onData);
|
|
17365
|
-
stdin.setRawMode(false);
|
|
17366
|
-
stdin.pause();
|
|
17367
|
-
stdout.write("\n");
|
|
17368
|
-
if (pasteBuffer) {
|
|
17369
|
-
resolve7(pasteBuffer.replace(/\r?\n/g, " ").trim());
|
|
17370
|
-
} else {
|
|
17371
|
-
resolve7(value);
|
|
17372
|
-
}
|
|
17373
|
-
};
|
|
17374
|
-
const onData = (ch) => {
|
|
17375
|
-
const data = ch.toString();
|
|
17376
|
-
if (data.includes(PASTE_OPEN)) {
|
|
17377
|
-
inPaste = true;
|
|
17378
|
-
pasteBuffer = value;
|
|
17379
|
-
pasteLineCount = 0;
|
|
17380
|
-
const afterOpen = data.slice(data.indexOf(PASTE_OPEN) + PASTE_OPEN.length);
|
|
17381
|
-
if (afterOpen) {
|
|
17382
|
-
processPasteData(afterOpen);
|
|
17383
|
-
}
|
|
17384
|
-
return;
|
|
17385
|
-
}
|
|
17386
|
-
if (inPaste) {
|
|
17387
|
-
processPasteData(data);
|
|
17388
|
-
return;
|
|
17389
|
-
}
|
|
17390
|
-
for (let i = 0; i < data.length; i++) {
|
|
17391
|
-
const c = data[i];
|
|
17392
|
-
if (c === "\r" || c === "\n") {
|
|
17393
|
-
finish();
|
|
17394
|
-
return;
|
|
17395
|
-
} else if (c === "") {
|
|
17396
|
-
stdin.removeListener("data", onData);
|
|
17397
|
-
stdin.setRawMode(false);
|
|
17398
|
-
stdout.write("\n");
|
|
17399
|
-
resolve7("");
|
|
17400
|
-
return;
|
|
17401
|
-
} else if (c === "\x7F" || c === "\b") {
|
|
17402
|
-
if (value.length > 0) {
|
|
17403
|
-
value = value.slice(0, -1);
|
|
17404
|
-
redrawLine(value);
|
|
17405
|
-
}
|
|
17406
|
-
} else if (c === "\x1B") {
|
|
17407
|
-
const now = Date.now();
|
|
17408
|
-
if (now - lastEscTime < 300) {
|
|
17409
|
-
value = "";
|
|
17410
|
-
pasteBuffer = "";
|
|
17411
|
-
redrawLine("");
|
|
17412
|
-
lastEscTime = 0;
|
|
17413
|
-
} else {
|
|
17414
|
-
lastEscTime = now;
|
|
17415
|
-
}
|
|
17416
|
-
return;
|
|
17417
|
-
} else if (c.charCodeAt(0) >= 32) {
|
|
17418
|
-
value += c;
|
|
17419
|
-
stdout.write(c);
|
|
17420
|
-
lastDisplayLen = value.length;
|
|
17421
|
-
}
|
|
17422
|
-
}
|
|
17423
|
-
};
|
|
17424
|
-
const processPasteData = (data) => {
|
|
17425
|
-
const closeIdx = data.indexOf(PASTE_CLOSE);
|
|
17426
|
-
if (closeIdx !== -1) {
|
|
17427
|
-
const remaining = data.slice(0, closeIdx);
|
|
17428
|
-
pasteBuffer += remaining;
|
|
17429
|
-
pasteLineCount += (remaining.match(/\n/g) || []).length;
|
|
17430
|
-
inPaste = false;
|
|
17431
|
-
const charCount = pasteBuffer.length;
|
|
17432
|
-
const summary = pasteLineCount > 0 ? dim(`[Pasted text #${charCount} +${pasteLineCount} lines]`) : pasteBuffer;
|
|
17433
|
-
redrawLine(pasteLineCount > 0 ? summary : pasteBuffer);
|
|
17434
|
-
if (pasteLineCount === 0) {
|
|
17435
|
-
value = pasteBuffer;
|
|
17436
|
-
pasteBuffer = "";
|
|
17437
|
-
}
|
|
17438
|
-
return;
|
|
17439
|
-
}
|
|
17440
|
-
pasteBuffer += data;
|
|
17441
|
-
pasteLineCount += (data.match(/\n/g) || []).length;
|
|
17442
|
-
if (pasteLineCount > 0) {
|
|
17443
|
-
const charCount = pasteBuffer.length;
|
|
17444
|
-
const summary = dim(`[Pasted text #${charCount} +${pasteLineCount} lines]`);
|
|
17445
|
-
redrawLine(summary);
|
|
17446
|
-
}
|
|
17447
|
-
};
|
|
17448
|
-
stdin.on("data", onData);
|
|
17449
|
-
});
|
|
17450
|
-
}
|
|
17451
|
-
|
|
17452
17834
|
// src/index.ts
|
|
17453
17835
|
init_colors();
|
|
17454
17836
|
|
|
@@ -21749,6 +22131,11 @@ var McpServerAdapter = class _McpServerAdapter {
|
|
|
21749
22131
|
deps;
|
|
21750
22132
|
httpServer;
|
|
21751
22133
|
lastVerifiedCaller = null;
|
|
22134
|
+
/**
|
|
22135
|
+
* Hook for relay re-registration on health checks. Set by startServiceServer
|
|
22136
|
+
* to close the stale-registration window when platforms freeze/resume processes.
|
|
22137
|
+
*/
|
|
22138
|
+
ensureRegistered;
|
|
21752
22139
|
constructor(config, deps) {
|
|
21753
22140
|
this.config = config;
|
|
21754
22141
|
this.deps = deps;
|
|
@@ -22082,9 +22469,6 @@ var McpServerAdapter = class _McpServerAdapter {
|
|
|
22082
22469
|
isError: true
|
|
22083
22470
|
};
|
|
22084
22471
|
}
|
|
22085
|
-
if (delegatedScope) {
|
|
22086
|
-
receipt.delegated_scope = delegatedScope;
|
|
22087
|
-
}
|
|
22088
22472
|
this.deps.logToolCall("motebit_task", args, { ok: true, data: receipt });
|
|
22089
22473
|
return fmt(receipt);
|
|
22090
22474
|
}
|
|
@@ -22309,6 +22693,9 @@ var McpServerAdapter = class _McpServerAdapter {
|
|
|
22309
22693
|
return;
|
|
22310
22694
|
}
|
|
22311
22695
|
if (url.pathname === "/health" && req.method === "GET") {
|
|
22696
|
+
if (this.ensureRegistered) {
|
|
22697
|
+
void this.ensureRegistered();
|
|
22698
|
+
}
|
|
22312
22699
|
res.writeHead(200, { "Content-Type": "application/json" });
|
|
22313
22700
|
res.end(JSON.stringify({
|
|
22314
22701
|
status: "ok",
|
|
@@ -22920,7 +23307,7 @@ Unknown model: ${cyan(args)}
|
|
|
22920
23307
|
const mid = repl.motebitId;
|
|
22921
23308
|
runtime.enableInteractiveDelegation({
|
|
22922
23309
|
syncUrl: connectUrl,
|
|
22923
|
-
authToken: async () => {
|
|
23310
|
+
authToken: async (audience = "task:submit") => {
|
|
22924
23311
|
const now = Date.now();
|
|
22925
23312
|
return createSignedToken(
|
|
22926
23313
|
{
|
|
@@ -22929,7 +23316,7 @@ Unknown model: ${cyan(args)}
|
|
|
22929
23316
|
iat: now,
|
|
22930
23317
|
exp: now + 5 * 60 * 1e3,
|
|
22931
23318
|
jti: crypto.randomUUID(),
|
|
22932
|
-
aud:
|
|
23319
|
+
aud: audience
|
|
22933
23320
|
},
|
|
22934
23321
|
pk
|
|
22935
23322
|
);
|
|
@@ -27822,19 +28209,19 @@ var GoalScheduler = class _GoalScheduler {
|
|
|
27822
28209
|
}
|
|
27823
28210
|
switch (chunk.type) {
|
|
27824
28211
|
case "text":
|
|
27825
|
-
|
|
28212
|
+
writeOutput(chunk.text);
|
|
27826
28213
|
responseText += chunk.text;
|
|
27827
28214
|
break;
|
|
27828
28215
|
case "tool_status":
|
|
27829
28216
|
if (chunk.status === "calling") {
|
|
27830
|
-
|
|
28217
|
+
writeOutput(`
|
|
27831
28218
|
[tool] ${chunk.name}...`);
|
|
27832
28219
|
toolCallsMade++;
|
|
27833
28220
|
if (toolCallsMade > MAX_TOOL_CALLS_PER_RUN) {
|
|
27834
28221
|
throw new Error(`Goal exceeded ${MAX_TOOL_CALLS_PER_RUN} tool calls \u2014 run stopped`);
|
|
27835
28222
|
}
|
|
27836
28223
|
} else {
|
|
27837
|
-
|
|
28224
|
+
writeOutput(" done\n");
|
|
27838
28225
|
}
|
|
27839
28226
|
break;
|
|
27840
28227
|
case "approval_request": {
|
|
@@ -27951,18 +28338,18 @@ var GoalScheduler = class _GoalScheduler {
|
|
|
27951
28338
|
break;
|
|
27952
28339
|
case "step_chunk":
|
|
27953
28340
|
if (chunk.chunk.type === "text") {
|
|
27954
|
-
|
|
28341
|
+
writeOutput(chunk.chunk.text);
|
|
27955
28342
|
responseText += chunk.chunk.text;
|
|
27956
28343
|
} else if (chunk.chunk.type === "tool_status") {
|
|
27957
28344
|
if (chunk.chunk.status === "calling") {
|
|
27958
|
-
|
|
28345
|
+
writeOutput(`
|
|
27959
28346
|
[tool] ${chunk.chunk.name}...`);
|
|
27960
28347
|
toolCallsMade++;
|
|
27961
28348
|
if (toolCallsMade > MAX_TOOL_CALLS_PER_RUN) {
|
|
27962
28349
|
throw new Error(`Goal exceeded ${MAX_TOOL_CALLS_PER_RUN} tool calls \u2014 run stopped`);
|
|
27963
28350
|
}
|
|
27964
28351
|
} else {
|
|
27965
|
-
|
|
28352
|
+
writeOutput(" done\n");
|
|
27966
28353
|
}
|
|
27967
28354
|
} else if (chunk.chunk.type === "injection_warning") {
|
|
27968
28355
|
console.warn(`
|
|
@@ -28470,7 +28857,7 @@ Agent task received: ${task.task_id.slice(0, 8)}... prompt: "${task.prompt.slice
|
|
|
28470
28857
|
wsAdapter.connect();
|
|
28471
28858
|
if (privKeyBytes) {
|
|
28472
28859
|
const privateKeyForDelegation = privKeyBytes;
|
|
28473
|
-
const tokenFactory = async () => {
|
|
28860
|
+
const tokenFactory = async (audience = "task:submit") => {
|
|
28474
28861
|
if (!fullConfig.device_id) return syncToken ?? "";
|
|
28475
28862
|
try {
|
|
28476
28863
|
return await createSignedToken(
|
|
@@ -28480,7 +28867,7 @@ Agent task received: ${task.task_id.slice(0, 8)}... prompt: "${task.prompt.slice
|
|
|
28480
28867
|
iat: Date.now(),
|
|
28481
28868
|
exp: Date.now() + 5 * 60 * 1e3,
|
|
28482
28869
|
jti: crypto.randomUUID(),
|
|
28483
|
-
aud:
|
|
28870
|
+
aud: audience
|
|
28484
28871
|
},
|
|
28485
28872
|
privateKeyForDelegation
|
|
28486
28873
|
);
|
|
@@ -29001,10 +29388,32 @@ async function handleServe(config) {
|
|
|
29001
29388
|
try {
|
|
29002
29389
|
await new Promise((r) => setTimeout(r, 500));
|
|
29003
29390
|
const firstToolName = toolNames[toolNames.length - 1] ?? "echo";
|
|
29004
|
-
|
|
29391
|
+
const mintToken = async (audience) => {
|
|
29392
|
+
if (servePrivateKey && fullConfigForServe.device_id) {
|
|
29393
|
+
return createSignedToken(
|
|
29394
|
+
{
|
|
29395
|
+
mid: motebitId,
|
|
29396
|
+
did: fullConfigForServe.device_id,
|
|
29397
|
+
iat: Date.now(),
|
|
29398
|
+
exp: Date.now() + 5 * 60 * 1e3,
|
|
29399
|
+
jti: crypto.randomUUID(),
|
|
29400
|
+
aud: audience
|
|
29401
|
+
},
|
|
29402
|
+
servePrivateKey
|
|
29403
|
+
);
|
|
29404
|
+
}
|
|
29405
|
+
return masterToken ?? "";
|
|
29406
|
+
};
|
|
29407
|
+
const submitToken = await mintToken("task:submit");
|
|
29408
|
+
const queryToken = await mintToken("task:query");
|
|
29409
|
+
const authMethod = servePrivateKey && fullConfigForServe.device_id ? "device token" : "master token";
|
|
29410
|
+
log(`[self-test] submitting task via relay (auth: ${authMethod})...`);
|
|
29005
29411
|
const taskResp = await fetch(`${syncUrl}/agent/${motebitId}/task`, {
|
|
29006
29412
|
method: "POST",
|
|
29007
|
-
headers:
|
|
29413
|
+
headers: {
|
|
29414
|
+
"Content-Type": "application/json",
|
|
29415
|
+
Authorization: `Bearer ${submitToken}`
|
|
29416
|
+
},
|
|
29008
29417
|
body: JSON.stringify({
|
|
29009
29418
|
prompt: "self-test",
|
|
29010
29419
|
submitted_by: motebitId,
|
|
@@ -29018,6 +29427,8 @@ async function handleServe(config) {
|
|
|
29018
29427
|
`[self-test] failed \u2014 relay returned ${status}${body ? `: ${body.slice(0, 100)}` : ""}`
|
|
29019
29428
|
);
|
|
29020
29429
|
if (status === 402) log("[self-test] hint: fund the agent's budget on the relay");
|
|
29430
|
+
if (status === 401 || status === 403)
|
|
29431
|
+
log("[self-test] hint: device may not be registered with relay");
|
|
29021
29432
|
return;
|
|
29022
29433
|
}
|
|
29023
29434
|
const taskData = await taskResp.json();
|
|
@@ -29032,7 +29443,7 @@ async function handleServe(config) {
|
|
|
29032
29443
|
while (Date.now() < deadline) {
|
|
29033
29444
|
await new Promise((r) => setTimeout(r, 2e3));
|
|
29034
29445
|
const pollResp = await fetch(`${syncUrl}/agent/${motebitId}/task/${taskId}`, {
|
|
29035
|
-
headers:
|
|
29446
|
+
headers: { Authorization: `Bearer ${queryToken}` }
|
|
29036
29447
|
});
|
|
29037
29448
|
if (!pollResp.ok) continue;
|
|
29038
29449
|
const pollData = await pollResp.json();
|
|
@@ -29290,6 +29701,8 @@ async function main() {
|
|
|
29290
29701
|
saveFullConfig2(fullConfig);
|
|
29291
29702
|
console.log(dim(" Encrypted. Plaintext removed."));
|
|
29292
29703
|
} else {
|
|
29704
|
+
console.log();
|
|
29705
|
+
console.log(` ${bold("Welcome to Motebit.")}`);
|
|
29293
29706
|
console.log();
|
|
29294
29707
|
console.log(dim(" ."));
|
|
29295
29708
|
console.log(dim(" .:::."));
|
|
@@ -29319,18 +29732,7 @@ async function main() {
|
|
|
29319
29732
|
}
|
|
29320
29733
|
}
|
|
29321
29734
|
}
|
|
29322
|
-
|
|
29323
|
-
let rl = null;
|
|
29324
|
-
const getOrCreateRl = () => {
|
|
29325
|
-
if (!rl) {
|
|
29326
|
-
rl = readline3.createInterface({
|
|
29327
|
-
input: process.stdin,
|
|
29328
|
-
output: process.stdout,
|
|
29329
|
-
escapeCodeTimeout: 50
|
|
29330
|
-
});
|
|
29331
|
-
}
|
|
29332
|
-
return rl;
|
|
29333
|
-
};
|
|
29735
|
+
initTerminal();
|
|
29334
29736
|
const dbPath = getDbPath(config.dbPath);
|
|
29335
29737
|
const tempDb = await openMotebitDatabase(dbPath);
|
|
29336
29738
|
const { motebitId, isFirstLaunch } = await bootstrapIdentity2(tempDb, fullConfig, passphrase);
|
|
@@ -29388,31 +29790,9 @@ async function main() {
|
|
|
29388
29790
|
}
|
|
29389
29791
|
}
|
|
29390
29792
|
await runtime.init();
|
|
29391
|
-
const
|
|
29392
|
-
|
|
29393
|
-
|
|
29394
|
-
const did = deviceId;
|
|
29395
|
-
runtime.enableInteractiveDelegation({
|
|
29396
|
-
syncUrl,
|
|
29397
|
-
authToken: async () => {
|
|
29398
|
-
const now = Date.now();
|
|
29399
|
-
return createSignedToken(
|
|
29400
|
-
{
|
|
29401
|
-
mid: motebitId,
|
|
29402
|
-
did,
|
|
29403
|
-
iat: now,
|
|
29404
|
-
exp: now + 5 * 60 * 1e3,
|
|
29405
|
-
jti: crypto.randomUUID(),
|
|
29406
|
-
aud: "task:submit"
|
|
29407
|
-
},
|
|
29408
|
-
pk
|
|
29409
|
-
);
|
|
29410
|
-
},
|
|
29411
|
-
routingStrategy: config.routingStrategy
|
|
29412
|
-
});
|
|
29413
|
-
}
|
|
29414
|
-
const hasSyncRemote = config.syncUrl != null || process.env["MOTEBIT_SYNC_URL"] != null || reloadedConfig.sync_url != null && reloadedConfig.sync_url !== "";
|
|
29415
|
-
if (hasSyncRemote) {
|
|
29793
|
+
const DEFAULT_SYNC_URL2 = "https://motebit-sync.fly.dev";
|
|
29794
|
+
const syncUrl = config.syncUrl ?? process.env["MOTEBIT_SYNC_URL"] ?? reloadedConfig.sync_url ?? DEFAULT_SYNC_URL2;
|
|
29795
|
+
{
|
|
29416
29796
|
try {
|
|
29417
29797
|
console.log(dim("Syncing..."));
|
|
29418
29798
|
const result = await runtime.sync.sync();
|
|
@@ -29444,6 +29824,39 @@ async function main() {
|
|
|
29444
29824
|
} catch {
|
|
29445
29825
|
}
|
|
29446
29826
|
}
|
|
29827
|
+
if (syncUrl) {
|
|
29828
|
+
if (privateKeyBytes && deviceId) {
|
|
29829
|
+
const pk = privateKeyBytes;
|
|
29830
|
+
const did = deviceId;
|
|
29831
|
+
runtime.enableInteractiveDelegation({
|
|
29832
|
+
syncUrl,
|
|
29833
|
+
authToken: async (audience = "task:submit") => {
|
|
29834
|
+
const now = Date.now();
|
|
29835
|
+
return createSignedToken(
|
|
29836
|
+
{
|
|
29837
|
+
mid: motebitId,
|
|
29838
|
+
did,
|
|
29839
|
+
iat: now,
|
|
29840
|
+
exp: now + 5 * 60 * 1e3,
|
|
29841
|
+
jti: crypto.randomUUID(),
|
|
29842
|
+
aud: audience
|
|
29843
|
+
},
|
|
29844
|
+
pk
|
|
29845
|
+
);
|
|
29846
|
+
},
|
|
29847
|
+
routingStrategy: config.routingStrategy
|
|
29848
|
+
});
|
|
29849
|
+
} else {
|
|
29850
|
+
const apiToken = config.syncToken ?? process.env["MOTEBIT_API_TOKEN"];
|
|
29851
|
+
if (apiToken) {
|
|
29852
|
+
runtime.enableInteractiveDelegation({
|
|
29853
|
+
syncUrl,
|
|
29854
|
+
authToken: () => Promise.resolve(apiToken),
|
|
29855
|
+
routingStrategy: config.routingStrategy
|
|
29856
|
+
});
|
|
29857
|
+
}
|
|
29858
|
+
}
|
|
29859
|
+
}
|
|
29447
29860
|
if (syncUrl) {
|
|
29448
29861
|
try {
|
|
29449
29862
|
const token = config.syncToken ?? process.env["MOTEBIT_API_TOKEN"];
|
|
@@ -29473,7 +29886,7 @@ async function main() {
|
|
|
29473
29886
|
}
|
|
29474
29887
|
}
|
|
29475
29888
|
const shutdown = async () => {
|
|
29476
|
-
|
|
29889
|
+
destroyTerminal();
|
|
29477
29890
|
runtime.stop();
|
|
29478
29891
|
await Promise.allSettled(mcpAdapters.map((a) => a.disconnect()));
|
|
29479
29892
|
try {
|
|
@@ -29500,6 +29913,24 @@ async function main() {
|
|
|
29500
29913
|
operator: config.operator
|
|
29501
29914
|
});
|
|
29502
29915
|
console.log();
|
|
29916
|
+
if (isFirstLaunch) {
|
|
29917
|
+
try {
|
|
29918
|
+
const activationRunId = crypto.randomUUID();
|
|
29919
|
+
writeOutput(prompt("mote>") + " ");
|
|
29920
|
+
await consumeStream(
|
|
29921
|
+
runtime.generateActivation(
|
|
29922
|
+
"You just came into existence. The person who created you is here. Speak first.",
|
|
29923
|
+
activationRunId
|
|
29924
|
+
),
|
|
29925
|
+
runtime
|
|
29926
|
+
);
|
|
29927
|
+
void runtime.autoTitle();
|
|
29928
|
+
} catch (err3) {
|
|
29929
|
+
const msg = err3 instanceof Error ? err3.message : String(err3);
|
|
29930
|
+
console.error(dim(` [activation failed: ${msg}]`));
|
|
29931
|
+
}
|
|
29932
|
+
console.log();
|
|
29933
|
+
}
|
|
29503
29934
|
const prompt2 = () => {
|
|
29504
29935
|
readInput(prompt("you>") + " ").then(
|
|
29505
29936
|
(line) => void handleLine(line),
|
|
@@ -29511,9 +29942,8 @@ async function main() {
|
|
|
29511
29942
|
const handleLine = async (line) => {
|
|
29512
29943
|
const trimmed = line.trim();
|
|
29513
29944
|
if (trimmed === "quit" || trimmed === "exit") {
|
|
29514
|
-
|
|
29945
|
+
writeOutput("Goodbye!\n");
|
|
29515
29946
|
await shutdown();
|
|
29516
|
-
rl?.close();
|
|
29517
29947
|
return;
|
|
29518
29948
|
}
|
|
29519
29949
|
if (trimmed === "") {
|
|
@@ -29555,11 +29985,8 @@ ${prompt("mote>")} ${result.response}
|
|
|
29555
29985
|
if (bodyLine) console.log(meta(` ${bodyLine}`));
|
|
29556
29986
|
console.log();
|
|
29557
29987
|
} else {
|
|
29558
|
-
|
|
29559
|
-
|
|
29560
|
-
await consumeStream(runtime.sendMessageStreaming(trimmed, chatRunId), runtime, streamRl);
|
|
29561
|
-
streamRl.close();
|
|
29562
|
-
rl = null;
|
|
29988
|
+
writeOutput("\n" + prompt("mote>") + " ");
|
|
29989
|
+
await consumeStream(runtime.sendMessageStreaming(trimmed, chatRunId), runtime);
|
|
29563
29990
|
}
|
|
29564
29991
|
void runtime.autoTitle();
|
|
29565
29992
|
} catch (err3) {
|