# What the WeKnora modelcontext Package Does: Request-Scoped Model Handling

> Learn how the WeKnora modelcontext package handles request-scoped models isolating temporary handles encoding LLM payloads and enforcing tool policies for secure and efficient operations.

- Repository: [Tencent/WeKnora](https://github.com/tencent/WeKnora)
- Tags: internals
- Published: 2026-09-13

---

**The `modelcontext` package in Tencent/WeKnora manages request-scoped model handling by isolating temporary handles, encoding LLM payloads, and enforcing tool policies.**

The `modelcontext` package serves as the central boundary for all request-local model operations in the WeKnora open-source project. It maintains strict separation between ephemeral identifiers used during a single LLM request and permanent resource IDs, ensuring clean session isolation and consistent protocol adherence across agent executions.

## Managing Temporary and Durable Identities

The `modelcontext.Registry` distinguishes between two handle categories with different lifecycles and persistence guarantees.

### Temporary Model Handles

All short-lived identifiers created for a single LLM request or agent execution are managed through the Registry. These include formats such as `cN`, `dN`, `bN`, `wN`, `iN`, and `res://NNNN`, which are **never persisted** and remain isolated per request to prevent cross-talk between sessions. According to the source code in [`internal/modelcontext/registry.go`](https://github.com/Tencent/WeKnora/blob/main/internal/modelcontext/registry.go) (lines 38-50), these handles exist only for the duration of the request scope and are automatically cleaned up afterward.

### Durable Identity Encoding

The package treats permanent identifiers—including UUIDs, wiki slugs, URLs, and `resource://` handles—as durable references. The Registry determines the safe ordering for encoding these durable references before temporary ones, ensuring that permanent IDs maintain referential integrity throughout the request lifecycle (see [`registry.go`](https://github.com/Tencent/WeKnora/blob/main/registry.go) lines 5-10).

## Codec Architecture for Sources and Resources

The Registry exposes specialized codecs that handle different data types without requiring callers to coordinate them independently.

**Source Registry** manages citation-style sources and applies citation policies including `sourceArgumentAllowed` and `sourceOutputAllowed`. **Resource Registry** handles knowledge-base resources and their associated chunk handles. Both registries are accessible through the main `Registry` struct at lines 45-48 of [`internal/modelcontext/registry.go`](https://github.com/Tencent/WeKnora/blob/main/internal/modelcontext/registry.go).

## Deterministic Message Encoding and Decoding

The package implements a strict encode/decode flow that maintains protocol consistency between the system and LLM agents.

### Encoding Outbound Messages

The `EncodeMessages` method (lines 74-92) converts outgoing LLM messages by inserting proper temporary handles and embedding the system-owned protocol prompt. This ensures the LLM receives correctly scoped identifiers for the current request context.

### Decoding Inbound Tool Calls and Responses

For incoming data, `DecodeToolCalls` (lines 105-124) restores temporary handles inside tool-call arguments, resolves relevant policies, and marks any unresolved handles. The `DecodeResponse` (lines 71-81) and `StreamDecoder` (lines 82-92) methods apply identical logic to both streaming and non-streaming responses, expanding citations and restoring resource handles on-the-fly.

## Tool Policy Enforcement

Built-in LLM tools such as web-fetch and web-search are registered with policies defined in [`internal/modelcontext/tool_policy.go`](https://github.com/Tencent/WeKnora/blob/main/internal/modelcontext/tool_policy.go). The Registry validates every tool call against these declared policies during the `DecodeToolCalls` phase (lines 119-130), guaranteeing that the model never invents or misuses tool identifiers outside the approved set.

## Protocol Prompt Generation

The `ProtocolPrompt()` method (lines 64-71) returns a description of handle conventions and MCP routing syntax that the LLM should follow when generating output. This prompt is automatically prefixed to system messages, providing the model with explicit guidance on handle usage without requiring manual prompt engineering.

## Working with the Registry

To utilize the modelcontext package in practice, instantiate a new Registry for each request scope and use its encoding methods before sending traffic to the LLM.

```go
// Create a new request-scoped registry (citations enabled)
reg := modelcontext.NewRegistry(true)

// Encode messages before sending them to the LLM
outMsgs := reg.EncodeMessages(inMsgs)

// After the LLM returns tool calls, decode the arguments back to
// temporary handles and resolve policies
reg.DecodeToolCalls(toolCalls)

// For streaming responses, obtain a decoder that will
// expand citations and restore resource handles on-the-fly
decoder := reg.StreamDecoder()

```

All functions above are defined in [`internal/modelcontext/registry.go`](https://github.com/Tencent/WeKnora/blob/main/internal/modelcontext/registry.go).

## Key Implementation Files

The `modelcontext` package consists of the following files:

- **[`internal/modelcontext/registry.go`](https://github.com/Tencent/WeKnora/blob/main/internal/modelcontext/registry.go)**: Central `Registry` type, encoding/decoding logic, and protocol prompt implementation.
- **[`internal/modelcontext/handles.go`](https://github.com/Tencent/WeKnora/blob/main/internal/modelcontext/handles.go)**: Definition of `HandleTable` and generic handle management structures.
- **[`internal/modelcontext/handle_table.go`](https://github.com/Tencent/WeKnora/blob/main/internal/modelcontext/handle_table.go)**: Implementation of handle allocation and reverse-lookup mechanisms.
- **[`internal/modelcontext/sources.go`](https://github.com/Tencent/WeKnora/blob/main/internal/modelcontext/sources.go)**: Source/citation codec and policy enforcement logic.
- **[`internal/modelcontext/resources.go`](https://github.com/Tencent/WeKnora/blob/main/internal/modelcontext/resources.go)**: Resource codec for knowledge-base chunks.
- **[`internal/modelcontext/tool_policy.go`](https://github.com/Tencent/WeKnora/blob/main/internal/modelcontext/tool_policy.go)**: Built-in tool-policy definitions and validation helpers.
- **[`internal/modelcontext/README.md`](https://github.com/Tencent/WeKnora/blob/main/internal/modelcontext/README.md)**: High-level architectural overview of the package.

## Summary

- The `modelcontext` package provides request-scoped isolation for temporary handles (`cN`, `dN`, `res://NNNN`) while preserving durable identities (UUIDs, URLs).
- It manages deterministic encoding via `EncodeMessages` and decoding via `DecodeToolCalls`, `DecodeResponse`, and `StreamDecoder`.
- Source and resource codecs handle citations and knowledge-base chunks through a unified `Registry` interface.
- Tool policies defined in [`tool_policy.go`](https://github.com/Tencent/WeKnora/blob/main/tool_policy.go) are enforced during the decode phase to prevent unauthorized tool usage.
- The `ProtocolPrompt()` method automatically injects handle conventions and MCP routing syntax into system messages.

## Frequently Asked Questions

### What are temporary handles in the WeKnora modelcontext package?

Temporary handles are short-lived identifiers such as `cN`, `dN`, `bN`, `wN`, `iN`, and `res://NNNN` created for a single LLM request. According to [`internal/modelcontext/registry.go`](https://github.com/Tencent/WeKnora/blob/main/internal/modelcontext/registry.go) (lines 38-50), these handles are never persisted and are isolated per request to prevent session cross-talk.

### How does the modelcontext Registry enforce tool policies?

The Registry validates tool calls during the `DecodeToolCalls` phase (lines 105-124 in [`registry.go`](https://github.com/Tencent/WeKnora/blob/main/registry.go)) by checking them against policies defined in [`internal/modelcontext/tool_policy.go`](https://github.com/Tencent/WeKnora/blob/main/internal/modelcontext/tool_policy.go). This ensures the LLM only invokes registered tools like web-fetch or web-search according to predefined rules.

### What is the difference between durable and temporary identities in WeKnora?

Durable identities include permanent references such as UUIDs, wiki slugs, URLs, and `resource://` handles that persist beyond a single request. Temporary handles exist only for the duration of one LLM request or agent execution, as implemented in the Registry's handle management logic (lines 5-10).

### How do I create a request-scoped Registry instance?

Import the `modelcontext` package and call `modelcontext.NewRegistry(true)` to instantiate a Registry with citations enabled. Use this instance to encode outbound messages with `EncodeMessages` and decode responses with `DecodeResponse` or `StreamDecoder` to maintain proper handle scoping throughout the request lifecycle.