feat: Android companion app improvements & gateway URL camera payloads (#13541)

Merged via /review-pr -> /prepare-pr -> /merge-pr.

Prepared head SHA: 9c179c9c31
Co-authored-by: smartprogrammer93 <33181301+smartprogrammer93@users.noreply.github.com>
Co-authored-by: steipete <58493+steipete@users.noreply.github.com>
Reviewed-by: @steipete
This commit is contained in:
Ahmad Bitar
2026-02-13 23:49:28 +08:00
committed by GitHub
parent 41f2f359a5
commit c179f71f42
38 changed files with 2158 additions and 748 deletions

View File

@@ -1,5 +1,5 @@
import type { ChildProcessWithoutNullStreams } from "node:child_process";
import { beforeEach, describe, expect, it } from "vitest";
import { beforeEach, describe, expect, it, vi } from "vitest";
import type { ProcessSession } from "./bash-process-registry.js";
import {
addSession,
@@ -20,7 +20,7 @@ describe("bash process registry", () => {
const session: ProcessSession = {
id: "sess",
command: "echo test",
child: { pid: 123 } as ChildProcessWithoutNullStreams,
child: { pid: 123, removeAllListeners: vi.fn() } as ChildProcessWithoutNullStreams,
startedAt: Date.now(),
cwd: "/tmp",
maxOutputChars: 10,
@@ -51,7 +51,7 @@ describe("bash process registry", () => {
const session: ProcessSession = {
id: "sess",
command: "echo test",
child: { pid: 123 } as ChildProcessWithoutNullStreams,
child: { pid: 123, removeAllListeners: vi.fn() } as ChildProcessWithoutNullStreams,
startedAt: Date.now(),
cwd: "/tmp",
maxOutputChars: 100_000,
@@ -85,7 +85,7 @@ describe("bash process registry", () => {
const session: ProcessSession = {
id: "sess",
command: "echo test",
child: { pid: 123 } as ChildProcessWithoutNullStreams,
child: { pid: 123, removeAllListeners: vi.fn() } as ChildProcessWithoutNullStreams,
startedAt: Date.now(),
cwd: "/tmp",
maxOutputChars: 5_000,
@@ -116,7 +116,7 @@ describe("bash process registry", () => {
const session: ProcessSession = {
id: "sess",
command: "echo test",
child: { pid: 123 } as ChildProcessWithoutNullStreams,
child: { pid: 123, removeAllListeners: vi.fn() } as ChildProcessWithoutNullStreams,
startedAt: Date.now(),
cwd: "/tmp",
maxOutputChars: 100,
@@ -150,7 +150,7 @@ describe("bash process registry", () => {
const session: ProcessSession = {
id: "sess",
command: "echo test",
child: { pid: 123 } as ChildProcessWithoutNullStreams,
child: { pid: 123, removeAllListeners: vi.fn() } as ChildProcessWithoutNullStreams,
startedAt: Date.now(),
cwd: "/tmp",
maxOutputChars: 100,

View File

@@ -168,7 +168,7 @@ function moveToFinished(session: ProcessSession, status: ProcessStatus) {
session.child.stderr?.destroy?.();
// Remove all event listeners to prevent memory leaks
session.child.removeAllListeners?.();
session.child.removeAllListeners();
// Clear the reference
delete session.child;

View File

@@ -8,6 +8,7 @@ import {
parseCameraClipPayload,
parseCameraSnapPayload,
writeBase64ToFile,
writeUrlToFile,
} from "../../cli/nodes-camera.js";
import { parseEnvPairs, parseTimeoutMs } from "../../cli/nodes-run.js";
import {
@@ -230,14 +231,20 @@ export function createNodesTool(options?: {
facing,
ext: isJpeg ? "jpg" : "png",
});
await writeBase64ToFile(filePath, payload.base64);
if (payload.url) {
await writeUrlToFile(filePath, payload.url);
} else if (payload.base64) {
await writeBase64ToFile(filePath, payload.base64);
}
content.push({ type: "text", text: `MEDIA:${filePath}` });
content.push({
type: "image",
data: payload.base64,
mimeType:
imageMimeFromFormat(payload.format) ?? (isJpeg ? "image/jpeg" : "image/png"),
});
if (payload.base64) {
content.push({
type: "image",
data: payload.base64,
mimeType:
imageMimeFromFormat(payload.format) ?? (isJpeg ? "image/jpeg" : "image/png"),
});
}
details.push({
facing,
path: filePath,
@@ -300,7 +307,11 @@ export function createNodesTool(options?: {
facing,
ext: payload.format,
});
await writeBase64ToFile(filePath, payload.base64);
if (payload.url) {
await writeUrlToFile(filePath, payload.url);
} else if (payload.base64) {
await writeBase64ToFile(filePath, payload.base64);
}
return {
content: [{ type: "text", text: `FILE:${filePath}` }],
details: {