viatris-exam-cli 0.0.0-stage → 1.3.0
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.
- package/README.md +211 -2
- package/package.json +22 -4
- package/skills/viatris-exam-cli/SKILL.md +44 -0
- package/skills/viatris-exam-cli/references/cli-reference.md +319 -0
- package/skills/viatris-exam-cli.zip +0 -0
- package/src/app.js +36 -0
- package/src/args.js +89 -0
- package/src/cli.js +11 -0
- package/src/command-handlers/content.js +43 -0
- package/src/command-handlers/exam-records.js +29 -0
- package/src/command-handlers/gen-tasks.js +53 -0
- package/src/command-handlers/medical-search.js +55 -0
- package/src/command-handlers/products.js +31 -0
- package/src/command-handlers/scoring.js +31 -0
- package/src/commands.js +28 -0
- package/src/config.js +85 -0
- package/src/errors.js +14 -0
- package/src/help.js +52 -0
- package/src/http.js +92 -0
- package/src/input.js +53 -0
- package/src/metadata.js +142 -0
- package/src/output.js +17 -0
package/README.md
CHANGED
|
@@ -1,3 +1,212 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Viatris Exam CLI
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
面向 Agent 的 Viatris 考试 OpenAPI 命令行客户端。运行时零第三方依赖,要求 Node.js 18 或更高版本。
|
|
4
|
+
|
|
5
|
+
## 安装
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm link
|
|
9
|
+
export VIATRIS_API_KEY="replace-with-real-key"
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
默认连接线上环境:
|
|
13
|
+
|
|
14
|
+
```text
|
|
15
|
+
https://apaaspsc.doubaoapps.com/app/app_17gbe211qq5/openapi/
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
切换到开发环境:
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
export VIATRIS_API_ENV="development"
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
开发环境地址:
|
|
25
|
+
|
|
26
|
+
```text
|
|
27
|
+
https://apaaspsc-app_17gbe211qq5-1879207268486311.aiforce.run/app/app_17gbe211qq5/openapi/
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
`VIATRIS_API_ENV` 支持 `production`、`development`,以及别名 `prod`、`dev`。如需临时连接其他部署,可设置 `VIATRIS_API_BASE_URL`;该变量的优先级高于环境预设。
|
|
31
|
+
|
|
32
|
+
CLI 不接受 `--api-key` 参数,避免密钥进入 shell history、进程列表或 Agent 日志。默认使用:
|
|
33
|
+
|
|
34
|
+
```text
|
|
35
|
+
X-API-Key: <VIATRIS_API_KEY>
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
若服务端使用 Bearer Token:
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
export VIATRIS_API_KEY_HEADER="Authorization"
|
|
42
|
+
export VIATRIS_API_KEY_PREFIX="Bearer "
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Agent 接口约定
|
|
46
|
+
|
|
47
|
+
- API 成功响应以 JSON 写入 `stdout`。
|
|
48
|
+
- 错误以单行结构化 JSON 写入 `stderr`。
|
|
49
|
+
- POST/PUT 请求从文件、`stdin` 或 `--json` 读取 JSON 对象。
|
|
50
|
+
- API Key 只从 `VIATRIS_API_KEY` 环境变量读取。
|
|
51
|
+
- 默认使用线上环境,可通过 `VIATRIS_API_ENV=development` 切换到开发环境。
|
|
52
|
+
- `VIATRIS_API_BASE_URL` 可覆盖当前环境地址。
|
|
53
|
+
- GET 请求遇到网络错误、HTTP 429 或 5xx 时自动重试,POST/PUT 不自动重试。
|
|
54
|
+
- `describe` 返回机器可读的命令、参数、认证和退出码清单。
|
|
55
|
+
- ID 路径参数自动进行 URL 编码。
|
|
56
|
+
- HTTP 401/403 使用专用退出码,方便 Agent 判断需要刷新认证。
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
viatris-exam describe --compact
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
退出码:
|
|
63
|
+
|
|
64
|
+
| 退出码 | 含义 |
|
|
65
|
+
| --- | --- |
|
|
66
|
+
| `0` | 成功 |
|
|
67
|
+
| `1` | API 返回错误 |
|
|
68
|
+
| `2` | 命令、参数、校验或输入错误 |
|
|
69
|
+
| `3` | 环境配置错误 |
|
|
70
|
+
| `4` | 网络或超时错误 |
|
|
71
|
+
| `5` | 认证或授权错误 |
|
|
72
|
+
|
|
73
|
+
## 命令
|
|
74
|
+
|
|
75
|
+
### 产品知识树
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
viatris-exam products get "$PRODUCT_ID"
|
|
79
|
+
viatris-exam products update-knowledge-tree "$PRODUCT_ID" \
|
|
80
|
+
--input knowledge-tree.json
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
知识树回写是完整替换操作,必须一次提交全部 10-500 个 L3/L4 动态节点。先查询产品以获取固定 L2 维度的 `clientRef`。
|
|
84
|
+
|
|
85
|
+
### 出题任务
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
viatris-exam gen-tasks list --status generating --limit 20
|
|
89
|
+
viatris-exam gen-tasks get "$TASK_ID"
|
|
90
|
+
viatris-exam gen-tasks submit "$TASK_ID" --input examples/generated-questions.json
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
`externalRef` 是题目回写的幂等键。Agent 重试 POST 前应复用原值。
|
|
94
|
+
|
|
95
|
+
### 考试记录
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
viatris-exam exam-records get "$RECORD_ID"
|
|
99
|
+
viatris-exam exam-records scoring-rules "$RECORD_ID"
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
第二个命令返回答卷绑定版本的完整评分规则及用于回写的 `taskId`。
|
|
103
|
+
|
|
104
|
+
### 评分任务
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
viatris-exam scoring get "$TASK_ID"
|
|
108
|
+
viatris-exam scoring submit "$TASK_ID" --input examples/scoring-results.json
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
评分规则 V2 使用稳定的评分点 ID、扣分规则 ID 和题目级封顶规则,由服务端计算最终得分。V1 `pointResults` 结构继续兼容。
|
|
112
|
+
|
|
113
|
+
### 考试与题库
|
|
114
|
+
|
|
115
|
+
```bash
|
|
116
|
+
viatris-exam exams create --input exam.json
|
|
117
|
+
viatris-exam questions create < questions.json
|
|
118
|
+
viatris-exam questions version "$QUESTION_ID" --input version.json
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### 医疗知识检索
|
|
122
|
+
|
|
123
|
+
简单查询可直接使用参数:
|
|
124
|
+
|
|
125
|
+
```bash
|
|
126
|
+
viatris-exam medical-search search "阿托伐他汀 适应症" \
|
|
127
|
+
--file-type drug \
|
|
128
|
+
--limit 4 \
|
|
129
|
+
--max-length 1200
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
也可提交完整 JSON:
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
printf '%s' '{"query":"阿托伐他汀 适应症","limit":4}' |
|
|
136
|
+
viatris-exam medical-search search
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
## 错误格式
|
|
140
|
+
|
|
141
|
+
```json
|
|
142
|
+
{
|
|
143
|
+
"error": {
|
|
144
|
+
"type": "http_error",
|
|
145
|
+
"message": "API request failed with HTTP 422.",
|
|
146
|
+
"details": {
|
|
147
|
+
"status": 422,
|
|
148
|
+
"method": "POST",
|
|
149
|
+
"path": "/openapi/questions",
|
|
150
|
+
"requestId": "request-id",
|
|
151
|
+
"response": {
|
|
152
|
+
"message": "validation failed"
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
## 全局参数
|
|
160
|
+
|
|
161
|
+
```text
|
|
162
|
+
--base-url <url> 覆盖当前环境地址
|
|
163
|
+
--key-header <name> 覆盖 VIATRIS_API_KEY_HEADER
|
|
164
|
+
--key-prefix <value> 覆盖 VIATRIS_API_KEY_PREFIX
|
|
165
|
+
--timeout <ms> 超时时间,默认 30000
|
|
166
|
+
--retries <n> GET 重试次数,默认 2
|
|
167
|
+
--compact 输出单行紧凑 JSON
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
地址选择优先级为 `--base-url`、`VIATRIS_API_BASE_URL`、`VIATRIS_API_ENV` 对应的预设地址。认证 Key 仍必须通过 `VIATRIS_API_KEY` 提供。
|
|
171
|
+
|
|
172
|
+
## 项目结构
|
|
173
|
+
|
|
174
|
+
```text
|
|
175
|
+
src/
|
|
176
|
+
├── cli.js # 入口与异常收口
|
|
177
|
+
├── app.js # 应用编排
|
|
178
|
+
├── commands.js # 领域命令路由
|
|
179
|
+
├── command-handlers/
|
|
180
|
+
│ └── *.js # 各领域到 OpenAPI 请求的映射
|
|
181
|
+
├── args.js # 参数解析与校验
|
|
182
|
+
├── input.js # JSON 文件、stdin 与内联输入
|
|
183
|
+
├── config.js # 环境、地址与认证配置
|
|
184
|
+
├── http.js # HTTP、重试与响应处理
|
|
185
|
+
├── metadata.js # 版本、命令和环境元数据
|
|
186
|
+
├── help.js # 帮助文本
|
|
187
|
+
├── output.js # 标准 JSON 输出
|
|
188
|
+
└── errors.js # 错误类型
|
|
189
|
+
skills/
|
|
190
|
+
└── viatris-exam-cli/
|
|
191
|
+
├── SKILL.md
|
|
192
|
+
└── references/cli-reference.md
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
可分发的 Agent Skill 位于 `skills/viatris-exam-cli/`,与 `src/` 同级并包含在 npm 发布包中。`skills/viatris-exam-cli.zip` 是同步生成的独立分发包。`.trae/skills/viatris-exam-cli` 是指向规范目录的相对符号链接,仅用于本地自动发现。
|
|
196
|
+
|
|
197
|
+
## 变更规则
|
|
198
|
+
|
|
199
|
+
任何代码、命令、接口结构、环境地址或文档变化都必须:
|
|
200
|
+
|
|
201
|
+
1. 更新 `skills/viatris-exam-cli/SKILL.md` 及受影响的参考文件。
|
|
202
|
+
2. 同步递增 `package.json`、`src/metadata.js` 和 Skill frontmatter 中的版本。
|
|
203
|
+
3. 保持 `src/cli.js` 为薄入口,将能力放在职责单一的模块中。
|
|
204
|
+
4. 重新生成 Skill ZIP 并执行验证:
|
|
205
|
+
|
|
206
|
+
```bash
|
|
207
|
+
npm run pack:skill
|
|
208
|
+
npm test
|
|
209
|
+
npm run check
|
|
210
|
+
npm run check:versions
|
|
211
|
+
npm run check:skill
|
|
212
|
+
```
|
package/package.json
CHANGED
|
@@ -1,6 +1,24 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "viatris-exam-cli",
|
|
3
|
-
"version": "
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "1.3.0",
|
|
4
|
+
"description": "Agent-friendly CLI for the Viatris exam OpenAPI",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"viatris-exam": "./src/cli.js"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"src/",
|
|
11
|
+
"skills/"
|
|
12
|
+
],
|
|
13
|
+
"scripts": {
|
|
14
|
+
"test": "node --test",
|
|
15
|
+
"check": "node --check src/*.js && node --check src/command-handlers/*.js",
|
|
16
|
+
"check:versions": "node scripts/check-versions.js",
|
|
17
|
+
"check:skill": "node scripts/check-skill.js",
|
|
18
|
+
"pack:skill": "cd skills && /bin/rm -f viatris-exam-cli.zip && /usr/bin/zip -qr viatris-exam-cli.zip viatris-exam-cli -x '*.DS_Store'"
|
|
19
|
+
},
|
|
20
|
+
"engines": {
|
|
21
|
+
"node": ">=18"
|
|
22
|
+
},
|
|
23
|
+
"license": "UNLICENSED"
|
|
24
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: viatris-exam-cli
|
|
3
|
+
description: Operate the Viatris exam OpenAPI through its agent-friendly CLI. Use for products, knowledge trees, generation tasks, exam records, scoring, exams, questions, or medical search.
|
|
4
|
+
version: 1.3.0
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Viatris Exam CLI
|
|
8
|
+
|
|
9
|
+
Use the repository-local CLI for every supported API operation. Do not call the HTTP endpoints directly when the CLI covers the task.
|
|
10
|
+
|
|
11
|
+
## Start
|
|
12
|
+
|
|
13
|
+
1. Run commands from the repository root.
|
|
14
|
+
2. Require `VIATRIS_API_KEY` in the environment. Never place the key in arguments, files, output, or logs.
|
|
15
|
+
3. Use production by default. Set `VIATRIS_API_ENV=development` only when the user requests development or testing.
|
|
16
|
+
4. Run `node src/cli.js describe --compact` when capability discovery or exact machine-readable metadata is needed.
|
|
17
|
+
5. Read [references/cli-reference.md](references/cli-reference.md) before constructing a write payload or handling a nonzero exit code.
|
|
18
|
+
|
|
19
|
+
## Execute
|
|
20
|
+
|
|
21
|
+
- Invoke the CLI as `node src/cli.js ...`. Do not require `npm link`.
|
|
22
|
+
- Prefer `--input <file>` for existing payloads and stdin for generated payloads.
|
|
23
|
+
- Parse successful `stdout` as JSON.
|
|
24
|
+
- Parse failed `stderr` as JSON and branch on both exit code and `error.type`.
|
|
25
|
+
- Preserve `externalRef` when retrying question submission. It is the idempotency key.
|
|
26
|
+
- Prefer scoring rule V2 for generated questions and scoring results. Use stable point and deduction-rule IDs.
|
|
27
|
+
- Do not automatically retry POST or PUT commands. Inspect the returned error and determine whether the server accepted the request.
|
|
28
|
+
- Keep temporary payloads outside the repository unless they are requested deliverables.
|
|
29
|
+
|
|
30
|
+
## Maintain
|
|
31
|
+
|
|
32
|
+
Treat every repository behavior, command, schema, URL, documentation, or implementation change as a versioned Skill change.
|
|
33
|
+
|
|
34
|
+
For every change:
|
|
35
|
+
|
|
36
|
+
1. Update `skills/viatris-exam-cli/` and its affected references.
|
|
37
|
+
2. Increment the semantic version in `package.json`, `src/metadata.js`, and this frontmatter `version`.
|
|
38
|
+
3. Keep all three versions identical.
|
|
39
|
+
4. Keep `src/cli.js` as a thin entrypoint. Put capabilities in focused modules under `src/`.
|
|
40
|
+
5. Keep `.trae/skills/viatris-exam-cli` as a relative symlink to the distributable Skill directory.
|
|
41
|
+
6. Run `npm run pack:skill` so `skills/viatris-exam-cli.zip` matches the canonical directory.
|
|
42
|
+
7. Run `npm test`, `npm run check`, `npm run check:versions`, and `npm run check:skill`.
|
|
43
|
+
|
|
44
|
+
Do not finish a code change while the Skill or any version is stale.
|
|
@@ -0,0 +1,319 @@
|
|
|
1
|
+
# CLI Reference
|
|
2
|
+
|
|
3
|
+
## Authentication And Environment
|
|
4
|
+
|
|
5
|
+
Required:
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
export VIATRIS_API_KEY="..."
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Environment selection:
|
|
12
|
+
|
|
13
|
+
| Value | Target |
|
|
14
|
+
| --- | --- |
|
|
15
|
+
| unset, `production`, `prod` | Production |
|
|
16
|
+
| `development`, `dev` | Development |
|
|
17
|
+
|
|
18
|
+
`VIATRIS_API_BASE_URL` overrides the selected environment. Use it only for an explicitly supplied custom deployment or local mock.
|
|
19
|
+
|
|
20
|
+
Default authentication header:
|
|
21
|
+
|
|
22
|
+
```text
|
|
23
|
+
X-API-Key: <VIATRIS_API_KEY>
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
For Bearer authentication:
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
export VIATRIS_API_KEY_HEADER="Authorization"
|
|
30
|
+
export VIATRIS_API_KEY_PREFIX="Bearer "
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Capability Discovery
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
node src/cli.js describe --compact
|
|
37
|
+
node src/cli.js --help
|
|
38
|
+
node src/cli.js --version
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
`describe` does not require credentials. It returns commands, paths, environment metadata, authentication metadata, and exit codes as JSON.
|
|
42
|
+
|
|
43
|
+
## Commands
|
|
44
|
+
|
|
45
|
+
Get a product and its fixed L2 dimensions:
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
node src/cli.js products get "$PRODUCT_ID" --compact
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Use each returned `fixedDimensions[].clientRef` as the parent reference for an L3 node.
|
|
52
|
+
|
|
53
|
+
Replace a product knowledge tree:
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
node src/cli.js products update-knowledge-tree "$PRODUCT_ID" \
|
|
57
|
+
--input knowledge-tree.json \
|
|
58
|
+
--compact
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Payload shape:
|
|
62
|
+
|
|
63
|
+
```json
|
|
64
|
+
{
|
|
65
|
+
"nodes": [
|
|
66
|
+
{
|
|
67
|
+
"clientRef": "disease.hypertension",
|
|
68
|
+
"parentClientRef": "dimension:disease",
|
|
69
|
+
"level": 3,
|
|
70
|
+
"dimensionCode": "disease",
|
|
71
|
+
"name": "高血压",
|
|
72
|
+
"sortOrder": 1
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
"clientRef": "disease.hypertension.definition",
|
|
76
|
+
"parentClientRef": "disease.hypertension",
|
|
77
|
+
"level": 4,
|
|
78
|
+
"dimensionCode": "disease",
|
|
79
|
+
"name": "定义与诊断",
|
|
80
|
+
"sortOrder": 1,
|
|
81
|
+
"documents": [
|
|
82
|
+
{
|
|
83
|
+
"title": "药品说明书",
|
|
84
|
+
"url": "https://example.com/source",
|
|
85
|
+
"summary": "与该知识点直接对应的证据摘录"
|
|
86
|
+
}
|
|
87
|
+
]
|
|
88
|
+
}
|
|
89
|
+
]
|
|
90
|
+
}
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
Submit the complete L3/L4 node set, between 10 and 500 nodes. Every `clientRef` must be unique within the payload. L3 nodes use `dimension:<code>` as `parentClientRef`; L4 nodes use an L3 `clientRef`. Every L4 node needs at least one document. A successful PUT replaces the previous dynamic nodes, so do not send a partial tree.
|
|
94
|
+
|
|
95
|
+
List generation tasks:
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
node src/cli.js gen-tasks list \
|
|
99
|
+
--status generating \
|
|
100
|
+
--limit 20 \
|
|
101
|
+
--compact
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
`--status` accepts `generating`, `partial_failed`, or `failed`. `--limit` accepts 1 through 50.
|
|
105
|
+
|
|
106
|
+
Get one generation task:
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
node src/cli.js gen-tasks get "$TASK_ID" --compact
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
Submit generated questions:
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
node src/cli.js gen-tasks submit "$TASK_ID" --input payload.json --compact
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
Payload shape:
|
|
119
|
+
|
|
120
|
+
```json
|
|
121
|
+
{
|
|
122
|
+
"items": [
|
|
123
|
+
{
|
|
124
|
+
"externalRef": "agent-q-0001",
|
|
125
|
+
"failureId": "optional-failure-id",
|
|
126
|
+
"content": {
|
|
127
|
+
"stem": "Question stem",
|
|
128
|
+
"referenceAnswer": "Reference answer",
|
|
129
|
+
"scoringPoints": [
|
|
130
|
+
{
|
|
131
|
+
"id": "dose-selection",
|
|
132
|
+
"point": "Scoring point",
|
|
133
|
+
"maxScore": 4,
|
|
134
|
+
"criteria": "Choose one deduction level",
|
|
135
|
+
"deductionRules": [
|
|
136
|
+
{
|
|
137
|
+
"id": "dose-selection-full",
|
|
138
|
+
"level": "full",
|
|
139
|
+
"deductScore": 0,
|
|
140
|
+
"criteria": "Complete answer"
|
|
141
|
+
},
|
|
142
|
+
{
|
|
143
|
+
"id": "dose-selection-zero",
|
|
144
|
+
"level": "zero",
|
|
145
|
+
"deductScore": 4,
|
|
146
|
+
"criteria": "Wrong or missing answer"
|
|
147
|
+
}
|
|
148
|
+
]
|
|
149
|
+
}
|
|
150
|
+
],
|
|
151
|
+
"scoringRuleVersion": 2,
|
|
152
|
+
"scoreCapRules": [
|
|
153
|
+
{
|
|
154
|
+
"id": "critical-error-1",
|
|
155
|
+
"description": "Critical contradictory conclusion",
|
|
156
|
+
"maxTotalScore": 2
|
|
157
|
+
}
|
|
158
|
+
],
|
|
159
|
+
"evidence": [
|
|
160
|
+
{
|
|
161
|
+
"source": "Source",
|
|
162
|
+
"citation": "Citation",
|
|
163
|
+
"relevance": "Relevance"
|
|
164
|
+
}
|
|
165
|
+
]
|
|
166
|
+
},
|
|
167
|
+
"qcResult": {
|
|
168
|
+
"outOfScope": false,
|
|
169
|
+
"insufficientEvidence": false,
|
|
170
|
+
"answerConflict": false,
|
|
171
|
+
"duplicateRisk": false,
|
|
172
|
+
"summary": "No obvious issue"
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
],
|
|
176
|
+
"finished": true
|
|
177
|
+
}
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
Get a submitted exam record and its frozen answers:
|
|
181
|
+
|
|
182
|
+
```bash
|
|
183
|
+
node src/cli.js exam-records get "$RECORD_ID" --compact
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
Get the complete scoring rules bound to the record:
|
|
187
|
+
|
|
188
|
+
```bash
|
|
189
|
+
node src/cli.js exam-records scoring-rules "$RECORD_ID" --compact
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
The response includes the scoring `taskId`, `schemaVersion`, frozen question versions, evidence, V2 deduction rules, score caps, and item IDs. Use its `taskId` for scoring submission.
|
|
193
|
+
|
|
194
|
+
Get a scoring task:
|
|
195
|
+
|
|
196
|
+
```bash
|
|
197
|
+
node src/cli.js scoring get "$TASK_ID" --compact
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
Submit scoring results:
|
|
201
|
+
|
|
202
|
+
```bash
|
|
203
|
+
node src/cli.js scoring submit "$TASK_ID" --input results.json --compact
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
Payload shape:
|
|
207
|
+
|
|
208
|
+
```json
|
|
209
|
+
{
|
|
210
|
+
"items": [
|
|
211
|
+
{
|
|
212
|
+
"itemId": "item-id",
|
|
213
|
+
"ok": true,
|
|
214
|
+
"pointJudgements": [
|
|
215
|
+
{
|
|
216
|
+
"pointId": "dose-selection",
|
|
217
|
+
"appliedDeductionRuleId": "dose-selection-full",
|
|
218
|
+
"reason": "Reason for selecting this deduction level",
|
|
219
|
+
"quote": "Supporting answer quote"
|
|
220
|
+
}
|
|
221
|
+
],
|
|
222
|
+
"triggeredScoreCaps": [],
|
|
223
|
+
"flags": [],
|
|
224
|
+
"needReview": false
|
|
225
|
+
}
|
|
226
|
+
]
|
|
227
|
+
}
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
For V2, submit exactly one `pointJudgement` per scoring point. IDs must match the fetched rule set. Add triggered cap rule IDs to `triggeredScoreCaps`; the server calculates the score, so `total` is optional and must match if supplied. V1 remains compatible through `pointResults` and required `total`. For a failed item, set `ok` to `false` and provide `failureReason`.
|
|
231
|
+
|
|
232
|
+
Create an exam:
|
|
233
|
+
|
|
234
|
+
```bash
|
|
235
|
+
node src/cli.js exams create --input exam.json --compact
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
Required top-level fields are `name`, `product`, `questionCount`, `startAt`, `endAt`, `resultPolicy`, and `assigneeIds`. `questionCount` is 1 through 150. Use either `questions` or legacy `questionIds`, never both. Each question score must be a positive integer and the complete exam must total exactly 100.
|
|
239
|
+
|
|
240
|
+
Create questions directly:
|
|
241
|
+
|
|
242
|
+
```bash
|
|
243
|
+
node src/cli.js questions create --input questions.json --compact
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
Payload shape is `{ "items": [...] }`. Each item requires `product`, `dimension`, and `content`; provide `externalRef` for idempotency. Prefer `scoringRuleVersion: 2`, stable IDs on scoring points and deduction rules, and explicit `scoreCapRules`.
|
|
247
|
+
|
|
248
|
+
The API has partial-success semantics: inspect `accepted`, `duplicates`, and every entry in `rejected` even when the HTTP response is successful.
|
|
249
|
+
|
|
250
|
+
Add a question version:
|
|
251
|
+
|
|
252
|
+
```bash
|
|
253
|
+
node src/cli.js questions version "$QUESTION_ID" --input version.json --compact
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
Required fields are `stem`, `referenceAnswer`, nonempty `scoringPoints`, `evidence`, and `editReason`. V2 versions may also include `scoringRuleVersion: 2`, deduction rules, and `scoreCapRules`.
|
|
257
|
+
|
|
258
|
+
Search medical evidence:
|
|
259
|
+
|
|
260
|
+
```bash
|
|
261
|
+
node src/cli.js medical-search search "阿托伐他汀 适应症" \
|
|
262
|
+
--file-type drug \
|
|
263
|
+
--limit 4 \
|
|
264
|
+
--max-length 1200 \
|
|
265
|
+
--compact
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
Or use JSON:
|
|
269
|
+
|
|
270
|
+
```bash
|
|
271
|
+
printf '%s' '{"query":"阿托伐他汀 适应症","limit":4}' |
|
|
272
|
+
node src/cli.js medical-search search --compact
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
Do not combine query flags with JSON input.
|
|
276
|
+
|
|
277
|
+
## Input Rules
|
|
278
|
+
|
|
279
|
+
Choose exactly one input form:
|
|
280
|
+
|
|
281
|
+
```bash
|
|
282
|
+
node src/cli.js questions create --input payload.json
|
|
283
|
+
node src/cli.js questions create --input - < payload.json
|
|
284
|
+
node src/cli.js questions create --json '{"items":[]}'
|
|
285
|
+
printf '%s' '{"items":[]}' | node src/cli.js questions create
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
The top-level JSON value must be an object.
|
|
289
|
+
|
|
290
|
+
## Output And Errors
|
|
291
|
+
|
|
292
|
+
Success writes API JSON to `stdout`. Errors write one JSON object to `stderr`:
|
|
293
|
+
|
|
294
|
+
```json
|
|
295
|
+
{
|
|
296
|
+
"error": {
|
|
297
|
+
"type": "http_error",
|
|
298
|
+
"message": "API request failed with HTTP 422.",
|
|
299
|
+
"details": {
|
|
300
|
+
"status": 422,
|
|
301
|
+
"method": "POST",
|
|
302
|
+
"path": "/openapi/questions",
|
|
303
|
+
"requestId": "optional-request-id",
|
|
304
|
+
"response": {}
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
| Exit | Meaning | Agent action |
|
|
311
|
+
| --- | --- | --- |
|
|
312
|
+
| `0` | Success | Parse stdout JSON |
|
|
313
|
+
| `1` | API error | Inspect status and response |
|
|
314
|
+
| `2` | Usage, validation, or input error | Correct command or payload |
|
|
315
|
+
| `3` | Configuration error | Check environment configuration |
|
|
316
|
+
| `4` | Network or timeout error | GET may be retried; inspect POST/PUT state first |
|
|
317
|
+
| `5` | Authentication or authorization error | Refresh or correct credentials |
|
|
318
|
+
|
|
319
|
+
GET automatically retries network errors, HTTP 429, and HTTP 5xx. POST and PUT never retry automatically.
|
|
Binary file
|
package/src/app.js
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { assertNoExtraPositionals, parseArgs } from "./args.js";
|
|
2
|
+
import { resolveCommand } from "./commands.js";
|
|
3
|
+
import { configFrom } from "./config.js";
|
|
4
|
+
import { helpText } from "./help.js";
|
|
5
|
+
import { request } from "./http.js";
|
|
6
|
+
import { describeCli, VERSION } from "./metadata.js";
|
|
7
|
+
import { writeJson } from "./output.js";
|
|
8
|
+
|
|
9
|
+
export async function run(
|
|
10
|
+
argv,
|
|
11
|
+
{
|
|
12
|
+
stdout = process.stdout,
|
|
13
|
+
environmentVariables = process.env,
|
|
14
|
+
} = {},
|
|
15
|
+
) {
|
|
16
|
+
const { positionals, options } = parseArgs(argv);
|
|
17
|
+
|
|
18
|
+
if (options.version) {
|
|
19
|
+
stdout.write(`${VERSION}\n`);
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
if (options.help || positionals.length === 0) {
|
|
23
|
+
stdout.write(helpText());
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
if (positionals[0] === "describe") {
|
|
27
|
+
assertNoExtraPositionals(positionals, 1);
|
|
28
|
+
writeJson(stdout, describeCli(), options.compact);
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const command = await resolveCommand(positionals, options);
|
|
33
|
+
const config = configFrom(options, environmentVariables);
|
|
34
|
+
const response = await request(command, config);
|
|
35
|
+
writeJson(stdout, response, options.compact);
|
|
36
|
+
}
|