migrate-bluejay
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseBluejay → Coval Migration
Bluejay → Coval 迁移指南
Migrate all configuration from Bluejay to Coval for .
$ARGUMENTS为将所有配置从Bluejay迁移至Coval。
$ARGUMENTSAPI References
API 参考文档
- references/bluejay-api.md — Bluejay endpoints, auth, pagination
- references/coval-api.md — Coval endpoints, auth, request schemas
- references/entity-mapping.md — Field-by-field mapping tables
- references/metric-type-mapping.md — Bluejay response_type → Coval metric_type
- references/bluejay-api.md — Bluejay接口、鉴权、分页机制
- references/coval-api.md — Coval接口、鉴权、请求 schema
- references/entity-mapping.md — 字段级映射表
- references/metric-type-mapping.md — Bluejay response_type → Coval metric_type 映射
Step 0: Pre-flight
步骤0:预检查
Collect API Keys
收集API密钥
Parse for two positional args: .
$ARGUMENTS[bluejay-api-key] [coval-api-key]If not provided, ask the user for each key individually.
从中解析两个位置参数:。
$ARGUMENTS[bluejay-api-key] [coval-api-key]如果未提供,分别向用户索要每个密钥。
Validate Bluejay Key
验证Bluejay密钥
bash
curl -s -o /dev/null -w "%{http_code}" \
-H "X-API-Key: <BLUEJAY_KEY>" \
"https://api.getbluejay.ai/v1/all-agents"Expect . On /, tell user key is invalid.
200401403bash
curl -s -o /dev/null -w "%{http_code}" \
-H "X-API-Key: <BLUEJAY_KEY>" \
"https://api.getbluejay.ai/v1/all-agents"预期返回。若返回/,告知用户密钥无效。
200401403Validate Coval Key
验证Coval密钥
bash
curl -s -o /dev/null -w "%{http_code}" \
-H "X-API-Key: <COVAL_KEY>" \
"https://api.coval.dev/v1/agents?page_size=1"Expect . On , tell user key is invalid.
200401bash
curl -s -o /dev/null -w "%{http_code}" \
-H "X-API-Key: <COVAL_KEY>" \
"https://api.coval.dev/v1/agents?page_size=1"预期返回。若返回,告知用户密钥无效。
200401Fetch Coval Voice Catalog
获取Coval语音库
bash
curl -s -H "X-API-Key: <COVAL_KEY>" \
"https://api.coval.dev/v1/personas/voices"Store the voice list for persona mapping in Step 4. Response shape:
json
{ "voices": [{ "voice_name": "aria", "supported_languages": ["en-US", ...] }] }bash
curl -s -H "X-API-Key: <COVAL_KEY>" \
"https://api.coval.dev/v1/personas/voices"存储语音列表,用于步骤4中的角色映射。响应格式:
json
{ "voices": [{ "voice_name": "aria", "supported_languages": ["en-US", ...] }] }Step 1: Inventory
步骤1:资源盘点
Fetch all Bluejay entities. Use the endpoints in references/bluejay-api.md.
Fetch these in parallel where possible:
| Entity | Endpoint |
|---|---|
| Agents | |
| Simulations | |
| Custom Metrics | |
| Communities | |
| Schedules | Derive from simulations (no list-all endpoint — check each simulation) |
| Customer Personas | Fetch per agent: |
| Folders | |
For each agent, also fetch:
- Latest prompt: (latest version)
GET /v1/agents/{agent_id}/prompts/versions?page_size=1 - Latest knowledge base:
GET /v1/agents/{agent_id}/knowledge-bases/versions?page_size=1 - Digital humans: Fetch per simulation:
GET /v1/digital-humans-by-simulation/{simulation_id}
Present summary to user:
Found:
- X agents
- Y digital humans (across Z simulations)
- N custom metrics
- M communities
- P customer personas
- Q schedules
- R folders
Proceed with migration?Wait for user confirmation before continuing.
获取所有Bluejay实体,使用references/bluejay-api.md中的接口。
尽可能并行获取以下资源:
| 实体 | 接口 |
|---|---|
| Agents | |
| Simulations | |
| Custom Metrics | |
| Communities | |
| Schedules | 从Simulations中提取(无批量获取接口——需逐个检查模拟场景) |
| Customer Personas | 按Agent获取: |
| Folders | |
对于每个Agent,还需获取:
- 最新提示词:(最新版本)
GET /v1/agents/{agent_id}/prompts/versions?page_size=1 - 最新知识库:
GET /v1/agents/{agent_id}/knowledge-bases/versions?page_size=1 - 数字人:按模拟场景获取:
GET /v1/digital-humans-by-simulation/{simulation_id}
向用户展示汇总信息:
已发现:
- X个Agent
- Y个数字人(分布在Z个模拟场景中)
- N个自定义指标
- M个社区
- P个客户角色
- Q个调度任务
- R个文件夹
是否继续迁移?等待用户确认后再继续。
Step 2: Check Existing Coval State
步骤2:检查Coval现有状态
Fetch existing Coval entities to enable idempotency:
bash
undefined获取Coval现有实体以实现幂等性:
bash
undefinedAgents
Agents
curl -s -H "X-API-Key: <COVAL_KEY>" "https://api.coval.dev/v1/agents?page_size=100"
curl -s -H "X-API-Key: <COVAL_KEY>" "https://api.coval.dev/v1/agents?page_size=100"
Personas
Personas
curl -s -H "X-API-Key: <COVAL_KEY>" "https://api.coval.dev/v1/personas?page_size=100"
curl -s -H "X-API-Key: <COVAL_KEY>" "https://api.coval.dev/v1/personas?page_size=100"
Test Sets
Test Sets
curl -s -H "X-API-Key: <COVAL_KEY>" "https://api.coval.dev/v1/test-sets?page_size=100"
curl -s -H "X-API-Key: <COVAL_KEY>" "https://api.coval.dev/v1/test-sets?page_size=100"
Metrics
Metrics
curl -s -H "X-API-Key: <COVAL_KEY>" "https://api.coval.dev/v1/metrics?page_size=100"
curl -s -H "X-API-Key: <COVAL_KEY>" "https://api.coval.dev/v1/metrics?page_size=100"
Run Templates
Run Templates
curl -s -H "X-API-Key: <COVAL_KEY>" "https://api.coval.dev/v1/run-templates?page_size=100"
curl -s -H "X-API-Key: <COVAL_KEY>" "https://api.coval.dev/v1/run-templates?page_size=100"
Scheduled Runs
Scheduled Runs
curl -s -H "X-API-Key: <COVAL_KEY>" "https://api.coval.dev/v1/scheduled-runs?page_size=100"
Paginate if `next_page_token` is present.
Build a lookup map of `display_name → ID` for each entity type. When checking for duplicates:
- If entity exists with `bluejay_migration: true` in metadata → **skip** (already migrated)
- If name collision with non-migrated entity → **ask user** whether to skip or renamecurl -s -H "X-API-Key: <COVAL_KEY>" "https://api.coval.dev/v1/scheduled-runs?page_size=100"
若存在`next_page_token`则分页获取。
为每种实体类型构建`display_name → ID`的查找映射。检查重复项时:
- 若实体元数据中存在`bluejay_migration: true` → **跳过**(已完成迁移)
- 若与非迁移实体重名 → **询问用户**是否跳过或重命名Phase 1: Independent Entities (Steps 3–5)
第一阶段:独立实体(步骤3–5)
These have no cross-references. Execute in order but each step is independent.
这些实体无交叉引用,可按顺序执行,且每个步骤相互独立。
Step 3: Migrate Metrics
步骤3:迁移指标
Map Bluejay Custom Metrics → Coval Metrics.
For each Bluejay metric, use the mapping in references/metric-type-mapping.md.
For each metric:
- Determine from Bluejay
metric_typeresponse_type - Build from Bluejay
prompt+scoring_guidancedescription - For → ask user for category list
qualitative - For → use Bluejay
quantitative/min_valueif present, else askmax_value - For → use
enumasenum_optionscategories - If → use
eval_route == "AUDIO"variantsMETRIC_AUDIO_LLM_* - For → use
json, warn user this is an approximationMETRIC_LLM_BINARY
bash
curl -s -X POST "https://api.coval.dev/v1/metrics" \
-H "X-API-Key: <COVAL_KEY>" \
-H "Content-Type: application/json" \
-d '{
"metric_name": "<bluejay_metric_name>",
"description": "<bluejay_description>",
"metric_type": "<mapped_type>",
"prompt": "<from_scoring_guidance>",
"metadata": {
"bluejay_migration": true,
"bluejay_original_id": "<bluejay_metric_id>"
}
}'Add type-specific fields (, , ) per the mapping table.
categoriesmin_valuemax_valueRecord:
bluejay_metric_id → coval_metric_id将Bluejay自定义指标映射至Coval指标。
对于每个Bluejay指标,使用references/metric-type-mapping.md中的映射规则。
每个指标的处理步骤:
- 根据Bluejay的确定
response_typemetric_type - 从Bluejay的+
scoring_guidance构建descriptionprompt - 若为类型 → 向用户询问分类列表
qualitative - 若为类型 → 若存在Bluejay的
quantitative/min_value则使用,否则询问用户max_value - 若为类型 → 将
enum作为enum_optionscategories - 若→ 使用
eval_route == "AUDIO"变体METRIC_AUDIO_LLM_* - 若为类型 → 使用
json,并告知用户这是近似处理METRIC_LLM_BINARY
bash
curl -s -X POST "https://api.coval.dev/v1/metrics" \
-H "X-API-Key: <COVAL_KEY>" \
-H "Content-Type: application/json" \
-d '{
"metric_name": "<bluejay_metric_name>",
"description": "<bluejay_description>",
"metric_type": "<mapped_type>",
"prompt": "<from_scoring_guidance>",
"metadata": {
"bluejay_migration": true,
"bluejay_original_id": "<bluejay_metric_id>"
}
}'根据映射表添加类型特定字段(、、)。
categoriesmin_valuemax_value记录映射关系:
bluejay_metric_id → coval_metric_idStep 4: Migrate Personas
步骤4:迁移角色
Map Bluejay Digital Humans (voice/behavior) AND Customer Personas → Coval Personas.
将Bluejay数字人(语音/行为)和客户角色映射至Coval角色。
Digital Human → Persona
数字人 → 角色
For each unique digital human:
-
Voice mapping — Present the Bluejay voice config to the user:
Bluejay Digital Human: "<name>" Gender: <gender> Accent: <accent> Language: <language> Available Coval voices: aria, asteria, athena, luna, ... Which Coval voice should map to this configuration?Cache voice mappings — if same gender+accent+language combo appears again, reuse the mapping without asking. -
Map→
language(e.g.,language_code→en,en-US→es)es-ES -
Map→
background_noise(see entity mapping reference)background_sound -
Buildfrom
persona_prompt+role_description+ behavioral fieldstraits
bash
curl -s -X POST "https://api.coval.dev/v1/personas" \
-H "X-API-Key: <COVAL_KEY>" \
-H "Content-Type: application/json" \
-d '{
"name": "<digital_human_name>",
"voice_name": "<mapped_coval_voice>",
"language_code": "<mapped_language_code>",
"persona_prompt": "<built_from_role_description_and_traits>",
"background_sound": "<mapped_background_noise>",
"conversation_initiation": "<from_speaks_first_config>",
"metadata": {
"bluejay_migration": true,
"bluejay_original_id": "<digital_human_id>"
}
}'Record:
bluejay_digital_human_id → coval_persona_id对于每个唯一的数字人:
-
语音映射 — 向用户展示Bluejay语音配置:
Bluejay数字人:"<name>" 性别: <gender> 口音: <accent> 语言: <language> 可用Coval语音:aria, asteria, athena, luna, ... 该配置应映射到哪个Coval语音?缓存语音映射 — 若相同性别+口音+语言组合再次出现,直接复用映射无需询问。 -
将映射为
language(例如:language_code→en,en-US→es)es-ES -
将映射为
background_noise(参考实体映射文档)background_sound -
从+
role_description+ 行为字段构建traitspersona_prompt
bash
curl -s -X POST "https://api.coval.dev/v1/personas" \
-H "X-API-Key: <COVAL_KEY>" \
-H "Content-Type: application/json" \
-d '{
"name": "<digital_human_name>",
"voice_name": "<mapped_coval_voice>",
"language_code": "<mapped_language_code>",
"persona_prompt": "<built_from_role_description_and_traits>",
"background_sound": "<mapped_background_noise>",
"conversation_initiation": "<from_speaks_first_config>",
"metadata": {
"bluejay_migration": true,
"bluejay_original_id": "<digital_human_id>"
}
}'记录映射关系:
bluejay_digital_human_id → coval_persona_idCustomer Persona → Persona
客户角色 → 角色
For each Bluejay Customer Persona:
bash
curl -s -X POST "https://api.coval.dev/v1/personas" \
-H "X-API-Key: <COVAL_KEY>" \
-H "Content-Type: application/json" \
-d '{
"name": "<customer_persona_name>",
"voice_name": "aria",
"language_code": "en-US",
"persona_prompt": "Name: <name>\nDescription: <description>\nGoal: <goal>",
"metadata": {
"bluejay_migration": true,
"bluejay_original_id": "<customer_persona_id>",
"bluejay_entity_type": "customer_persona"
}
}'Ask user which voice to use for customer personas (default to ).
aria对于每个Bluejay客户角色:
bash
curl -s -X POST "https://api.coval.dev/v1/personas" \
-H "X-API-Key: <COVAL_KEY>" \
-H "Content-Type: application/json" \
-d '{
"name": "<customer_persona_name>",
"voice_name": "aria",
"language_code": "en-US",
"persona_prompt": "Name: <name>\nDescription: <description>\nGoal: <goal>",
"metadata": {
"bluejay_migration": true,
"bluejay_original_id": "<customer_persona_id>",
"bluejay_entity_type": "customer_persona"
}
}'询问用户客户角色使用的语音(默认使用)。
ariaStep 5: Migrate Agents
步骤5:迁移Agent
Map Bluejay Agents → Coval Agents.
For each Bluejay agent:
- Determine : Bluejay
model_type→mode=VOICE,MODEL_TYPE_VOICE→mode=TEXTMODEL_TYPE_TEXT - Build from: latest Prompt version
prompt+ agentprompt_text(append as numbered list)goals - If agent has a , prepend it to the prompt
system_prompt - Store content in agent metadata
knowledge_base - If agent has a , prefix
folderwith folder name:display_name"[FolderName] AgentName"
bash
curl -s -X POST "https://api.coval.dev/v1/agents" \
-H "X-API-Key: <COVAL_KEY>" \
-H "Content-Type: application/json" \
-d '{
"display_name": "<folder_prefix><agent_name>",
"model_type": "<MODEL_TYPE_VOICE|MODEL_TYPE_TEXT>",
"prompt": "<system_prompt + latest_prompt + goals>",
"metadata": {
"bluejay_migration": true,
"bluejay_original_id": "<bluejay_agent_id>",
"knowledge_base": "<kb_text_content>",
"bluejay_connection_type": "<connection_type>",
"bluejay_phone_number": "<phone_number>"
}
}'Record:
bluejay_agent_id → coval_agent_id将Bluejay Agent映射至Coval Agent。
对于每个Bluejay Agent:
- 确定:Bluejay
model_type→mode=VOICE,MODEL_TYPE_VOICE→mode=TEXTMODEL_TYPE_TEXT - 构建:最新提示词版本的
prompt+ Agent的prompt_text(以编号列表追加)goals - 若Agent存在,将其前置到prompt中
system_prompt - 将知识库内容存储在Agent元数据中
- 若Agent属于某个文件夹,在前添加文件夹名称:
display_name"[FolderName] AgentName"
bash
curl -s -X POST "https://api.coval.dev/v1/agents" \
-H "X-API-Key: <COVAL_KEY>" \
-H "Content-Type: application/json" \
-d '{
"display_name": "<folder_prefix><agent_name>",
"model_type": "<MODEL_TYPE_VOICE|MODEL_TYPE_TEXT>",
"prompt": "<system_prompt + latest_prompt + goals>",
"metadata": {
"bluejay_migration": true,
"bluejay_original_id": "<bluejay_agent_id>",
"knowledge_base": "<kb_text_content>",
"bluejay_connection_type": "<connection_type>",
"bluejay_phone_number": "<phone_number>"
}
}'记录映射关系:
bluejay_agent_id → coval_agent_idPhase 2: Dependent on Phase 1 (Steps 6–7)
第二阶段:依赖第一阶段(步骤6–7)
Step 6: Migrate Test Sets
步骤6:迁移测试集
Map Bluejay Simulations + Communities → Coval Test Sets.
将Bluejay Simulations + Communities映射至Coval Test Sets。
Simulation → Test Set
模拟场景 → 测试集
For each Bluejay simulation:
bash
curl -s -X POST "https://api.coval.dev/v1/test-sets" \
-H "X-API-Key: <COVAL_KEY>" \
-H "Content-Type: application/json" \
-d '{
"display_name": "<simulation_name>",
"description": "Migrated from Bluejay simulation <simulation_id>",
"test_set_type": "SCENARIO",
"test_set_metadata": {
"bluejay_migration": true,
"bluejay_original_id": "<simulation_id>",
"bluejay_entity_type": "simulation"
}
}'Record:
bluejay_simulation_id → coval_test_set_id对于每个Bluejay模拟场景:
bash
curl -s -X POST "https://api.coval.dev/v1/test-sets" \
-H "X-API-Key: <COVAL_KEY>" \
-H "Content-Type: application/json" \
-d '{
"display_name": "<simulation_name>",
"description": "从Bluejay模拟场景<simulation_id>迁移而来",
"test_set_type": "SCENARIO",
"test_set_metadata": {
"bluejay_migration": true,
"bluejay_original_id": "<simulation_id>",
"bluejay_entity_type": "simulation"
}
}'记录映射关系:
bluejay_simulation_id → coval_test_set_idCommunity → Test Set
社区 → 测试集
For each Bluejay community:
bash
curl -s -X POST "https://api.coval.dev/v1/test-sets" \
-H "X-API-Key: <COVAL_KEY>" \
-H "Content-Type: application/json" \
-d '{
"display_name": "<community_title>",
"description": "<community_description>",
"test_set_type": "SCENARIO",
"test_set_metadata": {
"bluejay_migration": true,
"bluejay_original_id": "<community_id>",
"bluejay_entity_type": "community"
}
}'Record:
bluejay_community_id → coval_test_set_id对于每个Bluejay社区:
bash
curl -s -X POST "https://api.coval.dev/v1/test-sets" \
-H "X-API-Key: <COVAL_KEY>" \
-H "Content-Type: application/json" \
-d '{
"display_name": "<community_title>",
"description": "<community_description>",
"test_set_type": "SCENARIO",
"test_set_metadata": {
"bluejay_migration": true,
"bluejay_original_id": "<community_id>",
"bluejay_entity_type": "community"
}
}'记录映射关系:
bluejay_community_id → coval_test_set_idStep 7: Migrate Test Cases
步骤7:迁移测试用例
Map Bluejay Digital Human intents → Coval Test Cases.
For each digital human associated with a simulation:
- Use →
intentinput_str - Use →
success_criteria(split into array if multi-line)expected_behaviors - Look up from the simulation mapping (Step 6)
coval_test_set_id - If present → set
scripted_responseswithinput_type: "SCRIPT"simulation_metadata_input.script_turns
bash
curl -s -X POST "https://api.coval.dev/v1/test-cases" \
-H "X-API-Key: <COVAL_KEY>" \
-H "Content-Type: application/json" \
-d '{
"test_set_id": "<coval_test_set_id>",
"input_str": "<digital_human_intent>",
"expected_behaviors": ["<success_criteria_line_1>", "<success_criteria_line_2>"],
"description": "<digital_human_name>: <digital_human_tag>",
"input_type": "SCENARIO",
"metadata": {
"bluejay_migration": true,
"bluejay_original_id": "<digital_human_id>"
}
}'For scripted test cases:
bash
curl -s -X POST "https://api.coval.dev/v1/test-cases" \
-H "X-API-Key: <COVAL_KEY>" \
-H "Content-Type: application/json" \
-d '{
"test_set_id": "<coval_test_set_id>",
"input_str": "<digital_human_intent>",
"expected_behaviors": ["<success_criteria>"],
"input_type": "SCRIPT",
"simulation_metadata_input": {
"script_turns": ["<turn_1>", "<turn_2>", "..."]
},
"metadata": {
"bluejay_migration": true,
"bluejay_original_id": "<digital_human_id>"
}
}'Record:
bluejay_digital_human_id → coval_test_case_id将Bluejay数字人意图映射至Coval测试用例。
对于每个与模拟场景关联的数字人:
- 使用作为
intentinput_str - 使用作为
success_criteria(若为多行则拆分为数组)expected_behaviors - 从步骤6的模拟场景映射中查找
coval_test_set_id - 若存在→ 设置
scripted_responses并传入input_type: "SCRIPT"simulation_metadata_input.script_turns
bash
curl -s -X POST "https://api.coval.dev/v1/test-cases" \
-H "X-API-Key: <COVAL_KEY>" \
-H "Content-Type: application/json" \
-d '{
"test_set_id": "<coval_test_set_id>",
"input_str": "<digital_human_intent>",
"expected_behaviors": ["<success_criteria_line_1>", "<success_criteria_line_2>"],
"description": "<digital_human_name>: <digital_human_tag>",
"input_type": "SCENARIO",
"metadata": {
"bluejay_migration": true,
"bluejay_original_id": "<digital_human_id>"
}
}'对于脚本化测试用例:
bash
curl -s -X POST "https://api.coval.dev/v1/test-cases" \
-H "X-API-Key: <COVAL_KEY>" \
-H "Content-Type: application/json" \
-d '{
"test_set_id": "<coval_test_set_id>",
"input_str": "<digital_human_intent>",
"expected_behaviors": ["<success_criteria>"],
"input_type": "SCRIPT",
"simulation_metadata_input": {
"script_turns": ["<turn_1>", "<turn_2>", "..."]
},
"metadata": {
"bluejay_migration": true,
"bluejay_original_id": "<digital_human_id>"
}
}'记录映射关系:
bluejay_digital_human_id → coval_test_case_idPhase 3: Depends on Phase 1 + 2 (Step 8)
第三阶段:依赖第一、二阶段(步骤8)
Step 8: Migrate Run Templates
步骤8:迁移运行模板
Map Bluejay Simulations → Coval Run Templates.
For each Bluejay simulation, create a Run Template that ties together the migrated resources:
- Look up from
coval_agent_id(the simulation's agent)bluejay_agent_id - Pick the first persona mapped from a digital human in this simulation, or ask the user
- Look up from the simulation mapping
coval_test_set_id - Collect from the agent's associated metrics
coval_metric_ids
bash
curl -s -X POST "https://api.coval.dev/v1/run-templates" \
-H "X-API-Key: <COVAL_KEY>" \
-H "Content-Type: application/json" \
-d '{
"display_name": "<simulation_name> Template",
"description": "Migrated from Bluejay simulation <simulation_id>",
"agent_id": "<coval_agent_id>",
"persona_id": "<coval_persona_id>",
"test_set_id": "<coval_test_set_id>",
"metric_ids": ["<coval_metric_id_1>", "<coval_metric_id_2>"],
"iteration_count": 1,
"concurrency": 5,
"metadata": {
"bluejay_migration": true,
"bluejay_original_id": "<simulation_id>"
}
}'Record:
bluejay_simulation_id → coval_run_template_id将Bluejay Simulations映射至Coval Run Templates。
对于每个Bluejay模拟场景,创建一个关联已迁移资源的运行模板:
- 从(模拟场景关联的Agent)查找
bluejay_agent_idcoval_agent_id - 选择该模拟场景中数字人映射的第一个角色,或询问用户
- 从模拟场景映射中查找
coval_test_set_id - 收集Agent关联指标对应的
coval_metric_ids
bash
curl -s -X POST "https://api.coval.dev/v1/run-templates" \
-H "X-API-Key: <COVAL_KEY>" \
-H "Content-Type: application/json" \
-d '{
"display_name": "<simulation_name> Template",
"description": "从Bluejay模拟场景<simulation_id>迁移而来",
"agent_id": "<coval_agent_id>",
"persona_id": "<coval_persona_id>",
"test_set_id": "<coval_test_set_id>",
"metric_ids": ["<coval_metric_id_1>", "<coval_metric_id_2>"],
"iteration_count": 1,
"concurrency": 5,
"metadata": {
"bluejay_migration": true,
"bluejay_original_id": "<simulation_id>"
}
}'记录映射关系:
bluejay_simulation_id → coval_run_template_idPhase 4: Depends on Phase 3 (Step 9)
第四阶段:依赖第三阶段(步骤9)
Step 9: Migrate Scheduled Runs
步骤9:迁移调度任务
Map Bluejay Schedules → Coval Scheduled Runs.
All scheduled runs are created DISABLED for safety. The customer must manually enable them after review.
For each Bluejay schedule:
- Look up from the simulation mapping
coval_run_template_id - Convert schedule format:
- Bluejay expression → Coval
cronformatcron(...) - Bluejay →
every_n_minutesrate(<n> minutes) - Bluejay →
every_n_hoursrate(<n> hours) - Bluejay at HH:MM →
dailycron(<MM> <HH> ? * * *) - Bluejay →
weeklycron(<MM> <HH> ? * <DAY> *) - Bluejay →
monthlycron(<MM> <HH> <DOM> * ? *)
- Bluejay
bash
curl -s -X POST "https://api.coval.dev/v1/scheduled-runs" \
-H "X-API-Key: <COVAL_KEY>" \
-H "Content-Type: application/json" \
-d '{
"display_name": "<simulation_name> Schedule",
"run_template_id": "<coval_run_template_id>",
"schedule_expression": "<converted_schedule>",
"enabled": false,
"metadata": {
"bluejay_migration": true,
"bluejay_original_id": "<schedule_id>"
}
}'Record:
bluejay_schedule_id → coval_scheduled_run_id将Bluejay Schedules映射至Coval Scheduled Runs。
**出于安全考虑,所有创建的调度任务默认处于禁用状态。**客户需在审核后手动启用。
对于每个Bluejay调度任务:
- 从模拟场景映射中查找
coval_run_template_id - 转换调度格式:
- Bluejay 表达式 → Coval
cron格式cron(...) - Bluejay →
every_n_minutesrate(<n> minutes) - Bluejay →
every_n_hoursrate(<n> hours) - Bluejay 于HH:MM →
dailycron(<MM> <HH> ? * * *) - Bluejay →
weeklycron(<MM> <HH> ? * <DAY> *) - Bluejay →
monthlycron(<MM> <HH> <DOM> * ? *)
- Bluejay
bash
curl -s -X POST "https://api.coval.dev/v1/scheduled-runs" \
-H "X-API-Key: <COVAL_KEY>" \
-H "Content-Type: application/json" \
-d '{
"display_name": "<simulation_name> Schedule",
"run_template_id": "<coval_run_template_id>",
"schedule_expression": "<converted_schedule>",
"enabled": false,
"metadata": {
"bluejay_migration": true,
"bluejay_original_id": "<schedule_id>"
}
}'记录映射关系:
bluejay_schedule_id → coval_scheduled_run_idStep 10: Migration Report
步骤10:迁移报告
Print a final summary:
undefined打印最终汇总:
undefinedMigration Complete
迁移完成
Created Entities
创建的实体
| Type | Count | Details |
|---|---|---|
| Metrics | N | bluejay_id → coval_id for each |
| Personas | N | ... |
| Agents | N | ... |
| Test Sets | N | ... |
| Test Cases | N | ... |
| Run Templates | N | ... |
| Scheduled Runs | N | (all disabled) |
| 类型 | 数量 | 详情 |
|---|---|---|
| Metrics | N | 每个实体的bluejay_id → coval_id映射 |
| Personas | N | ... |
| Agents | N | ... |
| Test Sets | N | ... |
| Test Cases | N | ... |
| Run Templates | N | ... |
| Scheduled Runs | N | (全部禁用) |
Skipped (Already Existed)
已跳过(已存在)
- List any entities skipped due to idempotency
- 列出因幂等性而跳过的实体
Warnings
警告
- List any ambiguous mappings or approximations made
- Note any metrics mapped to METRIC_LLM_BINARY
json - Note any voice mappings that may need review
- 列出所有模糊映射或近似处理的内容
- 记录所有映射为METRIC_LLM_BINARY的json类型指标
- 记录所有需审核的语音映射
Next Steps
后续步骤
- Review migrated entities in the Coval dashboard: https://app.coval.dev
- Enable scheduled runs after verifying configuration
- Run a test evaluation from a migrated Run Template to verify
- Review persona voice assignments and adjust if needed
undefined- 在Coval控制台查看已迁移实体:https://app.coval.dev
- 验证配置后启用调度任务
- 运行一个迁移后的运行模板进行测试验证
- 审核角色语音分配并按需调整
undefinedError Handling
错误处理
- HTTP 429 (Rate Limited): Wait 5 seconds and retry. Max 3 retries per request.
- HTTP 400 (Bad Request): Show the error details to the user. Ask whether to fix the input and retry, or skip this entity.
- HTTP 401/403 (Auth Error): Stop and ask user to verify their API key.
- HTTP 500 (Server Error): Show error, skip entity, continue with others.
- Network Error: Retry once after 3 seconds. If still failing, stop and report what was created so far.
After any failure, always show what has been successfully created so far so the user can resume.
- HTTP 429(请求限流):等待5秒后重试,每个请求最多重试3次。
- HTTP 400(请求错误):向用户展示错误详情,询问是否修正输入后重试,或跳过该实体。
- HTTP 401/403(鉴权错误):停止操作并要求用户验证API密钥。
- HTTP 500(服务器错误):展示错误信息,跳过该实体,继续处理其他内容。
- 网络错误:等待3秒后重试一次。若仍失败,停止操作并报告已成功创建的内容。
无论发生何种失败,均需向用户展示已成功创建的内容,以便用户可以恢复迁移。
Idempotency Rules
幂等性规则
- Before creating any entity, check the name lookup from Step 2
- If entity exists with in metadata → skip silently
bluejay_migration: true - If name collision with non-migrated entity → ask user: "A Coval <entity_type> named '<name>' already exists but wasn't from a Bluejay migration. Skip, rename, or overwrite?"
- All created entities get metadata:
{ "bluejay_migration": true, "bluejay_original_id": "<id>" } - Re-running the migration should produce zero new entities if nothing changed
- 创建任何实体前,检查步骤2中的名称查找映射
- 若实体元数据中存在→ 静默跳过
bluejay_migration: true - 若与非迁移实体重名 → 询问用户:“名为'<name>'的Coval <entity_type>已存在,但并非来自Bluejay迁移。是否跳过、重命名或覆盖?”
- 所有创建的实体均添加元数据:
{ "bluejay_migration": true, "bluejay_original_id": "<id>" } - 若未发生任何变更,重新运行迁移不应创建新实体