optimus-tool-call-staging 0.2.4

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.
Files changed (87) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +194 -0
  3. package/dist/capture-prompt.d.ts +14 -0
  4. package/dist/capture-prompt.d.ts.map +1 -0
  5. package/dist/capture-prompt.js +173 -0
  6. package/dist/capture-prompt.js.map +1 -0
  7. package/dist/index.d.ts +9 -0
  8. package/dist/index.d.ts.map +1 -0
  9. package/dist/index.js +165 -0
  10. package/dist/index.js.map +1 -0
  11. package/dist/lib/endpoint-config.d.ts +2 -0
  12. package/dist/lib/endpoint-config.d.ts.map +1 -0
  13. package/dist/lib/endpoint-config.js +2 -0
  14. package/dist/lib/endpoint-config.js.map +1 -0
  15. package/dist/lib/hardware-uuid.d.ts +7 -0
  16. package/dist/lib/hardware-uuid.d.ts.map +1 -0
  17. package/dist/lib/hardware-uuid.js +52 -0
  18. package/dist/lib/hardware-uuid.js.map +1 -0
  19. package/dist/lib/machine-auth.d.ts +11 -0
  20. package/dist/lib/machine-auth.d.ts.map +1 -0
  21. package/dist/lib/machine-auth.js +46 -0
  22. package/dist/lib/machine-auth.js.map +1 -0
  23. package/dist/lib/startup-sync.d.ts +13 -0
  24. package/dist/lib/startup-sync.d.ts.map +1 -0
  25. package/dist/lib/startup-sync.js +147 -0
  26. package/dist/lib/startup-sync.js.map +1 -0
  27. package/dist/lib/streaming.d.ts +18 -0
  28. package/dist/lib/streaming.d.ts.map +1 -0
  29. package/dist/lib/streaming.js +243 -0
  30. package/dist/lib/streaming.js.map +1 -0
  31. package/dist/lib/telemetry/build-event.d.ts +10 -0
  32. package/dist/lib/telemetry/build-event.d.ts.map +1 -0
  33. package/dist/lib/telemetry/build-event.js +32 -0
  34. package/dist/lib/telemetry/build-event.js.map +1 -0
  35. package/dist/lib/telemetry/canonical.d.ts +26 -0
  36. package/dist/lib/telemetry/canonical.d.ts.map +1 -0
  37. package/dist/lib/telemetry/canonical.js +153 -0
  38. package/dist/lib/telemetry/canonical.js.map +1 -0
  39. package/dist/lib/telemetry/index.d.ts +9 -0
  40. package/dist/lib/telemetry/index.d.ts.map +1 -0
  41. package/dist/lib/telemetry/index.js +9 -0
  42. package/dist/lib/telemetry/index.js.map +1 -0
  43. package/dist/lib/telemetry/serialize.d.ts +3 -0
  44. package/dist/lib/telemetry/serialize.d.ts.map +1 -0
  45. package/dist/lib/telemetry/serialize.js +15 -0
  46. package/dist/lib/telemetry/serialize.js.map +1 -0
  47. package/dist/lib/telemetry/types.d.ts +34 -0
  48. package/dist/lib/telemetry/types.d.ts.map +1 -0
  49. package/dist/lib/telemetry/types.js +14 -0
  50. package/dist/lib/telemetry/types.js.map +1 -0
  51. package/dist/lib/telemetry/wire-metadata.d.ts +10 -0
  52. package/dist/lib/telemetry/wire-metadata.d.ts.map +1 -0
  53. package/dist/lib/telemetry/wire-metadata.js +28 -0
  54. package/dist/lib/telemetry/wire-metadata.js.map +1 -0
  55. package/dist/lib/telemetry.d.ts +2 -0
  56. package/dist/lib/telemetry.d.ts.map +1 -0
  57. package/dist/lib/telemetry.js +2 -0
  58. package/dist/lib/telemetry.js.map +1 -0
  59. package/dist/lib/user-profile.d.ts +16 -0
  60. package/dist/lib/user-profile.d.ts.map +1 -0
  61. package/dist/lib/user-profile.js +175 -0
  62. package/dist/lib/user-profile.js.map +1 -0
  63. package/dist/test/canonical.test.d.ts +2 -0
  64. package/dist/test/canonical.test.d.ts.map +1 -0
  65. package/dist/test/canonical.test.js +117 -0
  66. package/dist/test/canonical.test.js.map +1 -0
  67. package/dist/test/endpoint-config.test.d.ts +2 -0
  68. package/dist/test/endpoint-config.test.d.ts.map +1 -0
  69. package/dist/test/endpoint-config.test.js +43 -0
  70. package/dist/test/endpoint-config.test.js.map +1 -0
  71. package/dist/test/index.test.d.ts +2 -0
  72. package/dist/test/index.test.d.ts.map +1 -0
  73. package/dist/test/index.test.js +376 -0
  74. package/dist/test/index.test.js.map +1 -0
  75. package/dist/test/integration-canonical.test.d.ts +2 -0
  76. package/dist/test/integration-canonical.test.d.ts.map +1 -0
  77. package/dist/test/integration-canonical.test.js +157 -0
  78. package/dist/test/integration-canonical.test.js.map +1 -0
  79. package/dist/test/streaming.test.d.ts +2 -0
  80. package/dist/test/streaming.test.d.ts.map +1 -0
  81. package/dist/test/streaming.test.js +223 -0
  82. package/dist/test/streaming.test.js.map +1 -0
  83. package/dist/test/telemetry.test.d.ts +2 -0
  84. package/dist/test/telemetry.test.d.ts.map +1 -0
  85. package/dist/test/telemetry.test.js +201 -0
  86. package/dist/test/telemetry.test.js.map +1 -0
  87. package/package.json +50 -0
@@ -0,0 +1,52 @@
1
+ import { execSync } from "node:child_process";
2
+ /** Run a static shell command and return trimmed stdout (same pattern as log-llm-config). */
3
+ export function readCommandOutput(command) {
4
+ try {
5
+ return execSync(command, {
6
+ encoding: "utf8",
7
+ stdio: ["ignore", "pipe", "ignore"],
8
+ }).trim();
9
+ }
10
+ catch {
11
+ return "";
12
+ }
13
+ }
14
+ /** Resolve hardware UUID from environment or macOS system commands (same strategy as log-llm-config). */
15
+ function resolveHardwareUuid() {
16
+ const envUuid = process.env.OPTIMUS_HARDWARE_UUID?.trim();
17
+ if (envUuid)
18
+ return envUuid;
19
+ try {
20
+ const ioregOutput = execSync("ioreg -rd1 -c IOPlatformExpertDevice", {
21
+ encoding: "utf8",
22
+ }).trim();
23
+ const ioregMatch = ioregOutput.match(/"IOPlatformUUID"\s*=\s*"([^"]+)"/i);
24
+ if (ioregMatch?.[1])
25
+ return ioregMatch[1];
26
+ }
27
+ catch {
28
+ // try next method
29
+ }
30
+ try {
31
+ const profilerOutput = execSync("system_profiler SPHardwareDataType", {
32
+ encoding: "utf8",
33
+ }).trim();
34
+ const profilerMatch = profilerOutput.match(/Hardware UUID:\s*([A-F0-9-]+)/i);
35
+ if (profilerMatch?.[1])
36
+ return profilerMatch[1];
37
+ }
38
+ catch {
39
+ // both methods failed
40
+ }
41
+ throw new Error("Unable to determine hardware UUID via ioreg or system_profiler.");
42
+ }
43
+ export function tryResolveHardwareUuid() {
44
+ try {
45
+ return resolveHardwareUuid();
46
+ }
47
+ catch {
48
+ return null;
49
+ }
50
+ }
51
+ export { resolveHardwareUuid };
52
+ //# sourceMappingURL=hardware-uuid.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hardware-uuid.js","sourceRoot":"","sources":["../../src/lib/hardware-uuid.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAE9C,6FAA6F;AAC7F,MAAM,UAAU,iBAAiB,CAAC,OAAe;IAC/C,IAAI,CAAC;QACH,OAAO,QAAQ,CAAC,OAAO,EAAE;YACvB,QAAQ,EAAE,MAAM;YAChB,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC;SACpC,CAAC,CAAC,IAAI,EAAE,CAAC;IACZ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED,yGAAyG;AACzG,SAAS,mBAAmB;IAC1B,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,qBAAqB,EAAE,IAAI,EAAE,CAAC;IAC1D,IAAI,OAAO;QAAE,OAAO,OAAO,CAAC;IAE5B,IAAI,CAAC;QACH,MAAM,WAAW,GAAG,QAAQ,CAAC,sCAAsC,EAAE;YACnE,QAAQ,EAAE,MAAM;SACjB,CAAC,CAAC,IAAI,EAAE,CAAC;QACV,MAAM,UAAU,GAAG,WAAW,CAAC,KAAK,CAAC,mCAAmC,CAAC,CAAC;QAC1E,IAAI,UAAU,EAAE,CAAC,CAAC,CAAC;YAAE,OAAO,UAAU,CAAC,CAAC,CAAC,CAAC;IAC5C,CAAC;IAAC,MAAM,CAAC;QACP,kBAAkB;IACpB,CAAC;IAED,IAAI,CAAC;QACH,MAAM,cAAc,GAAG,QAAQ,CAAC,oCAAoC,EAAE;YACpE,QAAQ,EAAE,MAAM;SACjB,CAAC,CAAC,IAAI,EAAE,CAAC;QACV,MAAM,aAAa,GAAG,cAAc,CAAC,KAAK,CAAC,gCAAgC,CAAC,CAAC;QAC7E,IAAI,aAAa,EAAE,CAAC,CAAC,CAAC;YAAE,OAAO,aAAa,CAAC,CAAC,CAAC,CAAC;IAClD,CAAC;IAAC,MAAM,CAAC;QACP,sBAAsB;IACxB,CAAC;IAED,MAAM,IAAI,KAAK,CAAC,iEAAiE,CAAC,CAAC;AACrF,CAAC;AAED,MAAM,UAAU,sBAAsB;IACpC,IAAI,CAAC;QACH,OAAO,mBAAmB,EAAE,CAAC;IAC/B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,OAAO,EAAE,mBAAmB,EAAE,CAAC"}
@@ -0,0 +1,11 @@
1
+ import { type StoredAuthKey } from "optimus-tofu-staging";
2
+ /** Same path as log-llm-config: `~/opt-ai-sec/management/auth_key.txt` under `$HOME`. */
3
+ export declare const OPTIMUS_AUTH_KEY_RELATIVE_PATH: string;
4
+ /**
5
+ * Same TOFU + machine key flow as log-llm-config: verify stored key against
6
+ * `/endpoint_security/auth/` or request a new key and persist under HOME.
7
+ */
8
+ export declare function ensureToolCallAuth(hardwareUuid: string): Promise<StoredAuthKey>;
9
+ /** For tests: clear cached auth so HOME / env changes take effect. */
10
+ export declare function resetToolCallAuthCache(): void;
11
+ //# sourceMappingURL=machine-auth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"machine-auth.d.ts","sourceRoot":"","sources":["../../src/lib/machine-auth.ts"],"names":[],"mappings":"AACA,OAAO,EAKL,KAAK,aAAa,EACnB,MAAM,sBAAsB,CAAC;AAE9B,yFAAyF;AACzF,eAAO,MAAM,8BAA8B,QAI1C,CAAC;AAuBF;;;GAGG;AACH,wBAAsB,kBAAkB,CACtC,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,aAAa,CAAC,CAgBxB;AAED,sEAAsE;AACtE,wBAAgB,sBAAsB,IAAI,IAAI,CAE7C"}
@@ -0,0 +1,46 @@
1
+ import path from "node:path";
2
+ import { ensureAuthentication, loadEndpointBase, readStoredAuthKey, } from "optimus-tofu-staging";
3
+ /** Same path as log-llm-config: `~/opt-ai-sec/management/auth_key.txt` under `$HOME`. */
4
+ export const OPTIMUS_AUTH_KEY_RELATIVE_PATH = path.join("opt-ai-sec", "management", "auth_key.txt");
5
+ let cached = null;
6
+ async function postJsonForAuth(endpointUrl, body) {
7
+ const res = await fetch(endpointUrl, {
8
+ method: "POST",
9
+ headers: { "Content-Type": "application/json" },
10
+ body: JSON.stringify(body),
11
+ });
12
+ const text = await res.text();
13
+ if (!res.ok) {
14
+ throw new Error(`HTTP ${res.status}: ${text ? text.slice(0, 200) : res.statusText}`);
15
+ }
16
+ if (!text)
17
+ return { status: "error", error: "empty_response" };
18
+ return JSON.parse(text);
19
+ }
20
+ /**
21
+ * Same TOFU + machine key flow as log-llm-config: verify stored key against
22
+ * `/endpoint_security/auth/` or request a new key and persist under HOME.
23
+ */
24
+ export async function ensureToolCallAuth(hardwareUuid) {
25
+ const fromDisk = readStoredAuthKey({
26
+ authRelativePath: OPTIMUS_AUTH_KEY_RELATIVE_PATH,
27
+ });
28
+ if (!fromDisk?.key && cached?.hardwareUuid === hardwareUuid) {
29
+ cached = null;
30
+ }
31
+ if (cached?.hardwareUuid === hardwareUuid)
32
+ return cached.key;
33
+ const key = await ensureAuthentication({
34
+ hardwareUuid,
35
+ endpointBase: loadEndpointBase(),
36
+ authRelativePath: OPTIMUS_AUTH_KEY_RELATIVE_PATH,
37
+ postJson: postJsonForAuth,
38
+ });
39
+ cached = { hardwareUuid, key };
40
+ return key;
41
+ }
42
+ /** For tests: clear cached auth so HOME / env changes take effect. */
43
+ export function resetToolCallAuthCache() {
44
+ cached = null;
45
+ }
46
+ //# sourceMappingURL=machine-auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"machine-auth.js","sourceRoot":"","sources":["../../src/lib/machine-auth.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EACL,oBAAoB,EACpB,gBAAgB,EAChB,iBAAiB,GAGlB,MAAM,sBAAsB,CAAC;AAE9B,yFAAyF;AACzF,MAAM,CAAC,MAAM,8BAA8B,GAAG,IAAI,CAAC,IAAI,CACrD,YAAY,EACZ,YAAY,EACZ,cAAc,CACf,CAAC;AAEF,IAAI,MAAM,GAAwD,IAAI,CAAC;AAEvE,KAAK,UAAU,eAAe,CAC5B,WAAmB,EACnB,IAA6B;IAE7B,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,WAAW,EAAE;QACnC,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;QAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;KAC3B,CAAC,CAAC;IACH,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;IAC9B,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CACb,QAAQ,GAAG,CAAC,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,UAAU,EAAE,CACpE,CAAC;IACJ,CAAC;IACD,IAAI,CAAC,IAAI;QAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,gBAAgB,EAAE,CAAC;IAC/D,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAqB,CAAC;AAC9C,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,YAAoB;IAEpB,MAAM,QAAQ,GAAG,iBAAiB,CAAC;QACjC,gBAAgB,EAAE,8BAA8B;KACjD,CAAC,CAAC;IACH,IAAI,CAAC,QAAQ,EAAE,GAAG,IAAI,MAAM,EAAE,YAAY,KAAK,YAAY,EAAE,CAAC;QAC5D,MAAM,GAAG,IAAI,CAAC;IAChB,CAAC;IACD,IAAI,MAAM,EAAE,YAAY,KAAK,YAAY;QAAE,OAAO,MAAM,CAAC,GAAG,CAAC;IAC7D,MAAM,GAAG,GAAG,MAAM,oBAAoB,CAAC;QACrC,YAAY;QACZ,YAAY,EAAE,gBAAgB,EAAE;QAChC,gBAAgB,EAAE,8BAA8B;QAChD,QAAQ,EAAE,eAAe;KAC1B,CAAC,CAAC;IACH,MAAM,GAAG,EAAE,YAAY,EAAE,GAAG,EAAE,CAAC;IAC/B,OAAO,GAAG,CAAC;AACb,CAAC;AAED,sEAAsE;AACtE,MAAM,UAAU,sBAAsB;IACpC,MAAM,GAAG,IAAI,CAAC;AAChB,CAAC"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * POST `/endpoint_security/startup/` with `metadata.user_profile` so `EndpointMachine.user_profile`
3
+ * stays fresh even when `log_uuid` is throttled (e.g. customer hooks with existing auth_key.txt).
4
+ * Signs `payload` with the stored machine key when present (same as `log-llm-config` startup_sender)
5
+ * so the backend does not revoke keys on every unsigned sync.
6
+ *
7
+ * Throttled (default 30 min) on success to avoid an extra HTTP round-trip on every tool call.
8
+ * After failures (network, non-2xx, etc.), exponential backoff caps repeated work so hooks are
9
+ * not blocked on every batch. Override interval with `OPTIMUS_STARTUP_SYNC_INTERVAL_MS` (set to
10
+ * `0` to sync on every batch when healthy). Skip entirely with `OPTIMUS_SKIP_STARTUP_SYNC=1`.
11
+ */
12
+ export declare function ensureStartupMetadataSynced(hardwareUuid: string): Promise<void>;
13
+ //# sourceMappingURL=startup-sync.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"startup-sync.d.ts","sourceRoot":"","sources":["../../src/lib/startup-sync.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAuDH,wBAAsB,2BAA2B,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA4GrF"}
@@ -0,0 +1,147 @@
1
+ /**
2
+ * POST `/endpoint_security/startup/` with `metadata.user_profile` so `EndpointMachine.user_profile`
3
+ * stays fresh even when `log_uuid` is throttled (e.g. customer hooks with existing auth_key.txt).
4
+ * Signs `payload` with the stored machine key when present (same as `log-llm-config` startup_sender)
5
+ * so the backend does not revoke keys on every unsigned sync.
6
+ *
7
+ * Throttled (default 30 min) on success to avoid an extra HTTP round-trip on every tool call.
8
+ * After failures (network, non-2xx, etc.), exponential backoff caps repeated work so hooks are
9
+ * not blocked on every batch. Override interval with `OPTIMUS_STARTUP_SYNC_INTERVAL_MS` (set to
10
+ * `0` to sync on every batch when healthy). Skip entirely with `OPTIMUS_SKIP_STARTUP_SYNC=1`.
11
+ */
12
+ import { buildStartupEndpointUrl, createSignature, loadEndpointBase, persistAuthKey, readStoredAuthKey, } from "optimus-tofu-staging";
13
+ import { OPTIMUS_AUTH_KEY_RELATIVE_PATH, resetToolCallAuthCache } from "./machine-auth.js";
14
+ import { resolveUserProfile } from "./user-profile.js";
15
+ const emptyUserProfile = () => ({
16
+ generateduuid: "",
17
+ machineuuid: "",
18
+ mac_username: "",
19
+ github_username: "",
20
+ claude_email: "",
21
+ cursor_email: "",
22
+ });
23
+ const DEFAULT_STARTUP_SYNC_INTERVAL_MS = 1800000;
24
+ const STARTUP_SYNC_FAILURE_BACKOFF_BASE_MS = 5000;
25
+ const STARTUP_SYNC_FAILURE_BACKOFF_CAP_MS = 300000;
26
+ let lastStartupAttemptEndedMs = 0;
27
+ /** After a failed attempt, false until the next completed successful sync. */
28
+ let lastStartupAttemptOk = true;
29
+ let startupSyncFailureStreak = 0;
30
+ function recordStartupSyncAttemptEnd(ok) {
31
+ lastStartupAttemptEndedMs = Date.now();
32
+ lastStartupAttemptOk = ok;
33
+ if (ok) {
34
+ startupSyncFailureStreak = 0;
35
+ }
36
+ else {
37
+ startupSyncFailureStreak += 1;
38
+ }
39
+ }
40
+ function shouldSkipStartupSyncDueToCooldown(now, intervalMs) {
41
+ if (lastStartupAttemptEndedMs <= 0)
42
+ return false;
43
+ const failureBackoffMs = !lastStartupAttemptOk
44
+ ? Math.min(STARTUP_SYNC_FAILURE_BACKOFF_CAP_MS, STARTUP_SYNC_FAILURE_BACKOFF_BASE_MS *
45
+ 2 ** Math.min(Math.max(0, startupSyncFailureStreak - 1), 6))
46
+ : 0;
47
+ const successIntervalMs = lastStartupAttemptOk && intervalMs > 0 ? intervalMs : 0;
48
+ const cooldownMs = Math.max(failureBackoffMs, successIntervalMs);
49
+ return cooldownMs > 0 && now - lastStartupAttemptEndedMs < cooldownMs;
50
+ }
51
+ export async function ensureStartupMetadataSynced(hardwareUuid) {
52
+ if (process.env.OPTIMUS_SKIP_STARTUP_SYNC === "1")
53
+ return;
54
+ const rawInterval = process.env.OPTIMUS_STARTUP_SYNC_INTERVAL_MS;
55
+ let intervalMs = DEFAULT_STARTUP_SYNC_INTERVAL_MS;
56
+ if (rawInterval !== undefined && rawInterval !== "") {
57
+ const parsed = parseInt(rawInterval, 10);
58
+ intervalMs =
59
+ Number.isNaN(parsed) || parsed < 0 ? DEFAULT_STARTUP_SYNC_INTERVAL_MS : parsed;
60
+ }
61
+ const now = Date.now();
62
+ if (shouldSkipStartupSyncDueToCooldown(now, intervalMs)) {
63
+ return;
64
+ }
65
+ const timestamp = new Date().toISOString();
66
+ const payloadSummary = {
67
+ timestamp,
68
+ directory: process.cwd(),
69
+ hardware_uuid: hardwareUuid,
70
+ };
71
+ let user_profile;
72
+ try {
73
+ user_profile = { ...resolveUserProfile() };
74
+ }
75
+ catch (err) {
76
+ console.error(`[optimus-tool-call] resolveUserProfile failed; continuing startup sync with empty profile: ${err instanceof Error ? err.message : String(err)}`);
77
+ user_profile = emptyUserProfile();
78
+ }
79
+ const github_username = (typeof user_profile.github_username === "string" && user_profile.github_username.trim()) ||
80
+ process.env.GITHUB_USER ||
81
+ process.env.GH_USER ||
82
+ "";
83
+ const metadata = {
84
+ github_username,
85
+ org_identifier: process.env.GITHUB_ORG || "",
86
+ repo_identifier: process.env.GITHUB_REPOSITORY || "",
87
+ branch: process.env.GITHUB_REF_NAME || process.env.BRANCH_NAME || "",
88
+ commit_sha: process.env.GITHUB_SHA || "",
89
+ agent_name: process.env.OPTIMUS_AGENT || "",
90
+ user_profile,
91
+ };
92
+ const body = {
93
+ hardware_uuid: hardwareUuid,
94
+ payload: payloadSummary,
95
+ metadata,
96
+ scan_timestamp: timestamp,
97
+ };
98
+ const storedKey = readStoredAuthKey({
99
+ authRelativePath: OPTIMUS_AUTH_KEY_RELATIVE_PATH,
100
+ });
101
+ if (storedKey?.key && storedKey.hardware_uuid === hardwareUuid) {
102
+ body.signature = createSignature(payloadSummary, storedKey.key);
103
+ if (storedKey.key_id)
104
+ body.key_id = storedKey.key_id;
105
+ }
106
+ const url = buildStartupEndpointUrl(loadEndpointBase());
107
+ try {
108
+ const controller = new AbortController();
109
+ const timeoutId = setTimeout(() => controller.abort(), 5000);
110
+ let res;
111
+ try {
112
+ res = await fetch(url, {
113
+ method: "POST",
114
+ headers: { "Content-Type": "application/json" },
115
+ body: JSON.stringify(body),
116
+ signal: controller.signal,
117
+ });
118
+ }
119
+ finally {
120
+ clearTimeout(timeoutId);
121
+ }
122
+ const text = await res.text();
123
+ if (!res.ok) {
124
+ console.error(`[optimus-tool-call] startup metadata sync failed ${res.status}: ${text ? text.slice(0, 240) : res.statusText}`);
125
+ recordStartupSyncAttemptEnd(false);
126
+ return;
127
+ }
128
+ let parsed = {};
129
+ try {
130
+ parsed = JSON.parse(text);
131
+ }
132
+ catch {
133
+ recordStartupSyncAttemptEnd(false);
134
+ return;
135
+ }
136
+ if (parsed.status === "key_issued" && typeof parsed.key === "string") {
137
+ persistAuthKey(parsed.key, typeof parsed.key_id === "string" ? parsed.key_id : null, hardwareUuid, { authRelativePath: OPTIMUS_AUTH_KEY_RELATIVE_PATH });
138
+ resetToolCallAuthCache();
139
+ }
140
+ recordStartupSyncAttemptEnd(true);
141
+ }
142
+ catch (err) {
143
+ console.error(`[optimus-tool-call] startup metadata sync error: ${err instanceof Error ? err.message : String(err)}`);
144
+ recordStartupSyncAttemptEnd(false);
145
+ }
146
+ }
147
+ //# sourceMappingURL=startup-sync.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"startup-sync.js","sourceRoot":"","sources":["../../src/lib/startup-sync.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Telemetry streaming — batch and send events to Optimus backend.
3
+ */
4
+ import { TelemetryEvent } from "./telemetry.js";
5
+ /**
6
+ * Add an event to the queue and flush if needed.
7
+ */
8
+ export declare function queueEvent(event: TelemetryEvent): Promise<void>;
9
+ /**
10
+ * Flush all queued events to backend.
11
+ */
12
+ export declare function flushEvents(): Promise<void>;
13
+ /**
14
+ * Ensure all events are flushed on process exit.
15
+ * Uses beforeExit to allow async flush before process terminates.
16
+ */
17
+ export declare function ensureShutdown(): void;
18
+ //# sourceMappingURL=streaming.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"streaming.d.ts","sourceRoot":"","sources":["../../src/lib/streaming.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAiBhD;;GAEG;AACH,wBAAsB,UAAU,CAAC,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAoBrE;AAED;;GAEG;AACH,wBAAsB,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CAyBjD;AAiLD;;;GAGG;AACH,wBAAgB,cAAc,IAAI,IAAI,CA0BrC"}
@@ -0,0 +1,243 @@
1
+ /**
2
+ * Telemetry streaming — batch and send events to Optimus backend.
3
+ */
4
+ import { createSignature } from "optimus-tofu-staging";
5
+ import { ensureToolCallAuth } from "./machine-auth.js";
6
+ import { ensureStartupMetadataSynced } from "./startup-sync.js";
7
+ import { cloneToolCallMetadataForWire } from "./telemetry/wire-metadata.js";
8
+ import { loadEndpointBase } from "./endpoint-config.js";
9
+ import { tryResolveHardwareUuid } from "./hardware-uuid.js";
10
+ const DEBUG = !!process.env.OPTIMUS_DEBUG;
11
+ const dbg = (...args) => { if (DEBUG)
12
+ console.error(...args); };
13
+ // Backend configuration
14
+ const OPTIMUS_API_BASE = loadEndpointBase();
15
+ const BATCH_SIZE = parseInt(process.env.OPTIMUS_BATCH_SIZE || "1", 10); // Default to 1 for testing
16
+ const BATCH_TIMEOUT_MS = 5000; // 5 seconds
17
+ // In-memory event queue
18
+ let eventQueue = [];
19
+ let batchTimer = null;
20
+ /**
21
+ * Add an event to the queue and flush if needed.
22
+ */
23
+ export async function queueEvent(event) {
24
+ if (!event) {
25
+ return;
26
+ }
27
+ eventQueue.push(event);
28
+ // Flush immediately if batch size reached
29
+ if (eventQueue.length >= BATCH_SIZE) {
30
+ await flushEvents();
31
+ }
32
+ else if (!batchTimer) {
33
+ // Set timer for delayed flush if not already set
34
+ batchTimer = setTimeout(() => {
35
+ flushEvents().catch((err) => {
36
+ // Log but don't block
37
+ console.error("[optimus-tool-call] Failed to flush events:", err);
38
+ });
39
+ batchTimer = null;
40
+ }, BATCH_TIMEOUT_MS);
41
+ }
42
+ }
43
+ /**
44
+ * Flush all queued events to backend.
45
+ */
46
+ export async function flushEvents() {
47
+ if (eventQueue.length === 0) {
48
+ return;
49
+ }
50
+ // Clear timer
51
+ if (batchTimer) {
52
+ clearTimeout(batchTimer);
53
+ batchTimer = null;
54
+ }
55
+ const eventsToSend = eventQueue.splice(0, eventQueue.length);
56
+ try {
57
+ await sendBatch(eventsToSend);
58
+ }
59
+ catch (err) {
60
+ // Non-blocking: log error but don't throw
61
+ console.error(`[optimus-tool-call] Failed to send ${eventsToSend.length} events:`, err instanceof Error ? err.message : String(err));
62
+ // Optionally re-queue events on failure (for now, just drop)
63
+ // eventQueue.unshift(...eventsToSend);
64
+ }
65
+ }
66
+ /**
67
+ * Clone events for HTTP: drop metadata keys the backend recomputes (classification,
68
+ * MCP split, identity) so the client cannot spoof them.
69
+ */
70
+ function eventsWireFromTelemetry(events) {
71
+ return events.map((e) => {
72
+ const raw = JSON.parse(JSON.stringify(e));
73
+ const meta = raw.tool_call_metadata;
74
+ const cleaned = cloneToolCallMetadataForWire(meta);
75
+ if (cleaned !== undefined) {
76
+ raw.tool_call_metadata = cleaned;
77
+ }
78
+ return raw;
79
+ });
80
+ }
81
+ /**
82
+ * Send batch of events to Django backend.
83
+ */
84
+ async function sendBatch(events) {
85
+ if (events.length === 0) {
86
+ return;
87
+ }
88
+ dbg(`[optimus-tool-call] Sending ${events.length} events to backend...`);
89
+ dbg(`[optimus-tool-call] Event agents:`, events.map(e => e.agent_identity).join(", "));
90
+ const hardwareUuid = tryResolveHardwareUuid();
91
+ if (!hardwareUuid) {
92
+ const err = "Cannot send tool-call telemetry: set OPTIMUS_HARDWARE_UUID or run on a host with a hardware UUID.";
93
+ console.error(`[optimus-tool-call] ERROR: ${err}`);
94
+ throw new Error(err);
95
+ }
96
+ dbg(`[optimus-tool-call] Hardware UUID: ${hardwareUuid}`);
97
+ try {
98
+ await ensureStartupMetadataSynced(hardwareUuid);
99
+ dbg(`[optimus-tool-call] Startup metadata synced`);
100
+ }
101
+ catch (err) {
102
+ console.error(`[optimus-tool-call] ERROR syncing startup metadata:`, err);
103
+ throw err;
104
+ }
105
+ const eventsWire = eventsWireFromTelemetry(events);
106
+ dbg(`[optimus-tool-call] Events wire:`, JSON.stringify(eventsWire, null, 2).slice(0, 500));
107
+ const signingPayload = {
108
+ hardware_uuid: hardwareUuid,
109
+ events: eventsWire,
110
+ };
111
+ dbg(`[optimus-tool-call] Payload ready, signing...`);
112
+ const auth = await ensureToolCallAuth(hardwareUuid);
113
+ dbg(`[optimus-tool-call] Auth obtained, key_id: ${auth.key_id}`);
114
+ const signature = createSignature(signingPayload, auth.key);
115
+ const payload = {
116
+ ...signingPayload,
117
+ signature,
118
+ key_id: auth.key_id || "",
119
+ };
120
+ const endpoint = new URL("api/tool-calls/events/batch_create/", OPTIMUS_API_BASE).toString();
121
+ dbg(`[optimus-tool-call] Endpoint: ${endpoint}`);
122
+ dbg(`[optimus-tool-call] Payload size: ${JSON.stringify(payload).length} bytes`);
123
+ const headers = {
124
+ "Content-Type": "application/json",
125
+ };
126
+ try {
127
+ // Use fetch if available (Node 18+), fall back to node:http
128
+ if (typeof fetch !== "undefined") {
129
+ dbg(`[optimus-tool-call] Using fetch to send...`);
130
+ const controller = new AbortController();
131
+ const timeoutId = setTimeout(() => controller.abort(), 5000);
132
+ try {
133
+ const response = await fetch(endpoint, {
134
+ method: "POST",
135
+ headers,
136
+ body: JSON.stringify(payload),
137
+ signal: controller.signal,
138
+ });
139
+ dbg(`[optimus-tool-call] Response status: ${response.status} ${response.statusText}`);
140
+ if (!response.ok) {
141
+ const responseText = await response.text();
142
+ dbg(`[optimus-tool-call] Response body: ${responseText}`);
143
+ throw new Error(`HTTP ${response.status}: ${response.statusText} - ${responseText}`);
144
+ }
145
+ dbg(`[optimus-tool-call] ✅ Successfully sent ${events.length} events`);
146
+ }
147
+ finally {
148
+ clearTimeout(timeoutId);
149
+ }
150
+ }
151
+ else {
152
+ // Fallback for older Node versions
153
+ dbg(`[optimus-tool-call] Using http fallback...`);
154
+ await sendViaHttp(endpoint, headers, payload);
155
+ }
156
+ }
157
+ catch (err) {
158
+ const errorMsg = `Failed to send events to ${endpoint}: ${err instanceof Error ? err.message : String(err)}`;
159
+ console.error(`[optimus-tool-call] ❌ ${errorMsg}`);
160
+ throw new Error(errorMsg);
161
+ }
162
+ }
163
+ /**
164
+ * Fallback HTTP POST using node:http for older Node versions.
165
+ */
166
+ function sendViaHttp(endpoint, headers, payload) {
167
+ return new Promise((resolve, reject) => {
168
+ try {
169
+ const url = new URL(endpoint);
170
+ const protocol = url.protocol === "https:" ? require("https") : require("http");
171
+ const options = {
172
+ hostname: url.hostname,
173
+ port: url.port,
174
+ path: url.pathname + url.search,
175
+ method: "POST",
176
+ headers: {
177
+ ...headers,
178
+ "Content-Length": Buffer.byteLength(JSON.stringify(payload)),
179
+ },
180
+ timeout: 5000,
181
+ };
182
+ const req = protocol.request(options, (res) => {
183
+ let data = "";
184
+ res.on("data", (chunk) => {
185
+ data += chunk;
186
+ });
187
+ res.on("end", () => {
188
+ if (res.statusCode && res.statusCode >= 200 && res.statusCode < 300) {
189
+ resolve();
190
+ }
191
+ else {
192
+ reject(new Error(`HTTP ${res.statusCode}: ${res.statusMessage || "Unknown error"}`));
193
+ }
194
+ });
195
+ });
196
+ req.on("error", (err) => {
197
+ reject(err);
198
+ });
199
+ req.on("timeout", () => {
200
+ req.destroy();
201
+ reject(new Error("Request timeout"));
202
+ });
203
+ req.write(JSON.stringify(payload));
204
+ req.end();
205
+ }
206
+ catch (err) {
207
+ reject(err);
208
+ }
209
+ });
210
+ }
211
+ /**
212
+ * Ensure all events are flushed on process exit.
213
+ * Uses beforeExit to allow async flush before process terminates.
214
+ */
215
+ export function ensureShutdown() {
216
+ // beforeExit allows async operations, unlike exit
217
+ process.on("beforeExit", async () => {
218
+ if (eventQueue.length > 0) {
219
+ try {
220
+ await flushEvents();
221
+ }
222
+ catch (err) {
223
+ console.error("[optimus-tool-call] Failed to flush events on shutdown:", err);
224
+ }
225
+ }
226
+ });
227
+ // Also handle explicit termination signals
228
+ const signals = ["SIGTERM", "SIGINT"];
229
+ signals.forEach((sig) => {
230
+ process.on(sig, async () => {
231
+ if (eventQueue.length > 0) {
232
+ try {
233
+ await flushEvents();
234
+ }
235
+ catch (err) {
236
+ console.error(`[optimus-tool-call] Failed to flush events on ${sig}:`, err);
237
+ }
238
+ }
239
+ process.exit(0);
240
+ });
241
+ });
242
+ }
243
+ //# sourceMappingURL=streaming.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"streaming.js","sourceRoot":"","sources":["../../src/lib/streaming.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import type { TelemetryEvent, ToolInvocation } from "./types.js";
2
+ /**
3
+ * Build a telemetry event from a tool invocation.
4
+ *
5
+ * Sends raw hook fields only. Classification (`action_type`, `command_components`,
6
+ * paths, patterns, MCP split) is performed server-side in Django
7
+ * (`tool_call_audit.classification.enrich`).
8
+ */
9
+ export declare function buildTelemetryEvent(inv: ToolInvocation | null | undefined, agentIdentity?: string, sessionId?: string | null): TelemetryEvent | null;
10
+ //# sourceMappingURL=build-event.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build-event.d.ts","sourceRoot":"","sources":["../../../src/lib/telemetry/build-event.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjE;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CACjC,GAAG,EAAE,cAAc,GAAG,IAAI,GAAG,SAAS,EACtC,aAAa,GAAE,MAAkB,EACjC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,GACxB,cAAc,GAAG,IAAI,CA0BvB"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Build a telemetry event from a tool invocation.
3
+ *
4
+ * Sends raw hook fields only. Classification (`action_type`, `command_components`,
5
+ * paths, patterns, MCP split) is performed server-side in Django
6
+ * (`tool_call_audit.classification.enrich`).
7
+ */
8
+ export function buildTelemetryEvent(inv, agentIdentity = "unknown", sessionId) {
9
+ if (!inv) {
10
+ return null;
11
+ }
12
+ const toolName = inv.tool_name;
13
+ const toolNameNorm = typeof toolName === "string" ? toolName.trim() : "";
14
+ const normalizedToolInput = inv.tool_input || {};
15
+ const meta = {
16
+ tool_name: toolNameNorm || toolName,
17
+ tool_input: normalizedToolInput,
18
+ ...(inv.user_prompt ? { user_prompt: inv.user_prompt } : {}),
19
+ ...(inv.raw_event ? { raw_event: inv.raw_event } : {}),
20
+ };
21
+ return {
22
+ timestamp: new Date().toISOString(),
23
+ agent_identity: agentIdentity,
24
+ event_type: "tool_call",
25
+ session_id: sessionId,
26
+ tool_use_id: inv.tool_use_id || null,
27
+ hook_event_name: inv.hook_event_name || null,
28
+ working_directory: inv.cwd || null,
29
+ tool_call_metadata: meta,
30
+ };
31
+ }
32
+ //# sourceMappingURL=build-event.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build-event.js","sourceRoot":"","sources":["../../../src/lib/telemetry/build-event.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AACH,MAAM,UAAU,mBAAmB,CACjC,GAAsC,EACtC,gBAAwB,SAAS,EACjC,SAAyB;IAEzB,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,QAAQ,GAAG,GAAG,CAAC,SAAS,CAAC;IAC/B,MAAM,YAAY,GAAG,OAAO,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACzE,MAAM,mBAAmB,GAA4B,GAAG,CAAC,UAAU,IAAI,EAAE,CAAC;IAE1E,MAAM,IAAI,GAAyC;QACjD,SAAS,EAAE,YAAY,IAAI,QAAQ;QACnC,UAAU,EAAE,mBAAmB;QAC/B,GAAG,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC5D,GAAG,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,GAAG,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACvD,CAAC;IAEF,OAAO;QACL,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACnC,cAAc,EAAE,aAAa;QAC7B,UAAU,EAAE,WAAW;QACvB,UAAU,EAAE,SAAS;QACrB,WAAW,EAAE,GAAG,CAAC,WAAW,IAAI,IAAI;QACpC,eAAe,EAAE,GAAG,CAAC,eAAe,IAAI,IAAI;QAC5C,iBAAiB,EAAE,GAAG,CAAC,GAAG,IAAI,IAAI;QAClC,kBAAkB,EAAE,IAAI;KACzB,CAAC;AACJ,CAAC"}