Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .agents/rules/pytc-client.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
trigger: always_on
glob:
description:
---
17 changes: 17 additions & 0 deletions .logs/start/api-server.log
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
INFO: Started server process [1802573]
INFO: Waiting for application startup.
INFO: Application startup complete.
INFO: Uvicorn running on http://0.0.0.0:4242 (Press CTRL+C to quit)
================================================================================
EHTOOL ROUTER MODULE LOADED - VERSION: DEBUG v2
================================================================================
INFO: 127.0.0.1:52216 - "GET /health HTTP/1.1" 200 OK
INFO: 127.0.0.1:39000 - "GET /api/pm/data HTTP/1.1" 200 OK
INFO: 127.0.0.1:38992 - "GET /files?parent=root HTTP/1.1" 200 OK
INFO: 127.0.0.1:39000 - "GET /api/pm/data HTTP/1.1" 200 OK
INFO: 127.0.0.1:55914 - "OPTIONS /api/pm/login HTTP/1.1" 200 OK
INFO: 127.0.0.1:55930 - "POST /api/pm/login HTTP/1.1" 200 OK
INFO: Shutting down
INFO: Waiting for application shutdown.
INFO: Application shutdown complete.
INFO: Finished server process [1802573]
1 change: 1 addition & 0 deletions .logs/start/data-server.log
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
127.0.0.1 - - [26/Mar/2026 14:48:47] "GET / HTTP/1.1" 200 -
21 changes: 21 additions & 0 deletions .logs/start/pytc-server.log
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
INFO: Started server process [1802650]
INFO: Waiting for application startup.
INFO: Application startup complete.
INFO: Uvicorn running on http://0.0.0.0:4243 (Press CTRL+C to quit)

================================================================================
SERVER_PYTC STARTING UP
Python executable: /home/sam/Workshop/pytc-client/.venv/bin/python3
Working directory: /home/sam/Workshop/pytc-client
================================================================================


================================================================================
SERVER_PYTC: Starting Uvicorn server on port 4243...
================================================================================

INFO: 127.0.0.1:50152 - "GET /hello HTTP/1.1" 200 OK
INFO: Shutting down
INFO: Waiting for application shutdown.
INFO: Application shutdown complete.
INFO: Finished server process [1802650]
82 changes: 82 additions & 0 deletions .logs/start/react-build.log
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@

> PyTC Client@0.1.0 build
> cross-env CI=false react-scripts build

[baseline-browser-mapping] The data in this module is over two months old. To ensure accurate Baseline data, please update: `npm i baseline-browser-mapping@latest -D`
Creating an optimized production build...
[baseline-browser-mapping] The data in this module is over two months old. To ensure accurate Baseline data, please update: `npm i baseline-browser-mapping@latest -D`
Compiled with warnings.

[eslint]
src/components/FilePickerModal.js
Line 102:35: Function declared in a loop contains unsafe references to variable(s) 'curr' no-loop-func
Line 124:35: Function declared in a loop contains unsafe references to variable(s) 'currParentId' no-loop-func
Line 243:15: The href attribute is required for an anchor to be keyboard accessible. Provide a valid, navigable address as the href value. If you cannot provide an href, but still need the element to resemble a link, use a button and change it with appropriate styles. Learn more: https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/HEAD/docs/rules/anchor-is-valid.md jsx-a11y/anchor-is-valid

src/components/YamlFileUploader.js
Line 347:6: React Hook useEffect has missing dependencies: 'getCurrentConfig' and 'syncYamlContext'. Either include them or remove the dependency array react-hooks/exhaustive-deps
Line 361:6: React Hook useEffect has missing dependencies: 'getCurrentConfig', 'setCurrentConfig', and 'updateInputSelectorInformation'. Either include them or remove the dependency array react-hooks/exhaustive-deps
Line 374:6: React Hook useMemo has a missing dependency: 'getCurrentConfig'. Either include it or remove the dependency array react-hooks/exhaustive-deps

src/views/FilesManager.js
Line 81:31: Function declared in a loop contains unsafe references to variable(s) 'current' no-loop-func
Line 420:27: Function declared in a loop contains unsafe references to variable(s) 'curr' no-loop-func
Line 772:32: Function declared in a loop contains unsafe references to variable(s) 'descendantSizeKb', 'descendantSizeKb', 'descendantSizeKb', 'descendantSizeKb' no-loop-func
Line 1069:6: React Hook useEffect has missing dependencies: 'finishCreateFolder', 'finishRename', 'handleCopy', 'handleCut', 'handleDelete', and 'handlePaste'. Either include them or remove the dependency array react-hooks/exhaustive-deps

src/views/Views.js
Line 11:3: 'BarChartOutlined' is defined but never used no-unused-vars

src/views/mask-proofreading/MaskProofreading.js
Line 5:10: 'ehToolSession' is assigned a value but never used no-unused-vars
Line 5:25: 'setEhToolSession' is assigned a value but never used no-unused-vars
Line 6:10: 'refreshTrigger' is assigned a value but never used no-unused-vars
Line 6:26: 'setRefreshTrigger' is assigned a value but never used no-unused-vars

src/views/project-manager/AnnotationDashboard.js
Line 340:5: 'isAdmin' is assigned a value but never used no-unused-vars

src/views/project-manager/ModelQualityDashboard.js
Line 40:7: 'CONFUSION_MATRIX' is assigned a value but never used no-unused-vars

src/views/project-manager/ProjectManager.js
Line 19:3: 'UserOutlined' is defined but never used no-unused-vars
Line 20:3: 'CrownOutlined' is defined but never used no-unused-vars
Line 38:61: 'loading' is assigned a value but never used no-unused-vars

src/views/project-manager/ProjectManagerLogin.js
Line 14:11: 'success' is assigned a value but never used no-unused-vars

src/views/project-manager/ProofreaderProgress.js
Line 163:6: React Hook useMemo has a missing dependency: 'getStats'. Either include it or remove the dependency array react-hooks/exhaustive-deps

src/views/project-manager/QuotaManagement.js
Line 29:3: 'SaveOutlined' is defined but never used no-unused-vars
Line 98:5: 'activeWorker' is assigned a value but never used no-unused-vars

src/views/project-manager/VolumeTracker.js
Line 16:3: 'Popconfirm' is defined but never used no-unused-vars
Line 127:6: React Hook useMemo has an unnecessary dependency: 'isAdmin'. Either exclude it or remove the dependency array react-hooks/exhaustive-deps
Line 184:15: 'cfg' is assigned a value but never used no-unused-vars

Search for the keywords to learn more about each warning.
To ignore, add // eslint-disable-next-line to the line before.

File sizes after gzip:

553.16 kB build/static/js/main.be80df26.js
465 B build/static/css/main.40821645.css

The bundle size is significantly larger than recommended.
Consider reducing it with code splitting: https://goo.gl/9VhYWB
You can also analyze the project dependencies: https://goo.gl/LeUzfb

The project was built assuming it is hosted at ./.
You can control this with the homepage field in your package.json.

The build folder is ready to be deployed.

Find out more about deployment here:

https://cra.link/deployment

21 changes: 21 additions & 0 deletions .logs/start/react-dev.log
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@

> PyTC Client@0.1.0 start
> react-scripts start

[baseline-browser-mapping] The data in this module is over two months old. To ensure accurate Baseline data, please update: `npm i baseline-browser-mapping@latest -D`
(node:1802959) [DEP_WEBPACK_DEV_SERVER_ON_AFTER_SETUP_MIDDLEWARE] DeprecationWarning: 'onAfterSetupMiddleware' option is deprecated. Please use the 'setupMiddlewares' option.
(Use `node --trace-deprecation ...` to show where the warning was created)
(node:1802959) [DEP_WEBPACK_DEV_SERVER_ON_BEFORE_SETUP_MIDDLEWARE] DeprecationWarning: 'onBeforeSetupMiddleware' option is deprecated. Please use the 'setupMiddlewares' option.
Starting the development server...

Compiled successfully!

You can now view PyTC Client in the browser.

Local: http://localhost:3000
On Your Network: http://10.101.188.107:3000

Note that the development build is not optimized.
To create a production build, use npm run build.

webpack compiled successfully
1 change: 1 addition & 0 deletions client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
},
"scripts": {
"start": "react-scripts start",
"test": "react-scripts test",
"build": "cross-env CI=false react-scripts build",
"electron": "electron ."
},
Expand Down
13 changes: 8 additions & 5 deletions client/src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import "./App.css";
import Views from "./views/Views";
import { AppContext, ContextWrapper } from "./contexts/GlobalContext";
import { YamlContextWrapper } from "./contexts/YamlContext";
import { WorkflowProvider } from "./contexts/WorkflowContext";

function CacheBootstrapper({ children }) {
const { resetFileState } = useContext(AppContext);
Expand Down Expand Up @@ -38,11 +39,13 @@ function App() {
return (
<ContextWrapper>
<YamlContextWrapper>
<CacheBootstrapper>
<div className="App">
<MainContent />
</div>
</CacheBootstrapper>
<WorkflowProvider>
<CacheBootstrapper>
<div className="App">
<MainContent />
</div>
</CacheBootstrapper>
</WorkflowProvider>
</YamlContextWrapper>
</ContextWrapper>
);
Expand Down
78 changes: 78 additions & 0 deletions client/src/__tests__/agentProposalCards.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import React from "react";
import { fireEvent, render, screen } from "@testing-library/react";

import AgentProposalCard from "../components/chat/AgentProposalCard";

jest.mock("antd", () => ({
Button: ({ children, ...props }) => (
<button type="button" {...props}>
{children}
</button>
),
Space: ({ children }) => <div>{children}</div>,
Tag: ({ children }) => <span>{children}</span>,
Typography: {
Text: ({ children }) => <span>{children}</span>,
},
}));

describe("AgentProposalCard", () => {
it("renders hotspot proposal fields and approve/reject actions", () => {
const onApprove = jest.fn();
const onReject = jest.fn();
const proposal = {
type: "prioritize_failure_hotspots",
rationale: "Focus annotation where the model fails most often.",
target_dataset: "set-a",
hotspots: ["z:11", "z:12"],
priority_metric: "error_rate",
min_failure_rate: 0.2,
};

render(
<AgentProposalCard
proposal={proposal}
onApprove={onApprove}
onReject={onReject}
/>,
);

expect(screen.getByText("Prioritize Failure Hotspots")).toBeTruthy();
expect(screen.getByText("set-a")).toBeTruthy();

fireEvent.click(screen.getByRole("button", { name: "Approve" }));
fireEvent.click(screen.getByRole("button", { name: "Reject" }));

expect(onApprove).toHaveBeenCalledWith(proposal);
expect(onReject).toHaveBeenCalledWith(proposal);
});

it("supports correction-impact cards with compact rationale", () => {
const proposal = {
proposal_type: "preview_correction_impact",
rationale: "A".repeat(200),
target_metric: "f1",
expected_delta: "+0.05",
sample_size: 128,
confidence: "high",
};

render(<AgentProposalCard proposal={proposal} />);

expect(screen.getByText("Preview Correction Impact")).toBeTruthy();
expect(screen.getByText(/A{157}…/)).toBeTruthy();
expect(screen.getByText("+0.05")).toBeTruthy();
});

it("renders fallback proposal content", () => {
render(
<AgentProposalCard
proposal={{ type: "custom_type", rationale: "Keep behavior stable", foo: "bar" }}
/>,
);

expect(screen.getByText("Agent Proposal")).toBeTruthy();
expect(screen.getByText("Keep behavior stable")).toBeTruthy();
expect(screen.getByText("bar")).toBeTruthy();
});
});
34 changes: 34 additions & 0 deletions client/src/__tests__/workflowTimelineFilters.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import {
DEFAULT_TIMELINE_FILTERS,
filterTimelineEvents,
} from "../contexts/workflow/timelineFilters";

const EVENTS = [
{ id: "1", actor: "user", event_type: "dataset.loaded" },
{ id: "2", actor: "agent", event_type: "agent.proposal_created" },
{ id: "3", actor: "system", event_type: "inference.completed" },
{ id: "4", actor: "agent", event_type: "agent.proposal_approved" },
];

describe("workflow timeline filters", () => {
it("preserves the full timeline by default", () => {
const visible = filterTimelineEvents(EVENTS, DEFAULT_TIMELINE_FILTERS);
expect(visible).toHaveLength(EVENTS.length);
expect(visible).toBe(EVENTS);
});

it("filters by actor and event type combinations", () => {
expect(filterTimelineEvents(EVENTS, { actor: "agent", eventType: "" })).toEqual([
EVENTS[1],
EVENTS[3],
]);

expect(
filterTimelineEvents(EVENTS, { actor: "agent", eventType: "approved" }),
).toEqual([EVENTS[3]]);

expect(
filterTimelineEvents(EVENTS, { actor: "all", eventType: "proposal" }),
).toEqual([EVENTS[1], EVENTS[3]]);
});
});
Loading
Loading