diff --git a/apps/web/src/app/dashboard/agents/[id]/page.tsx b/apps/web/src/app/dashboard/agents/[id]/page.tsx
index 9d49904..3efb612 100644
--- a/apps/web/src/app/dashboard/agents/[id]/page.tsx
+++ b/apps/web/src/app/dashboard/agents/[id]/page.tsx
@@ -1029,14 +1029,26 @@ export default function AgentDetailPage(): React.ReactElement {
{
+ onChange={async (newEnvVars) => {
setEnvVars(newEnvVars);
- // Auto-save env vars
- fetch(`/api/agents/${agentId}`, {
- method: 'PATCH',
- headers: { 'Content-Type': 'application/json' },
- body: JSON.stringify({ envVars: newEnvVars }),
- });
+ // Auto-save env vars with error handling
+ try {
+ const response = await fetch(`/api/agents/${agentId}`, {
+ method: 'PATCH',
+ headers: { 'Content-Type': 'application/json' },
+ body: JSON.stringify({ envVars: newEnvVars }),
+ });
+ const result = await response.json();
+ if (!result.success) {
+ console.error('Failed to save env vars:', result.error);
+ alert(
+ 'Failed to save environment variables: ' + (result.error || 'Unknown error')
+ );
+ }
+ } catch (err) {
+ console.error('Failed to save env vars:', err);
+ alert('Failed to save environment variables. Please try again.');
+ }
}}
title="Environment Variables"
description="Passed to tools at runtime. Agent vars override collection vars. Changes are saved automatically."
diff --git a/packages/tools/official/sprites-exec/package.json b/packages/tools/official/sprites-exec/package.json
index 2628486..ccc204c 100644
--- a/packages/tools/official/sprites-exec/package.json
+++ b/packages/tools/official/sprites-exec/package.json
@@ -1,6 +1,6 @@
{
"name": "@tpmjs/tools-sprites-exec",
- "version": "0.1.3",
+ "version": "0.1.4",
"description": "Execute a command inside a sprite and return the output with exit code",
"type": "module",
"keywords": [
diff --git a/packages/tools/official/sprites-exec/src/index.ts b/packages/tools/official/sprites-exec/src/index.ts
index 08208d9..2550790 100644
--- a/packages/tools/official/sprites-exec/src/index.ts
+++ b/packages/tools/official/sprites-exec/src/index.ts
@@ -254,9 +254,30 @@ export const spritesExecTool = tool({
);
}
- // Parse binary response
+ // Parse response - handle both binary and JSON error responses
const arrayBuffer = await response.arrayBuffer();
const buffer = new Uint8Array(arrayBuffer);
+
+ // Check if response is JSON error (starts with '{') instead of binary (starts with 0x00-0x03)
+ // Sprites API returns HTTP 200 with JSON body for some errors like auth failures
+ if (buffer.length > 0 && buffer[0] === 0x7b) {
+ // 0x7B = '{'
+ const decoder = new TextDecoder();
+ const jsonText = decoder.decode(buffer);
+ try {
+ const errorResponse = JSON.parse(jsonText) as { error?: string };
+ if (errorResponse.error) {
+ throw new Error(`Failed to execute command in sprite "${name}": ${errorResponse.error}`);
+ }
+ } catch (parseError) {
+ // If JSON parsing fails, throw generic error with raw text
+ if (parseError instanceof SyntaxError) {
+ throw new Error(`Failed to execute command in sprite "${name}": ${jsonText}`);
+ }
+ throw parseError;
+ }
+ }
+
const { stdout, stderr, exitCode } = parseBinaryResponse(buffer);
return {