diff --git a/web/apps/labelstudio/src/config/ApiConfig.js b/web/apps/labelstudio/src/config/ApiConfig.js
index 62c8f95cb572..969a654b490a 100644
--- a/web/apps/labelstudio/src/config/ApiConfig.js
+++ b/web/apps/labelstudio/src/config/ApiConfig.js
@@ -92,6 +92,9 @@ export const API_CONFIG = {
accessTokenSettings: "GET:/jwt/settings",
accessTokenUpdateSettings: "POST:/jwt/settings",
+
+ // FSM
+ fsmStateHistory: "GET:/fsm/entities/:entityType/:entityId/history",
},
alwaysExpectJSON: false,
};
diff --git a/web/libs/app-common/src/components/state-chips/annotation-state-chip.tsx b/web/libs/app-common/src/components/state-chips/annotation-state-chip.tsx
new file mode 100644
index 000000000000..fbb402880a3e
--- /dev/null
+++ b/web/libs/app-common/src/components/state-chips/annotation-state-chip.tsx
@@ -0,0 +1,49 @@
+/**
+ * AnnotationStateChip - Annotation-specific state chip with history popover
+ */
+
+import { useState } from "react";
+import { StateChip } from "@humansignal/ui";
+import { getStateColorClass, formatStateName, getStateDescription } from "./utils";
+import { StateHistoryPopoverContent } from "./state-history-popover-content";
+
+export interface AnnotationStateChipProps {
+ /**
+ * Current state of the annotation
+ */
+ state: string;
+
+ /**
+ * Annotation ID for fetching state history
+ */
+ annotationId?: number;
+
+ /**
+ * Whether the chip should be interactive (show history popover)
+ */
+ interactive?: boolean;
+}
+
+export function AnnotationStateChip({ state, annotationId, interactive = true }: AnnotationStateChipProps) {
+ const [open, setOpen] = useState(false);
+
+ const label = formatStateName(state);
+ const description = getStateDescription(state, "annotation");
+ const colorClasses = getStateColorClass(state);
+
+ const popoverContent = annotationId ? (
+