Saltar al contenido principal

Redacción del manifiesto del Workflow

workflow.json es el archivo de manifiesto de un workflow, que define todos sus metadatos y comportamiento. El Workflow Manager descubre y carga los workflows a través de este archivo.

Estructura básica

{
"id": "my-workflow",
"label": "My Workflow",
"version": "1.0.0",
"provider": "pass-through",
"display": {
"core": false,
"emoji": "🔧"
},
"inputs": { "unit": "parent" },
"parameters": {},
"execution": {},
"request": { "kind": "pass-through.run.v1" },
"hooks": {
"preflight": "hooks/preflight.mjs",
"applyResult": "hooks/applyResult.mjs"
}
}

Referencia de campos

Identificación básica

CampoRequeridoTipoDescripción
idstringIdentificador único; no debe duplicarse. Se recomienda kebab-case
labelstringNombre visible para el usuario
versionstringNúmero de versión semántica, p. ej., "1.0.0"
providerstringTipo de backend. Ver abajo los valores disponibles

Valores de Provider

ValorDescripción
"pass-through"Ejecución puramente local, sin necesidad de backend. Adecuado para operaciones de archivo, exportaciones, etc.
"skillrunner"Ejecuta skills a través del backend Skill-Runner
"acp"Ejecuta skills a través del backend ACP
"generic-http"Llama APIs a través del backend Generic HTTP

provider determina con qué tipos de backend es compatible el workflow, y también determina qué backends se muestran como ejecutables en el Dashboard.

Control de visualización

{
"display": {
"core": true,
"emoji": "📊"
},
"taskNameTemplate": "Processing: {query}",
"debug_only": false
}
CampoTipoDescripción
display.corebooleanSi marcar como workflow principal (visualización prioritaria en el Dashboard, con insignia de principal)
display.emojistringIcono prefijo del nombre visible, p. ej., "📖"
taskNameTemplatestringPlantilla de nombre de tarea usando marcadores {nombre de parámetro}, reemplazados con valores reales en tiempo de ejecución
debug_onlybooleanCuando es true, solo visible en modo de depuración

Definición de entrada

{
"inputs": {
"unit": "attachment",
"accepts": {
"mime": ["text/markdown", "text/x-markdown", "application/pdf"]
},
"per_parent": {
"min": 1,
"max": 1
}
}
}
CampoDescripción
unitTipo de unidad de entrada. "attachment" (adjunto), "parent" (elemento padre), "note" (nota), "workflow" (no se necesita selección de elementos, se activa directamente desde el Dashboard)
accepts.mimeTipos MIME aceptados (solo aplicable cuando unit: "attachment"). Si no se especifica, se aceptan todos los tipos
per_parent.minNúmero mínimo de adjuntos por elemento padre
per_parent.maxNúmero máximo de adjuntos por elemento padre

Cuando unit: "workflow", no se requieren elementos seleccionados por el usuario para activar (p. ej., "Crear síntesis de tema").

validateSelection — Validación de selección

validateSelection es validación de selección declarativa. Cubre escenarios comunes como "omitir elementos que ya tienen resultados" o "aceptar solo selecciones de tipos específicos" — sin escribir JavaScript.

{
"validateSelection": {
"select": {
"policy": "literature-source"
},
"require": {
"counts": {
"parents": 1
},
"allowMixed": false
},
"exclude": [
{
"kind": "generated-notes-all",
"noteKinds": ["digest", "references", "citation-analysis"]
}
]
}
}

select — Política de selección

CampoTipoDescripción
select.policystringPolítica de selección. Valores soportados abajo
select.unitstringAnula la unidad de entrada para la validación de selección. "attachment" / "parent" / "note" / "workflow"

Valores soportados de select.policy:

PolíticaDescripción
input-unitAceptar elementos que coincidan con la unidad de entrada
literature-sourceAceptar fuentes literarias (adjuntos o elementos padre con adjuntos expandibles)
pdf-attachmentAceptar solo adjuntos PDF
selected-parentAceptar elementos padre de la selección
generated-note-candidatesAceptar elementos candidatos para notas generadas
digest-representative-imageElementos objetivo para extracción de imagen representativa

require — Requisitos de selección

CampoTipoDescripción
require.counts.parentsnumberMínimo de elementos padre requeridos
require.counts.attachmentsnumberMínimo de elementos adjunto requeridos
require.counts.notesnumberMínimo de elementos nota requeridos
require.counts.childrennumberMínimo de elementos hijo requeridos
require.counts.totalnumberMínimo total de elementos requeridos
require.allowMixedbooleanSi se permite mezclar diferentes tipos de elementos en la selección

exclude — Reglas de exclusión

CampoTipoDescripción
exclude[]arrayLista de reglas de exclusión. Si alguna regla coincide, el elemento actual se omite

Valores soportados de exclude.kind:

kindDescripciónParámetros adicionales
generated-notes-allEl elemento ya tiene notas generadas del tipo especificadonoteKinds: lista de tipos de nota, p. ej., ["digest", "references", "citation-analysis"]
artifact-existsEl elemento ya tiene el artefacto especificado (para evitar ejecución redundante)target: "deep-reading-html" / "translator-markdown" / "mineru-markdown"; parameter: parámetro de idioma opcional para coincidencia de artefactos

derive — Selecciones derivadas

CampoTipoDescripción
derive[]arrayOperaciones de selección derivada. "exportCandidates" — derivar candidatos para exportación de notas; "digestRepresentativeImageTarget" — derivar objetivos de imagen representativa de notas digest

Ejemplo:

{
"validateSelection": {
"select": { "policy": "literature-source" },
"exclude": [
{ "kind": "artifact-exists", "target": "deep-reading-html" }
]
}
}

En este ejemplo, los elementos que ya tienen el artefacto HTML de lectura profunda se omiten automáticamente, sin requerir filtrado manual por parte del usuario.

Control de activación

{
"trigger": {
"requiresSelection": false
}
}
CampoDescripción
requiresSelectionSi se requieren elementos seleccionados por el usuario para activar. Por defecto es true. Cuando se establece en false, el workflow puede ejecutarse desde el Dashboard sin seleccionar ningún elemento. Normalmente se establece en false cuando inputs.unit: "workflow"

Control de ejecución

{
"execution": {
"timeout_ms": 600000,
"poll_interval_ms": 2000,
"mcp": {
"requiredTools": ["search_items", "get_item_detail"]
},
"zoteroHostAccess": {
"required": false,
"allowWriteApprovalBypass": false
},
"feedback": {
"showNotifications": true
}
}
}
CampoDescripción
timeout_msTiempo de espera en milisegundos (solo efectivo para backends Generic HTTP)
poll_interval_msIntervalo de sondeo en milisegundos, controla la frecuencia de verificación de progreso
mcp.requiredToolsHerramientas MCP requeridas por este workflow (array de cadenas de nombres de herramientas)
zoteroHostAccess.requiredSi se requiere acceso al host de Zotero (para leer/escribir datos de la biblioteca)
zoteroHostAccess.allowWriteApprovalBypassSi se permite la omisión de aprobación de operaciones de escritura
feedback.showNotificationsSi mostrar notificaciones de ejecución. Por defecto es true; establecer en false para ejecución silenciosa

El modo de ejecución (auto / interactive) se ha movido a request.create.mode — consulta Tipos de solicitud.

Obtención de resultados

{
"result": {
"fetch": { "type": "bundle" },
"final_step_id": "finalize",
"expects": {
"result_json": "result/result.json",
"artifacts": [
"result/artifact1",
"result/artifact2"
]
}
}
}
CampoDescripción
fetch.typeMétodo de obtención. "bundle" (descargar bundle zip), "result" (solo obtener JSON de resultado)
final_step_idPara workflows de secuencia, especifica el id del paso final, usado para determinar el resultado final
expects.result_jsonRuta esperada del archivo JSON de resultado (relativa al workspace de ejecución)
expects.artifactsLista de rutas esperadas de archivos de artefactos

Definición de solicitud

Definición de solicitud declarativa, mutuamente excluyente con hooks.buildRequest (si ambos existen, hooks.buildRequest tiene prioridad).

{
"request": {
"kind": "skillrunner.job.v1",
"create": {
"skill_id": "my-skill",
"skill_source": "local-package"
},
"input": {
"upload": {
"files": [
{ "key": "source", "from": "selected.markdown" }
]
}
},
"poll": {
"interval_ms": 2000,
"timeout_ms": 600000
}
}
}

Para información detallada sobre cada kind, consulta Tipos de solicitud.

Declaración de Hooks

{
"hooks": {
"preflight": "hooks/preflight.mjs",
"buildRequest": "hooks/buildRequest.mjs",
"normalizeSettings": "hooks/normalizeSettings.mjs",
"applyResult": "hooks/applyResult.mjs"
}
}
CampoRequeridoDescripción
applyResultRequerido. Ruta del script para el manejo de resultados post-ejecución
preflightOpcional. Se ejecuta después de la resolución de selección y antes de la construcción de la solicitud. Puede continuar, omitir, cortocircuitar hacia applyResult, o reemplazar una unidad de entrada con unidades de solicitud virtuales
buildRequestOpcional. Construir la solicitud a enviar al backend. Mutuamente excluyente con el campo request
normalizeSettingsOpcional. Normalizar parámetros establecidos por el usuario

El filtrado de entrada ha sido reemplazado por el mecanismo declarativo validateSelection — consulta Validación de selección abajo.

preflight no participa en la habilitación del menú, la clasificación de selección de depuración ni las verificaciones de disponibilidad de Host Bridge. Mantén las restricciones de selección en validateSelection, la construcción de solicitudes del proveedor en buildRequest o request, y las escrituras de Zotero en applyResult.

Las rutas son relativas al directorio que contiene workflow.json.

Localización

{
"i18n": {
"defaultLocale": "en-US",
"messages": {
"zh-CN": {
"label": "My Workflow",
"parameters.language.title": "Language"
}
}
}
}

Consulta la página de Localización para información detallada.

Ejemplo completo: Un workflow de análisis de literatura con parámetros

{
"id": "my-literature-analysis",
"label": "My Literature Analysis",
"version": "1.0.0",
"provider": "skillrunner",
"display": { "emoji": "📄" },
"inputs": {
"unit": "attachment",
"accepts": { "mime": ["application/pdf"] },
"per_parent": { "min": 1, "max": 1 }
},
"parameters": {
"language": {
"type": "string",
"title": "Output Language",
"default": "en-US",
"enum": ["en-US", "zh-CN", "ja-JP"],
"allowCustom": true
}
},
"execution": {
"mode": "auto",
"skillrunner_mode": "auto",
"timeout_ms": 600000
},
"request": {
"kind": "skillrunner.job.v1",
"create": { "skill_id": "literature-analysis" }
},
"result": {
"fetch": { "type": "bundle" },
"expects": {
"result_json": "result/result.json"
}
},
"hooks": {
"applyResult": "hooks/applyResult.mjs"
}
}

Próximos pasos