mirror of
https://github.com/infiniflow/ragflow.git
synced 2026-10-12 02:16:39 +00:00
feat(go): MonkeyOCR env keys and tenant provisioning (#20468)
This commit is contained in:
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"name": "MonkeyOCR",
|
||||
"url_suffix": {
|
||||
"doc_parse": "file_parse",
|
||||
"task": "tasks"
|
||||
},
|
||||
"url_hint": "http://host.docker.internal:7861",
|
||||
"class": "local",
|
||||
"models": [
|
||||
{
|
||||
"name": "MonkeyOCR-model",
|
||||
"model_types": [
|
||||
"ocr"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -200,6 +200,11 @@ const (
|
||||
EnvMineruServerURL = "MINERU_SERVER_URL"
|
||||
EnvMonkeyOCRv2ServerURL = "MONKEYOCRV2_SERVER_URL"
|
||||
EnvMonkeyOCRv2Timeout = "MONKEYOCRV2_TIMEOUT"
|
||||
EnvMonkeyOCRAPIServer = "MONKEYOCR_APISERVER"
|
||||
EnvMonkeyOCROutputDir = "MONKEYOCR_OUTPUT_DIR"
|
||||
EnvMonkeyOCRServerURL = "MONKEYOCR_SERVER_URL"
|
||||
EnvMonkeyOCRBackend = "MONKEYOCR_BACKEND"
|
||||
EnvMonkeyOCRDeleteOutput = "MONKEYOCR_DELETE_OUTPUT"
|
||||
EnvOpenDataLoaderAPIServer = "OPENDATALOADER_APISERVER"
|
||||
EnvOpenDataLoaderAPIKey = "OPENDATALOADER_API_KEY"
|
||||
EnvPaddleOCRBaseUrl = "PADDLEOCR_BASE_URL"
|
||||
|
||||
@@ -149,6 +149,9 @@ func (f *ModelFactory) CreateModelDriver(providerName string, baseURL map[string
|
||||
return NewMinerLocalUModel(baseURL, urlSuffix), nil
|
||||
case "monkeyocrv2":
|
||||
return NewMonkeyOCRv2Model(baseURL, urlSuffix), nil
|
||||
case "monkeyocr":
|
||||
// MonkeyOCR's RAGFlow adapter uses the same /file_parse ZIP protocol as MinerU.
|
||||
return NewMonkeyOCRModel(baseURL, urlSuffix), nil
|
||||
case "futurmix":
|
||||
return NewFuturMixModel(baseURL, urlSuffix), nil
|
||||
case "perplexity":
|
||||
|
||||
@@ -162,7 +162,7 @@ func TestBedrockConfigPreservesEmbeddingMaxTokens(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestLocalOCRProviderConfigsLoadLocalDrivers(t *testing.T) {
|
||||
dir, restore := setupProviderTestDir(t, "mineru_local.json", "monkeyocrv2.json", "paddleocr_local.json")
|
||||
dir, restore := setupProviderTestDir(t, "mineru_local.json", "monkeyocr.json", "monkeyocrv2.json", "paddleocr_local.json")
|
||||
defer restore()
|
||||
|
||||
err := InitProviderManager(dir)
|
||||
@@ -183,6 +183,20 @@ func TestLocalOCRProviderConfigsLoadLocalDrivers(t *testing.T) {
|
||||
t.Errorf("MinerU doc_parse suffix=%q", minerU.URLSuffix.DocumentParse)
|
||||
}
|
||||
|
||||
monkeyOCR := pm.FindProvider("MonkeyOCR")
|
||||
if monkeyOCR == nil {
|
||||
t.Fatal("MonkeyOCR provider not found")
|
||||
}
|
||||
if _, ok := monkeyOCR.ModelDriver.(*MonkeyOCRModel); !ok {
|
||||
t.Fatalf("MonkeyOCR ModelDriver=%T, want *models.MonkeyOCRModel", monkeyOCR.ModelDriver)
|
||||
}
|
||||
if monkeyOCR.ModelDriver.Name() != "monkeyocr" {
|
||||
t.Fatalf("MonkeyOCR Name()=%q, want monkeyocr", monkeyOCR.ModelDriver.Name())
|
||||
}
|
||||
if monkeyOCR.URLSuffix.DocumentParse != "file_parse" {
|
||||
t.Errorf("MonkeyOCR doc_parse suffix=%q", monkeyOCR.URLSuffix.DocumentParse)
|
||||
}
|
||||
|
||||
monkeyOCRv2 := pm.FindProvider("MonkeyOCRv2")
|
||||
if monkeyOCRv2 == nil {
|
||||
t.Fatal("MonkeyOCRv2 provider not found")
|
||||
@@ -206,6 +220,23 @@ func TestLocalOCRProviderConfigsLoadLocalDrivers(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestModelFactoryCreatesMonkeyOCRDriver(t *testing.T) {
|
||||
driver, err := NewModelFactory().CreateModelDriver("MonkeyOCR", map[string]string{"default": "http://localhost:7861"}, URLSuffix{DocumentParse: "file_parse"})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if driver.Name() != "monkeyocr" {
|
||||
t.Fatalf("driver.Name()=%q", driver.Name())
|
||||
}
|
||||
cloned := driver.NewInstance(map[string]string{"default": "http://cloned"})
|
||||
if cloned.Name() != "monkeyocr" {
|
||||
t.Fatalf("NewInstance().Name()=%q", cloned.Name())
|
||||
}
|
||||
if _, ok := driver.(*MonkeyOCRModel); !ok {
|
||||
t.Fatalf("driver=%T, want *MonkeyOCRModel", driver)
|
||||
}
|
||||
}
|
||||
|
||||
func TestModelFactoryCreatesMonkeyOCRv2Driver(t *testing.T) {
|
||||
driver, err := NewModelFactory().CreateModelDriver("MonkeyOCRv2", map[string]string{"default": "http://localhost:8000"}, URLSuffix{})
|
||||
if err != nil {
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
// Copyright 2026 The InfiniFlow Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
package models
|
||||
|
||||
// MonkeyOCRModel reuses MinerU's local /file_parse ZIP client while
|
||||
// identifying the provider as MonkeyOCR. Dispatch and UUID classification
|
||||
// both key off Name(); NewInstance must preserve that identity.
|
||||
type MonkeyOCRModel struct {
|
||||
*MinerULocalModel
|
||||
}
|
||||
|
||||
func NewMonkeyOCRModel(baseURL map[string]string, urlSuffix URLSuffix) *MonkeyOCRModel {
|
||||
return &MonkeyOCRModel{MinerULocalModel: NewMinerLocalUModel(baseURL, urlSuffix)}
|
||||
}
|
||||
|
||||
func (m *MonkeyOCRModel) NewInstance(baseURL map[string]string) ModelDriver {
|
||||
return NewMonkeyOCRModel(baseURL, m.baseModel.URLSuffix)
|
||||
}
|
||||
|
||||
func (m *MonkeyOCRModel) Name() string {
|
||||
return "monkeyocr"
|
||||
}
|
||||
@@ -103,6 +103,11 @@ type Environments struct {
|
||||
MinerUAPIServer string `mapstructure:"miner_userver"` // MINERU_APISERVER
|
||||
MinerUAPIKey string `mapstructure:"mineru_api_key"` // MINERU_API_KEY
|
||||
MinerUBackend string `mapstructure:"mineru_backend"` // MINERU_BACKEND
|
||||
MonkeyOCRAPIServer string `mapstructure:"monkeyocr_apiserver"` // MONKEYOCR_APISERVER
|
||||
MonkeyOCROutputDir string `mapstructure:"monkeyocr_output_dir"` // MONKEYOCR_OUTPUT_DIR
|
||||
MonkeyOCRServerURL string `mapstructure:"monkeyocr_server_url"` // MONKEYOCR_SERVER_URL
|
||||
MonkeyOCRBackend string `mapstructure:"monkeyocr_backend"` // MONKEYOCR_BACKEND
|
||||
MonkeyOCRDeleteOutput string `mapstructure:"monkeyocr_delete_output"` // MONKEYOCR_DELETE_OUTPUT
|
||||
TavilyAPIKey string `mapstructure:"tavily_api_key"`
|
||||
QueritAPIKey string `mapstructure:"querit_api_key"`
|
||||
KeenableAPIURL string `mapstructure:"keenable_api_url"` // KEENABLE_API_URL
|
||||
@@ -529,6 +534,22 @@ func (c *Config) GetEnvironments() error {
|
||||
c.environments.MinerUBackend = MinerUBackendStr
|
||||
}
|
||||
|
||||
if v := common.GetEnv(common.EnvMonkeyOCRAPIServer); v != "" {
|
||||
c.environments.MonkeyOCRAPIServer = v
|
||||
}
|
||||
if v := common.GetEnv(common.EnvMonkeyOCROutputDir); v != "" {
|
||||
c.environments.MonkeyOCROutputDir = v
|
||||
}
|
||||
if v := common.GetEnv(common.EnvMonkeyOCRServerURL); v != "" {
|
||||
c.environments.MonkeyOCRServerURL = v
|
||||
}
|
||||
if v := common.GetEnv(common.EnvMonkeyOCRBackend); v != "" {
|
||||
c.environments.MonkeyOCRBackend = v
|
||||
}
|
||||
if v := common.GetEnv(common.EnvMonkeyOCRDeleteOutput); v != "" {
|
||||
c.environments.MonkeyOCRDeleteOutput = v
|
||||
}
|
||||
|
||||
TavilyAPIKeyStr := common.GetEnv(common.EnvTavilyAPIKey)
|
||||
if TavilyAPIKeyStr != "" {
|
||||
c.environments.TavilyAPIKey = TavilyAPIKeyStr
|
||||
@@ -810,6 +831,26 @@ func (c *Config) GetMinerUBackend() string {
|
||||
return c.environments.MinerUBackend
|
||||
}
|
||||
|
||||
func (c *Config) GetMonkeyOCRAPIServer() string {
|
||||
return c.environments.MonkeyOCRAPIServer
|
||||
}
|
||||
|
||||
func (c *Config) GetMonkeyOCROutputDir() string {
|
||||
return c.environments.MonkeyOCROutputDir
|
||||
}
|
||||
|
||||
func (c *Config) GetMonkeyOCRServerURL() string {
|
||||
return c.environments.MonkeyOCRServerURL
|
||||
}
|
||||
|
||||
func (c *Config) GetMonkeyOCRBackend() string {
|
||||
return c.environments.MonkeyOCRBackend
|
||||
}
|
||||
|
||||
func (c *Config) GetMonkeyOCRDeleteOutput() string {
|
||||
return c.environments.MonkeyOCRDeleteOutput
|
||||
}
|
||||
|
||||
func (c *Config) GetQueritAPIKey() string {
|
||||
return c.environments.QueritAPIKey
|
||||
}
|
||||
|
||||
@@ -1300,6 +1300,7 @@ func (m *ModelProviderService) ListTenantAddedModels(ctx context.Context, userID
|
||||
// Mirror Python's ensure_*_from_env calls.
|
||||
_ = m.ensureMineruFromEnv(ctx, tenantID)
|
||||
_ = m.ensureMonkeyOCRv2FromEnv(ctx, tenantID)
|
||||
_ = m.ensureMonkeyOCRFromEnv(ctx, tenantID)
|
||||
_ = m.ensurePaddleOCREnabledFromEnv(ctx, tenantID)
|
||||
_ = m.ensureOpenDataLoaderFromEnv(ctx, tenantID)
|
||||
|
||||
@@ -1550,6 +1551,19 @@ func (m *ModelProviderService) ensureMonkeyOCRv2FromEnv(ctx context.Context, ten
|
||||
return m.ensureOCRProviderFromEnv(ctx, tenantID, "MonkeyOCRv2", "monkeyocrv2-from-env", config)
|
||||
}
|
||||
|
||||
// ensureMonkeyOCRFromEnv mirrors Python's ensure_monkeyocr_from_env.
|
||||
func (m *ModelProviderService) ensureMonkeyOCRFromEnv(ctx context.Context, tenantID string) error {
|
||||
config := collectEnvConfig(monkeyOCREnvKeys, monkeyOCRDefaultConfig)
|
||||
if config == nil {
|
||||
return nil
|
||||
}
|
||||
apiserver, _ := config[common.EnvMonkeyOCRAPIServer].(string)
|
||||
if strings.TrimSpace(apiserver) == "" {
|
||||
return nil
|
||||
}
|
||||
return m.ensureOCRProviderFromEnv(ctx, tenantID, "MonkeyOCR", "monkeyocr-from-env", config)
|
||||
}
|
||||
|
||||
// Environment-key/default tables mirror the Python OCR provider settings.
|
||||
var (
|
||||
mineruEnvKeys = []string{
|
||||
@@ -1592,6 +1606,20 @@ var (
|
||||
common.EnvMonkeyOCRv2ServerURL: "",
|
||||
common.EnvMonkeyOCRv2Timeout: 600,
|
||||
}
|
||||
monkeyOCREnvKeys = []string{
|
||||
common.EnvMonkeyOCRAPIServer,
|
||||
common.EnvMonkeyOCROutputDir,
|
||||
common.EnvMonkeyOCRServerURL,
|
||||
common.EnvMonkeyOCRBackend,
|
||||
common.EnvMonkeyOCRDeleteOutput,
|
||||
}
|
||||
monkeyOCRDefaultConfig = map[string]interface{}{
|
||||
common.EnvMonkeyOCRAPIServer: "",
|
||||
common.EnvMonkeyOCROutputDir: "",
|
||||
common.EnvMonkeyOCRServerURL: "",
|
||||
common.EnvMonkeyOCRBackend: "vlm-engine",
|
||||
common.EnvMonkeyOCRDeleteOutput: 1,
|
||||
}
|
||||
)
|
||||
|
||||
// collectEnvConfig collects environment variable values for the given keys
|
||||
|
||||
@@ -37,6 +37,34 @@ func (d *remoteModelProbeDriver) CheckConnection(context.Context, *modelModule.A
|
||||
return d.checkErr
|
||||
}
|
||||
|
||||
func TestMonkeyOCREnvConfig(t *testing.T) {
|
||||
t.Setenv(common.EnvMonkeyOCRAPIServer, "http://monkeyocr:7861")
|
||||
|
||||
config := collectEnvConfig(monkeyOCREnvKeys, monkeyOCRDefaultConfig)
|
||||
if config == nil {
|
||||
t.Fatal("collectEnvConfig returned nil")
|
||||
}
|
||||
if config[common.EnvMonkeyOCRAPIServer] != "http://monkeyocr:7861" {
|
||||
t.Fatalf("API server = %#v", config[common.EnvMonkeyOCRAPIServer])
|
||||
}
|
||||
if config[common.EnvMonkeyOCRBackend] != "vlm-engine" {
|
||||
t.Fatalf("backend = %#v", config[common.EnvMonkeyOCRBackend])
|
||||
}
|
||||
if config[common.EnvMonkeyOCRDeleteOutput] != 1 {
|
||||
t.Fatalf("delete output = %#v", config[common.EnvMonkeyOCRDeleteOutput])
|
||||
}
|
||||
}
|
||||
|
||||
func TestEnsureMonkeyOCRFromEnvSkipsBlankAPIServer(t *testing.T) {
|
||||
t.Setenv(common.EnvMonkeyOCRBackend, "vlm-engine")
|
||||
t.Setenv(common.EnvMonkeyOCRAPIServer, "")
|
||||
|
||||
svc := &ModelProviderService{}
|
||||
if err := svc.ensureMonkeyOCRFromEnv(context.Background(), "tenant-id"); err != nil {
|
||||
t.Fatalf("ensureMonkeyOCRFromEnv: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMonkeyOCRv2EnvConfig(t *testing.T) {
|
||||
t.Setenv(common.EnvMonkeyOCRv2ServerURL, "http://monkeyocrv2:8000")
|
||||
t.Setenv(common.EnvMonkeyOCRv2Timeout, "120")
|
||||
|
||||
Reference in New Issue
Block a user