Files
0pt/src/document-workbench/candidate-catalog.ts
T
admin bd1c20edb2
CI (SIAX Cloud) / integration (push) Skipped
CI (SIAX Cloud) / sonar (push) Skipped
masterplan-lock / check (push) Successful in 5s
Security Scan (SIAX Cloud) / security (push) Successful in 15s
CI (SIAX Cloud) / security (push) Successful in 16s
CI (SIAX Cloud) / sonar (pull_request) Skipped
masterplan-lock / check (pull_request) Successful in 7s
Security Scan (SIAX Cloud) / security (pull_request) Successful in 21s
CI (SIAX Cloud) / security (pull_request) Successful in 25s
CI (SIAX Cloud) / quality (push) Successful in 1m17s
CI (SIAX Cloud) / integration (pull_request) Successful in 54s
CI (SIAX Cloud) / quality (pull_request) Successful in 1m7s
feat: add guarded document workbench foundations
2026-11-02 01:26:36 +01:00

230 lines
7.9 KiB
TypeScript

/**
* Product planning inventory, NOT an execution registry. Every entry needs
* version pinning, licence/model review, installation and integration tests
* before a separately authorized DocumentTool may be created for it.
*/
export type CandidateRole =
| 'detection'
| 'document'
| 'ocr'
| 'table'
| 'quality'
| 'mapping'
| 'entity'
| 'media'
| 'chat'
| 'workflow'
| 'metering'
| 'model'
| 'integration'
| 'agent'
| 'decision'
| 'evaluation'
| 'observability'
| 'browser';
export interface ToolCandidate {
id: string;
name: string;
source: string;
roles: readonly CandidateRole[];
/** Planning only; no candidate is automatically allowed to execute. */
status: 'qualification_required';
review: 'standard' | 'additional_license_or_service_review';
}
const candidate = (
id: string,
name: string,
source: string,
roles: readonly CandidateRole[],
review: ToolCandidate['review'] = 'standard',
): ToolCandidate => ({ id, name, source, roles, status: 'qualification_required', review });
export const TOOL_CANDIDATES: readonly ToolCandidate[] = [
candidate('tika', 'Apache Tika', 'https://github.com/apache/tika', ['detection', 'document']),
candidate('docling', 'Docling', 'https://github.com/docling-project/docling', [
'detection',
'document',
'table',
]),
candidate('unstructured', 'Unstructured', 'https://github.com/Unstructured-IO/unstructured', [
'document',
'table',
]),
candidate('pdfplumber', 'pdfplumber', 'https://github.com/jsvine/pdfplumber', ['document', 'table']),
candidate('tesseract', 'Tesseract', 'https://github.com/tesseract-ocr/tesseract', ['ocr']),
candidate('paddleocr', 'PaddleOCR', 'https://github.com/PaddlePaddle/PaddleOCR', ['ocr', 'document']),
candidate('ocrmypdf', 'OCRmyPDF', 'https://github.com/ocrmypdf/OCRmyPDF', ['ocr', 'document']),
candidate('markitdown', 'MarkItDown', 'https://github.com/microsoft/markitdown', ['document']),
candidate('duckdb', 'DuckDB', 'https://github.com/duckdb/duckdb', ['table', 'quality']),
candidate('polars', 'Polars', 'https://github.com/pola-rs/polars', ['table', 'quality']),
candidate('arrow', 'Apache Arrow and Parquet', 'https://github.com/apache/arrow', ['table']),
candidate('frictionless', 'Frictionless', 'https://github.com/frictionlessdata/frictionless-py', [
'table',
'quality',
]),
candidate('pandera', 'Pandera', 'https://github.com/unionai-oss/pandera', ['table', 'quality']),
candidate(
'great-expectations',
'Great Expectations',
'https://github.com/great-expectations/great_expectations',
['quality'],
),
candidate('openrefine', 'OpenRefine', 'https://github.com/OpenRefine/OpenRefine', [
'table',
'quality',
'mapping',
]),
candidate('valentine', 'Valentine', 'https://github.com/delftdata/valentine', ['mapping']),
candidate('rapidfuzz', 'RapidFuzz', 'https://github.com/rapidfuzz/RapidFuzz', ['entity', 'mapping']),
candidate('splink', 'Splink', 'https://github.com/moj-analytical-services/splink', ['entity']),
candidate('sqlglot', 'SQLGlot', 'https://github.com/tobymao/sqlglot', ['table', 'mapping']),
candidate('assistant-ui', 'assistant-ui', 'https://github.com/assistant-ui/assistant-ui', ['chat']),
candidate('temporal', 'Temporal', 'https://github.com/temporalio/temporal', ['workflow']),
candidate('langgraph', 'LangGraph', 'https://github.com/langchain-ai/langgraph', ['workflow', 'agent']),
candidate(
'jev',
'TypeSafe Jev',
'https://docs.typesafe.ai/',
['decision', 'model'],
'additional_license_or_service_review',
),
candidate('pydantic-ai', 'PydanticAI', 'https://github.com/pydantic/pydantic-ai', ['agent']),
candidate(
'microsoft-agent-framework',
'Microsoft Agent Framework',
'https://github.com/microsoft/agent-framework',
['agent', 'workflow'],
),
candidate('semantic-kernel', 'Semantic Kernel', 'https://github.com/microsoft/semantic-kernel', ['agent']),
candidate(
'autogen',
'AutoGen',
'https://github.com/microsoft/autogen',
['agent'],
'additional_license_or_service_review',
),
candidate('crewai', 'CrewAI', 'https://github.com/crewAIInc/crewAI', ['agent', 'workflow']),
candidate('haystack', 'Haystack', 'https://github.com/deepset-ai/haystack', ['agent', 'workflow']),
candidate(
'llama-index',
'LlamaIndex',
'https://github.com/run-llama/llama_index',
['agent', 'document'],
'additional_license_or_service_review',
),
candidate('llama-agents', 'llama-agents', 'https://github.com/run-llama/llama-agents', [
'agent',
'workflow',
]),
candidate('google-adk', 'Google ADK', 'https://github.com/google/adk-python', ['agent', 'workflow']),
candidate(
'mastra',
'Mastra',
'https://github.com/mastra-ai/mastra',
['agent', 'workflow'],
'additional_license_or_service_review',
),
candidate('openai-agents-sdk', 'OpenAI Agents SDK', 'https://github.com/openai/openai-agents-python', [
'agent',
]),
candidate('smolagents', 'smolagents', 'https://github.com/huggingface/smolagents', ['agent']),
candidate('dspy', 'DSPy', 'https://github.com/stanfordnlp/dspy', ['agent', 'evaluation']),
candidate(
'flowise',
'Flowise',
'https://github.com/FlowiseAI/Flowise',
['agent', 'workflow'],
'additional_license_or_service_review',
),
candidate(
'browser-use',
'browser-use',
'https://github.com/browser-use/browser-use',
['browser', 'agent'],
'additional_license_or_service_review',
),
candidate('playwright-mcp', 'Playwright MCP', 'https://github.com/microsoft/playwright-mcp', ['browser']),
candidate('promptfoo', 'Promptfoo', 'https://github.com/promptfoo/promptfoo', ['evaluation']),
candidate('deepeval', 'DeepEval', 'https://github.com/confident-ai/deepeval', ['evaluation']),
candidate('ragas', 'Ragas', 'https://github.com/vibrantlabsai/ragas', ['evaluation']),
candidate(
'langfuse',
'Langfuse',
'https://github.com/langfuse/langfuse',
['evaluation', 'observability'],
'additional_license_or_service_review',
),
candidate(
'arize-phoenix',
'Arize Phoenix',
'https://github.com/Arize-ai/phoenix',
['evaluation', 'observability'],
'additional_license_or_service_review',
),
candidate('openmeter', 'OpenMeter', 'https://github.com/openmeterio/openmeter', ['metering']),
candidate('whisper', 'Whisper', 'https://github.com/openai/whisper', ['media']),
candidate('faster-whisper', 'faster-whisper', 'https://github.com/SYSTRAN/faster-whisper', ['media']),
candidate('ffmpeg', 'FFmpeg', 'https://ffmpeg.org/', ['media'], 'additional_license_or_service_review'),
candidate(
'pymupdf',
'PyMuPDF',
'https://github.com/pymupdf/PyMuPDF',
['document'],
'additional_license_or_service_review',
),
candidate(
'marker',
'Marker',
'https://github.com/datalab-to/marker',
['document', 'ocr'],
'additional_license_or_service_review',
),
candidate(
'mineru',
'MinerU',
'https://github.com/opendatalab/MinerU',
['document', 'ocr'],
'additional_license_or_service_review',
),
candidate(
'airbyte',
'Airbyte',
'https://github.com/airbytehq/airbyte',
['integration'],
'additional_license_or_service_review',
),
candidate(
'dify',
'Dify',
'https://github.com/langgenius/dify',
['workflow', 'chat'],
'additional_license_or_service_review',
),
candidate(
'n8n',
'n8n',
'https://github.com/n8n-io/n8n',
['workflow', 'integration'],
'additional_license_or_service_review',
),
candidate(
'open-webui',
'Open WebUI',
'https://github.com/open-webui/open-webui',
['chat'],
'additional_license_or_service_review',
),
candidate(
'openrouter',
'OpenRouter',
'https://openrouter.ai/',
['model'],
'additional_license_or_service_review',
),
];
export function candidatesForRole(role: CandidateRole): readonly ToolCandidate[] {
return TOOL_CANDIDATES.filter((entry) => entry.roles.includes(role));
}