@metrevals/inspect-scout-viewer 0.4.3-beta.1765899631 → 0.4.4-beta.20251223202036

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,9 +1,7 @@
1
1
  import { GridState } from 'ag-grid-community';
2
- import { ColumnTable } from 'arquero';
3
2
  import { StateSnapshot } from 'react-virtuoso';
4
3
  import { ScanApi } from '../api/api';
5
- import { ScanResultInputData, ErrorScope, ResultGroup, ScanResultSummary, SortColumn } from '../app/types';
6
- import { Status } from '../types';
4
+ import { ErrorScope, ResultGroup, ScanResultSummary, SortColumn } from '../app/types';
7
5
  interface StoreState {
8
6
  singleFileMode?: boolean;
9
7
  hasInitializedEmbeddedData?: boolean;
@@ -11,11 +9,8 @@ interface StoreState {
11
9
  loading: number;
12
10
  loadingData: number;
13
11
  scopedErrors: Record<ErrorScope, string | undefined>;
14
- resultsDir?: string;
15
- scans: Status[];
16
12
  visibleScanJobCount?: number;
17
13
  selectedScanLocation?: string;
18
- selectedScanStatus?: Status;
19
14
  visibleScannerResults: ScanResultSummary[];
20
15
  visibleScannerResultsCount: number;
21
16
  selectedScanResult?: string;
@@ -51,20 +46,10 @@ interface StoreState {
51
46
  clearError: (scope: ErrorScope) => void;
52
47
  setLoading: (loading: boolean) => void;
53
48
  setLoadingData: (loading: boolean) => void;
54
- setResultsDir: (dir: string) => void;
55
- setScans: (scans: Status[]) => void;
56
49
  setVisibleScanJobCount: (count: number) => void;
57
50
  setSelectedScanLocation: (location: string) => void;
58
- setSelectedScanStatus: (status: Status) => void;
59
- clearSelectedScanStatus: () => void;
60
51
  setSelectedScanner: (scanner: string) => void;
61
52
  setSelectedScanResult: (result: string) => void;
62
- setSelectedScanResultData: (scanner: string, data: ColumnTable) => void;
63
- getSelectedScanResultData: (scanner?: string) => ColumnTable | undefined;
64
- setSelectedScanResultInputData: (uuid: string, inputData: ScanResultInputData) => void;
65
- getSelectedScanResultInputData: (uuid: string) => ScanResultInputData | undefined;
66
- setSelectedScanResultPreviews: (scanner?: string, previews?: ScanResultSummary[]) => void;
67
- getSelectedScanResultPreviews: (scanner?: string) => ScanResultSummary[] | undefined;
68
53
  setVisibleScannerResults: (results: ScanResultSummary[]) => void;
69
54
  setVisibleScannerResultsCount: (count: number) => void;
70
55
  clearScanState: () => void;
@@ -4236,7 +4236,7 @@ pre._value_1uivt_24 {
4236
4236
  padding-right: 0.5rem;
4237
4237
  margin-top: 2px;
4238
4238
  }
4239
- ._header_87o1i_1 {
4239
+ ._header_1eu50_1 {
4240
4240
  padding-left: 1rem;
4241
4241
  padding-right: 1rem;
4242
4242
  display: grid;
@@ -4247,28 +4247,28 @@ pre._value_1uivt_24 {
4247
4247
  grid-template-rows: max-content max-content;
4248
4248
  }
4249
4249
 
4250
- ._oneCol_87o1i_12 {
4251
- grid-template-columns: 2fr;
4250
+ ._oneCol_1eu50_12 {
4251
+ grid-template-columns: auto;
4252
4252
  }
4253
4253
 
4254
- ._twoCol_87o1i_16 {
4255
- grid-template-columns: 1fr 1fr;
4254
+ ._twoCol_1eu50_16 {
4255
+ grid-template-columns: auto auto;
4256
4256
  }
4257
4257
 
4258
- ._threeCol_87o1i_20 {
4259
- grid-template-columns: 2fr 1fr 1fr;
4258
+ ._threeCol_1eu50_20 {
4259
+ grid-template-columns: auto auto auto;
4260
4260
  }
4261
4261
 
4262
- ._fourCol_87o1i_24 {
4263
- grid-template-columns: 2fr 1fr 1fr 1fr;
4262
+ ._fourCol_1eu50_24 {
4263
+ grid-template-columns: auto auto auto auto;
4264
4264
  }
4265
4265
 
4266
- ._fiveCol_87o1i_28 {
4267
- grid-template-columns: 3fr 1fr 1fr 1fr 1fr;
4266
+ ._fiveCol_1eu50_28 {
4267
+ grid-template-columns: auto auto auto auto auto;
4268
4268
  }
4269
4269
 
4270
- ._sixCol_87o1i_32 {
4271
- grid-template-columns: 3fr 1fr 1fr 1fr 1fr;
4270
+ ._sixCol_1eu50_32 {
4271
+ grid-template-columns: auto auto auto auto auto auto;
4272
4272
  }
4273
4273
  ._resultNav_oszqi_1 {
4274
4274
  display: grid;
@@ -4477,60 +4477,73 @@ button._segment_19z32_10 {
4477
4477
  color: var(--bs-primary) !important;
4478
4478
  margin-right: 0.3rem;
4479
4479
  }
4480
- ._id_3fl9e_1 {
4481
- display: grid;
4482
- grid-template-rows: auto auto;
4483
- row-gap: 0;
4484
- }
4485
-
4486
- ._idContainer_3fl9e_7 {
4487
- overflow-wrap: anywhere;
4488
- }
4489
- ._row_diloz_1 {
4480
+ ._row_1ukc2_1 {
4490
4481
  border-bottom: solid 1px var(--bs-border-color);
4491
- padding: 0.5rem 1rem;
4492
- height: 150px;
4482
+ padding: 0.5rem 1rem 1rem 1rem;
4483
+ max-height: 200px;
4493
4484
  }
4494
4485
 
4495
- ._row_diloz_1._noExplanation_diloz_7 {
4496
- height: 50px;
4486
+ ._row_1ukc2_1._noExplanation_1ukc2_7 {
4487
+ max-height: 100px;
4497
4488
  }
4498
4489
 
4499
- ._row_diloz_1:hover {
4490
+ ._row_1ukc2_1:hover {
4500
4491
  cursor: pointer;
4501
4492
  }
4502
4493
 
4503
- ._row_diloz_1._disabled_diloz_15 {
4494
+ ._row_1ukc2_1._disabled_1ukc2_15 {
4504
4495
  opacity: 0.7;
4505
4496
  }
4506
4497
 
4507
- ._row_diloz_1._disabled_diloz_15:hover {
4498
+ ._row_1ukc2_1._disabled_1ukc2_15:hover {
4508
4499
  cursor: default;
4509
4500
  }
4510
4501
 
4511
- ._explanation_diloz_23 {
4502
+ ._result_1ukc2_23 {
4503
+ display: grid;
4504
+ grid-template-columns: max-content 1fr;
4505
+ grid-template-rows: auto auto;
4506
+ column-gap: 0.5rem;
4507
+ row-gap: 0.5rem;
4508
+ justify-content: space-between;
4509
+ }
4510
+
4511
+ ._id_1ukc2_32 {
4512
+ }
4513
+
4514
+ ._model_1ukc2_35 {
4515
+ text-align: right;
4516
+ }
4517
+
4518
+ ._label_1ukc2_39 {
4519
+ overflow-wrap: break-word;
4520
+ }
4521
+
4522
+ ._explanation_1ukc2_43 {
4512
4523
  overflow: hidden;
4513
4524
  text-overflow: ellipsis;
4514
- height: calc(150px - 3em);
4525
+
4526
+ grid-column: span 2;
4527
+ max-height: calc(160px - 3rem);
4515
4528
  }
4516
4529
 
4517
- ._row_diloz_1._selected_diloz_29 {
4530
+ ._row_1ukc2_1._selected_1ukc2_51 {
4518
4531
  background-color: rgba(var(--bs-secondary-rgb), 0.07);
4519
4532
  }
4520
4533
 
4521
- ._link_diloz_33 {
4534
+ ._link_1ukc2_55 {
4522
4535
  color: var(--bs-body-color);
4523
4536
  text-decoration: none;
4524
4537
  }
4525
4538
 
4526
- ._link_diloz_33:hover {
4539
+ ._link_1ukc2_55:hover {
4527
4540
  color: var(--bs-body-color);
4528
4541
  }
4529
4542
 
4530
- ._error_diloz_42 {
4543
+ ._error_1ukc2_64 {
4531
4544
  overflow: hidden;
4532
4545
  text-overflow: ellipsis;
4533
- height: calc(150px - 3em);
4546
+ max-height: calc(160px - 3rem);
4534
4547
  }
4535
4548
  ._scannerHeaderRow_94id2_1 {
4536
4549
  display: grid;
@@ -1,8 +1,4 @@
1
1
  import { ChatMessageAssistant, ChatMessageSystem, ChatMessageTool, ChatMessageUser, ContentImage, ContentText, Events } from './log';
2
- export interface Scans {
3
- results_dir: string;
4
- scans: Status[];
5
- }
6
2
  export interface Status {
7
3
  complete: boolean;
8
4
  spec: ScanSpec;
@@ -32,12 +28,6 @@ export interface Model {
32
28
  config: Record<string, unknown>;
33
29
  args: Record<string, unknown>;
34
30
  }
35
- export interface Transcript {
36
- type: string;
37
- location?: string;
38
- transcript_ids: Record<string, string | null>;
39
- count?: number;
40
- }
41
31
  export interface ScanSpec {
42
32
  scan_file?: string;
43
33
  scan_id: string;
@@ -50,7 +40,12 @@ export interface ScanSpec {
50
40
  packages?: Record<string, unknown>;
51
41
  revision?: Record<string, unknown>;
52
42
  scanners: Record<string, Scanner>;
53
- transcripts?: Transcript;
43
+ transcripts?: {
44
+ type: string;
45
+ location?: string;
46
+ transcript_ids: Record<string, string | null>;
47
+ count?: number;
48
+ };
54
49
  }
55
50
  export interface Scanner {
56
51
  name: string;
@@ -76,25 +71,44 @@ export interface ModelUsage {
76
71
  }
77
72
  export type ChatMessages = ChatMessage[];
78
73
  export type ChatMessage = ChatMessageSystem | ChatMessageUser | ChatMessageAssistant | ChatMessageTool;
79
- export interface Transcript {
74
+ export interface TranscriptInfo {
80
75
  id: string;
81
76
  source_id: string;
82
- source_url: string;
77
+ source_uri: string;
78
+ source_type: string;
79
+ filename?: string;
80
+ date?: string;
81
+ task_set?: string;
82
+ task_id?: string;
83
+ task_repeat?: number;
84
+ agent?: string;
85
+ agent_args?: string;
86
+ model?: string;
87
+ model_options?: string;
88
+ score?: string;
89
+ success?: boolean;
90
+ total_time?: number;
91
+ total_tokens?: number;
92
+ error?: string;
93
+ limit?: string;
94
+ metadata: TranscriptMetadata;
95
+ }
96
+ export interface Transcript extends TranscriptInfo {
83
97
  messages: ChatMessages;
84
98
  events: Events;
85
- metadata: TranscriptMetadata;
86
99
  }
87
100
  export interface TranscriptMetadata {
88
- sample_id: string;
89
- id: string | number;
90
- epoch: number;
91
- eval_id: string;
92
- log: string;
93
- eval_created: string;
94
- eval_metadata: Record<string, unknown>;
95
- task_name: string;
96
- model: string;
97
- score: string;
101
+ sample_id?: string;
102
+ id?: string | number;
103
+ epoch?: number;
104
+ eval_id?: string;
105
+ log?: string;
106
+ date?: string;
107
+ eval_metadata?: Record<string, unknown>;
108
+ task?: string;
109
+ task_name?: string;
110
+ model?: string;
111
+ score?: string;
98
112
  [key: string]: unknown;
99
113
  }
100
114
  export interface ContentTool {
@@ -0,0 +1,66 @@
1
+ import { Brand } from './brand';
2
+ /**
3
+ * AsyncData represents the possible states of some asynchronous operation like
4
+ * a network request to an API. When the request is first made, it's `loading`, but
5
+ * once we get a response, it will either represent the requested `data` or maybe
6
+ * the operation failed due to an `error`.
7
+ *
8
+ * @typeParam T - the data that will be returned
9
+ */
10
+ export type AsyncData<T> = AsyncDataLoading | AsyncDataNotLoading<T>;
11
+ export type AsyncDataLoading = Brand<{
12
+ data?: undefined;
13
+ loading: true;
14
+ error?: undefined;
15
+ }, "_please_use_AsyncData.loading_rather_than_your_own_instance_of_this_type_">;
16
+ /**
17
+ * The different states the async data can be in when loading is finished.
18
+ *
19
+ * @typeParam T - the data type that can be returned when error is undefined
20
+ */
21
+ export type AsyncDataNotLoading<T> = {
22
+ data: T;
23
+ loading: false;
24
+ error?: undefined;
25
+ } | {
26
+ data?: undefined;
27
+ loading: false;
28
+ error: Error;
29
+ };
30
+ type AsyncDataMap<Mapping> = {
31
+ [K in keyof Mapping]: AsyncData<Mapping[K]>;
32
+ };
33
+ /**
34
+ * The `compose` function allows a set of `AsyncData` values to be combined into
35
+ * a single `AsyncData`. The complex type of the function represents a transformation
36
+ * from an argument like this...
37
+ *
38
+ * ```typescript
39
+ * { a: AsyncData<A>, b: AsyncData<B>, c: AsyncData<C> }
40
+ *```
41
+ * ...to a return value like this...
42
+ *```
43
+ * AsyncData<{ a: A, b: B, c: C }>
44
+ *```
45
+ *
46
+ * In practice, this can be used to create hooks that depend on multiple API
47
+ * calls.
48
+ *
49
+ */
50
+ export declare function compose<Mapping>(hooks: AsyncDataMap<Mapping>): AsyncData<Mapping>;
51
+ /**
52
+ * The `data` function wraps the provided data in an `AsyncData` object, indicating
53
+ * that the data is not loading and there is no error.
54
+ *
55
+ * @template T - The type of the data
56
+ * @param {T} data - The data to wrap
57
+ * @returns {AsyncData<T>} - An `AsyncData` object with `loading` set to `false`
58
+ * and `data` set to the provided data
59
+ */
60
+ export declare function data<T>(data: T): AsyncData<T>;
61
+ /**
62
+ * The `loading` constant is an instance of `AsyncDataLoading` that can be shared
63
+ * to provide identity stability. It represents the state when the data is loading.
64
+ */
65
+ export declare const loading: AsyncDataLoading;
66
+ export {};
@@ -0,0 +1,13 @@
1
+ import { QueryKey, UseQueryOptions } from '@tanstack/react-query';
2
+ import { AsyncData } from './asyncData';
3
+ /**
4
+ * Custom hook that retrieves data using `useQuery` from the `@tanstack/react-query`
5
+ * library. It wraps the `QueryResult` from the hook in a simpler `AsyncData`.
6
+ *
7
+ * @param options - An object of type `UseQueryOptions`.
8
+ * @returns An object of type `AsyncData`. If the query is pending, it returns a
9
+ * loading state. If there's an error, it returns an object with the error and loading
10
+ * state as false. If the query is successful, it returns the data and loading state
11
+ * as false.
12
+ */
13
+ export declare function useAsyncDataFromQuery<TQueryFnData = unknown, TData = TQueryFnData, TQueryKey extends QueryKey = QueryKey>(options: UseQueryOptions<TQueryFnData, Error, TData, TQueryKey>): AsyncData<TData>;
@@ -0,0 +1,70 @@
1
+ /**
2
+ * Branded types for nominal typing in TypeScript.
3
+ *
4
+ * Branded types create distinct types from the same base type,
5
+ * preventing accidental misuse at compile time with zero runtime overhead.
6
+ *
7
+ * @example
8
+ * ```ts
9
+ * type UserId = Brand<number, "UserId">;
10
+ * type PostId = Brand<number, "PostId">;
11
+ *
12
+ * const makeUserId = make<UserId>();
13
+ * const makePostId = make<PostId>();
14
+ *
15
+ * const userId = makeUserId(42);
16
+ * const postId = makePostId(42);
17
+ * getUser(postId); // ✗ compile error - PostId !== UserId
18
+ * ```
19
+ *
20
+ * @module
21
+ */
22
+ declare const __brand: unique symbol;
23
+ /**
24
+ * Creates a branded type from a base type.
25
+ *
26
+ * The brand exists only at compile time—no runtime overhead.
27
+ *
28
+ * @typeParam Base - The underlying primitive or object type
29
+ * @typeParam Branding - A unique type used to distinguish this brand (often the entity type itself)
30
+ *
31
+ * @example
32
+ * ```ts
33
+ * type UserId = Brand<number, User>;
34
+ * type PostId = Brand<number, Post>;
35
+ * // UserId and PostId are incompatible even though both are numbers
36
+ * ```
37
+ */
38
+ export type Brand<Base, Branding> = Base & {
39
+ [__brand]: Branding;
40
+ };
41
+ /**
42
+ * Extracts the base type from a branded type.
43
+ *
44
+ * @typeParam B - A branded type
45
+ * @returns The underlying base type without the brand
46
+ *
47
+ * @example
48
+ * ```ts
49
+ * type UserId = Brand<number, User>;
50
+ * type Base = BaseOf<UserId>; // number
51
+ * ```
52
+ */
53
+ type BaseOf<B extends Brand<unknown, unknown>> = Omit<B, typeof __brand>;
54
+ /** A function that converts a base value into a branded value. */
55
+ type Brander<B extends Brand<unknown, unknown>> = (value: BaseOf<B>) => B;
56
+ /**
57
+ * Creates a brander function for a given branded type.
58
+ *
59
+ * @typeParam B - The branded type to produce
60
+ * @returns A function that casts base values to the branded type
61
+ *
62
+ * @example
63
+ * ```ts
64
+ * type UserId = Brand<number, "UserId">;
65
+ * const makeUserId = make<UserId>();
66
+ * const id = makeUserId(42);
67
+ * ```
68
+ */
69
+ export declare function make<B extends Brand<unknown, unknown>>(): Brander<B>;
70
+ export {};
@@ -13,11 +13,14 @@ export declare const dirname: (path: string) => string;
13
13
  export declare const isInDirectory: (path: string, directory: string) => boolean;
14
14
  export declare const ensureTrailingSlash: (path?: string) => string;
15
15
  /**
16
- * Converts an absolute path to a relative path based on the results directory.
17
- * Handles nested subdirectories within the results directory.
18
- * For example: "/Users/user/scans/subdir/scan_id=123" -> "subdir/scan_id=123"
16
+ * Converts an absolute path to a relative path based on the basePath directory.
17
+ * Handles nested subdirectories within the basePath directory.
18
+ * For example:
19
+ * ```
20
+ * toRelativePath("/Users/user/scans/subdir/scan_id=123", "/Users/user/scans") === "subdir/scan_id=123"
21
+ * ```
19
22
  */
20
- export declare const toRelativePath: (absolutePath: string, basePath: string) => string;
23
+ export declare const toRelativePath: (absolutePath: string | undefined, basePath: string | undefined) => string;
21
24
  /**
22
25
  * Converts a relative path to an absolute path based on the results directory.
23
26
  * For example: "subdir/scan_id=123" + "/Users/user/scans/" -> "/Users/user/scans/subdir/scan_id=123"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@metrevals/inspect-scout-viewer",
3
- "version": "0.4.3-beta.1765899631",
3
+ "version": "0.4.4-beta.20251223202036",
4
4
  "description": "Inspect Scout viewer for evaluation logs.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -17,27 +17,10 @@
17
17
  "url": "https://github.com/meridianlabs-ai/inspect_scout",
18
18
  "directory": "src/inspect_scout/_view/www"
19
19
  },
20
- "packageManager": "pnpm@10.20.0",
21
20
  "engines": {
22
21
  "node": "22.21.1",
23
22
  "pnpm": ">=9.0.0"
24
23
  },
25
- "scripts": {
26
- "build": "npm run build:app",
27
- "build:lib": "vite build --mode library",
28
- "build:app": "vite build --mode development",
29
- "watch": "vite build --watch",
30
- "watch:dev": "NODE_ENV=development vite build --watch --mode development",
31
- "dev": "vite",
32
- "prepublishOnly": "pnpm build:lib",
33
- "preview": "vite preview",
34
- "lint": "eslint . --max-warnings 0",
35
- "lint:fix": "eslint . --fix --max-warnings 0",
36
- "format": "prettier --write \"src/**/*.{ts,tsx,js,jsx,json,css,md}\"",
37
- "format:check": "prettier --check \"src/**/*.{ts,tsx,js,jsx,json,css,md}\"",
38
- "typecheck": "tsc --noEmit",
39
- "check": "pnpm lint:fix && pnpm format && pnpm typecheck"
40
- },
41
24
  "exports": {
42
25
  ".": {
43
26
  "import": "./lib/index.js",
@@ -46,11 +29,13 @@
46
29
  "./styles/index.css": "./lib/styles/index.css"
47
30
  },
48
31
  "peerDependencies": {
32
+ "@tanstack/react-query": "^5.0.0",
49
33
  "react": "^19.0.0",
50
34
  "react-dom": "^19.0.0"
51
35
  },
52
36
  "devDependencies": {
53
37
  "@eslint/js": "^9.38.0",
38
+ "@testing-library/react": "^16.3.1",
54
39
  "@types/bootstrap": "^5.2.10",
55
40
  "@types/css-modules": "^1.0.5",
56
41
  "@types/eslint__js": "^9.14.0",
@@ -68,6 +53,7 @@
68
53
  "eslint-plugin-react": "^7.37.5",
69
54
  "eslint-plugin-react-hooks": "^7.0.1",
70
55
  "eslint-plugin-react-refresh": "^0.4.24",
56
+ "jsdom": "^27.3.0",
71
57
  "postcss-url": "^10.1.3",
72
58
  "prettier": "^3.6.2",
73
59
  "react": "^19.2.0",
@@ -77,8 +63,11 @@
77
63
  "typescript": "^5.7.3",
78
64
  "typescript-eslint": "^8.46.2",
79
65
  "typescript-plugin-css-modules": "^5.2.0",
66
+ "@tanstack/react-query": "^5.90.12",
67
+ "@tanstack/react-query-devtools": "^5.91.1",
80
68
  "vite": "^7.1.5",
81
- "vite-plugin-dts": "^4.3.0"
69
+ "vite-plugin-dts": "^4.3.0",
70
+ "vitest": "^4.0.16"
82
71
  },
83
72
  "dependencies": {
84
73
  "@popperjs/core": "^2.11.8",
@@ -104,9 +93,21 @@
104
93
  "react-virtuoso": "^4.14.1",
105
94
  "zustand": "^5.0.8"
106
95
  },
107
- "pnpm": {
108
- "overrides": {
109
- "yaml": "^2.4.2"
110
- }
96
+ "scripts": {
97
+ "build": "npm run build:app",
98
+ "build:lib": "vite build --mode library",
99
+ "build:app": "vite build --mode development",
100
+ "watch": "vite build --watch",
101
+ "watch:dev": "NODE_ENV=development vite build --watch --mode development",
102
+ "dev": "vite",
103
+ "preview": "vite preview",
104
+ "lint": "eslint . --max-warnings 0",
105
+ "lint:fix": "eslint . --fix --max-warnings 0",
106
+ "format": "prettier --write \"src/**/*.{ts,tsx,js,jsx,json,css,md}\"",
107
+ "format:check": "prettier --check \"src/**/*.{ts,tsx,js,jsx,json,css,md}\"",
108
+ "typecheck": "tsc --noEmit",
109
+ "check": "pnpm lint:fix && pnpm format && pnpm typecheck",
110
+ "test": "vitest run",
111
+ "test:watch": "vitest"
111
112
  }
112
- }
113
+ }
@@ -1,2 +0,0 @@
1
- import { default as React } from 'react';
2
- export declare const ScannerPanel: React.FC;
@@ -1,3 +0,0 @@
1
- export declare const kSegmentList = "list";
2
- export declare const kSegmentDataframe = "dataframe";
3
- export declare const ScannerPanelBody: React.FC;
@@ -1,2 +0,0 @@
1
- import { FC } from 'react';
2
- export declare const ScannerPanelTitle: FC;