pi-harness-runtime 1.1.380 → 1.1.382
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/index.ts +153 -9
- package/package.json +1 -1
- package/packages/a2a-adapter/package.json +1 -1
- package/packages/agent-policy/package.json +1 -1
- package/packages/architecture-generator/package.json +1 -1
- package/packages/auth/package.json +1 -1
- package/packages/autonomous-refactor/package.json +1 -1
- package/packages/autonomous-runtime/package.json +1 -1
- package/packages/cache-strategy/package.json +1 -1
- package/packages/capability-registry/package.json +1 -1
- package/packages/checkpoint/package.json +1 -1
- package/packages/cli-plugin-sdk/package.json +1 -1
- package/packages/clipboard/package.json +1 -1
- package/packages/clipboard-plugin/package.json +1 -1
- package/packages/code-generation/package.json +1 -1
- package/packages/code-review/package.json +1 -1
- package/packages/codex-adapter/package.json +1 -1
- package/packages/codex-watcher/package.json +1 -1
- package/packages/config-capture/package.json +1 -1
- package/packages/connection-runtime/package.json +1 -1
- package/packages/context-compiler/package.json +1 -1
- package/packages/context-discovery/package.json +1 -1
- package/packages/context-manager/package.json +1 -1
- package/packages/contracts/package.json +1 -1
- package/packages/cookie-sanitizer/package.json +1 -1
- package/packages/cost-optimizer/package.json +1 -1
- package/packages/dependency-analyzer/package.json +1 -1
- package/packages/django-plugin/package.json +1 -1
- package/packages/doc-generator/package.json +1 -1
- package/packages/durable-review/package.json +1 -1
- package/packages/e2e-tester/package.json +1 -1
- package/packages/evaluation-engine/package.json +1 -1
- package/packages/evaluation-runner/package.json +1 -1
- package/packages/event-bus/package.json +1 -1
- package/packages/event-sink/package.json +1 -1
- package/packages/event-store/package.json +1 -1
- package/packages/experience-replay/package.json +1 -1
- package/packages/feedback-collector/package.json +1 -1
- package/packages/file-copy-helper/package.json +1 -1
- package/packages/framework-detector/package.json +1 -1
- package/packages/framework-plugin-sdk/package.json +1 -1
- package/packages/frappe-plugin/package.json +1 -1
- package/packages/generic-web-plugin/package.json +1 -1
- package/packages/health-monitor/package.json +1 -1
- package/packages/intent-analyzer/package.json +1 -1
- package/packages/jev-judge/package.json +1 -1
- package/packages/knowledge-graph/package.json +1 -1
- package/packages/knowledge-retrieval/package.json +1 -1
- package/packages/laravel-plugin/package.json +1 -1
- package/packages/learning-engine/package.json +1 -1
- package/packages/mcp-adapter/package.json +1 -1
- package/packages/memory-engine/package.json +1 -1
- package/packages/milestone-manager/package.json +1 -1
- package/packages/model-registry/package.json +1 -1
- package/packages/nextjs-plugin/package.json +1 -1
- package/packages/notification/dist/adapters/telegram-adapter.d.ts.map +1 -1
- package/packages/notification/dist/adapters/telegram-adapter.js +37 -4
- package/packages/notification/dist/adapters/telegram-adapter.js.map +1 -1
- package/packages/notification/package.json +1 -1
- package/packages/notification/src/adapters/telegram-adapter.ts +45 -4
- package/packages/observability/package.json +1 -1
- package/packages/okf-indexer/package.json +1 -1
- package/packages/paperclip-integration/package.json +1 -1
- package/packages/performance-optimizer/package.json +1 -1
- package/packages/permission-mode/package.json +1 -1
- package/packages/privilege-broker/package.json +1 -1
- package/packages/project-analyzer/package.json +1 -1
- package/packages/project-bootstrap/package.json +1 -1
- package/packages/projection-engine/package.json +1 -1
- package/packages/prompt-compiler/package.json +1 -1
- package/packages/prompt-versioning/package.json +1 -1
- package/packages/provider-adapter-sdk/package.json +1 -1
- package/packages/provider-router/package.json +1 -1
- package/packages/provider-selector/package.json +1 -1
- package/packages/providers/package.json +1 -1
- package/packages/qdrant-skills/package.json +1 -1
- package/packages/quota-manager/package.json +1 -1
- package/packages/rate-limiter/package.json +1 -1
- package/packages/react-vite-plugin/package.json +1 -1
- package/packages/relay/dist/types.d.ts +2 -0
- package/packages/relay/package.json +1 -1
- package/packages/relay/src/types.ts +3 -0
- package/packages/release-manager/package.json +1 -1
- package/packages/requirement-compiler/package.json +1 -1
- package/packages/runtime/package.json +1 -1
- package/packages/scheduler/package.json +1 -1
- package/packages/scheduler-adapter/package.json +1 -1
- package/packages/session/package.json +1 -1
- package/packages/session-api/package.json +1 -1
- package/packages/session-export/package.json +1 -1
- package/packages/shared-context/package.json +1 -1
- package/packages/skill-mcp-client/package.json +1 -1
- package/packages/skill-registry/package.json +1 -1
- package/packages/skills/package.json +1 -1
- package/packages/sprint-planner/package.json +1 -1
- package/packages/subscription-engine/package.json +1 -1
- package/packages/task-compiler/package.json +1 -1
- package/packages/telegram/package.json +1 -1
- package/packages/tencentdb-memory/package.json +1 -1
- package/packages/tencentdb-sync/package.json +1 -1
- package/packages/test-data-generator/package.json +1 -1
- package/packages/test-generator/package.json +1 -1
- package/packages/todo-bd-sync/package.json +1 -1
- package/packages/token-estimation/package.json +1 -1
- package/packages/token-optimizer/package.json +1 -1
- package/packages/trajectory/package.json +1 -1
- package/packages/tui/package.json +1 -1
- package/packages/types/package.json +1 -1
- package/packages/voice-api/package.json +1 -1
- package/packages/webmcp-tester/package.json +1 -1
- package/packages/wiki/package.json +1 -1
- package/packages/workflow-events/package.json +1 -1
- package/packages/workspace-scanner/package.json +1 -1
- package/packages/worktree/package.json +1 -1
- package/packages/write-review/package.json +1 -1
- package/scripts/unified-webhook-server.ts +9 -3
package/index.ts
CHANGED
|
@@ -54,6 +54,10 @@ import {
|
|
|
54
54
|
shouldTriggerProactiveCompact,
|
|
55
55
|
} from "./proactive-compact.ts";
|
|
56
56
|
import { aggregateWindows } from "./windows.ts";
|
|
57
|
+
|
|
58
|
+
// Relay client for streaming callbacks (t3code-style two-way communication)
|
|
59
|
+
import { RelayClient } from "./packages/relay/src/client.js";
|
|
60
|
+
import type { CallbackPayload } from "./packages/relay/src/types.js";
|
|
57
61
|
import { renderStatus } from "./renderer.ts";
|
|
58
62
|
import {
|
|
59
63
|
JobStateMachine,
|
|
@@ -1238,7 +1242,11 @@ async function initTelegram(pi: ExtensionAPI): Promise<void> {
|
|
|
1238
1242
|
enabled: true,
|
|
1239
1243
|
config: { channelAccessToken: lineAccessToken, userId: lineUserId },
|
|
1240
1244
|
});
|
|
1241
|
-
addHarnessMessage("LINE", "configured and enabled", "ok");
|
|
1245
|
+
addHarnessMessage("LINE", "configured and enabled (tap Toggle LINE to disable)", "ok");
|
|
1246
|
+
} else {
|
|
1247
|
+
addHarnessMessage("LINE", "not configured", "warn", [
|
|
1248
|
+
"Configure LINE in ~/.pi-harness-runtime/keys/",
|
|
1249
|
+
]);
|
|
1242
1250
|
}
|
|
1243
1251
|
|
|
1244
1252
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
@@ -1447,12 +1455,25 @@ async function initTelegram(pi: ExtensionAPI): Promise<void> {
|
|
|
1447
1455
|
const botUsername = center.getTelegramBotUsername();
|
|
1448
1456
|
const telegram = center.getTelegramAdapter();
|
|
1449
1457
|
telegram?.setGreetingVerifiedHandler(() => {
|
|
1450
|
-
addHarnessMessage("Telegram", "ready (
|
|
1458
|
+
addHarnessMessage("Telegram", "ready (tap Toggle Telegram to disable)", "ok");
|
|
1459
|
+
});
|
|
1460
|
+
|
|
1461
|
+
// Set adapter for relay streaming (receives callbacks via WebSocket)
|
|
1462
|
+
setRelayTelegramAdapter(telegram);
|
|
1463
|
+
|
|
1464
|
+
pi.on("session_shutdown", () => {
|
|
1465
|
+
telegram?.stopPolling();
|
|
1466
|
+
_relayClient?.disconnect();
|
|
1451
1467
|
});
|
|
1452
|
-
|
|
1468
|
+
|
|
1469
|
+
// Initialize relay streaming (receives callbacks via WebSocket)
|
|
1470
|
+
// In webhook mode, streaming delivers callbacks in real-time
|
|
1471
|
+
await initRelayStream();
|
|
1472
|
+
|
|
1453
1473
|
const greeting = await telegram?.sendStartupGreeting();
|
|
1474
|
+
logStartup(`[pi-harness] Telegram greeting result: ${JSON.stringify(greeting)}`);
|
|
1454
1475
|
if (!greeting?.success) {
|
|
1455
|
-
logStartup("[pi-harness] Telegram: startup greeting delivery failed");
|
|
1476
|
+
logStartup("[pi-harness] Telegram: startup greeting delivery failed - see logs");
|
|
1456
1477
|
addHarnessMessage("Telegram", "bot verified; Hi delivery failed", "err", [
|
|
1457
1478
|
"Open your bot in Telegram and press Start; unblock it if necessary.",
|
|
1458
1479
|
"Verify telegram-chat-id.txt in ~/.pi-harness-runtime/keys/ and network access, then reload Pi.",
|
|
@@ -1461,7 +1482,7 @@ async function initTelegram(pi: ExtensionAPI): Promise<void> {
|
|
|
1461
1482
|
}
|
|
1462
1483
|
telegram?.startPolling();
|
|
1463
1484
|
if (!telegram?.isGreetingVerified()) {
|
|
1464
|
-
addHarnessMessage("Telegram", "Hi sent; tap Say Hi
|
|
1485
|
+
addHarnessMessage("Telegram", "Hi sent; tap Say Hi to verify inbound (tap Toggle Telegram to disable)", "wait");
|
|
1465
1486
|
}
|
|
1466
1487
|
if (botUsername) {
|
|
1467
1488
|
logStartup(`[pi-harness] Telegram (@${botUsername}) ready — DM the bot to receive alerts`);
|
|
@@ -1477,6 +1498,114 @@ async function initTelegram(pi: ExtensionAPI): Promise<void> {
|
|
|
1477
1498
|
}
|
|
1478
1499
|
}
|
|
1479
1500
|
|
|
1501
|
+
// ============================================================================
|
|
1502
|
+
// --- relay-stream: WebSocket streaming for real-time Telegram callbacks -------
|
|
1503
|
+
// ============================================================================
|
|
1504
|
+
// Wires RelayClient to the Telegram adapter for two-way streaming communication.
|
|
1505
|
+
// When callbacks arrive via WebSocket, they are forwarded to the adapter's
|
|
1506
|
+
// handleWebhookUpdate() for proper greeting verification and callback handling.
|
|
1507
|
+
|
|
1508
|
+
let _relayTelegramAdapter: any = null;
|
|
1509
|
+
let _relayClient: RelayClient | null = null;
|
|
1510
|
+
|
|
1511
|
+
/**
|
|
1512
|
+
* Set the Telegram adapter for relay streaming (called from initTelegram)
|
|
1513
|
+
*/
|
|
1514
|
+
function setRelayTelegramAdapter(adapter: any) {
|
|
1515
|
+
_relayTelegramAdapter = adapter;
|
|
1516
|
+
}
|
|
1517
|
+
|
|
1518
|
+
/**
|
|
1519
|
+
* Initialize relay streaming for real-time callback delivery.
|
|
1520
|
+
* Connects to the relay WebSocket server and forwards Telegram callbacks
|
|
1521
|
+
* to the adapter for proper greeting verification and handling.
|
|
1522
|
+
*/
|
|
1523
|
+
async function initRelayStream(): Promise<void> {
|
|
1524
|
+
const homedir = process.env.HOME || process.env.USERPROFILE || "/home/frappe";
|
|
1525
|
+
const keysDir = join(homedir, ".pi-harness-runtime", "keys");
|
|
1526
|
+
|
|
1527
|
+
// Check for relay WebSocket URL
|
|
1528
|
+
const relayWsUrlPath = join(keysDir, "relay-ws-url.txt");
|
|
1529
|
+
const relayTokenPath = join(keysDir, "relay-auth-token.txt");
|
|
1530
|
+
|
|
1531
|
+
if (!existsSync(relayWsUrlPath) || !existsSync(relayTokenPath)) {
|
|
1532
|
+
logToFile("[RelayStream]", "Relay WebSocket URL or token not configured - skipping streaming");
|
|
1533
|
+
return;
|
|
1534
|
+
}
|
|
1535
|
+
|
|
1536
|
+
const relayWsUrl = readFileSync(relayWsUrlPath, "utf-8").trim();
|
|
1537
|
+
const relayToken = readFileSync(relayTokenPath, "utf-8").trim();
|
|
1538
|
+
|
|
1539
|
+
if (!relayWsUrl || !relayToken) {
|
|
1540
|
+
logToFile("[RelayStream]", "Relay URL or token is empty - skipping streaming");
|
|
1541
|
+
return;
|
|
1542
|
+
}
|
|
1543
|
+
|
|
1544
|
+
logToFile("[RelayStream]", `Connecting to relay at ${relayWsUrl}`);
|
|
1545
|
+
|
|
1546
|
+
_relayClient = new RelayClient(
|
|
1547
|
+
{
|
|
1548
|
+
serverUrl: relayWsUrl,
|
|
1549
|
+
token: relayToken,
|
|
1550
|
+
},
|
|
1551
|
+
{
|
|
1552
|
+
onConnected: (sessionId) => {
|
|
1553
|
+
logToFile("[RelayStream]", `Connected to relay, session: ${sessionId}`);
|
|
1554
|
+
},
|
|
1555
|
+
onDisconnected: () => {
|
|
1556
|
+
logToFile("[RelayStream]", "Disconnected from relay");
|
|
1557
|
+
},
|
|
1558
|
+
onSnapshot: (snapshot) => {
|
|
1559
|
+
logToFile("[RelayStream]", `Snapshot: ${snapshot.recentCallbacks.length} recent callbacks`);
|
|
1560
|
+
},
|
|
1561
|
+
onSynchronized: () => {
|
|
1562
|
+
logToFile("[RelayStream]", "Synchronized - receiving live events");
|
|
1563
|
+
},
|
|
1564
|
+
onCallback: async (callback: CallbackPayload) => {
|
|
1565
|
+
logToFile("[RelayStream]", `Callback: ${callback.action} ${callback.targetId}`);
|
|
1566
|
+
|
|
1567
|
+
// Forward Telegram callbacks to the adapter
|
|
1568
|
+
if (callback.type === "telegram_callback" && _relayTelegramAdapter) {
|
|
1569
|
+
// Convert relay callback to Telegram update format
|
|
1570
|
+
const update = {
|
|
1571
|
+
callback_query: {
|
|
1572
|
+
id: callback.callbackQueryId || String(callback.id),
|
|
1573
|
+
from: {
|
|
1574
|
+
id: callback.userId,
|
|
1575
|
+
is_bot: false,
|
|
1576
|
+
first_name: callback.username || "User",
|
|
1577
|
+
username: callback.username,
|
|
1578
|
+
},
|
|
1579
|
+
data: `${callback.action}:${callback.targetId}`,
|
|
1580
|
+
message: {
|
|
1581
|
+
chat: { id: callback.chatId || callback.userId },
|
|
1582
|
+
message_id: callback.messageId || 0,
|
|
1583
|
+
},
|
|
1584
|
+
},
|
|
1585
|
+
};
|
|
1586
|
+
|
|
1587
|
+
try {
|
|
1588
|
+
await _relayTelegramAdapter.handleWebhookUpdate(update);
|
|
1589
|
+
logToFile("[RelayStream]", "Callback processed by Telegram adapter");
|
|
1590
|
+
} catch (err) {
|
|
1591
|
+
logToFile("[RelayStream]", `Adapter error: ${err}`);
|
|
1592
|
+
}
|
|
1593
|
+
}
|
|
1594
|
+
},
|
|
1595
|
+
onError: (error) => {
|
|
1596
|
+
logToFile("[RelayStream]", `Error: ${error.message}`);
|
|
1597
|
+
},
|
|
1598
|
+
}
|
|
1599
|
+
);
|
|
1600
|
+
|
|
1601
|
+
try {
|
|
1602
|
+
await _relayClient.connect();
|
|
1603
|
+
logToFile("[RelayStream]", "Relay stream initialized successfully");
|
|
1604
|
+
} catch (err) {
|
|
1605
|
+
logToFile("[RelayStream]", `Failed to connect: ${err}`);
|
|
1606
|
+
}
|
|
1607
|
+
}
|
|
1608
|
+
|
|
1480
1609
|
// --- honcho-memory: Honcho MCP for peer/user memory via https://mcp.honcho.dev ------
|
|
1481
1610
|
// Registers Honcho MCP server and implements automatic memory lifecycle:
|
|
1482
1611
|
// - Ingest sanitized messages on completed turns
|
|
@@ -2483,6 +2612,7 @@ function initJobPipeWatcher(pi: ExtensionAPI): void {
|
|
|
2483
2612
|
// Get webhook server URL and API key from config
|
|
2484
2613
|
const getWebhookConfig = () => {
|
|
2485
2614
|
const webhookUrlPath = join(keysDir, "telegram-webhook-url.txt");
|
|
2615
|
+
const apiUrlPath = join(keysDir, "relay-api-url.txt"); // Separate API base URL
|
|
2486
2616
|
const secretPath = join(keysDir, "telegram-webhook-secret.txt");
|
|
2487
2617
|
|
|
2488
2618
|
if (!existsSync(webhookUrlPath) || !existsSync(secretPath)) {
|
|
@@ -2492,11 +2622,25 @@ function initJobPipeWatcher(pi: ExtensionAPI): void {
|
|
|
2492
2622
|
const webhookUrl = readFileSync(webhookUrlPath, "utf-8").trim();
|
|
2493
2623
|
const secret = readFileSync(secretPath, "utf-8").trim();
|
|
2494
2624
|
|
|
2625
|
+
// Use separate API URL if configured, otherwise extract origin from webhook URL
|
|
2626
|
+
let apiBaseUrl: string;
|
|
2627
|
+
if (existsSync(apiUrlPath)) {
|
|
2628
|
+
apiBaseUrl = readFileSync(apiUrlPath, "utf-8").trim().replace(/\/$/, "");
|
|
2629
|
+
} else {
|
|
2630
|
+
// Extract origin from webhook URL (e.g., https://example.com from https://example.com/telegram)
|
|
2631
|
+
try {
|
|
2632
|
+
const url = new URL(webhookUrl);
|
|
2633
|
+
apiBaseUrl = `${url.protocol}//${url.host}`;
|
|
2634
|
+
} catch {
|
|
2635
|
+
apiBaseUrl = webhookUrl;
|
|
2636
|
+
}
|
|
2637
|
+
}
|
|
2638
|
+
|
|
2495
2639
|
if (!webhookUrl || !secret) {
|
|
2496
2640
|
return null;
|
|
2497
2641
|
}
|
|
2498
2642
|
|
|
2499
|
-
return { webhookUrl: webhookUrl.replace(/\/$/, ""), secret };
|
|
2643
|
+
return { webhookUrl: webhookUrl.replace(/\/$/, ""), apiBaseUrl, secret };
|
|
2500
2644
|
};
|
|
2501
2645
|
|
|
2502
2646
|
const processCommand = (cmd: { command: string; jobId: string; userId: number }) => {
|
|
@@ -2521,9 +2665,9 @@ function initJobPipeWatcher(pi: ExtensionAPI): void {
|
|
|
2521
2665
|
};
|
|
2522
2666
|
|
|
2523
2667
|
// Acknowledge processed commands
|
|
2524
|
-
const acknowledgeCommands = async (jobIds: string[], config: { webhookUrl: string; secret: string }) => {
|
|
2668
|
+
const acknowledgeCommands = async (jobIds: string[], config: { webhookUrl: string; apiBaseUrl: string; secret: string }) => {
|
|
2525
2669
|
try {
|
|
2526
|
-
await fetch(`${config.
|
|
2670
|
+
await fetch(`${config.apiBaseUrl}/api/acknowledge-commands`, {
|
|
2527
2671
|
method: "POST",
|
|
2528
2672
|
headers: {
|
|
2529
2673
|
"Content-Type": "application/json",
|
|
@@ -2543,7 +2687,7 @@ function initJobPipeWatcher(pi: ExtensionAPI): void {
|
|
|
2543
2687
|
}
|
|
2544
2688
|
|
|
2545
2689
|
try {
|
|
2546
|
-
const response = await fetch(`${config.
|
|
2690
|
+
const response = await fetch(`${config.apiBaseUrl}/api/pending-commands`, {
|
|
2547
2691
|
headers: {
|
|
2548
2692
|
"Authorization": `Bearer ${config.secret}`,
|
|
2549
2693
|
},
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pi-harness/capability-registry",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.382",
|
|
4
4
|
"description": "Capability Registry for pi-harness-runtime — tracks model capabilities and enables capability-based routing",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|