mcpField
M
migrate-bluejay

migrate-bluejay

github.com/coval-ai测试与质量352 次安装1 天前更新
代码仓库

关于 migrate-bluejay

用于将 Bluejay 配置和实体迁移到 Coval 的引导式技能。它盘点源数据、映射相互依赖的实体、检查重复项并处理失败;创建的计划运行会保持禁用,供审核后启用。

主要功能

  1. 01盘点 Bluejay 实体
  2. 02映射指标、角色和 Agent
  3. 03创建 Coval 测试集与测试用例
  4. 04迁移运行模板和计划任务
  5. 05检查重复项并报告进度

适用场景

  1. 01将 Bluejay 配置迁移至 Coval
  2. 02创建依赖资源前核对实体映射
  3. 03部分失败后查看进度并继续迁移

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/coval-ai/coval-external-skills --skill migrate-bluejay

安装后在 Claude Code 中输入/migrate-bluejay确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
bluejay-api.md
coval-api.md
entity-mapping.md
metric-type-mapping.md

详细介绍

Bluejay → Coval 迁移

为 $ARGUMENTS 将所有配置从 Bluejay 迁移到 Coval。

API 参考

步骤 0:迁移前检查

收集 API 密钥

解析 $ARGUMENTS 中的两个位置参数:[bluejay-api-key] [coval-api-key]。

如果未提供,请分别向用户询问每个密钥。

验证 Bluejay 密钥
curl -s -o /dev/null -w "%{http_code}" \
  -H "X-API-Key: <BLUEJAY_KEY>" \
  "https://api.getbluejay.ai/v1/all-agents"

预期为 200。如果返回 401/403,请告知用户密钥无效。

验证 Coval 密钥
curl -s -o /dev/null -w "%{http_code}" \
  -H "X-API-Key: <COVAL_KEY>" \
  "https://api.coval.dev/v1/agents?page_size=1"

预期为 200。如果返回 401,请告知用户密钥无效。

获取 Coval 语音目录
curl -s -H "X-API-Key: <COVAL_KEY>" \
  "https://api.coval.dev/v1/personas/voices"

保存语音列表,以便在步骤 4 中映射角色。响应格式:

{ "voices": [{ "voice_name": "aria", "supported_languages": ["en-US", ...] }] }

步骤 1:盘点

获取所有 Bluejay 实体。使用 references/bluejay-api.md 中的端点。

尽可能并行获取以下数据:

实体端点
AgentsGET /v1/all-agents
模拟GET /v1/get-all-simulations
自定义指标GET /v1/custom-metrics?page=1&page_size=100(分页)
社区GET /v1/communities
计划从模拟中推导(没有列出所有计划的端点——检查每个模拟)
客户角色按 Agent 获取:GET /v1/customer-personas-by-agent/{agent_id}
文件夹GET /v1/all-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}

向用户展示摘要:

Found:
  - X agents
  - Y digital humans (across Z simulations)
  - N custom metrics
  - M communities
  - P customer personas
  - Q schedules
  - R folders

Proceed with migration?

继续之前,请等待用户确认。

步骤 2:检查现有 Coval 状态

获取现有 Coval 实体,以支持幂等操作:

# Agents
curl -s -H "X-API-Key: <COVAL_KEY>" "https://api.coval.dev/v1/agents?page_size=100"

# Personas
curl -s -H "X-API-Key: <COVAL_KEY>" "https://api.coval.dev/v1/personas?page_size=100"

# Test Sets
curl -s -H "X-API-Key: <COVAL_KEY>" "https://api.coval.dev/v1/test-sets?page_size=100"

# Metrics
curl -s -H "X-API-Key: <COVAL_KEY>" "https://api.coval.dev/v1/metrics?page_size=100"

# Run Templates
curl -s -H "X-API-Key: <COVAL_KEY>" "https://api.coval.dev/v1/run-templates?page_size=100"

# Scheduled Runs
curl -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 → 跳过(已迁移)
  • 如果名称与非迁移实体冲突 → 询问用户是跳过还是重命名

阶段 1:独立实体(步骤 3–5)

这些实体没有交叉引用。按顺序执行,但每个步骤彼此独立。

步骤 3:迁移指标

将 Bluejay 自定义指标映射为 Coval 指标。

对于每个 Bluejay 指标,使用 references/metric-type-mapping.md 中的映射。

对于每个指标:

  1. 根据 Bluejay response_type 确定 metric_type
  2. 使用 Bluejay scoring_guidance + description 构建 prompt
  3. 对于 qualitative → 向用户询问类别列表
  4. 对于 quantitative → 如果存在则使用 Bluejay min_value/max_value,否则询问用户
  5. 对于 enum → 使用 enum_options 作为 categories
  6. 如果 eval_route == "AUDIO" → 使用 METRIC_AUDIO_LLM_* 变体
  7. 对于 json → 使用 METRIC_LLM_BINARY,并提醒用户这只是近似方案
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>"
    }
  }'

根据映射表添加特定类型的字段(categories、min_value、max_value)。

记录:bluejay_metric_id → coval_metric_id

步骤 4:迁移角色

将 Bluejay 数字人(语音/行为)和客户角色映射为 Coval 角色。

数字人 → Persona

对于每个唯一的数字人:

  1. 语音映射 — 向用户展示 Bluejay 语音配置:

    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?
    

    缓存语音映射 — 如果再次出现相同的性别、口音和语言组合,则重复使用该映射,无需询问。

  2. 将 language 映射为 language_code(例如,en → en-US,es → es-ES)

  3. 将 background_noise 映射为 background_sound(参见实体映射参考)

  4. 根据 role_description、traits 和行为字段构建 persona_prompt

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_id

客户 Persona → Persona

对于每个 Bluejay 客户 Persona:

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"
    }
  }'

询问用户客户 Persona 应使用哪种语音(默认为 aria)。

步骤 5:迁移 Agent

将 Bluejay Agent 映射为 Coval Agent。

对于每个 Bluejay Agent:

  1. 确定 model_type:Bluejay mode=VOICE → MODEL_TYPE_VOICE,mode=TEXT → MODEL_TYPE_TEXT
  2. 根据以下内容构建 prompt:最新版本 Prompt 的 prompt_text + Agent 的 goals(以编号列表形式追加)
  3. 如果 Agent 有 system_prompt,则将其添加到提示词前面
  4. 将 knowledge_base 内容存储在 Agent 元数据中
  5. 如果 Agent 有 folder,则在 display_name 前加上文件夹名称:"[FolderName] AgentName"
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_id

阶段 2:依赖阶段 1(步骤 6–7)

步骤 6:迁移测试集

将 Bluejay 模拟 + 社区映射为 Coval 测试集。

模拟 → 测试集

对于每个 Bluejay 模拟:

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"
    }
  }'

记录:bluejay_simulation_id → coval_test_set_id

社区 → 测试集

对于每个 Bluejay 社区:

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_id

步骤 7:迁移测试用例

将 Bluejay 数字人意图映射为 Coval 测试用例。

对于与模拟关联的每个数字人:

  1. 使用 intent → input_str
  2. 使用 success_criteria → expected_behaviors(如果有多行,则拆分为数组)
  3. 从模拟映射中查找 coval_test_set_id(步骤 6)
  4. 如果存在 scripted_responses,则设置 input_type: "SCRIPT",并使用 simulation_metadata_input.script_turns
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>"
    }
  }'

对于脚本化测试用例:

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_id

阶段 3:依赖阶段 1 + 2(步骤 8)

步骤 8:迁移运行模板

将 Bluejay 模拟映射为 Coval 运行模板。

对于每个 Bluejay 模拟,创建一个运行模板,将迁移后的资源关联起来:

  1. 根据 bluejay_agent_id 查找 coval_agent_id(该模拟的 Agent)
  2. 选择此模拟中由数字人映射得到的第一个 Persona,或询问用户
  3. 从模拟映射中查找 coval_test_set_id
  4. 收集与 Agent 关联的 coval_metric_ids
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>"
    }
  }'

记录:bluejay_simulation_id → coval_run_template_id

阶段 4:依赖阶段 3(步骤 9)

步骤 9:迁移计划运行

将 Bluejay 计划映射为 Coval 计划运行。

为安全起见,所有计划运行均创建为 DISABLED。 客户必须在审核后手动启用它们。

对于每个 Bluejay 计划:

  1. 从模拟映射中查找 coval_run_template_id
  2. 转换计划格式:
    • Bluejay cron 表达式 → Coval cron(...) 格式
    • Bluejay every_n_minutes → rate(<n> minutes)
    • Bluejay every_n_hours → rate(<n> hours)
    • Bluejay 每日 HH:MM → cron(<MM> <HH> ? * * *)
    • Bluejay 每周 → cron(<MM> <HH> ? * <DAY> *)
    • Bluejay 每月 → cron(<MM> <HH> <DOM> * ? *)
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_id

步骤 10:迁移报告

打印最终摘要:

## Migration 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) |

### Skipped (Already Existed)
- List any entities skipped due to idempotency

### Warnings
- List any ambiguous mappings or approximations made
- Note any `json` metrics mapped to METRIC_LLM_BINARY
- Note any voice mappings that may need review

### Next Steps
1. Review migrated entities in the Coval dashboard: https://app.coval.dev
2. Enable scheduled runs after verifying configuration
3. Run a test evaluation from a migrated Run Template to verify
4. Review persona voice assignments and adjust if needed

错误处理

  • HTTP 429(速率受限):等待 5 秒后重试。每个请求最多重试 3 次。
  • HTTP 400(错误请求):向用户显示错误详情。询问用户是修正输入后重试,还是跳过此实体。
  • HTTP 401/403(身份验证错误):停止操作,并请用户核验 API key。
  • HTTP 500(服务器错误):显示错误,跳过此实体并继续处理其他实体。
  • 网络错误:等待 3 秒后重试一次。如果仍然失败,则停止并报告目前已创建的内容。

发生任何故障后,始终向用户显示目前已成功创建的内容,以便用户继续操作。

幂等性规则

  1. 创建任何实体之前,先执行步骤 2 中的名称查找
  2. 如果实体存在,且其元数据中 bluejay_migration: true → 静默跳过
  3. 如果名称与非迁移实体冲突 → 询问用户:“名为 '' 的 Coval <entity_type> 已存在,但并非由 Bluejay 迁移创建。要跳过、重命名还是覆盖?”
  4. 所有已创建的实体都添加以下元数据:{ "bluejay_migration": true, "bluejay_original_id": "<id>" }
  5. 如果没有任何更改,重新运行迁移不应创建任何新实体

评论

支持 Markdown