mirror of
https://github.com/farcasclaudiu/openclaw.git
synced 2026-06-29 11:02:12 +03:00
refactor(process): share stdin/session guards
This commit is contained in:
@@ -143,6 +143,46 @@ export function createProcessTool(
|
|||||||
const scopedSession = isInScope(session) ? session : undefined;
|
const scopedSession = isInScope(session) ? session : undefined;
|
||||||
const scopedFinished = isInScope(finished) ? finished : undefined;
|
const scopedFinished = isInScope(finished) ? finished : undefined;
|
||||||
|
|
||||||
|
const failedResult = (text: string) => ({
|
||||||
|
content: [{ type: "text", text }],
|
||||||
|
details: { status: "failed" },
|
||||||
|
});
|
||||||
|
|
||||||
|
const resolveBackgroundedWritableStdin = () => {
|
||||||
|
if (!scopedSession) {
|
||||||
|
return {
|
||||||
|
ok: false as const,
|
||||||
|
result: failedResult(`No active session found for ${params.sessionId}`),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (!scopedSession.backgrounded) {
|
||||||
|
return {
|
||||||
|
ok: false as const,
|
||||||
|
result: failedResult(`Session ${params.sessionId} is not backgrounded.`),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
const stdin = scopedSession.stdin ?? scopedSession.child?.stdin;
|
||||||
|
if (!stdin || stdin.destroyed) {
|
||||||
|
return {
|
||||||
|
ok: false as const,
|
||||||
|
result: failedResult(`Session ${params.sessionId} stdin is not writable.`),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return { ok: true as const, session: scopedSession, stdin };
|
||||||
|
};
|
||||||
|
|
||||||
|
const writeToStdin = async (stdin: NodeJS.WritableStream, data: string) => {
|
||||||
|
await new Promise<void>((resolve, reject) => {
|
||||||
|
stdin.write(data, (err) => {
|
||||||
|
if (err) {
|
||||||
|
reject(err);
|
||||||
|
} else {
|
||||||
|
resolve();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
switch (params.action) {
|
switch (params.action) {
|
||||||
case "poll": {
|
case "poll": {
|
||||||
if (!scopedSession) {
|
if (!scopedSession) {
|
||||||
@@ -300,51 +340,13 @@ export function createProcessTool(
|
|||||||
}
|
}
|
||||||
|
|
||||||
case "write": {
|
case "write": {
|
||||||
if (!scopedSession) {
|
const resolved = resolveBackgroundedWritableStdin();
|
||||||
return {
|
if (!resolved.ok) {
|
||||||
content: [
|
return resolved.result;
|
||||||
{
|
|
||||||
type: "text",
|
|
||||||
text: `No active session found for ${params.sessionId}`,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
details: { status: "failed" },
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
if (!scopedSession.backgrounded) {
|
await writeToStdin(resolved.stdin, params.data ?? "");
|
||||||
return {
|
|
||||||
content: [
|
|
||||||
{
|
|
||||||
type: "text",
|
|
||||||
text: `Session ${params.sessionId} is not backgrounded.`,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
details: { status: "failed" },
|
|
||||||
};
|
|
||||||
}
|
|
||||||
const stdin = scopedSession.stdin ?? scopedSession.child?.stdin;
|
|
||||||
if (!stdin || stdin.destroyed) {
|
|
||||||
return {
|
|
||||||
content: [
|
|
||||||
{
|
|
||||||
type: "text",
|
|
||||||
text: `Session ${params.sessionId} stdin is not writable.`,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
details: { status: "failed" },
|
|
||||||
};
|
|
||||||
}
|
|
||||||
await new Promise<void>((resolve, reject) => {
|
|
||||||
stdin.write(params.data ?? "", (err) => {
|
|
||||||
if (err) {
|
|
||||||
reject(err);
|
|
||||||
} else {
|
|
||||||
resolve();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
if (params.eof) {
|
if (params.eof) {
|
||||||
stdin.end();
|
resolved.stdin.end();
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
content: [
|
content: [
|
||||||
@@ -358,45 +360,15 @@ export function createProcessTool(
|
|||||||
details: {
|
details: {
|
||||||
status: "running",
|
status: "running",
|
||||||
sessionId: params.sessionId,
|
sessionId: params.sessionId,
|
||||||
name: scopedSession ? deriveSessionName(scopedSession.command) : undefined,
|
name: deriveSessionName(resolved.session.command),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
case "send-keys": {
|
case "send-keys": {
|
||||||
if (!scopedSession) {
|
const resolved = resolveBackgroundedWritableStdin();
|
||||||
return {
|
if (!resolved.ok) {
|
||||||
content: [
|
return resolved.result;
|
||||||
{
|
|
||||||
type: "text",
|
|
||||||
text: `No active session found for ${params.sessionId}`,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
details: { status: "failed" },
|
|
||||||
};
|
|
||||||
}
|
|
||||||
if (!scopedSession.backgrounded) {
|
|
||||||
return {
|
|
||||||
content: [
|
|
||||||
{
|
|
||||||
type: "text",
|
|
||||||
text: `Session ${params.sessionId} is not backgrounded.`,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
details: { status: "failed" },
|
|
||||||
};
|
|
||||||
}
|
|
||||||
const stdin = scopedSession.stdin ?? scopedSession.child?.stdin;
|
|
||||||
if (!stdin || stdin.destroyed) {
|
|
||||||
return {
|
|
||||||
content: [
|
|
||||||
{
|
|
||||||
type: "text",
|
|
||||||
text: `Session ${params.sessionId} stdin is not writable.`,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
details: { status: "failed" },
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
const { data, warnings } = encodeKeySequence({
|
const { data, warnings } = encodeKeySequence({
|
||||||
keys: params.keys,
|
keys: params.keys,
|
||||||
@@ -414,15 +386,7 @@ export function createProcessTool(
|
|||||||
details: { status: "failed" },
|
details: { status: "failed" },
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
await new Promise<void>((resolve, reject) => {
|
await writeToStdin(resolved.stdin, data);
|
||||||
stdin.write(data, (err) => {
|
|
||||||
if (err) {
|
|
||||||
reject(err);
|
|
||||||
} else {
|
|
||||||
resolve();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
return {
|
return {
|
||||||
content: [
|
content: [
|
||||||
{
|
{
|
||||||
@@ -435,55 +399,17 @@ export function createProcessTool(
|
|||||||
details: {
|
details: {
|
||||||
status: "running",
|
status: "running",
|
||||||
sessionId: params.sessionId,
|
sessionId: params.sessionId,
|
||||||
name: scopedSession ? deriveSessionName(scopedSession.command) : undefined,
|
name: deriveSessionName(resolved.session.command),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
case "submit": {
|
case "submit": {
|
||||||
if (!scopedSession) {
|
const resolved = resolveBackgroundedWritableStdin();
|
||||||
return {
|
if (!resolved.ok) {
|
||||||
content: [
|
return resolved.result;
|
||||||
{
|
|
||||||
type: "text",
|
|
||||||
text: `No active session found for ${params.sessionId}`,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
details: { status: "failed" },
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
if (!scopedSession.backgrounded) {
|
await writeToStdin(resolved.stdin, "\r");
|
||||||
return {
|
|
||||||
content: [
|
|
||||||
{
|
|
||||||
type: "text",
|
|
||||||
text: `Session ${params.sessionId} is not backgrounded.`,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
details: { status: "failed" },
|
|
||||||
};
|
|
||||||
}
|
|
||||||
const stdin = scopedSession.stdin ?? scopedSession.child?.stdin;
|
|
||||||
if (!stdin || stdin.destroyed) {
|
|
||||||
return {
|
|
||||||
content: [
|
|
||||||
{
|
|
||||||
type: "text",
|
|
||||||
text: `Session ${params.sessionId} stdin is not writable.`,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
details: { status: "failed" },
|
|
||||||
};
|
|
||||||
}
|
|
||||||
await new Promise<void>((resolve, reject) => {
|
|
||||||
stdin.write("\r", (err) => {
|
|
||||||
if (err) {
|
|
||||||
reject(err);
|
|
||||||
} else {
|
|
||||||
resolve();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
return {
|
return {
|
||||||
content: [
|
content: [
|
||||||
{
|
{
|
||||||
@@ -494,45 +420,15 @@ export function createProcessTool(
|
|||||||
details: {
|
details: {
|
||||||
status: "running",
|
status: "running",
|
||||||
sessionId: params.sessionId,
|
sessionId: params.sessionId,
|
||||||
name: scopedSession ? deriveSessionName(scopedSession.command) : undefined,
|
name: deriveSessionName(resolved.session.command),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
case "paste": {
|
case "paste": {
|
||||||
if (!scopedSession) {
|
const resolved = resolveBackgroundedWritableStdin();
|
||||||
return {
|
if (!resolved.ok) {
|
||||||
content: [
|
return resolved.result;
|
||||||
{
|
|
||||||
type: "text",
|
|
||||||
text: `No active session found for ${params.sessionId}`,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
details: { status: "failed" },
|
|
||||||
};
|
|
||||||
}
|
|
||||||
if (!scopedSession.backgrounded) {
|
|
||||||
return {
|
|
||||||
content: [
|
|
||||||
{
|
|
||||||
type: "text",
|
|
||||||
text: `Session ${params.sessionId} is not backgrounded.`,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
details: { status: "failed" },
|
|
||||||
};
|
|
||||||
}
|
|
||||||
const stdin = scopedSession.stdin ?? scopedSession.child?.stdin;
|
|
||||||
if (!stdin || stdin.destroyed) {
|
|
||||||
return {
|
|
||||||
content: [
|
|
||||||
{
|
|
||||||
type: "text",
|
|
||||||
text: `Session ${params.sessionId} stdin is not writable.`,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
details: { status: "failed" },
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
const payload = encodePaste(params.text ?? "", params.bracketed !== false);
|
const payload = encodePaste(params.text ?? "", params.bracketed !== false);
|
||||||
if (!payload) {
|
if (!payload) {
|
||||||
@@ -546,15 +442,7 @@ export function createProcessTool(
|
|||||||
details: { status: "failed" },
|
details: { status: "failed" },
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
await new Promise<void>((resolve, reject) => {
|
await writeToStdin(resolved.stdin, payload);
|
||||||
stdin.write(payload, (err) => {
|
|
||||||
if (err) {
|
|
||||||
reject(err);
|
|
||||||
} else {
|
|
||||||
resolve();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
return {
|
return {
|
||||||
content: [
|
content: [
|
||||||
{
|
{
|
||||||
@@ -565,7 +453,7 @@ export function createProcessTool(
|
|||||||
details: {
|
details: {
|
||||||
status: "running",
|
status: "running",
|
||||||
sessionId: params.sessionId,
|
sessionId: params.sessionId,
|
||||||
name: scopedSession ? deriveSessionName(scopedSession.command) : undefined,
|
name: deriveSessionName(resolved.session.command),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user