Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/zamilmajdy/revert-converted-func…
Browse files Browse the repository at this point in the history
…tion-to-async' into zamilmajdy/revert-converted-function-to-async
  • Loading branch information
majdyz committed Nov 21, 2024
2 parents 04e1362 + e26923f commit a8ed0d0
Show file tree
Hide file tree
Showing 23 changed files with 502 additions and 76 deletions.
4 changes: 4 additions & 0 deletions .github/workflows/platform-frontend-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,10 @@ jobs:
run: |
cp ../supabase/docker/.env.example ../.env
- name: Copy backend .env
run: |
cp ../backend/.env.example ../backend/.env
- name: Run docker compose
run: |
docker compose -f ../docker-compose.yml up -d
Expand Down
6 changes: 2 additions & 4 deletions autogpt_platform/backend/backend/data/graph.py
Original file line number Diff line number Diff line change
Expand Up @@ -547,16 +547,14 @@ async def fix_llm_provider_credentials():

broken_nodes = await prisma.get_client().query_raw(
"""
SELECT "User".id user_id,
SELECT graph."userId" user_id,
node.id node_id,
node."constantInput" node_preset_input
FROM platform."AgentNode" node
LEFT JOIN platform."AgentGraph" graph
ON node."agentGraphId" = graph.id
LEFT JOIN platform."User" "User"
ON graph."userId" = "User".id
WHERE node."constantInput"::jsonb->'credentials'->>'provider' = 'llm'
ORDER BY user_id;
ORDER BY graph."userId";
"""
)
logger.info(f"Fixing LLM credential inputs on {len(broken_nodes)} nodes")
Expand Down
2 changes: 2 additions & 0 deletions autogpt_platform/backend/backend/util/request.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

# List of IP networks to block
BLOCKED_IP_NETWORKS = [
# --8<-- [start:BLOCKED_IP_NETWORKS]
ipaddress.ip_network("0.0.0.0/8"), # "This" Network
ipaddress.ip_network("10.0.0.0/8"), # Private-Use
ipaddress.ip_network("127.0.0.0/8"), # Loopback
Expand All @@ -17,6 +18,7 @@
ipaddress.ip_network("192.168.0.0/16"), # Private-Use
ipaddress.ip_network("224.0.0.0/4"), # Multicast
ipaddress.ip_network("240.0.0.0/4"), # Reserved for Future Use
# --8<-- [end:BLOCKED_IP_NETWORKS]
]


Expand Down
1 change: 1 addition & 0 deletions autogpt_platform/frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
"defaults"
],
"dependencies": {
"@faker-js/faker": "^9.2.0",
"@hookform/resolvers": "^3.9.1",
"@next/third-parties": "^15.0.3",
"@radix-ui/react-avatar": "^1.1.1",
Expand Down
8 changes: 4 additions & 4 deletions autogpt_platform/frontend/playwright.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ import { defineConfig, devices } from "@playwright/test";
* Read environment variables from file.
* https://github.com/motdotla/dotenv
*/
// import dotenv from 'dotenv';
// import path from 'path';
// dotenv.config({ path: path.resolve(__dirname, '.env') });

import dotenv from "dotenv";
import path from "path";
dotenv.config({ path: path.resolve(__dirname, ".env") });
dotenv.config({ path: path.resolve(__dirname, "../backend/.env") });
/**
* See https://playwright.dev/docs/test-configuration.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,6 @@ const RunnerUIWrapper = forwardRef<RunnerUIWrapperRef, RunnerUIWrapperProps>(
const outputs = outputBlocks.map((node) => ({
id: node.id,
type: "output" as const,
outputSchema: node.data.outputSchema as BlockIORootSchema,
hardcodedValues: {
name: (node.data.hardcodedValues as any).name || "Output",
description:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
PopoverContent,
PopoverTrigger,
} from "@/components/ui/popover";
import { Block, BlockUIType } from "@/lib/autogpt-server-api";
import { Block, BlockUIType, SpecialBlockID } from "@/lib/autogpt-server-api";
import { MagnifyingGlassIcon, PlusIcon } from "@radix-ui/react-icons";
import { IconToyBrick } from "@/components/ui/icons";
import { getPrimaryCategoryColor } from "@/lib/utils";
Expand Down Expand Up @@ -57,7 +57,7 @@ export const BlocksControl: React.FC<BlocksControlProps> = ({
const agentList = flows.map(
(flow) =>
({
id: "e189baac-8c20-45a1-94a7-55177ea42565", // TODO: fetch this programmatically.
id: SpecialBlockID.AGENT,
name: flow.name,
description:
`Ver.${flow.version}` +
Expand Down
174 changes: 125 additions & 49 deletions autogpt_platform/frontend/src/components/monitor/FlowRunInfo.tsx
Original file line number Diff line number Diff line change
@@ -1,79 +1,155 @@
import React, { useCallback } from "react";
import AutoGPTServerAPI, { GraphMeta } from "@/lib/autogpt-server-api";
import React, { useCallback, useEffect, useMemo, useState } from "react";
import AutoGPTServerAPI, {
BlockIORootSchema,
Graph,
GraphMeta,
NodeExecutionResult,
SpecialBlockID,
} from "@/lib/autogpt-server-api";
import { FlowRun } from "@/lib/types";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import Link from "next/link";
import { Button, buttonVariants } from "@/components/ui/button";
import { IconSquare } from "@/components/ui/icons";
import { Pencil2Icon } from "@radix-ui/react-icons";
import { ExitIcon, Pencil2Icon } from "@radix-ui/react-icons";
import moment from "moment/moment";
import { FlowRunStatusBadge } from "@/components/monitor/FlowRunStatusBadge";
import RunnerOutputUI, { BlockOutput } from "../runner-ui/RunnerOutputUI";

export const FlowRunInfo: React.FC<
React.HTMLAttributes<HTMLDivElement> & {
flow: GraphMeta;
flowRun: FlowRun;
}
> = ({ flow, flowRun, ...props }) => {
const [isOutputOpen, setIsOutputOpen] = useState(false);
const [blockOutputs, setBlockOutputs] = useState<BlockOutput[]>([]);
const api = useMemo(() => new AutoGPTServerAPI(), []);

const fetchBlockResults = useCallback(async () => {
const executionResults = await api.getGraphExecutionInfo(
flow.id,
flowRun.id,
);

// Create a map of the latest COMPLETED execution results of output nodes by node_id
const latestCompletedResults = executionResults
.filter(
(result) =>
result.status === "COMPLETED" &&
result.block_id === SpecialBlockID.OUTPUT,
)
.reduce((acc, result) => {
const existing = acc.get(result.node_id);

// Compare dates if there's an existing result
if (existing) {
const existingDate = existing.end_time || existing.add_time;
const currentDate = result.end_time || result.add_time;

if (currentDate > existingDate) {
acc.set(result.node_id, result);
}
} else {
acc.set(result.node_id, result);
}

return acc;
}, new Map<string, NodeExecutionResult>());

// Transform results to BlockOutput format
setBlockOutputs(
Array.from(latestCompletedResults.values()).map((result) => ({
id: result.node_id,
type: "output" as const,
hardcodedValues: {
name: result.input_data.name || "Output",
description: result.input_data.description || "Output from the agent",
value: result.input_data.value,
},
// Change this line to extract the array directly
result: result.output_data?.output || undefined,
})),
);
}, [api, flow.id, flow.version, flowRun.id]);

// Fetch graph and execution data
useEffect(() => {
if (!isOutputOpen || blockOutputs.length > 0) {
return;
}

fetchBlockResults();
}, [isOutputOpen, blockOutputs]);

if (flowRun.graphID != flow.id) {
throw new Error(
`FlowRunInfo can't be used with non-matching flowRun.flowID and flow.id`,
);
}

const handleStopRun = useCallback(() => {
const api = new AutoGPTServerAPI();
api.stopGraphExecution(flow.id, flowRun.id);
}, [flow.id, flowRun.id]);

return (
<Card {...props}>
<CardHeader className="flex-row items-center justify-between space-x-3 space-y-0">
<div>
<CardTitle>
{flow.name} <span className="font-light">v{flow.version}</span>
</CardTitle>
<p className="mt-2">
Agent ID: <code>{flow.id}</code>
<>
<Card {...props}>
<CardHeader className="flex-row items-center justify-between space-x-3 space-y-0">
<div>
<CardTitle>
{flow.name} <span className="font-light">v{flow.version}</span>
</CardTitle>
<p className="mt-2">
Agent ID: <code>{flow.id}</code>
</p>
<p className="mt-1">
Run ID: <code>{flowRun.id}</code>
</p>
</div>
<div className="flex space-x-2">
{flowRun.status === "running" && (
<Button onClick={handleStopRun} variant="destructive">
<IconSquare className="mr-2" /> Stop Run
</Button>
)}
<Button onClick={() => setIsOutputOpen(true)} variant="outline">
<ExitIcon className="mr-2" /> View Outputs
</Button>
<Link
className={buttonVariants({ variant: "default" })}
href={`/build?flowID=${flow.id}`}
>
<Pencil2Icon className="mr-2" /> Open in Builder
</Link>
</div>
</CardHeader>
<CardContent>
<div>
<strong>Status:</strong>{" "}
<FlowRunStatusBadge status={flowRun.status} />
</div>
<p>
<strong>Started:</strong>{" "}
{moment(flowRun.startTime).format("YYYY-MM-DD HH:mm:ss")}
</p>
<p className="mt-1">
Run ID: <code>{flowRun.id}</code>
<p>
<strong>Finished:</strong>{" "}
{moment(flowRun.endTime).format("YYYY-MM-DD HH:mm:ss")}
</p>
</div>
<div className="flex space-x-2">
{flowRun.status === "running" && (
<Button onClick={handleStopRun} variant="destructive">
<IconSquare className="mr-2" /> Stop Run
</Button>
)}
<Link
className={buttonVariants({ variant: "default" })}
href={`/build?flowID=${flow.id}`}
>
<Pencil2Icon className="mr-2" /> Open in Builder
</Link>
</div>
</CardHeader>
<CardContent>
<div>
<strong>Status:</strong>{" "}
<FlowRunStatusBadge status={flowRun.status} />
</div>
<p>
<strong>Started:</strong>{" "}
{moment(flowRun.startTime).format("YYYY-MM-DD HH:mm:ss")}
</p>
<p>
<strong>Finished:</strong>{" "}
{moment(flowRun.endTime).format("YYYY-MM-DD HH:mm:ss")}
</p>
<p>
<strong>Duration (run time):</strong> {flowRun.duration} (
{flowRun.totalRunTime}) seconds
</p>
{/* <p><strong>Total cost:</strong> €1,23</p> */}
</CardContent>
</Card>
<p>
<strong>Duration (run time):</strong> {flowRun.duration} (
{flowRun.totalRunTime}) seconds
</p>
</CardContent>
</Card>
<RunnerOutputUI
isOpen={isOutputOpen}
onClose={() => setIsOutputOpen(false)}
blockOutputs={blockOutputs}
/>
</>
);
};

export default FlowRunInfo;
Loading

0 comments on commit a8ed0d0

Please sign in to comment.