Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Styles in Css, zustand subscribe, colors, add ul, Spinner while running #1

Closed
wants to merge 9 commits into from
44 changes: 22 additions & 22 deletions .github/workflows/pr-validation-workflow.yml
Original file line number Diff line number Diff line change
@@ -1,31 +1,31 @@
name: PR Validation CI

on:
pull_request:
branches: [main] # Triggered on PRs targeting these branches
pull_request:
branches: [main] # Triggered on PRs targeting these branches

jobs:
build-and-test:
runs-on: ubuntu-latest
env:
OPENAI_API_KEY: "fake-api-key-so-we-can-use-ci-in-forked-repositories"
ANTHROPIC_API_KEY: "fake-api-key-so-we-can-use-ci-in-forked-repositories"
GOOGLE_API_KEY: "fake-api-key-so-we-can-use-ci-in-forked-repositories"
MISTRAL_API_KEY: "fake-api-key-so-we-can-use-ci-in-forked-repositories"
steps:
- name: Checkout code
uses: actions/checkout@v2
build-and-test:
runs-on: ubuntu-latest
env:
OPENAI_API_KEY: "fake-api-key-so-we-can-use-ci-in-forked-repositories"
ANTHROPIC_API_KEY: "fake-api-key-so-we-can-use-ci-in-forked-repositories"
GOOGLE_API_KEY: "fake-api-key-so-we-can-use-ci-in-forked-repositories"
MISTRAL_API_KEY: "fake-api-key-so-we-can-use-ci-in-forked-repositories"
steps:
- name: Checkout code
uses: actions/checkout@v2

- name: Set up Node.js
uses: actions/setup-node@v2
with:
node-version: '18'
- name: Set up Node.js
uses: actions/setup-node@v2
with:
node-version: "18"

- name: Install dependencies
run: npm install --also=dev
- name: Install dependencies
run: npm install --also=dev

- name: Build for integration tests
run: npm run build:test
- name: Build for integration tests
run: npm run build:test

- name: Run integration tests
run: npm run test:integration
- name: Run integration tests
run: npm run test:integration
15 changes: 13 additions & 2 deletions playground/react/.eslintrc.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,16 @@ module.exports = {
'warn',
{ allowConstantExport: true },
],
},
}
ignorePatterns: ["dist", ".eslintrc.cjs"],
parserOptions: { ecmaVersion: "latest", sourceType: "module" },
settings: { react: { version: "18.2" } },
plugins: ["react-refresh"],
rules: {
"react/jsx-no-target-blank": "off",
"react/prop-types": "off",
"react-refresh/only-export-components": [
"warn",
{ allowConstantExport: true },
],
},
};
18 changes: 9 additions & 9 deletions playground/react/src/App.jsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import AgentsBoardDebugger from './AgentsBoardDebugger';
import team from './teams/product_specs/openai';
import AgentsBoardDebugger from "./AgentsBoardDebugger";
import team from "./teams/product_specs/openai";

function App() {
return (
<>
<h1>KaibanJS Playground</h1>
<AgentsBoardDebugger team={team}/>
</>
)
return (
<>
<h1>KaibanJS Playground</h1>
<AgentsBoardDebugger team={team} />
</>
);
}

export default App
export default App;
213 changes: 213 additions & 0 deletions playground/react/src/components/AgentDebbuger/AgentsBoardDebugger.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,213 @@
import { useEffect, useState } from "react";
import Spinner from "../Spinner/Spinner";
import "./appDebuggerStyles.css";

const AgentsBoardDebugger = ({ team }) => {
const useTeamStore = team.useStore();
const {
agents,
tasks,
workflowLogs,
teamWorkflowStatus,
workflowResult,
inputs,
setInputs,
} = useTeamStore((state) => ({
agents: state.agents,
tasks: state.tasks,
workflowLogs: state.workflowLogs,
teamWorkflowStatus: state.teamWorkflowStatus,
workflowResult: state.workflowResult,
inputs: state.inputs,
setInputs: state.setInputs,
}));
console.log("🚀 ~ AgentsBoardDebugger ~ workflowLogs:", workflowLogs);

const [statusLog, setStatusLog] = useState([teamWorkflowStatus]);

useEffect(() => {
const unsub = useTeamStore.subscribe((state, previusState) => {
if (state.teamWorkflowStatus !== previusState.teamWorkflowStatus)
setStatusLog((prevLog) => [
...prevLog,
state.teamWorkflowStatus,
]);
});

return unsub;
}, []);

const startTeam = () => {
try {
team.start(inputs);
} catch (error) {
console.error("Invalid JSON input:", error);
}
};

return (
<div>
<h1 className="title">Agents Team Debugger</h1>
<div className="inputSection">
<h2 className="sectionTitle">Team Inputs</h2>
<div>
<textarea
value={JSON.stringify(inputs, null, 2)}
onChange={(e) => setInputs(JSON.parse(e.target.value))}
placeholder="Enter JSON input"
className="inputTextarea"
/>
</div>

<div className="actionWrapper">
<button onClick={startTeam} className="actionButton">
Start Workflow
</button>

{teamWorkflowStatus === "running_workflow" && <Spinner />}
</div>
</div>

<div className="section">
<h2 className="sectionTitle">🕵️‍♂️ Agents</h2>
<ul>
{agents.map((agent) => (
<li key={agent.id} className="listItem agentName">
<span>
{agent.name} - {agent.role}
</span>
</li>
))}
</ul>
</div>
<div className="section">
<h2 className="sectionTitle">📝 Tasks</h2>
<ul>
{tasks.map((task) => (
<li key={task.id} className="listItem">
<div className="taskContainer">
<span className="taskDescription">
{task.description}
</span>
<span className="taskStatus">
{task.status}{" "}
{task.status === "doing" && (
<Spinner color="white" />
)}
</span>
</div>
</li>
))}
</ul>
</div>
<div className="section">
<h2 className="sectionTitle">
🔄 Team Workflow Status Changes
</h2>

<ul>
{statusLog.map((status, index) => (
<li key={index} className="listItem">
Status: {status}
</li>
))}
</ul>
</div>
<div className="section">
<h2 className="sectionTitle">📋 Task Logs</h2>

{workflowLogs.length > 0 ? (
<ul>
{workflowLogs
.filter(
(log, index, self) =>
index ===
self.findIndex(
(t) =>
t.task.description ===
log.task.description &&
t.timestamp === log.timestamp &&
t.agent.name === log.agent.name &&
t.task.status === log.task.status
)
)
.map((log) => (
<li
key={
log.task.id +
log.task.status +
log.agent.name +
log.logDescription
}
className="listItem"
>
({log.task.status}) - timestamp:{" "}
{log.timestamp} - {log.agent.name} -{" "}
{log.task.description}
</li>
))}
</ul>
) : (
<div className="noAvailableData">
<span>Not yet available</span>
</div>
)}
</div>
<div className="section">
<h2 className="sectionTitle">Workflow Result</h2>
<div>
{workflowResult ? (
workflowResult
) : (
<div className="noAvailableData">
<span>Not yet available</span>
</div>
)}
</div>
</div>
<div className="section">
<h2 className="sectionTitle">📊 Task Results</h2>

<ul>
{tasks.map((task) => (
<li
key={task.id}
className="listItem taskResult_Container last_child"
>
<div>
<strong className="subtitle">Task:</strong>
<span> {task.description} </span>
</div>

<div>
<strong className="subtitle">Time:</strong>
<span>
{" "}
{task.duration
? `${task.duration} seconds`
: "Not yet available"}
</span>
</div>

<div className="taskResult_response">
<p>
<strong className="subtitle">
Result:
</strong>
</p>

<p>
{task.result
? task.result
: "Not yet available"}
</p>
</div>
</li>
))}
</ul>
</div>
</div>
);
};

export default AgentsBoardDebugger;
Loading