pi-harness-runtime 1.1.379 → 1.1.381
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 +149 -5
- 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/package.json +1 -1
- 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 +66 -6
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,
|
|
@@ -1449,7 +1453,24 @@ async function initTelegram(pi: ExtensionAPI): Promise<void> {
|
|
|
1449
1453
|
telegram?.setGreetingVerifiedHandler(() => {
|
|
1450
1454
|
addHarnessMessage("Telegram", "ready (Hi reply received; two-way verified)", "ok");
|
|
1451
1455
|
});
|
|
1452
|
-
|
|
1456
|
+
|
|
1457
|
+
// Set adapter for relay streaming (receives callbacks via WebSocket)
|
|
1458
|
+
setRelayTelegramAdapter(telegram);
|
|
1459
|
+
|
|
1460
|
+
pi.on("session_shutdown", () => {
|
|
1461
|
+
telegram?.stopPolling();
|
|
1462
|
+
_relayClient?.disconnect();
|
|
1463
|
+
});
|
|
1464
|
+
|
|
1465
|
+
// Check if webhook mode is configured
|
|
1466
|
+
const homedir2 = process.env.HOME || process.env.USERPROFILE || "/home/frappe";
|
|
1467
|
+
const webhookUrlPath = join(homedir2, ".pi-harness-runtime", "keys", "telegram-webhook-url.txt");
|
|
1468
|
+
const _hasWebhook = existsSync(webhookUrlPath);
|
|
1469
|
+
|
|
1470
|
+
// Initialize relay streaming (receives callbacks via WebSocket)
|
|
1471
|
+
// In webhook mode, streaming delivers callbacks in real-time
|
|
1472
|
+
await initRelayStream();
|
|
1473
|
+
|
|
1453
1474
|
const greeting = await telegram?.sendStartupGreeting();
|
|
1454
1475
|
if (!greeting?.success) {
|
|
1455
1476
|
logStartup("[pi-harness] Telegram: startup greeting delivery failed");
|
|
@@ -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.381",
|
|
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",
|