fix(frontend): make reading input_schema way more defensive (#10318)

## Changes 🏗️

<img width="800" alt="Screenshot 2025-07-07 at 22 24 07"
src="https://github.com/user-attachments/assets/72551f58-e41d-4a67-839b-98f63c6aad6b"
/>

Looking at the generated types, it looks like `input_schema` for the
agent can be anything:
-
[libraryAgent](https://github.com/Significant-Gravitas/AutoGPT/blob/dev/autogpt_platform/frontend/src/app/api/__generated__/models/libraryAgent.ts#L18-L38)
-
[libraryAgentInputSchema](https://github.com/Significant-Gravitas/AutoGPT/blob/dev/autogpt_platform/frontend/src/app/api/__generated__/models/libraryAgentInputSchema.ts#L9)

But the Front-end is reading it optimistically through the hardcoded
types on Backend API:

-
[GraphIOSchema](443995d79a/autogpt_platform/frontend/src/lib/autogpt-server-api/types.ts (L324-L329))

## Checklist 📋

### For code changes:
- [x] I have clearly listed my changes in the PR description
- [x] I have made a test plan
- [x] I have tested my changes according to the test plan:
  - [x] Login
  - [x] Open agents in library
  - [x] The page does not break  

### For configuration changes:

No configuration changes.
This commit is contained in:
Ubbe
2025-07-07 22:43:55 +04:00
committed by GitHub
parent 07461a88cf
commit 189c353c59
4 changed files with 33 additions and 34 deletions

View File

@@ -1,23 +1,23 @@
"use client";
import SmartImage from "@/components/agptui/SmartImage";
import { useOnboarding } from "@/components/onboarding/onboarding-provider";
import OnboardingButton from "@/components/onboarding/OnboardingButton";
import {
OnboardingStep,
OnboardingHeader,
OnboardingStep,
} from "@/components/onboarding/OnboardingStep";
import { OnboardingText } from "@/components/onboarding/OnboardingText";
import StarRating from "@/components/onboarding/StarRating";
import { Play } from "lucide-react";
import { cn } from "@/lib/utils";
import { useCallback, useEffect, useState } from "react";
import { GraphMeta, StoreAgentDetails } from "@/lib/autogpt-server-api";
import { useBackendAPI } from "@/lib/autogpt-server-api/context";
import { useRouter } from "next/navigation";
import { useOnboarding } from "@/components/onboarding/onboarding-provider";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import SchemaTooltip from "@/components/SchemaTooltip";
import { TypeBasedInput } from "@/components/type-based-input";
import SmartImage from "@/components/agptui/SmartImage";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { useToast } from "@/components/ui/use-toast";
import { GraphMeta, StoreAgentDetails } from "@/lib/autogpt-server-api";
import { useBackendAPI } from "@/lib/autogpt-server-api/context";
import { cn } from "@/lib/utils";
import { Play } from "lucide-react";
import { useRouter } from "next/navigation";
import { useCallback, useEffect, useState } from "react";
export default function Page() {
const { state, updateState, setStep } = useOnboarding(
@@ -52,7 +52,7 @@ export default function Page() {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const update: { [key: string]: any } = {};
// Set default values from schema
Object.entries(agent.input_schema.properties).forEach(
Object.entries(agent.input_schema?.properties || {}).forEach(
([key, value]) => {
// Skip if already set
if (state.agentInput && state.agentInput[key]) {
@@ -224,7 +224,7 @@ export default function Page() {
<CardTitle className="font-poppins text-lg">Input</CardTitle>
</CardHeader>
<CardContent className="flex flex-col gap-4">
{Object.entries(agent?.input_schema.properties || {}).map(
{Object.entries(agent?.input_schema?.properties || {}).map(
([key, inputSubSchema]) => (
<div key={key} className="flex flex-col space-y-2">
<label className="flex items-center gap-1 text-sm font-medium">

View File

@@ -1,9 +1,8 @@
"use client";
import React, { useCallback, useMemo } from "react";
import { isEmpty } from "lodash";
import moment from "moment";
import React, { useCallback, useMemo } from "react";
import { useBackendAPI } from "@/lib/autogpt-server-api/context";
import {
Graph,
GraphExecution,
@@ -11,14 +10,15 @@ import {
GraphExecutionMeta,
LibraryAgent,
} from "@/lib/autogpt-server-api";
import { useBackendAPI } from "@/lib/autogpt-server-api/context";
import ActionButtonGroup from "@/components/agptui/action-button-group";
import type { ButtonAction } from "@/components/agptui/types";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { IconRefresh, IconSquare } from "@/components/ui/icons";
import { useToastOnFail } from "@/components/ui/use-toast";
import ActionButtonGroup from "@/components/agptui/action-button-group";
import LoadingBox from "@/components/ui/loading";
import { Input } from "@/components/ui/input";
import LoadingBox from "@/components/ui/loading";
import { useToastOnFail } from "@/components/ui/use-toast";
import {
AgentRunStatus,
@@ -199,7 +199,7 @@ export default function AgentRunDetailsView({
stopRun,
deleteRun,
graph.has_webhook_trigger,
graph.credentials_input_schema.properties,
graph.credentials_input_schema?.properties,
agent.can_access_graph,
run.graph_id,
run.graph_version,

View File

@@ -1,7 +1,6 @@
"use client";
import React, { useCallback, useEffect, useMemo, useState } from "react";
import { useBackendAPI } from "@/lib/autogpt-server-api/context";
import {
CredentialsMetaInput,
GraphExecutionID,
@@ -11,21 +10,21 @@ import {
LibraryAgentPresetUpdatable,
Schedule,
} from "@/lib/autogpt-server-api";
import { useBackendAPI } from "@/lib/autogpt-server-api/context";
import ActionButtonGroup from "@/components/agptui/action-button-group";
import type { ButtonAction } from "@/components/agptui/types";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { IconCross, IconPlay, IconSave } from "@/components/ui/icons";
import { CalendarClockIcon, Trash2Icon } from "lucide-react";
import { CronSchedulerDialog } from "@/components/cron-scheduler-dialog";
import { CredentialsInput } from "@/components/integrations/credentials-input";
import { TypeBasedInput } from "@/components/type-based-input";
import { useToastOnFail } from "@/components/ui/use-toast";
import ActionButtonGroup from "@/components/agptui/action-button-group";
import { useOnboarding } from "@/components/onboarding/onboarding-provider";
import SchemaTooltip from "@/components/SchemaTooltip";
import { useToast } from "@/components/ui/use-toast";
import { isEmpty } from "lodash";
import { TypeBasedInput } from "@/components/type-based-input";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { IconCross, IconPlay, IconSave } from "@/components/ui/icons";
import { Input } from "@/components/ui/input";
import { useToast, useToastOnFail } from "@/components/ui/use-toast";
import { isEmpty } from "lodash";
import { CalendarClockIcon, Trash2Icon } from "lucide-react";
export default function AgentRunDraftView({
agent,
@@ -98,7 +97,7 @@ export default function AgentRunDraftView({
[agentInputSchema],
);
const agentCredentialsInputFields = useMemo(
() => agent.credentials_input_schema.properties,
() => agent.credentials_input_schema?.properties,
[agent],
);

View File

@@ -9,16 +9,16 @@ import {
} from "@/lib/autogpt-server-api";
import { useBackendAPI } from "@/lib/autogpt-server-api/context";
import { AgentRunStatus } from "@/components/agents/agent-run-status-chip";
import ActionButtonGroup from "@/components/agptui/action-button-group";
import type { ButtonAction } from "@/components/agptui/types";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { humanizeCronExpression } from "@/lib/cron-expression-utils";
import { AgentRunStatus } from "@/components/agents/agent-run-status-chip";
import { useToastOnFail } from "@/components/ui/use-toast";
import ActionButtonGroup from "@/components/agptui/action-button-group";
import { IconCross } from "@/components/ui/icons";
import { PlayIcon } from "lucide-react";
import LoadingBox from "@/components/ui/loading";
import { Input } from "@/components/ui/input";
import LoadingBox from "@/components/ui/loading";
import { useToastOnFail } from "@/components/ui/use-toast";
import { humanizeCronExpression } from "@/lib/cron-expression-utils";
import { PlayIcon } from "lucide-react";
export default function AgentScheduleDetailsView({
graph,