inspect-ai 0.3.58__py3-none-any.whl → 0.3.60__py3-none-any.whl
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.
- inspect_ai/_cli/common.py +3 -1
- inspect_ai/_cli/eval.py +15 -9
- inspect_ai/_display/core/active.py +4 -1
- inspect_ai/_display/core/config.py +3 -3
- inspect_ai/_display/core/panel.py +7 -3
- inspect_ai/_display/plain/__init__.py +0 -0
- inspect_ai/_display/plain/display.py +203 -0
- inspect_ai/_display/rich/display.py +0 -5
- inspect_ai/_display/textual/widgets/port_mappings.py +110 -0
- inspect_ai/_display/textual/widgets/samples.py +79 -12
- inspect_ai/_display/textual/widgets/sandbox.py +37 -0
- inspect_ai/_eval/eval.py +10 -1
- inspect_ai/_eval/loader.py +79 -19
- inspect_ai/_eval/registry.py +6 -0
- inspect_ai/_eval/score.py +3 -1
- inspect_ai/_eval/task/results.py +51 -22
- inspect_ai/_eval/task/run.py +47 -13
- inspect_ai/_eval/task/sandbox.py +10 -5
- inspect_ai/_util/constants.py +1 -0
- inspect_ai/_util/port_names.py +61 -0
- inspect_ai/_util/text.py +23 -0
- inspect_ai/_view/www/App.css +31 -1
- inspect_ai/_view/www/dist/assets/index.css +31 -1
- inspect_ai/_view/www/dist/assets/index.js +25498 -2044
- inspect_ai/_view/www/log-schema.json +32 -2
- inspect_ai/_view/www/package.json +2 -0
- inspect_ai/_view/www/src/App.mjs +14 -16
- inspect_ai/_view/www/src/Types.mjs +1 -2
- inspect_ai/_view/www/src/api/Types.ts +133 -0
- inspect_ai/_view/www/src/api/{api-browser.mjs → api-browser.ts} +25 -13
- inspect_ai/_view/www/src/api/api-http.ts +219 -0
- inspect_ai/_view/www/src/api/api-shared.ts +47 -0
- inspect_ai/_view/www/src/api/{api-vscode.mjs → api-vscode.ts} +22 -19
- inspect_ai/_view/www/src/api/{client-api.mjs → client-api.ts} +93 -53
- inspect_ai/_view/www/src/api/index.ts +51 -0
- inspect_ai/_view/www/src/api/jsonrpc.ts +225 -0
- inspect_ai/_view/www/src/components/ChatView.mjs +133 -43
- inspect_ai/_view/www/src/components/DownloadButton.mjs +1 -1
- inspect_ai/_view/www/src/components/ExpandablePanel.mjs +0 -4
- inspect_ai/_view/www/src/components/LargeModal.mjs +19 -20
- inspect_ai/_view/www/src/components/TabSet.mjs +3 -1
- inspect_ai/_view/www/src/components/VirtualList.mjs +266 -84
- inspect_ai/_view/www/src/index.js +77 -4
- inspect_ai/_view/www/src/log/{remoteLogFile.mjs → remoteLogFile.ts} +62 -46
- inspect_ai/_view/www/src/navbar/Navbar.mjs +4 -1
- inspect_ai/_view/www/src/navbar/SecondaryBar.mjs +19 -10
- inspect_ai/_view/www/src/samples/SampleDialog.mjs +5 -1
- inspect_ai/_view/www/src/samples/SampleDisplay.mjs +23 -15
- inspect_ai/_view/www/src/samples/SampleList.mjs +19 -49
- inspect_ai/_view/www/src/samples/SampleScores.mjs +1 -1
- inspect_ai/_view/www/src/samples/SampleTranscript.mjs +8 -3
- inspect_ai/_view/www/src/samples/SamplesDescriptor.mjs +38 -26
- inspect_ai/_view/www/src/samples/SamplesTab.mjs +14 -11
- inspect_ai/_view/www/src/samples/SamplesTools.mjs +8 -8
- inspect_ai/_view/www/src/samples/tools/SampleFilter.mjs +712 -89
- inspect_ai/_view/www/src/samples/tools/SortFilter.mjs +2 -2
- inspect_ai/_view/www/src/samples/tools/filters.mjs +260 -87
- inspect_ai/_view/www/src/samples/transcript/ErrorEventView.mjs +24 -2
- inspect_ai/_view/www/src/samples/transcript/EventPanel.mjs +29 -24
- inspect_ai/_view/www/src/samples/transcript/EventRow.mjs +1 -1
- inspect_ai/_view/www/src/samples/transcript/InfoEventView.mjs +24 -2
- inspect_ai/_view/www/src/samples/transcript/InputEventView.mjs +24 -2
- inspect_ai/_view/www/src/samples/transcript/ModelEventView.mjs +31 -10
- inspect_ai/_view/www/src/samples/transcript/SampleInitEventView.mjs +24 -2
- inspect_ai/_view/www/src/samples/transcript/SampleLimitEventView.mjs +23 -2
- inspect_ai/_view/www/src/samples/transcript/ScoreEventView.mjs +24 -2
- inspect_ai/_view/www/src/samples/transcript/StepEventView.mjs +33 -3
- inspect_ai/_view/www/src/samples/transcript/SubtaskEventView.mjs +25 -2
- inspect_ai/_view/www/src/samples/transcript/ToolEventView.mjs +25 -2
- inspect_ai/_view/www/src/samples/transcript/TranscriptView.mjs +193 -11
- inspect_ai/_view/www/src/samples/transcript/Types.mjs +10 -0
- inspect_ai/_view/www/src/samples/transcript/state/StateEventView.mjs +26 -2
- inspect_ai/_view/www/src/types/log.d.ts +13 -2
- inspect_ai/_view/www/src/utils/Format.mjs +10 -3
- inspect_ai/_view/www/src/utils/{Json.mjs → json-worker.ts} +13 -9
- inspect_ai/_view/www/src/utils/vscode.ts +36 -0
- inspect_ai/_view/www/src/workspace/WorkSpace.mjs +11 -5
- inspect_ai/_view/www/vite.config.js +7 -0
- inspect_ai/_view/www/yarn.lock +116 -0
- inspect_ai/approval/_human/__init__.py +0 -0
- inspect_ai/approval/_human/manager.py +1 -1
- inspect_ai/approval/_policy.py +12 -6
- inspect_ai/log/_log.py +1 -1
- inspect_ai/log/_samples.py +16 -0
- inspect_ai/log/_transcript.py +4 -1
- inspect_ai/model/_call_tools.py +59 -0
- inspect_ai/model/_conversation.py +16 -7
- inspect_ai/model/_generate_config.py +12 -12
- inspect_ai/model/_model.py +117 -18
- inspect_ai/model/_model_output.py +22 -2
- inspect_ai/model/_openai.py +383 -0
- inspect_ai/model/_providers/anthropic.py +152 -55
- inspect_ai/model/_providers/azureai.py +21 -21
- inspect_ai/model/_providers/bedrock.py +37 -40
- inspect_ai/model/_providers/goodfire.py +248 -0
- inspect_ai/model/_providers/google.py +46 -54
- inspect_ai/model/_providers/groq.py +7 -3
- inspect_ai/model/_providers/hf.py +6 -0
- inspect_ai/model/_providers/mistral.py +13 -12
- inspect_ai/model/_providers/openai.py +51 -218
- inspect_ai/model/_providers/openai_o1.py +11 -12
- inspect_ai/model/_providers/providers.py +23 -1
- inspect_ai/model/_providers/together.py +12 -12
- inspect_ai/model/_providers/util/__init__.py +2 -3
- inspect_ai/model/_providers/util/hf_handler.py +1 -1
- inspect_ai/model/_providers/util/llama31.py +1 -1
- inspect_ai/model/_providers/util/util.py +0 -76
- inspect_ai/model/_providers/vertex.py +1 -4
- inspect_ai/scorer/_metric.py +3 -0
- inspect_ai/scorer/_reducer/reducer.py +1 -1
- inspect_ai/scorer/_scorer.py +4 -3
- inspect_ai/solver/__init__.py +4 -5
- inspect_ai/solver/_basic_agent.py +1 -1
- inspect_ai/solver/_bridge/__init__.py +3 -0
- inspect_ai/solver/_bridge/bridge.py +100 -0
- inspect_ai/solver/_bridge/patch.py +170 -0
- inspect_ai/solver/_prompt.py +35 -5
- inspect_ai/solver/_solver.py +6 -0
- inspect_ai/solver/_task_state.py +80 -38
- inspect_ai/tool/__init__.py +2 -0
- inspect_ai/tool/_tool.py +12 -1
- inspect_ai/tool/_tool_call.py +10 -0
- inspect_ai/tool/_tool_def.py +16 -5
- inspect_ai/tool/_tool_with.py +21 -4
- inspect_ai/tool/beta/__init__.py +5 -0
- inspect_ai/tool/beta/_computer/__init__.py +3 -0
- inspect_ai/tool/beta/_computer/_common.py +133 -0
- inspect_ai/tool/beta/_computer/_computer.py +155 -0
- inspect_ai/tool/beta/_computer/_computer_split.py +198 -0
- inspect_ai/tool/beta/_computer/_resources/Dockerfile +100 -0
- inspect_ai/tool/beta/_computer/_resources/README.md +30 -0
- inspect_ai/tool/beta/_computer/_resources/entrypoint/entrypoint.sh +18 -0
- inspect_ai/tool/beta/_computer/_resources/entrypoint/novnc_startup.sh +20 -0
- inspect_ai/tool/beta/_computer/_resources/entrypoint/x11vnc_startup.sh +48 -0
- inspect_ai/tool/beta/_computer/_resources/entrypoint/xfce_startup.sh +13 -0
- inspect_ai/tool/beta/_computer/_resources/entrypoint/xvfb_startup.sh +48 -0
- inspect_ai/tool/beta/_computer/_resources/image_home_dir/Desktop/Firefox Web Browser.desktop +10 -0
- inspect_ai/tool/beta/_computer/_resources/image_home_dir/Desktop/Visual Studio Code.desktop +10 -0
- inspect_ai/tool/beta/_computer/_resources/image_home_dir/Desktop/XPaint.desktop +10 -0
- inspect_ai/tool/beta/_computer/_resources/tool/__init__.py +0 -0
- inspect_ai/tool/beta/_computer/_resources/tool/_logger.py +22 -0
- inspect_ai/tool/beta/_computer/_resources/tool/_run.py +42 -0
- inspect_ai/tool/beta/_computer/_resources/tool/_tool_result.py +33 -0
- inspect_ai/tool/beta/_computer/_resources/tool/_x11_client.py +262 -0
- inspect_ai/tool/beta/_computer/_resources/tool/computer_tool.py +85 -0
- inspect_ai/tool/beta/_computer/_resources/tool/requirements.txt +0 -0
- inspect_ai/util/__init__.py +2 -0
- inspect_ai/util/_display.py +5 -0
- inspect_ai/util/_limit.py +26 -0
- inspect_ai/util/_sandbox/docker/docker.py +64 -1
- inspect_ai/util/_sandbox/docker/internal.py +3 -1
- inspect_ai/util/_sandbox/docker/prereqs.py +1 -1
- inspect_ai/util/_sandbox/environment.py +14 -0
- {inspect_ai-0.3.58.dist-info → inspect_ai-0.3.60.dist-info}/METADATA +3 -2
- {inspect_ai-0.3.58.dist-info → inspect_ai-0.3.60.dist-info}/RECORD +159 -126
- inspect_ai/_view/www/src/api/Types.mjs +0 -117
- inspect_ai/_view/www/src/api/api-http.mjs +0 -300
- inspect_ai/_view/www/src/api/api-shared.mjs +0 -10
- inspect_ai/_view/www/src/api/index.mjs +0 -49
- inspect_ai/_view/www/src/api/jsonrpc.mjs +0 -208
- inspect_ai/_view/www/src/samples/transcript/TranscriptState.mjs +0 -70
- inspect_ai/_view/www/src/utils/vscode.mjs +0 -16
- {inspect_ai-0.3.58.dist-info → inspect_ai-0.3.60.dist-info}/LICENSE +0 -0
- {inspect_ai-0.3.58.dist-info → inspect_ai-0.3.60.dist-info}/WHEEL +0 -0
- {inspect_ai-0.3.58.dist-info → inspect_ai-0.3.60.dist-info}/entry_points.txt +0 -0
- {inspect_ai-0.3.58.dist-info → inspect_ai-0.3.60.dist-info}/top_level.txt +0 -0
@@ -1,117 +0,0 @@
|
|
1
|
-
//@ts-check
|
2
|
-
|
3
|
-
/**
|
4
|
-
* @typedef {Object} EvalSummary
|
5
|
-
* @property {import("../types/log").Version} [version]
|
6
|
-
* @property {import("../types/log").Status} [status]
|
7
|
-
* @property {import("../types/log").EvalSpec} eval
|
8
|
-
* @property {import("../types/log").EvalPlan} [plan]
|
9
|
-
* @property {import("../types/log").EvalResults | null } [results]
|
10
|
-
* @property {import("../types/log").EvalStats} [stats]
|
11
|
-
* @property {import("../types/log").EvalError | null } [error]
|
12
|
-
* @property {SampleSummary[]} sampleSummaries
|
13
|
-
*/
|
14
|
-
|
15
|
-
/**
|
16
|
-
* @typedef {Object} EvalLogHeader
|
17
|
-
* @property {import("../types/log").Version} [version]
|
18
|
-
* @property {import("../types/log").Status} [status]
|
19
|
-
* @property {import("../types/log").EvalSpec} eval
|
20
|
-
* @property {import("../types/log").EvalPlan} [plan]
|
21
|
-
* @property {import("../types/log").EvalResults} [results]
|
22
|
-
* @property {import("../types/log").EvalStats} [stats]
|
23
|
-
* @property {import("../types/log").EvalError} [error]
|
24
|
-
*/
|
25
|
-
|
26
|
-
/**
|
27
|
-
* @typedef {Object} SampleSummary
|
28
|
-
* @property { number | string } id
|
29
|
-
* @property { number } epoch
|
30
|
-
* @property { import("../types/log").Input } input
|
31
|
-
* @property { import("../types/log").Target } target
|
32
|
-
* @property { import("../types/log").Scores1 } scores
|
33
|
-
* @property { string } [error]
|
34
|
-
* @property { import("../types/log").Type11 } [limit]
|
35
|
-
*/
|
36
|
-
|
37
|
-
/**
|
38
|
-
* Fields shared by EvalSample and SampleSummary.
|
39
|
-
* Contains only fields that are copied verbatim in src/inspect_ai/log/_recorders/eval.py.
|
40
|
-
*
|
41
|
-
* @typedef {Object} BasicSampleData
|
42
|
-
* @property { number | string } id
|
43
|
-
* @property { number } epoch
|
44
|
-
* @property { import("../types/log").Target } target
|
45
|
-
* @property { import("../types/log").Scores1 } scores
|
46
|
-
*/
|
47
|
-
|
48
|
-
/**
|
49
|
-
* @typedef {Object} Capabilities
|
50
|
-
* @property {boolean} downloadFiles - Indicates if file downloads are supported.
|
51
|
-
* @property {boolean} webWorkers - Indicates if web workers are supported.
|
52
|
-
*/
|
53
|
-
|
54
|
-
/**
|
55
|
-
* @typedef {Object} LogViewAPI
|
56
|
-
* @property { () => Promise<any[]> } client_events - A function which can be polled to check for client events.
|
57
|
-
* @property { () => Promise<LogFiles>} eval_logs - Read the list of files
|
58
|
-
* @property { (log_file: string, headerOnly?: number, capabilities?: Capabilities) => Promise<LogContents> } eval_log - Read the log contents
|
59
|
-
* @property { (log_file: string) => Promise<number>} eval_log_size - Get log size
|
60
|
-
* @property { (log_file: string, start: number, end: number) => Promise<Uint8Array>} eval_log_bytes - Read bytes
|
61
|
-
* @property { (log_files: string[]) => Promise<import("../types/log").EvalLog[]>} eval_log_headers - Read the log headers
|
62
|
-
* @property { (logFile: string, downloadFiles?: boolean, webWorkers?: boolean) => Promise<void> } download_file - Execute a file download
|
63
|
-
* @property { (logFile: string, log_dir: string) => Promise<void> } open_log_file - Execute a file open
|
64
|
-
*/
|
65
|
-
|
66
|
-
/**
|
67
|
-
* @typedef {Object} ClientAPI
|
68
|
-
* @property { () => Promise<string[]> } client_events - A function which can be polled to check for client events.
|
69
|
-
* @property { () => Promise<LogFiles>} get_log_paths - Get the list of files
|
70
|
-
* @property { (log_files: string[]) => Promise<import("../types/log").EvalLog[]>} get_log_headers - Get the log headers
|
71
|
-
* @property { (log_file: string) => Promise<EvalSummary>} get_log_summary - Get the log summary
|
72
|
-
* @property { (log_file: string, id: string | number, epoch: number) => Promise<import("../types/log").EvalSample | undefined>} get_log_sample - Get a sample
|
73
|
-
* @property { (log_file: string, download_files?: boolean, web_workers?: boolean) => Promise<void> } download_file - Execute a file download
|
74
|
-
* @property { (log_file: string, log_dir: string) => Promise<void> } open_log_file - Execute a file open
|
75
|
-
*/
|
76
|
-
|
77
|
-
/**
|
78
|
-
* @typedef {Object} FetchResponse
|
79
|
-
* @property {string} raw - The raw string content of the fetched file.
|
80
|
-
* @property {Object} parsed - The parsed content of the file as an object.
|
81
|
-
*/
|
82
|
-
|
83
|
-
/**
|
84
|
-
* @typedef {Object} EvalHeader
|
85
|
-
* @property {import("../types/log").Version | undefined} version - The raw string content of the fetched file.
|
86
|
-
* @property {import("../types/log").Status | undefined} status - The raw string content of the fetched file.
|
87
|
-
* @property {import("../types/log").EvalSpec } eval - The raw string content of the fetched file.
|
88
|
-
* @property {import("../types/log").EvalPlan | undefined } plan - The raw string content of the fetched file.
|
89
|
-
* @property {import("../types/log").EvalResults | undefined | null } results - The raw string content of the fetched file.
|
90
|
-
* @property {import("../types/log").EvalStats | undefined } stats - The raw string content of the fetched file.
|
91
|
-
* @property {import("../types/log").EvalError | undefined | null } error - The raw string content of the fetched file.
|
92
|
-
*/
|
93
|
-
|
94
|
-
/**
|
95
|
-
* @typedef {Object} LogFiles
|
96
|
-
* @property {LogFile[]} files - The log files
|
97
|
-
* @property {string} log_dir - The log dir
|
98
|
-
*/
|
99
|
-
|
100
|
-
/**
|
101
|
-
* @typedef {Object} LogFile
|
102
|
-
* @property {string} name - The path to this log file
|
103
|
-
* @property {string} task - The name of the task
|
104
|
-
* @property {string} task_id - The the id of the task
|
105
|
-
*/
|
106
|
-
|
107
|
-
/**
|
108
|
-
* @typedef {Object} LogContents
|
109
|
-
* @property {string} raw - The raw string content of the fetched file.
|
110
|
-
* @property {import("../types/log").EvalLog} parsed - The parsed content of the file as an object.
|
111
|
-
*/
|
112
|
-
|
113
|
-
/**
|
114
|
-
* @typedef {Object} LogFilesFetchResponse
|
115
|
-
* @property {string} raw - The raw string content of the fetched file.
|
116
|
-
* @property {Record<string, EvalHeader>} parsed - The parsed content of the file as an object.
|
117
|
-
*/
|
@@ -1,300 +0,0 @@
|
|
1
|
-
//@ts-check
|
2
|
-
import { asyncJsonParse } from "../utils/Json.mjs";
|
3
|
-
import { download_file } from "./api-shared.mjs";
|
4
|
-
import { fetchRange, fetchSize } from "../utils/remoteZipFile.mjs";
|
5
|
-
|
6
|
-
/**
|
7
|
-
* This provides an API implementation that will serve a single
|
8
|
-
* file using an http parameter, designed to be deployed
|
9
|
-
* to a webserver without inspect or the ability to enumerate log
|
10
|
-
* files
|
11
|
-
*
|
12
|
-
* @param { string } log_dir - The log directory for this API.
|
13
|
-
* @param { string } [log_file] - The log file for this API.
|
14
|
-
* @returns { import("./Types.mjs").LogViewAPI } A Log Viewer API
|
15
|
-
*/
|
16
|
-
export default function simpleHttpApi(log_dir, log_file) {
|
17
|
-
const resolved_log_dir = log_dir.replace(" ", "+");
|
18
|
-
const resolved_log_path = log_file ? log_file.replace(" ", "+") : undefined;
|
19
|
-
return simpleHttpAPI({
|
20
|
-
log_file: resolved_log_path,
|
21
|
-
log_dir: resolved_log_dir,
|
22
|
-
});
|
23
|
-
}
|
24
|
-
|
25
|
-
/**
|
26
|
-
* Fetches a file from the specified URL and parses its content.
|
27
|
-
*
|
28
|
-
* @param {{ log_file?: string, log_dir: string }} logInfo - The logInfo for this API.
|
29
|
-
* @returns { import("./Types.mjs").LogViewAPI } An object containing the parsed data and the raw text of the file.
|
30
|
-
*/
|
31
|
-
function simpleHttpAPI(logInfo) {
|
32
|
-
const log_file = logInfo.log_file;
|
33
|
-
const log_dir = logInfo.log_dir;
|
34
|
-
|
35
|
-
// Use a cache for the single file case
|
36
|
-
// since we just use the log file that we already read
|
37
|
-
const cache = log_file_cache(log_file);
|
38
|
-
|
39
|
-
async function open_log_file() {
|
40
|
-
// No op
|
41
|
-
}
|
42
|
-
return {
|
43
|
-
client_events: async () => {
|
44
|
-
return Promise.resolve([]);
|
45
|
-
},
|
46
|
-
eval_logs: async () => {
|
47
|
-
const headers = await fetchLogHeaders(log_dir);
|
48
|
-
if (headers) {
|
49
|
-
const logRecord = headers.parsed;
|
50
|
-
const logs = Object.keys(logRecord).map((key) => {
|
51
|
-
return {
|
52
|
-
name: joinURI(log_dir, key),
|
53
|
-
task: logRecord[key].eval.task,
|
54
|
-
task_id: logRecord[key].eval.task_id,
|
55
|
-
};
|
56
|
-
});
|
57
|
-
return Promise.resolve({
|
58
|
-
files: logs,
|
59
|
-
log_dir,
|
60
|
-
});
|
61
|
-
} else if (log_file) {
|
62
|
-
// Check the cache
|
63
|
-
let evalLog = cache.get();
|
64
|
-
if (!evalLog) {
|
65
|
-
const response = await fetchLogFile(log_file);
|
66
|
-
cache.set(response.parsed);
|
67
|
-
evalLog = response.parsed;
|
68
|
-
}
|
69
|
-
|
70
|
-
// Since no log directory manifest was found, just use
|
71
|
-
// the log file to generate a single file manifest
|
72
|
-
const result = {
|
73
|
-
name: log_file,
|
74
|
-
task: evalLog.eval.task,
|
75
|
-
task_id: evalLog.eval.task_id,
|
76
|
-
};
|
77
|
-
|
78
|
-
return {
|
79
|
-
files: [result],
|
80
|
-
log_dir,
|
81
|
-
};
|
82
|
-
} else {
|
83
|
-
// No log.json could be found, and there isn't a log file,
|
84
|
-
throw new Error(
|
85
|
-
`Failed to load a manifest files using the directory: ${log_dir}. Please be sure you have deployed a manifest file (logs.json).`,
|
86
|
-
);
|
87
|
-
}
|
88
|
-
},
|
89
|
-
eval_log: async (file) => {
|
90
|
-
const response = await fetchLogFile(file);
|
91
|
-
cache.set(response.parsed);
|
92
|
-
return response;
|
93
|
-
},
|
94
|
-
eval_log_size: async (log_file) => {
|
95
|
-
return await fetchSize(log_file);
|
96
|
-
},
|
97
|
-
eval_log_bytes: async (log_file, start, end) => {
|
98
|
-
return await fetchRange(log_file, start, end);
|
99
|
-
},
|
100
|
-
eval_log_headers: async (files) => {
|
101
|
-
const headers = await fetchLogHeaders(log_dir);
|
102
|
-
if (headers) {
|
103
|
-
const keys = Object.keys(headers.parsed);
|
104
|
-
const result = [];
|
105
|
-
files.forEach((file) => {
|
106
|
-
const fileKey = keys.find((key) => {
|
107
|
-
return file.endsWith(key);
|
108
|
-
});
|
109
|
-
if (fileKey) {
|
110
|
-
result.push(headers.parsed[fileKey]);
|
111
|
-
}
|
112
|
-
});
|
113
|
-
return result;
|
114
|
-
} else if (log_file) {
|
115
|
-
// Check the cache
|
116
|
-
let evalLog = cache.get();
|
117
|
-
if (!evalLog) {
|
118
|
-
const response = await fetchLogFile(log_file);
|
119
|
-
cache.set(response.parsed);
|
120
|
-
evalLog = response.parsed;
|
121
|
-
}
|
122
|
-
return [evalLog];
|
123
|
-
} else {
|
124
|
-
// No log.json could be found, and there isn't a log file,
|
125
|
-
throw new Error(
|
126
|
-
`Failed to load a manifest files using the directory: ${log_dir}. Please be sure you have deployed a manifest file (logs.json).`,
|
127
|
-
);
|
128
|
-
}
|
129
|
-
},
|
130
|
-
download_file,
|
131
|
-
open_log_file,
|
132
|
-
};
|
133
|
-
}
|
134
|
-
|
135
|
-
/**
|
136
|
-
* Fetches a file from the specified URL and parses its content.
|
137
|
-
*
|
138
|
-
* @param {string} url - The URL to fetch the file from.
|
139
|
-
* @param {(text: string) => Promise<Object>} parse - A function that takes the raw file text and returns a parsed object.
|
140
|
-
* @param {(response: Response) => boolean } [handleError] - A function that may process the error and determine whether to throw
|
141
|
-
* @returns {Promise<import("./Types.mjs").FetchResponse | undefined> } An object containing the parsed data and the raw text of the file.
|
142
|
-
* @throws {Error} Will throw an error if the HTTP request fails or the response is not OK (status code not 200).
|
143
|
-
*/
|
144
|
-
async function fetchFile(url, parse, handleError) {
|
145
|
-
const safe_url = encodePathParts(url);
|
146
|
-
const response = await fetch(`${safe_url}`, { method: "GET" });
|
147
|
-
if (response.ok) {
|
148
|
-
const text = await response.text();
|
149
|
-
return {
|
150
|
-
parsed: await parse(text),
|
151
|
-
raw: text,
|
152
|
-
};
|
153
|
-
} else if (response.status !== 200) {
|
154
|
-
if (handleError && handleError(response)) {
|
155
|
-
return undefined;
|
156
|
-
}
|
157
|
-
const message = (await response.text()) || response.statusText;
|
158
|
-
const error = new Error(`${response.status}: ${message})`);
|
159
|
-
throw error;
|
160
|
-
} else {
|
161
|
-
throw new Error(`${response.status} - ${response.statusText} `);
|
162
|
-
}
|
163
|
-
}
|
164
|
-
|
165
|
-
/**
|
166
|
-
* Fetches a log file and parses its content, updating the log structure if necessary.
|
167
|
-
*
|
168
|
-
* @param {string} file - The path or URL of the log file to fetch.
|
169
|
-
* @returns {Promise<import("./Types.mjs").LogContents | undefined>} The parsed log file, potentially updated to version 2 format.
|
170
|
-
* @throws {Error} Will throw an error if the fetching or parsing fails.
|
171
|
-
*/
|
172
|
-
const fetchLogFile = async (file) => {
|
173
|
-
return fetchFile(file, async (text) => {
|
174
|
-
const log = await asyncJsonParse(text);
|
175
|
-
if (log.version === 1) {
|
176
|
-
// Update log structure to v2 format
|
177
|
-
if (log.results) {
|
178
|
-
log.results.scores = [];
|
179
|
-
log.results.scorer.scorer = log.results.scorer.name;
|
180
|
-
log.results.scores.push(log.results.scorer);
|
181
|
-
delete log.results.scorer;
|
182
|
-
log.results.scores[0].metrics = log.results.metrics;
|
183
|
-
delete log.results.metrics;
|
184
|
-
|
185
|
-
// migrate samples
|
186
|
-
const scorerName = log.results.scores[0].name;
|
187
|
-
log.samples.forEach((sample) => {
|
188
|
-
sample.scores = { [scorerName]: sample.score };
|
189
|
-
delete sample.score;
|
190
|
-
});
|
191
|
-
}
|
192
|
-
}
|
193
|
-
return log;
|
194
|
-
});
|
195
|
-
};
|
196
|
-
|
197
|
-
/**
|
198
|
-
* Fetches a log file and parses its content, updating the log structure if necessary.
|
199
|
-
*
|
200
|
-
* @param {string} log_dir - The path to the log directory
|
201
|
-
* @returns {Promise<import("./Types.mjs").LogFilesFetchResponse | undefined>} The parsed log file, potentially updated to version 2 format.
|
202
|
-
* @throws {Error} Will throw an error if the fetching or parsing fails.
|
203
|
-
*/
|
204
|
-
const fetchLogHeaders = async (log_dir) => {
|
205
|
-
const logs = await fetchFile(
|
206
|
-
log_dir + "/logs.json",
|
207
|
-
async (text) => {
|
208
|
-
return await asyncJsonParse(text);
|
209
|
-
},
|
210
|
-
(response) => {
|
211
|
-
if (response.status === 404) {
|
212
|
-
// Couldn't find a header file
|
213
|
-
return true;
|
214
|
-
}
|
215
|
-
},
|
216
|
-
);
|
217
|
-
return logs;
|
218
|
-
};
|
219
|
-
|
220
|
-
/**
|
221
|
-
* Joins multiple URI segments into a single URI string.
|
222
|
-
*
|
223
|
-
* This function removes any leading or trailing slashes from each segment
|
224
|
-
* and then joins them with a single slash (`/`).
|
225
|
-
*
|
226
|
-
* @param {...string} segments - The URI segments to join.
|
227
|
-
* @returns {string} The joined URI string.
|
228
|
-
*/
|
229
|
-
function joinURI(...segments) {
|
230
|
-
return segments
|
231
|
-
.map((segment) => segment.replace(/(^\/+|\/+$)/g, "")) // Remove leading/trailing slashes from each segment
|
232
|
-
.join("/");
|
233
|
-
}
|
234
|
-
|
235
|
-
/**
|
236
|
-
* Creates a cache mechanism for a log file. If no log file is provided,
|
237
|
-
* a no-op cache is returned. Otherwise, it allows caching of a single log file.
|
238
|
-
*
|
239
|
-
* @param {string | undefined} log_file - The log file to be cached. If null or undefined, a no-op cache is used.
|
240
|
-
* @returns {{ set: function(import("../types/log").EvalLog): void, get: function(): (import("../types/log").EvalLog|undefined) }}
|
241
|
-
* An object with `set` and `get` methods for caching the log file.
|
242
|
-
*/
|
243
|
-
const log_file_cache = (log_file) => {
|
244
|
-
// Use a no-op cache for non-single file
|
245
|
-
// cases
|
246
|
-
if (!log_file) {
|
247
|
-
return {
|
248
|
-
set: () => {},
|
249
|
-
get: () => {
|
250
|
-
return undefined;
|
251
|
-
},
|
252
|
-
};
|
253
|
-
}
|
254
|
-
|
255
|
-
// For a single file request, cache the log file request
|
256
|
-
let cache_file;
|
257
|
-
return {
|
258
|
-
set: (log_file) => {
|
259
|
-
cache_file = log_file;
|
260
|
-
},
|
261
|
-
get: () => {
|
262
|
-
return cache_file;
|
263
|
-
},
|
264
|
-
};
|
265
|
-
};
|
266
|
-
|
267
|
-
/**
|
268
|
-
* Encodes the path segments of a URL or relative path to ensure special characters
|
269
|
-
* (like `+`, spaces, etc.) are properly encoded without affecting legal characters like `/`.
|
270
|
-
*
|
271
|
-
* This function will encode file names and path portions of both absolute URLs and
|
272
|
-
* relative paths. It ensures that components of a full URL, such as the protocol and
|
273
|
-
* query parameters, remain intact, while only encoding the path.
|
274
|
-
*
|
275
|
-
* @param {string} url - The URL or relative path to encode.
|
276
|
-
* @returns {string} - The URL or path with the path segments properly encoded.
|
277
|
-
*/
|
278
|
-
function encodePathParts(url) {
|
279
|
-
if (!url) return url; // Handle empty strings
|
280
|
-
|
281
|
-
try {
|
282
|
-
// Parse a full Uri
|
283
|
-
const fullUrl = new URL(url);
|
284
|
-
fullUrl.pathname = fullUrl.pathname
|
285
|
-
.split("/")
|
286
|
-
.map((segment) =>
|
287
|
-
segment ? encodeURIComponent(decodeURIComponent(segment)) : "",
|
288
|
-
)
|
289
|
-
.join("/");
|
290
|
-
return fullUrl.toString();
|
291
|
-
} catch {
|
292
|
-
// This is a relative path that isn't parseable as Uri
|
293
|
-
return url
|
294
|
-
.split("/")
|
295
|
-
.map((segment) =>
|
296
|
-
segment ? encodeURIComponent(decodeURIComponent(segment)) : "",
|
297
|
-
)
|
298
|
-
.join("/");
|
299
|
-
}
|
300
|
-
}
|
@@ -1,10 +0,0 @@
|
|
1
|
-
// Function that uses the dom to download the contents provided in filecontents
|
2
|
-
export async function download_file(filename, filecontents) {
|
3
|
-
const blob = new Blob([filecontents], { type: "text/plain" });
|
4
|
-
const link = document.createElement("a");
|
5
|
-
link.href = URL.createObjectURL(blob);
|
6
|
-
link.download = filename;
|
7
|
-
document.body.appendChild(link);
|
8
|
-
link.click();
|
9
|
-
document.body.removeChild(link);
|
10
|
-
}
|
@@ -1,49 +0,0 @@
|
|
1
|
-
// @ts-check
|
2
|
-
|
3
|
-
import browserApi from "./api-browser.mjs";
|
4
|
-
import vscodeApi from "./api-vscode.mjs";
|
5
|
-
import simpleHttpApi from "./api-http.mjs";
|
6
|
-
import { dirname } from "../utils/Path.mjs";
|
7
|
-
import { getVscodeApi } from "../utils/vscode.mjs";
|
8
|
-
import { clientApi } from "./client-api.mjs";
|
9
|
-
|
10
|
-
//
|
11
|
-
/**
|
12
|
-
* Resolves the client API
|
13
|
-
*
|
14
|
-
* @returns { import("./Types.mjs").ClientAPI } A Client API for the viewer
|
15
|
-
*/
|
16
|
-
const resolveApi = () => {
|
17
|
-
// @ts-ignore
|
18
|
-
if (getVscodeApi()) {
|
19
|
-
return clientApi(vscodeApi);
|
20
|
-
} else {
|
21
|
-
// See if there is an log_file, log_dir embedded in the
|
22
|
-
// document or passed via URL
|
23
|
-
const scriptEl = document.getElementById("log_dir_context");
|
24
|
-
if (scriptEl) {
|
25
|
-
// Read the contents
|
26
|
-
const data = JSON.parse(scriptEl.textContent);
|
27
|
-
if (data.log_dir || data.log_file) {
|
28
|
-
const log_dir = data.log_dir || dirname(data.log_file);
|
29
|
-
const api = simpleHttpApi(log_dir, data.log_file);
|
30
|
-
return clientApi(api);
|
31
|
-
}
|
32
|
-
}
|
33
|
-
|
34
|
-
// See if there is url params passing info
|
35
|
-
const urlParams = new URLSearchParams(window.location.search);
|
36
|
-
const log_file = urlParams.get("log_file");
|
37
|
-
const log_dir = urlParams.get("log_dir");
|
38
|
-
if (log_file || log_dir) {
|
39
|
-
const api = simpleHttpApi(log_dir, log_file);
|
40
|
-
return clientApi(api);
|
41
|
-
}
|
42
|
-
|
43
|
-
// No signal information so use the standard
|
44
|
-
// browser API
|
45
|
-
return clientApi(browserApi);
|
46
|
-
}
|
47
|
-
};
|
48
|
-
|
49
|
-
export default resolveApi();
|
@@ -1,208 +0,0 @@
|
|
1
|
-
var kMethodEvalLogs = "eval_logs";
|
2
|
-
|
3
|
-
var kMethodEvalLog = "eval_log";
|
4
|
-
|
5
|
-
var kMethodEvalLogSize = "eval_log_size";
|
6
|
-
var kMethodEvalLogBytes = "eval_log_bytes";
|
7
|
-
|
8
|
-
var kMethodEvalLogHeaders = "eval_log_headers";
|
9
|
-
|
10
|
-
function webViewJsonRpcClient(vscode) {
|
11
|
-
var target = {
|
12
|
-
postMessage: function (data) {
|
13
|
-
vscode.postMessage(data);
|
14
|
-
},
|
15
|
-
onMessage: function (handler) {
|
16
|
-
var onMessage = function (ev) {
|
17
|
-
handler(ev.data);
|
18
|
-
};
|
19
|
-
window.addEventListener("message", onMessage);
|
20
|
-
return function () {
|
21
|
-
window.removeEventListener("message", onMessage);
|
22
|
-
};
|
23
|
-
},
|
24
|
-
};
|
25
|
-
var request = jsonRpcPostMessageRequestTransport(target).request;
|
26
|
-
return request;
|
27
|
-
}
|
28
|
-
|
29
|
-
var kJsonRpcParseError = -32700;
|
30
|
-
|
31
|
-
var kJsonRpcInvalidRequest = -32600;
|
32
|
-
|
33
|
-
var kJsonRpcMethodNotFound = -32601;
|
34
|
-
|
35
|
-
var kJsonRpcInvalidParams = -32602;
|
36
|
-
|
37
|
-
var kJsonRpcInternalError = -32603;
|
38
|
-
|
39
|
-
function jsonRpcError(message, data, code) {
|
40
|
-
if (typeof data === "string") {
|
41
|
-
data = {
|
42
|
-
description: data,
|
43
|
-
};
|
44
|
-
}
|
45
|
-
return {
|
46
|
-
code: code || -3200,
|
47
|
-
message,
|
48
|
-
data,
|
49
|
-
};
|
50
|
-
}
|
51
|
-
|
52
|
-
function asJsonRpcError(error) {
|
53
|
-
if (typeof error === "object") {
|
54
|
-
var err = error;
|
55
|
-
if (typeof err.message === "string") {
|
56
|
-
return jsonRpcError(err.message, err.data, err.code);
|
57
|
-
}
|
58
|
-
}
|
59
|
-
return jsonRpcError(String(error));
|
60
|
-
}
|
61
|
-
|
62
|
-
function jsonRpcPostMessageRequestTransport(target) {
|
63
|
-
var requests = new Map();
|
64
|
-
var disconnect = target.onMessage(function (ev) {
|
65
|
-
var response = asJsonRpcResponse(ev);
|
66
|
-
if (response) {
|
67
|
-
var request = requests.get(response.id);
|
68
|
-
if (request) {
|
69
|
-
requests["delete"](response.id);
|
70
|
-
if (response.error) {
|
71
|
-
request.reject(response.error);
|
72
|
-
} else {
|
73
|
-
request.resolve(response.result);
|
74
|
-
}
|
75
|
-
}
|
76
|
-
}
|
77
|
-
});
|
78
|
-
return {
|
79
|
-
request: function (method, params) {
|
80
|
-
return new Promise(function (resolve, reject) {
|
81
|
-
var requestId = Math.floor(Math.random() * 1e6);
|
82
|
-
requests.set(requestId, {
|
83
|
-
resolve,
|
84
|
-
reject,
|
85
|
-
});
|
86
|
-
var request = {
|
87
|
-
jsonrpc: kJsonRpcVersion,
|
88
|
-
id: requestId,
|
89
|
-
method,
|
90
|
-
params,
|
91
|
-
};
|
92
|
-
target.postMessage(request);
|
93
|
-
});
|
94
|
-
},
|
95
|
-
disconnect,
|
96
|
-
};
|
97
|
-
}
|
98
|
-
|
99
|
-
function jsonRpcPostMessageServer(target, methods) {
|
100
|
-
var lookupMethod =
|
101
|
-
typeof methods === "function"
|
102
|
-
? methods
|
103
|
-
: function (name) {
|
104
|
-
return methods[name];
|
105
|
-
};
|
106
|
-
return target.onMessage(function (data) {
|
107
|
-
var request = asJsonRpcRequest(data);
|
108
|
-
if (request) {
|
109
|
-
var method = lookupMethod(request.method);
|
110
|
-
if (!method) {
|
111
|
-
target.postMessage(methodNotFoundResponse(request));
|
112
|
-
return;
|
113
|
-
}
|
114
|
-
/* eslint-disable no-unexpected-multiline */
|
115
|
-
method(request.params || [])
|
116
|
-
.then(function (value) {
|
117
|
-
target.postMessage(jsonRpcResponse(request, value));
|
118
|
-
})
|
119
|
-
["catch"](function (error) {
|
120
|
-
target.postMessage({
|
121
|
-
jsonrpc: request.jsonrpc,
|
122
|
-
id: request.id,
|
123
|
-
error: asJsonRpcError(error),
|
124
|
-
});
|
125
|
-
});
|
126
|
-
/* eslint-enable no-unexpected-multiline */
|
127
|
-
}
|
128
|
-
});
|
129
|
-
}
|
130
|
-
|
131
|
-
var kJsonRpcVersion = "2.0";
|
132
|
-
|
133
|
-
function isJsonRpcMessage(message) {
|
134
|
-
var jsMessage = message;
|
135
|
-
return jsMessage.jsonrpc !== undefined && jsMessage.id !== undefined;
|
136
|
-
}
|
137
|
-
|
138
|
-
function isJsonRpcRequest(message) {
|
139
|
-
return message.method !== undefined;
|
140
|
-
}
|
141
|
-
|
142
|
-
function asJsonRpcMessage(data) {
|
143
|
-
if (isJsonRpcMessage(data) && data.jsonrpc === kJsonRpcVersion) {
|
144
|
-
return data;
|
145
|
-
} else {
|
146
|
-
return null;
|
147
|
-
}
|
148
|
-
}
|
149
|
-
|
150
|
-
function asJsonRpcRequest(data) {
|
151
|
-
var message = asJsonRpcMessage(data);
|
152
|
-
if (message && isJsonRpcRequest(message)) {
|
153
|
-
return message;
|
154
|
-
} else {
|
155
|
-
return null;
|
156
|
-
}
|
157
|
-
}
|
158
|
-
|
159
|
-
function asJsonRpcResponse(data) {
|
160
|
-
var message = asJsonRpcMessage(data);
|
161
|
-
if (message) {
|
162
|
-
return message;
|
163
|
-
} else {
|
164
|
-
return null;
|
165
|
-
}
|
166
|
-
}
|
167
|
-
|
168
|
-
function jsonRpcResponse(request, result) {
|
169
|
-
return {
|
170
|
-
jsonrpc: request.jsonrpc,
|
171
|
-
id: request.id,
|
172
|
-
result,
|
173
|
-
};
|
174
|
-
}
|
175
|
-
|
176
|
-
function jsonRpcErrorResponse(request, code, message) {
|
177
|
-
return {
|
178
|
-
jsonrpc: request.jsonrpc,
|
179
|
-
id: request.id,
|
180
|
-
error: jsonRpcError(message, undefined, code),
|
181
|
-
};
|
182
|
-
}
|
183
|
-
|
184
|
-
function methodNotFoundResponse(request) {
|
185
|
-
return jsonRpcErrorResponse(
|
186
|
-
request,
|
187
|
-
kJsonRpcMethodNotFound,
|
188
|
-
"Method '".concat(request.method, "' not found."),
|
189
|
-
);
|
190
|
-
}
|
191
|
-
|
192
|
-
export {
|
193
|
-
asJsonRpcError,
|
194
|
-
jsonRpcError,
|
195
|
-
jsonRpcPostMessageRequestTransport,
|
196
|
-
jsonRpcPostMessageServer,
|
197
|
-
kJsonRpcInternalError,
|
198
|
-
kJsonRpcInvalidParams,
|
199
|
-
kJsonRpcInvalidRequest,
|
200
|
-
kJsonRpcMethodNotFound,
|
201
|
-
kJsonRpcParseError,
|
202
|
-
webViewJsonRpcClient,
|
203
|
-
kMethodEvalLog,
|
204
|
-
kMethodEvalLogSize,
|
205
|
-
kMethodEvalLogBytes,
|
206
|
-
kMethodEvalLogs,
|
207
|
-
kMethodEvalLogHeaders,
|
208
|
-
};
|