What the internal/application Package Handles in WeKnora: Business Logic and Service Layer

The internal/application package serves as the core business-logic layer of WeKnora, orchestrating wiki page lifecycles, content ingestion, tenant skill execution, and vector search operations while bridging HTTP handlers and data repositories.

The internal/application package sits at the heart of the Tencent/WeKnora architecture, implementing the domain logic that powers the knowledge-base platform. Located between the API handlers in internal/api and the data-access layer in internal/application/repository, this package encapsulates everything from CRUD operations on wiki pages to LLM pipeline orchestration. Understanding its structure is essential for developers extending WeKnora’s capabilities or debugging service-level issues.

Core Responsibilities of the internal/application Package

The package organizes its functionality into cohesive service modules that handle distinct domain concerns. Each service operates as a facade over lower-level repositories, enforcing business rules and transaction boundaries.

Wiki Page Orchestration and Lifecycle Management

At the center of the package, internal/application/service/wiki_page.go defines the wikiPageService struct, which implements the full CRUD lifecycle for wiki content. This service handles versioning, bidirectional link maintenance, and graph generation for knowledge bases.

Key capabilities include:

  • CreatePage and UpdatePage: Persist wiki content while parsing internal links and maintaining slug integrity.
  • GetGraph: Generate subgraph views of the knowledge base with BFS ego-mode traversal (implemented via bfsEgoSlugs).
  • RebuildLinks: Repair and synchronize bidirectional wiki links after content changes.
  • Content normalization: Utilities like normalizeSlug and rewriteDeadWikiLinks ensure consistent URL slugs and repair broken references.

Content Ingest Pipeline

The ingest subsystem processes bulk wiki imports through a coordinated pipeline spread across wiki_ingest.go, wiki_ingest_dedup.go, and wiki_ingest_cite.go. This pipeline handles taxonomy extraction, deduplication, citation processing, and dead-link repair when migrating existing content into WeKnora.

Tenant Skill Execution Engine

WeKnora supports per-tenant plugins called "skills" that augment the knowledge base or run custom LLM pipelines. The internal/application/service/tenant_skill_service.go file implements the skill lifecycle management, including:

  • Verification and installation of skill packages.
  • Runtime execution control via RunSkill.
  • Cleanup and resource isolation between tenants.

This allows individual knowledge bases to load custom logic without affecting the core system stability.

The vectorstore.go file provides a unified interface for semantic retrieval via the VectorStoreService. It abstracts multiple backends—such as OpenSearch and SSRF-safe SQLite—behind methods like AddEmbedding and Search. This abstraction lets the rest of the application perform vector operations without coupling to specific storage engines.

Web Search Integration

To augment LLM prompts with real-time data, web_search_provider.go encapsulates remote web-search providers. It handles provider authentication, result fetching, and content filtering before injecting search context into chat pipelines.

Access Control and Knowledge Base Sharing

Security logic resides in internal/application/access/ownership.go and related kb_* files. These modules enforce ownership verification, write-permission checks, and sharing mechanics before any service modifies knowledge base data. This ensures that multi-tenant isolation and collaboration rules are applied consistently across all operations.

User and Tenant Utilities

Supporting infrastructure for authentication and configuration lives in files like user_env.go, user_oidc_security.go, and user_admin_create.go. These handle JWT validation, OIDC verification, environment-variable resolution, and tenant-scoped context propagation throughout the service layer.

Chat Pipeline Helpers

The chat_pipeline/ subdirectory contains specialized utilities for LLM workflows, including rerank.go for result reordering and memory_recall.go for conversational context retrieval. These helpers implement query expansion, semantic reranking, and session memory management to improve response quality.

Key Source Files and Their Roles

Understanding the file layout helps navigate the codebase effectively:

Practical Code Examples

The following snippets demonstrate typical interactions with the internal/application services.

Creating a Wiki Page

svc := NewWikiPageService(repo, chunkRepo, kbService, taskPendingRepo, redisClient)
ctx := types.WithWikiEditSource(context.Background(), types.WikiEditSourceUser)
page := &types.WikiPage{
    KnowledgeBaseID: "kb-123",
    Slug:            "example-page",
    Title:           "Example Page",
    Content:         "This is a [[linked-page]] in markdown.",
    PageType:        types.WikiPageTypeSummary,
}
created, err := svc.CreatePage(ctx, page)
if err != nil {
    // handle error
}
fmt.Println("Created page ID:", created.ID)

Generating a Knowledge Graph

graphReq := &types.WikiGraphRequest{
    KnowledgeBaseID: "kb-123",
    Mode:            types.WikiGraphModeOverview,
    Limit:           200,
}
graph, err := svc.GetGraph(context.Background(), graphReq)
if err != nil {
    // handle error
}
fmt.Printf("Graph contains %d nodes, %d edges\n", len(graph.Nodes), len(graph.Edges))

Executing a Tenant Skill

skillSvc := NewTenantSkillService(repo, taskPendingRepo, redisClient)
err := skillSvc.RunSkill(context.Background(), "kb-123", "my-skill-id")
if err != nil {
    // handle error
}

Summary

  • The internal/application package implements WeKnora’s business-logic layer, isolating domain rules from HTTP transport and data persistence.
  • Core services manage wiki page lifecycles, batch ingestion, tenant skill execution, and vector search operations.
  • Access control is enforced centrally through the access/ subdirectory, ensuring secure multi-tenant operations.
  • The package provides abstractions for web search and vector stores, allowing backend implementations to change without affecting API consumers.
  • All service implementations reside in internal/application/service/, with clear separation between orchestration logic and repository concerns.

Frequently Asked Questions

What is the difference between internal/application and internal/api in WeKnora?

The internal/api package handles HTTP routing, request validation, and JSON serialization, while internal/application contains the domain logic that processes those requests. The API layer translates HTTP calls into service method invocations, and the application layer enforces business rules, coordinates transactions, and interacts with repositories. This separation ensures that core logic remains transport-agnostic and testable without HTTP dependencies.

The package exposes semantic search through service/vectorstore.go, which defines the VectorStoreService interface with methods like AddEmbedding and Search. This service abstracts underlying storage engines—such as OpenSearch or SQLite—providing a unified API for the rest of the system. Callers simply invoke Search with a query embedding, and the service handles backend-specific query construction and result retrieval.

Where are tenant skills defined and executed within the application layer?

Tenant skills are managed by service/tenant_skill_service.go. This service handles the installation, validation, and runtime execution of per-tenant plugins. The RunSkill method accepts a knowledge base ID and skill identifier, loads the appropriate plugin code in an isolated context, and executes it against the tenant’s data. This architecture allows custom extensions without modifying core WeKnora binaries.

How is access control enforced in the internal/application package?

Access control logic resides in access/ownership.go and associated knowledge base permission files. Before executing destructive operations, services invoke ownership checks to verify that the requesting user has write permissions or ownership rights for the target knowledge base. These checks run after authentication (handled upstream) but before any repository modifications, ensuring consistent enforcement of multi-tenant security policies.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →