anna-agent 0.2.0__tar.gz → 0.2.2__tar.gz
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.
- {anna_agent-0.2.0 → anna_agent-0.2.2}/PKG-INFO +23 -23
- {anna_agent-0.2.0 → anna_agent-0.2.2}/README.md +22 -22
- {anna_agent-0.2.0 → anna_agent-0.2.2}/pyproject.toml +1 -1
- {anna_agent-0.2.0 → anna_agent-0.2.2}/src/anna_agent/__init__.py +1 -1
- {anna_agent-0.2.0 → anna_agent-0.2.2}/src/anna_agent/anna_agent_template.py +8 -5
- {anna_agent-0.2.0 → anna_agent-0.2.2}/src/anna_agent/cli.py +153 -40
- anna_agent-0.2.2/src/anna_agent/complaint_elicitor.py +71 -0
- {anna_agent-0.2.0 → anna_agent-0.2.2}/src/anna_agent/config/defaults.py +4 -4
- {anna_agent-0.2.0 → anna_agent-0.2.2}/src/anna_agent/config/init_content.py +13 -12
- {anna_agent-0.2.0 → anna_agent-0.2.2}/src/anna_agent/config/load_config.py +36 -19
- {anna_agent-0.2.0 → anna_agent-0.2.2}/src/anna_agent/diagnostics.py +4 -2
- anna_agent-0.2.2/src/anna_agent/fill_scales.py +175 -0
- {anna_agent-0.2.0 → anna_agent-0.2.2}/src/anna_agent/model_services.py +2 -2
- {anna_agent-0.2.0 → anna_agent-0.2.2}/src/anna_agent/querier.py +8 -52
- {anna_agent-0.2.0 → anna_agent-0.2.2}/src/anna_agent/runtime.py +11 -2
- anna_agent-0.2.2/src/anna_agent/short_term_memory.py +185 -0
- {anna_agent-0.2.0 → anna_agent-0.2.2}/src/anna_agent.egg-info/PKG-INFO +23 -23
- anna_agent-0.2.0/src/anna_agent/complaint_elicitor.py +0 -88
- anna_agent-0.2.0/src/anna_agent/fill_scales.py +0 -385
- anna_agent-0.2.0/src/anna_agent/short_term_memory.py +0 -286
- {anna_agent-0.2.0 → anna_agent-0.2.2}/LICENSE +0 -0
- {anna_agent-0.2.0 → anna_agent-0.2.2}/setup.cfg +0 -0
- {anna_agent-0.2.0 → anna_agent-0.2.2}/src/anna_agent/__main__.py +0 -0
- {anna_agent-0.2.0 → anna_agent-0.2.2}/src/anna_agent/assets.py +0 -0
- {anna_agent-0.2.0 → anna_agent-0.2.2}/src/anna_agent/backbone.py +0 -0
- {anna_agent-0.2.0 → anna_agent-0.2.2}/src/anna_agent/case_data.py +0 -0
- {anna_agent-0.2.0 → anna_agent-0.2.2}/src/anna_agent/common/registry.py +0 -0
- {anna_agent-0.2.0 → anna_agent-0.2.2}/src/anna_agent/common/tool_calls.py +0 -0
- {anna_agent-0.2.0 → anna_agent-0.2.2}/src/anna_agent/complaint_chain.py +0 -0
- {anna_agent-0.2.0 → anna_agent-0.2.2}/src/anna_agent/config/__init__.py +0 -0
- {anna_agent-0.2.0 → anna_agent-0.2.2}/src/anna_agent/config/environment_reader.py +0 -0
- {anna_agent-0.2.0 → anna_agent-0.2.2}/src/anna_agent/config/initialize.py +0 -0
- {anna_agent-0.2.0 → anna_agent-0.2.2}/src/anna_agent/config/models/anna_engine_config.py +0 -0
- {anna_agent-0.2.0 → anna_agent-0.2.2}/src/anna_agent/counselor.py +0 -0
- {anna_agent-0.2.0 → anna_agent-0.2.2}/src/anna_agent/datasets/cbt-triggering-events.csv +0 -0
- {anna_agent-0.2.0 → anna_agent-0.2.2}/src/anna_agent/emotion_modulator.py +0 -0
- {anna_agent-0.2.0 → anna_agent-0.2.2}/src/anna_agent/emotion_pertuber.py +0 -0
- {anna_agent-0.2.0 → anna_agent-0.2.2}/src/anna_agent/event_trigger.py +0 -0
- {anna_agent-0.2.0 → anna_agent-0.2.2}/src/anna_agent/figure/readme.md +0 -0
- {anna_agent-0.2.0 → anna_agent-0.2.2}/src/anna_agent/figure/whiteboard_exported_image_en.png +0 -0
- {anna_agent-0.2.0 → anna_agent-0.2.2}/src/anna_agent/initialize.py +0 -0
- {anna_agent-0.2.0 → anna_agent-0.2.2}/src/anna_agent/memory/__init__.py +0 -0
- {anna_agent-0.2.0 → anna_agent-0.2.2}/src/anna_agent/memory/chunking.py +0 -0
- {anna_agent-0.2.0 → anna_agent-0.2.2}/src/anna_agent/memory/embeddings.py +0 -0
- {anna_agent-0.2.0 → anna_agent-0.2.2}/src/anna_agent/memory/models.py +0 -0
- {anna_agent-0.2.0 → anna_agent-0.2.2}/src/anna_agent/memory/store.py +0 -0
- {anna_agent-0.2.0 → anna_agent-0.2.2}/src/anna_agent/ms_patient.py +0 -0
- {anna_agent-0.2.0 → anna_agent-0.2.2}/src/anna_agent/ms_patient_with_prompt.py +0 -0
- {anna_agent-0.2.0 → anna_agent-0.2.2}/src/anna_agent/scales/__init__.py +0 -0
- {anna_agent-0.2.0 → anna_agent-0.2.2}/src/anna_agent/scales/bdi.json +0 -0
- {anna_agent-0.2.0 → anna_agent-0.2.2}/src/anna_agent/scales/ghq-28.json +0 -0
- {anna_agent-0.2.0 → anna_agent-0.2.2}/src/anna_agent/scales/sass.json +0 -0
- {anna_agent-0.2.0 → anna_agent-0.2.2}/src/anna_agent/server/complaint.sh +0 -0
- {anna_agent-0.2.0 → anna_agent-0.2.2}/src/anna_agent/server/counselor.sh +0 -0
- {anna_agent-0.2.0 → anna_agent-0.2.2}/src/anna_agent/server/emotion.sh +0 -0
- {anna_agent-0.2.0 → anna_agent-0.2.2}/src/anna_agent/service.py +0 -0
- {anna_agent-0.2.0 → anna_agent-0.2.2}/src/anna_agent/style_analyzer.py +0 -0
- {anna_agent-0.2.0 → anna_agent-0.2.2}/src/anna_agent/workspace.py +0 -0
- {anna_agent-0.2.0 → anna_agent-0.2.2}/src/anna_agent.egg-info/SOURCES.txt +0 -0
- {anna_agent-0.2.0 → anna_agent-0.2.2}/src/anna_agent.egg-info/dependency_links.txt +0 -0
- {anna_agent-0.2.0 → anna_agent-0.2.2}/src/anna_agent.egg-info/entry_points.txt +0 -0
- {anna_agent-0.2.0 → anna_agent-0.2.2}/src/anna_agent.egg-info/requires.txt +0 -0
- {anna_agent-0.2.0 → anna_agent-0.2.2}/src/anna_agent.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: anna-agent
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.2
|
|
4
4
|
Summary: Dynamic Evolution Agent System with Multi-Session Memory for Realistic Seeker Simulation
|
|
5
5
|
Project-URL: Documentation, https://sci-m-wang.github.io/AnnaAgent/
|
|
6
6
|
Project-URL: Repository, https://github.com/sci-m-wang/AnnaAgent
|
|
@@ -61,7 +61,7 @@ After installation, the short command `anna` is available in any terminal:
|
|
|
61
61
|
|
|
62
62
|
```bash
|
|
63
63
|
anna --version
|
|
64
|
-
anna
|
|
64
|
+
anna create anna-workspace
|
|
65
65
|
anna doctor --workspace anna-workspace
|
|
66
66
|
```
|
|
67
67
|
|
|
@@ -72,7 +72,7 @@ a workspace deployment environment on the Linux/GPU machine. This keeps the
|
|
|
72
72
|
lightweight `anna` CLI install separate from heavy vLLM dependencies:
|
|
73
73
|
|
|
74
74
|
```bash
|
|
75
|
-
anna
|
|
75
|
+
anna create anna-workspace --deploy-env
|
|
76
76
|
|
|
77
77
|
# Or add it later to an existing workspace.
|
|
78
78
|
anna models env setup --workspace anna-workspace
|
|
@@ -117,17 +117,17 @@ First, create a workspace, choose whether to use the SFT modules, and let the CL
|
|
|
117
117
|
write the resulting configuration:
|
|
118
118
|
|
|
119
119
|
```bash
|
|
120
|
-
anna
|
|
120
|
+
anna create anna-workspace
|
|
121
121
|
|
|
122
122
|
# Optional on GPU machines: create anna-workspace/.anna-deploy-venv for vLLM.
|
|
123
|
-
anna
|
|
123
|
+
anna create anna-workspace --deploy-env
|
|
124
124
|
|
|
125
125
|
# Fast path: use the base chat model for complaint-chain and emotion modules.
|
|
126
126
|
anna models use-base --target all --workspace anna-workspace
|
|
127
127
|
|
|
128
128
|
# SFT path: deploy local vLLM services from downloaded HuggingFace assets.
|
|
129
|
-
anna assets
|
|
130
|
-
anna models env setup --workspace anna-workspace # optional if
|
|
129
|
+
anna assets download paper --workspace anna-workspace
|
|
130
|
+
anna models env setup --workspace anna-workspace # optional if create used --deploy-env
|
|
131
131
|
anna models deploy --target complaint --backend vllm --workspace anna-workspace \
|
|
132
132
|
--gpu 0 --gpu-memory-utilization 0.85 --wait-timeout 900
|
|
133
133
|
anna models deploy --target emotion --backend vllm --workspace anna-workspace \
|
|
@@ -169,7 +169,7 @@ AnnaAgent provides a Typer-based CLI organized around the reader journey from
|
|
|
169
169
|
paper reproduction to application use. Start by creating an isolated workspace:
|
|
170
170
|
|
|
171
171
|
```bash
|
|
172
|
-
anna
|
|
172
|
+
anna create anna-workspace
|
|
173
173
|
anna doctor --workspace anna-workspace
|
|
174
174
|
```
|
|
175
175
|
|
|
@@ -188,7 +188,7 @@ anna config validate --workspace anna-workspace
|
|
|
188
188
|
|
|
189
189
|
`config wizard` and `config secrets` use hidden password-style prompts for API
|
|
190
190
|
keys and write them to `.env`. The generated `.env` and `.env.example` files
|
|
191
|
-
include commented placeholders showing exactly where to put
|
|
191
|
+
include commented placeholders showing exactly where to put backbone, SFT and
|
|
192
192
|
embedding credentials if you prefer manual editing.
|
|
193
193
|
|
|
194
194
|
Assets are manifest-driven. The default `paper` preset points to the released
|
|
@@ -197,23 +197,23 @@ HuggingFace SFT models and synthetic data, and you can override or extend it in
|
|
|
197
197
|
|
|
198
198
|
```bash
|
|
199
199
|
anna assets list --workspace anna-workspace
|
|
200
|
-
anna assets
|
|
200
|
+
anna assets download paper --workspace anna-workspace
|
|
201
201
|
```
|
|
202
202
|
|
|
203
|
-
Always pass `--workspace` or `--manifest` when
|
|
204
|
-
`anna assets
|
|
205
|
-
to `./assets/...` instead of your intended AnnaAgent workspace. You can
|
|
203
|
+
Always pass `--workspace` or `--manifest` when downloading assets. Without either,
|
|
204
|
+
`anna assets download` uses the current directory as the workspace and may download
|
|
205
|
+
to `./assets/...` instead of your intended AnnaAgent workspace. You can download one
|
|
206
206
|
specific resource or override the target directory explicitly:
|
|
207
207
|
|
|
208
208
|
```bash
|
|
209
|
-
#
|
|
210
|
-
anna assets
|
|
209
|
+
# Download one asset from anna-workspace/assets/anna-assets.json.
|
|
210
|
+
anna assets download complaint-sft --workspace anna-workspace
|
|
211
211
|
|
|
212
212
|
# Use an explicit manifest JSON, including absolute target paths in that file.
|
|
213
|
-
anna assets
|
|
213
|
+
anna assets download complaint-sft --manifest anna-workspace/assets/anna-assets.json
|
|
214
214
|
|
|
215
215
|
# Override the target directory for exactly one selected asset.
|
|
216
|
-
anna assets
|
|
216
|
+
anna assets download complaint-sft --workspace anna-workspace \
|
|
217
217
|
--target /path/to/models/complaint-sft
|
|
218
218
|
```
|
|
219
219
|
|
|
@@ -272,7 +272,7 @@ anna models deploy --target complaint --backend vllm --workspace anna-workspace
|
|
|
272
272
|
```
|
|
273
273
|
When `--model-path` is omitted, deploy reads the corresponding SFT asset target
|
|
274
274
|
from `assets/anna-assets.json`, including absolute paths. Pass the same
|
|
275
|
-
`--workspace` or `--manifest` that you used during `assets
|
|
275
|
+
`--workspace` or `--manifest` that you used during `assets download`.
|
|
276
276
|
|
|
277
277
|
If `models deploy` reports that vLLM is unavailable, run
|
|
278
278
|
`anna models env setup --workspace anna-workspace` to create the workspace deploy
|
|
@@ -299,11 +299,11 @@ Initialization can be run as a full AnnaAgent initialization, or as a prompt-onl
|
|
|
299
299
|
state for cheap dry-runs and reproducible prompt freezing:
|
|
300
300
|
|
|
301
301
|
```bash
|
|
302
|
-
anna
|
|
302
|
+
anna init prompt-only anna-workspace/cases/family_stress_case.json \
|
|
303
303
|
--out anna-workspace/prompts/family.prompt.json
|
|
304
|
-
anna
|
|
304
|
+
anna init full anna-workspace/cases/family_stress_case.json \
|
|
305
305
|
--out anna-workspace/prompts/family.full.json --workspace anna-workspace
|
|
306
|
-
anna
|
|
306
|
+
anna init from-prompt anna-workspace/prompts/family.prompt.json
|
|
307
307
|
```
|
|
308
308
|
|
|
309
309
|
Chat interactively from either a case file or a frozen prompt state:
|
|
@@ -458,8 +458,8 @@ the base model, or `true` to call the configured SFT endpoint.
|
|
|
458
458
|
|
|
459
459
|
```yaml
|
|
460
460
|
model_service:
|
|
461
|
-
model_name:
|
|
462
|
-
api_key:
|
|
461
|
+
model_name: anna-backbone
|
|
462
|
+
api_key: anna-backbone
|
|
463
463
|
base_url: http://localhost:8002/v1
|
|
464
464
|
servers:
|
|
465
465
|
complaint:
|
|
@@ -37,7 +37,7 @@ After installation, the short command `anna` is available in any terminal:
|
|
|
37
37
|
|
|
38
38
|
```bash
|
|
39
39
|
anna --version
|
|
40
|
-
anna
|
|
40
|
+
anna create anna-workspace
|
|
41
41
|
anna doctor --workspace anna-workspace
|
|
42
42
|
```
|
|
43
43
|
|
|
@@ -48,7 +48,7 @@ a workspace deployment environment on the Linux/GPU machine. This keeps the
|
|
|
48
48
|
lightweight `anna` CLI install separate from heavy vLLM dependencies:
|
|
49
49
|
|
|
50
50
|
```bash
|
|
51
|
-
anna
|
|
51
|
+
anna create anna-workspace --deploy-env
|
|
52
52
|
|
|
53
53
|
# Or add it later to an existing workspace.
|
|
54
54
|
anna models env setup --workspace anna-workspace
|
|
@@ -93,17 +93,17 @@ First, create a workspace, choose whether to use the SFT modules, and let the CL
|
|
|
93
93
|
write the resulting configuration:
|
|
94
94
|
|
|
95
95
|
```bash
|
|
96
|
-
anna
|
|
96
|
+
anna create anna-workspace
|
|
97
97
|
|
|
98
98
|
# Optional on GPU machines: create anna-workspace/.anna-deploy-venv for vLLM.
|
|
99
|
-
anna
|
|
99
|
+
anna create anna-workspace --deploy-env
|
|
100
100
|
|
|
101
101
|
# Fast path: use the base chat model for complaint-chain and emotion modules.
|
|
102
102
|
anna models use-base --target all --workspace anna-workspace
|
|
103
103
|
|
|
104
104
|
# SFT path: deploy local vLLM services from downloaded HuggingFace assets.
|
|
105
|
-
anna assets
|
|
106
|
-
anna models env setup --workspace anna-workspace # optional if
|
|
105
|
+
anna assets download paper --workspace anna-workspace
|
|
106
|
+
anna models env setup --workspace anna-workspace # optional if create used --deploy-env
|
|
107
107
|
anna models deploy --target complaint --backend vllm --workspace anna-workspace \
|
|
108
108
|
--gpu 0 --gpu-memory-utilization 0.85 --wait-timeout 900
|
|
109
109
|
anna models deploy --target emotion --backend vllm --workspace anna-workspace \
|
|
@@ -145,7 +145,7 @@ AnnaAgent provides a Typer-based CLI organized around the reader journey from
|
|
|
145
145
|
paper reproduction to application use. Start by creating an isolated workspace:
|
|
146
146
|
|
|
147
147
|
```bash
|
|
148
|
-
anna
|
|
148
|
+
anna create anna-workspace
|
|
149
149
|
anna doctor --workspace anna-workspace
|
|
150
150
|
```
|
|
151
151
|
|
|
@@ -164,7 +164,7 @@ anna config validate --workspace anna-workspace
|
|
|
164
164
|
|
|
165
165
|
`config wizard` and `config secrets` use hidden password-style prompts for API
|
|
166
166
|
keys and write them to `.env`. The generated `.env` and `.env.example` files
|
|
167
|
-
include commented placeholders showing exactly where to put
|
|
167
|
+
include commented placeholders showing exactly where to put backbone, SFT and
|
|
168
168
|
embedding credentials if you prefer manual editing.
|
|
169
169
|
|
|
170
170
|
Assets are manifest-driven. The default `paper` preset points to the released
|
|
@@ -173,23 +173,23 @@ HuggingFace SFT models and synthetic data, and you can override or extend it in
|
|
|
173
173
|
|
|
174
174
|
```bash
|
|
175
175
|
anna assets list --workspace anna-workspace
|
|
176
|
-
anna assets
|
|
176
|
+
anna assets download paper --workspace anna-workspace
|
|
177
177
|
```
|
|
178
178
|
|
|
179
|
-
Always pass `--workspace` or `--manifest` when
|
|
180
|
-
`anna assets
|
|
181
|
-
to `./assets/...` instead of your intended AnnaAgent workspace. You can
|
|
179
|
+
Always pass `--workspace` or `--manifest` when downloading assets. Without either,
|
|
180
|
+
`anna assets download` uses the current directory as the workspace and may download
|
|
181
|
+
to `./assets/...` instead of your intended AnnaAgent workspace. You can download one
|
|
182
182
|
specific resource or override the target directory explicitly:
|
|
183
183
|
|
|
184
184
|
```bash
|
|
185
|
-
#
|
|
186
|
-
anna assets
|
|
185
|
+
# Download one asset from anna-workspace/assets/anna-assets.json.
|
|
186
|
+
anna assets download complaint-sft --workspace anna-workspace
|
|
187
187
|
|
|
188
188
|
# Use an explicit manifest JSON, including absolute target paths in that file.
|
|
189
|
-
anna assets
|
|
189
|
+
anna assets download complaint-sft --manifest anna-workspace/assets/anna-assets.json
|
|
190
190
|
|
|
191
191
|
# Override the target directory for exactly one selected asset.
|
|
192
|
-
anna assets
|
|
192
|
+
anna assets download complaint-sft --workspace anna-workspace \
|
|
193
193
|
--target /path/to/models/complaint-sft
|
|
194
194
|
```
|
|
195
195
|
|
|
@@ -248,7 +248,7 @@ anna models deploy --target complaint --backend vllm --workspace anna-workspace
|
|
|
248
248
|
```
|
|
249
249
|
When `--model-path` is omitted, deploy reads the corresponding SFT asset target
|
|
250
250
|
from `assets/anna-assets.json`, including absolute paths. Pass the same
|
|
251
|
-
`--workspace` or `--manifest` that you used during `assets
|
|
251
|
+
`--workspace` or `--manifest` that you used during `assets download`.
|
|
252
252
|
|
|
253
253
|
If `models deploy` reports that vLLM is unavailable, run
|
|
254
254
|
`anna models env setup --workspace anna-workspace` to create the workspace deploy
|
|
@@ -275,11 +275,11 @@ Initialization can be run as a full AnnaAgent initialization, or as a prompt-onl
|
|
|
275
275
|
state for cheap dry-runs and reproducible prompt freezing:
|
|
276
276
|
|
|
277
277
|
```bash
|
|
278
|
-
anna
|
|
278
|
+
anna init prompt-only anna-workspace/cases/family_stress_case.json \
|
|
279
279
|
--out anna-workspace/prompts/family.prompt.json
|
|
280
|
-
anna
|
|
280
|
+
anna init full anna-workspace/cases/family_stress_case.json \
|
|
281
281
|
--out anna-workspace/prompts/family.full.json --workspace anna-workspace
|
|
282
|
-
anna
|
|
282
|
+
anna init from-prompt anna-workspace/prompts/family.prompt.json
|
|
283
283
|
```
|
|
284
284
|
|
|
285
285
|
Chat interactively from either a case file or a frozen prompt state:
|
|
@@ -434,8 +434,8 @@ the base model, or `true` to call the configured SFT endpoint.
|
|
|
434
434
|
|
|
435
435
|
```yaml
|
|
436
436
|
model_service:
|
|
437
|
-
model_name:
|
|
438
|
-
api_key:
|
|
437
|
+
model_name: anna-backbone
|
|
438
|
+
api_key: anna-backbone
|
|
439
439
|
base_url: http://localhost:8002/v1
|
|
440
440
|
servers:
|
|
441
441
|
complaint:
|
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
## 主诉请求和情绪通过reminder来控制
|
|
2
2
|
|
|
3
3
|
prompt_template = """
|
|
4
|
-
|
|
5
|
-
结合历史内容的内容用一致性的语气回复。配合我进行演出,
|
|
6
|
-
请不要回答你是语言模型,永远记住你正在扮演 心理咨询患者
|
|
7
|
-
注意保持你的性格特点包括 {situation}
|
|
4
|
+
# Role: 心理咨询患者
|
|
8
5
|
|
|
9
6
|
## Profile
|
|
10
7
|
- 性别: {gender}
|
|
11
8
|
- 年龄: {age}
|
|
12
9
|
- 职业: {occupation}
|
|
13
10
|
- 婚姻状况: {marriage}
|
|
14
|
-
|
|
11
|
+
|
|
12
|
+
## Situation
|
|
13
|
+
- 你是一个有心理障碍的患者,正在与心理咨询师进行对话。
|
|
14
|
+
{situation}
|
|
15
|
+
|
|
15
16
|
## Status
|
|
16
17
|
{status}
|
|
17
18
|
|
|
@@ -24,4 +25,6 @@ prompt_template = """
|
|
|
24
25
|
## Constraints
|
|
25
26
|
- 使用中文回复
|
|
26
27
|
- 一次不能提及过多的症状信息,每轮最多讨论一个症状。
|
|
28
|
+
- 你应该用含糊和口语化的方式表达你的症状,并将其与你的生活经历联系起来。
|
|
29
|
+
- 不要使用专业术语。
|
|
27
30
|
"""
|
|
@@ -79,7 +79,8 @@ app.add_typer(config_app, name="config")
|
|
|
79
79
|
app.add_typer(test_app, name="test")
|
|
80
80
|
app.add_typer(data_app, name="data")
|
|
81
81
|
app.add_typer(memory_app, name="memory")
|
|
82
|
-
app.add_typer(initialize_app, name="
|
|
82
|
+
app.add_typer(initialize_app, name="init")
|
|
83
|
+
app.add_typer(initialize_app, name="initialize", hidden=True)
|
|
83
84
|
app.add_typer(models_app, name="models")
|
|
84
85
|
models_app.add_typer(models_env_app, name="env")
|
|
85
86
|
app.add_typer(run_app, name="run")
|
|
@@ -147,8 +148,8 @@ def _render_config_summary(
|
|
|
147
148
|
table.add_row("Workspace", str(workspace))
|
|
148
149
|
if source:
|
|
149
150
|
table.add_row(source_kind, str(source))
|
|
150
|
-
table.add_row("
|
|
151
|
-
table.add_row("
|
|
151
|
+
table.add_row("AnnaAgent backbone model", cfg.model_name)
|
|
152
|
+
table.add_row("Backbone endpoint", cfg.base_url)
|
|
152
153
|
table.add_row("Memory", "on" if cfg.memory_enabled else "off")
|
|
153
154
|
table.add_row("Debug UI", "on" if debug_ui else "off")
|
|
154
155
|
console.print(Panel(table, title="配置摘要", border_style="blue"))
|
|
@@ -195,17 +196,77 @@ def _print_deploy_env_status(status: dict[str, Any]) -> None:
|
|
|
195
196
|
console.print(table)
|
|
196
197
|
|
|
197
198
|
|
|
198
|
-
def
|
|
199
|
+
def _iter_exception_chain(err: BaseException):
|
|
199
200
|
current: BaseException | None = err
|
|
200
201
|
while current is not None:
|
|
201
|
-
|
|
202
|
-
return True
|
|
202
|
+
yield current
|
|
203
203
|
current = current.__cause__ or current.__context__
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
def _looks_like_connection_error(err: BaseException) -> bool:
|
|
207
|
+
for current in _iter_exception_chain(err):
|
|
208
|
+
if current.__class__.__name__ in {
|
|
209
|
+
"APIConnectionError",
|
|
210
|
+
"APITimeoutError",
|
|
211
|
+
"ConnectError",
|
|
212
|
+
"ConnectTimeout",
|
|
213
|
+
"ReadTimeout",
|
|
214
|
+
"TimeoutException",
|
|
215
|
+
}:
|
|
216
|
+
return True
|
|
217
|
+
return False
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
def _looks_like_auth_error(err: BaseException) -> bool:
|
|
221
|
+
for current in _iter_exception_chain(err):
|
|
222
|
+
class_name = current.__class__.__name__
|
|
223
|
+
status_code = getattr(current, "status_code", None)
|
|
224
|
+
text = str(current).lower()
|
|
225
|
+
if class_name in {"AuthenticationError", "PermissionDeniedError"}:
|
|
226
|
+
return True
|
|
227
|
+
if status_code in {401, 403}:
|
|
228
|
+
return True
|
|
229
|
+
if "invalid api key" in text or "invalid_key" in text:
|
|
230
|
+
return True
|
|
204
231
|
return False
|
|
205
232
|
|
|
206
233
|
|
|
234
|
+
def _looks_like_model_service_error(err: BaseException) -> bool:
|
|
235
|
+
if _looks_like_connection_error(err) or _looks_like_auth_error(err):
|
|
236
|
+
return True
|
|
237
|
+
for current in _iter_exception_chain(err):
|
|
238
|
+
if current.__class__.__name__ in {"APIStatusError", "RateLimitError"}:
|
|
239
|
+
return True
|
|
240
|
+
return False
|
|
241
|
+
|
|
242
|
+
|
|
243
|
+
def _configured_secret_values() -> list[str]:
|
|
244
|
+
try:
|
|
245
|
+
cfg = registry.get("anna_engine_config")
|
|
246
|
+
except Exception:
|
|
247
|
+
return []
|
|
248
|
+
return [
|
|
249
|
+
cfg.api_key,
|
|
250
|
+
cfg.complaint_api_key,
|
|
251
|
+
cfg.counselor_api_key,
|
|
252
|
+
cfg.emotion_api_key,
|
|
253
|
+
cfg.embedding_api_key,
|
|
254
|
+
]
|
|
255
|
+
|
|
256
|
+
|
|
207
257
|
def _print_model_connection_help(workspace: Path, err: BaseException) -> None:
|
|
208
|
-
|
|
258
|
+
detail = escape(_redact_text(str(err), _configured_secret_values()))
|
|
259
|
+
if _looks_like_auth_error(err):
|
|
260
|
+
console.print(f"[red]Model service authentication failed:[/red] {detail}")
|
|
261
|
+
console.print(
|
|
262
|
+
"Check [bold]ANNA_ENGINE_API_KEY[/bold] or [bold]MIMO_API_KEY[/bold] "
|
|
263
|
+
"in the workspace .env and ensure the key matches the configured "
|
|
264
|
+
"base_url/model."
|
|
265
|
+
)
|
|
266
|
+
elif _looks_like_connection_error(err):
|
|
267
|
+
console.print(f"[red]Model service connection failed:[/red] {detail}")
|
|
268
|
+
else:
|
|
269
|
+
console.print(f"[red]Model service request failed:[/red] {detail}")
|
|
209
270
|
console.print(
|
|
210
271
|
"Run [bold]anna doctor --workspace {workspace}[/bold] and "
|
|
211
272
|
"[bold]anna models status --workspace {workspace}[/bold]. If you use "
|
|
@@ -397,8 +458,8 @@ def doctor(
|
|
|
397
458
|
console.print(table)
|
|
398
459
|
|
|
399
460
|
|
|
400
|
-
@app.command("
|
|
401
|
-
def
|
|
461
|
+
@app.command("create")
|
|
462
|
+
def create_workspace(
|
|
402
463
|
target: Path = typer.Argument(Path("anna-workspace"), help="Workspace directory."),
|
|
403
464
|
force: bool = typer.Option(False, "--force", help="Overwrite generated files."),
|
|
404
465
|
deploy_env: bool = typer.Option(
|
|
@@ -418,7 +479,7 @@ def init_workspace(
|
|
|
418
479
|
),
|
|
419
480
|
) -> None:
|
|
420
481
|
initialize_workspace(target, force=force)
|
|
421
|
-
console.print(f"[green]Workspace
|
|
482
|
+
console.print(f"[green]Workspace created:[/green] {target}")
|
|
422
483
|
if deploy_env:
|
|
423
484
|
try:
|
|
424
485
|
status = setup_deploy_env(
|
|
@@ -464,8 +525,9 @@ def assets_list(
|
|
|
464
525
|
console.print(table)
|
|
465
526
|
|
|
466
527
|
|
|
467
|
-
@assets_app.command("pull")
|
|
468
|
-
|
|
528
|
+
@assets_app.command("pull", hidden=True)
|
|
529
|
+
@assets_app.command("download")
|
|
530
|
+
def assets_download(
|
|
469
531
|
names: list[str] = typer.Argument(None, help="Asset names or preset names."),
|
|
470
532
|
workspace: Path = typer.Option(Path(), "--workspace", "--root", resolve_path=True),
|
|
471
533
|
force: bool = typer.Option(False, "--force", help="Redownload existing files."),
|
|
@@ -488,7 +550,7 @@ def assets_pull(
|
|
|
488
550
|
manifest_file=manifest,
|
|
489
551
|
target_override=target,
|
|
490
552
|
)
|
|
491
|
-
table = Table(title="Asset
|
|
553
|
+
table = Table(title="Asset Download Results")
|
|
492
554
|
table.add_column("Name")
|
|
493
555
|
table.add_column("Status")
|
|
494
556
|
table.add_column("Path")
|
|
@@ -533,11 +595,20 @@ def config_wizard(
|
|
|
533
595
|
workspace: Path = typer.Option(Path(), "--workspace", "--root", resolve_path=True),
|
|
534
596
|
) -> None:
|
|
535
597
|
data = load_settings(workspace)
|
|
598
|
+
console.print(
|
|
599
|
+
Panel(
|
|
600
|
+
"[bold]AnnaAgent backbone model[/bold]\n"
|
|
601
|
+
"This model drives AnnaAgent's internal seeker-simulation modules.",
|
|
602
|
+
border_style="cyan",
|
|
603
|
+
)
|
|
604
|
+
)
|
|
536
605
|
data.setdefault("model_service", {})["model_name"] = typer.prompt(
|
|
537
|
-
"
|
|
606
|
+
"AnnaAgent backbone model name",
|
|
607
|
+
default=data.get("model_service", {}).get("model_name", ""),
|
|
538
608
|
)
|
|
539
609
|
data["model_service"]["base_url"] = typer.prompt(
|
|
540
|
-
"
|
|
610
|
+
"AnnaAgent backbone base URL",
|
|
611
|
+
default=data.get("model_service", {}).get("base_url", ""),
|
|
541
612
|
)
|
|
542
613
|
data.setdefault("embedding", {})["model_name"] = typer.prompt(
|
|
543
614
|
"Embedding model", default=data.get("embedding", {}).get("model_name", "")
|
|
@@ -563,14 +634,14 @@ def config_secrets(
|
|
|
563
634
|
|
|
564
635
|
def _prompt_and_write_secrets(workspace: Path, include_sft: bool = False) -> None:
|
|
565
636
|
prompts = [
|
|
566
|
-
("ANNA_ENGINE_API_KEY", "
|
|
637
|
+
("ANNA_ENGINE_API_KEY", "AnnaAgent backbone API key"),
|
|
567
638
|
("ANNA_ENGINE_EMBEDDING_API_KEY", "Embedding API key"),
|
|
568
639
|
]
|
|
569
640
|
if include_sft:
|
|
570
641
|
prompts.extend(
|
|
571
642
|
[
|
|
572
643
|
("ANNA_ENGINE_COMPLAINT_API_KEY", "Complaint SFT API key"),
|
|
573
|
-
("ANNA_ENGINE_COUNSELOR_API_KEY", "
|
|
644
|
+
("ANNA_ENGINE_COUNSELOR_API_KEY", "Backbone fallback API key"),
|
|
574
645
|
("ANNA_ENGINE_EMOTION_API_KEY", "Emotion SFT API key"),
|
|
575
646
|
]
|
|
576
647
|
)
|
|
@@ -612,10 +683,16 @@ def test_model(
|
|
|
612
683
|
_configure(workspace)
|
|
613
684
|
cfg = registry.get("anna_engine_config")
|
|
614
685
|
client = backbone.get_openai_client()
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
686
|
+
try:
|
|
687
|
+
response = client.chat.completions.create(
|
|
688
|
+
model=cfg.model_name,
|
|
689
|
+
messages=[{"role": "user", "content": "Reply with OK."}],
|
|
690
|
+
)
|
|
691
|
+
except Exception as err:
|
|
692
|
+
if _looks_like_model_service_error(err):
|
|
693
|
+
_print_model_connection_help(workspace, err)
|
|
694
|
+
raise typer.Exit(code=1) from None
|
|
695
|
+
raise
|
|
619
696
|
console.print(
|
|
620
697
|
f"[green]Model OK[/green] response={response.choices[0].message.content}"
|
|
621
698
|
)
|
|
@@ -796,7 +873,10 @@ def initialize_prompt_only(
|
|
|
796
873
|
case_file: Path = typer.Argument(..., help="Case file."),
|
|
797
874
|
output: Path = typer.Option(Path("prompts/prompt_state.json"), "--out", "-o"),
|
|
798
875
|
) -> None:
|
|
876
|
+
console.print(Rule("[bold blue]Initialization · prompt-only[/bold blue]"))
|
|
877
|
+
console.print(f"[blue]Running:[/blue] load case and build prompt for {case_file}")
|
|
799
878
|
state = build_prompt_only_state(case_file)
|
|
879
|
+
console.print(f"[blue]Running:[/blue] write initialization state to {output}")
|
|
800
880
|
save_state(state, output)
|
|
801
881
|
console.print(f"[green]Wrote prompt-only state[/green] {output}")
|
|
802
882
|
|
|
@@ -808,13 +888,26 @@ def initialize_full(
|
|
|
808
888
|
workspace: Path = typer.Option(Path(), "--workspace", "--root", resolve_path=True),
|
|
809
889
|
) -> None:
|
|
810
890
|
_configure(workspace)
|
|
891
|
+
events: list[tuple[str, str]] = []
|
|
892
|
+
|
|
893
|
+
def progress(stage: str, detail: str) -> None:
|
|
894
|
+
events.append((stage, detail))
|
|
895
|
+
console.print(f"[blue]Running {escape(stage)}:[/blue] {escape(detail)}")
|
|
896
|
+
|
|
897
|
+
console.print(Rule("[bold blue]Initialization · full[/bold blue]"))
|
|
898
|
+
console.print(
|
|
899
|
+
f"[blue]Running:[/blue] load case and configure services for {case_file}"
|
|
900
|
+
)
|
|
811
901
|
try:
|
|
812
|
-
state = build_full_state(case_file)
|
|
902
|
+
state = build_full_state(case_file, progress_callback=progress)
|
|
813
903
|
except Exception as err:
|
|
814
|
-
if
|
|
904
|
+
if _looks_like_model_service_error(err):
|
|
815
905
|
_print_model_connection_help(workspace, err)
|
|
816
906
|
raise typer.Exit(code=1) from None
|
|
817
907
|
raise
|
|
908
|
+
if events:
|
|
909
|
+
_render_initialization_events(events)
|
|
910
|
+
console.print(f"[blue]Running:[/blue] write initialization state to {output}")
|
|
818
911
|
save_state(state, output)
|
|
819
912
|
console.print(f"[green]Wrote full state[/green] {output}")
|
|
820
913
|
|
|
@@ -967,7 +1060,7 @@ def models_deploy(
|
|
|
967
1060
|
None, help="Override vLLM max model length."
|
|
968
1061
|
),
|
|
969
1062
|
pull: bool = typer.Option(
|
|
970
|
-
True, "--
|
|
1063
|
+
True, "--download/--no-download", help="Download default asset if missing."
|
|
971
1064
|
),
|
|
972
1065
|
background: bool = typer.Option(True, "--background/--foreground"),
|
|
973
1066
|
dry_run: bool = typer.Option(
|
|
@@ -1121,11 +1214,17 @@ def chat(
|
|
|
1121
1214
|
console.print(Rule("[bold blue]Stage 1/2 · Initialize[/bold blue]"))
|
|
1122
1215
|
_configure(workspace)
|
|
1123
1216
|
init_events: list[tuple[str, str]] = []
|
|
1217
|
+
compact_status: Any = None
|
|
1124
1218
|
|
|
1125
1219
|
def progress(stage: str, detail: str) -> None:
|
|
1126
1220
|
init_events.append((stage, detail))
|
|
1127
1221
|
if debug_ui:
|
|
1128
1222
|
console.print(f"[dim]• {escape(stage)}[/dim] {escape(detail)}")
|
|
1223
|
+
else:
|
|
1224
|
+
message = f"正在运行:{detail}"
|
|
1225
|
+
if compact_status is not None:
|
|
1226
|
+
compact_status.update(f"[blue]{escape(message)}...[/blue]")
|
|
1227
|
+
console.print(f"[blue]{escape(message)}[/blue]")
|
|
1129
1228
|
|
|
1130
1229
|
if state:
|
|
1131
1230
|
_render_config_summary(
|
|
@@ -1151,22 +1250,26 @@ def chat(
|
|
|
1151
1250
|
progress_callback=progress,
|
|
1152
1251
|
)
|
|
1153
1252
|
except Exception as err:
|
|
1154
|
-
if
|
|
1253
|
+
if _looks_like_model_service_error(err):
|
|
1155
1254
|
_print_model_connection_help(workspace, err)
|
|
1156
1255
|
raise typer.Exit(code=1) from None
|
|
1157
1256
|
raise
|
|
1158
1257
|
else:
|
|
1159
1258
|
try:
|
|
1160
|
-
with console.status(
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1259
|
+
with console.status(
|
|
1260
|
+
"[blue]正在运行:初始化来访者状态...[/blue]"
|
|
1261
|
+
) as status:
|
|
1262
|
+
compact_status = status
|
|
1263
|
+
seeker = MsPatient(
|
|
1264
|
+
portrait,
|
|
1265
|
+
report,
|
|
1266
|
+
conversations,
|
|
1267
|
+
progress_callback=progress,
|
|
1268
|
+
)
|
|
1269
|
+
compact_status = None
|
|
1168
1270
|
except Exception as err:
|
|
1169
|
-
|
|
1271
|
+
compact_status = None
|
|
1272
|
+
if _looks_like_model_service_error(err):
|
|
1170
1273
|
_print_model_connection_help(workspace, err)
|
|
1171
1274
|
raise typer.Exit(code=1) from None
|
|
1172
1275
|
raise
|
|
@@ -1215,12 +1318,18 @@ def run_batch(
|
|
|
1215
1318
|
output.mkdir(parents=True, exist_ok=True)
|
|
1216
1319
|
summary_path = output / "summary.jsonl"
|
|
1217
1320
|
for case_file in case_files:
|
|
1218
|
-
state
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1321
|
+
console.print(f"[blue]Running:[/blue] build {mode} state for {case_file}")
|
|
1322
|
+
if mode == "full":
|
|
1323
|
+
state = build_full_state(
|
|
1324
|
+
case_file,
|
|
1325
|
+
progress_callback=lambda stage, detail: console.print(
|
|
1326
|
+
f"[blue]Running {escape(stage)}:[/blue] {escape(detail)}"
|
|
1327
|
+
),
|
|
1328
|
+
)
|
|
1329
|
+
else:
|
|
1330
|
+
state = build_prompt_only_state(case_file)
|
|
1223
1331
|
state_path = output / f"{state['case_id']}.state.json"
|
|
1332
|
+
console.print(f"[blue]Running:[/blue] write state to {state_path}")
|
|
1224
1333
|
save_state(state, state_path)
|
|
1225
1334
|
record = {
|
|
1226
1335
|
"case_id": state["case_id"],
|
|
@@ -1230,7 +1339,11 @@ def run_batch(
|
|
|
1230
1339
|
if live and messages:
|
|
1231
1340
|
session = FrozenPromptSession(state)
|
|
1232
1341
|
transcript_path = output / f"{state['case_id']}.transcript.jsonl"
|
|
1233
|
-
for message in messages:
|
|
1342
|
+
for index, message in enumerate(messages, start=1):
|
|
1343
|
+
console.print(
|
|
1344
|
+
f"[blue]Running:[/blue] live scripted turn {index} "
|
|
1345
|
+
f"for {state['case_id']}"
|
|
1346
|
+
)
|
|
1234
1347
|
response = session.chat(message)
|
|
1235
1348
|
append_jsonl(transcript_path, {"role": "Counselor", "content": message})
|
|
1236
1349
|
append_jsonl(transcript_path, {"role": "Seeker", "content": response})
|