Skip to content

feat(integrations): support pydantic-ai integrate - #1295

Open
thunguo wants to merge 3 commits into
oceanbase:masterfrom
thunguo:feat/pydantic-ai-integrate
Open

feat(integrations): support pydantic-ai integrate#1295
thunguo wants to merge 3 commits into
oceanbase:masterfrom
thunguo:feat/pydantic-ai-integrate

Conversation

@thunguo

@thunguo thunguo commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

Which issue or RFC does this PR close?

Closes #1269 .

Rationale for this change

Pydantic AI users currently lack a native PowerContext integration that follows Pydantic AI’s toolset and capability lifecycles.

This PR adds an independent adapter that provides Memory tools, automatic context preparation, optional event capture, and checkpoint flushing through the public PowerContext Python Client.

What changes are included in this PR?

  • Add the independently distributable powercontext-pydantic-ai package.
  • Export the following public APIs:
    • PowerContextSettings
    • PowerContextToolset
    • PowerContext
  • Add per-run PowerContextClient lifecycle management and the following tools:
    • powercontext_search
    • powercontext_remember
    • powercontext_context
  • Add automatic context preparation from the latest user prompt.
    • Context is injected once per run as untrusted historical evidence.
    • Reusing history in a new run prepares context again.
    • Empty context is not injected.
  • Add deterministic scope resolution using:
    1. Constructor value or callback
    2. POWERCONTEXT_PYDANTIC_AI_SCOPE_ID
    3. Normalized Git origin
    4. A deterministic local hash
  • Convert tool-side client errors into Pydantic AI ModelRetry errors.
  • Keep context recall, capture, and flush operations fail-open when the PowerContext server is unavailable.
  • Add optional event capture for user prompts, visible model output, tool calls, arguments, and results.
    • Thinking content is excluded.
    • Capture is disabled by default.
    • Captured JSON is bounded and credentials are redacted.
    • Source IDs are deterministic and idempotent.
    • Checkpoint and final-run flushing are supported.
  • Extract shared capture sanitization and bounded JSON rendering into powercontext.client.capture, and reuse it in the Bub integration.
  • Add English and Chinese configuration documentation and update the documentation navigation and interface reference.
  • Add adapter unit tests and an end-to-end test using FunctionModel, the real server lifecycle, and SQLite.
  • Update root type-checking and test import paths for the new integration.

This PR does not modify the server API, OpenAPI schema, or MCP allow-list.

Are there any user-facing changes?

Yes. Users can install the new package and attach PowerContext directly to a Pydantic AI agent.

The integration introduces new POWERCONTEXT_PYDANTIC_AI_* configuration variables. The token setting expects a raw token; users should not include the Bearer prefix.

Capture is opt-in and disabled by default because enabling it may persist prompts, visible model output, tool calls, and tool results. Sensitive values are redacted before capture, but users should still review the associated data-retention risk.

There are no breaking changes to existing public APIs or persisted formats, and no migration is required. Durable execution frameworks such as Temporal, DBOS, and Prefect have not been validated in this initial release.

How was this change tested?

The following validation was completed:

  • Adapter unit and end-to-end tests: 25 passed
  • Full test suite via make test: 631 passed, 12 skipped
  • Bub capture sanitization regression test: 1 passed
  • make check
  • make docs-test
  • uv build --project integrations/pydantic-ai
  • tox across Python 3.11, 3.12, 3.13, and 3.14
  • Explicit type checking of integrations/pydantic-ai/src
  • Manual inspection of the generated wheel metadata and contents, including verification that no entry point is registered

The end-to-end test verifies the complete flow:

  1. A tool result is captured.
  2. The capture checkpoint is flushed.
  3. The next model step recalls the prepared context.
  4. A final PowerContext search returns the stored result with its citation.

An initial Python 3.12 tox run encountered an existing readiness-test timeout; both the isolated test and the complete Python 3.12 environment passed on rerun.

AI usage statement

Copilot AI lite review requested due to automatic review settings August 20, 2026 14:14

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a first-class Pydantic AI integration for PowerContext as an independently distributable package under integrations/, aligning PowerContext’s memory/tooling with Pydantic AI’s run lifecycle (context prep, optional capture, flushing) via the public Python client.

Changes:

  • Introduces powercontext-pydantic-ai with public APIs (PowerContext, PowerContextToolset, PowerContextSettings), memory tools, deterministic scope resolution, and per-run client lifecycle.
  • Adds optional bounded, redacted trajectory capture + checkpoint/final flushing, and factors shared capture rendering/redaction into powercontext.client.capture (reused by Bub).
  • Adds adapter unit tests, an e2e chain test, and updates docs/navigation and repo test/type-check import paths for the new integration.

Reviewed changes

Copilot reviewed 23 out of 24 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
zensical.toml Adds Pydantic AI docs pages into EN/ZH navigation.
pyproject.toml Updates type-check/test import paths to include the integration source during repo tests.
src/powercontext/client/capture.py New shared bounded/redacted JSON rendering utilities for capture events.
integrations/pydantic-ai/pyproject.toml Declares the independently distributable powercontext-pydantic-ai package metadata/deps.
integrations/pydantic-ai/README.md Provides installation, configuration, and behavior documentation for the adapter package.
integrations/pydantic-ai/src/powercontext_pydantic_ai/init.py Exposes the adapter’s public API surface.
integrations/pydantic-ai/src/powercontext_pydantic_ai/settings.py Adds validated settings loading via pydantic-settings env prefix.
integrations/pydantic-ai/src/powercontext_pydantic_ai/scope.py Implements deterministic scope resolution (constructor/env/git/local hash).
integrations/pydantic-ai/src/powercontext_pydantic_ai/toolset.py Implements the toolset (search/remember/context) with per-run client management and ModelRetry mapping.
integrations/pydantic-ai/src/powercontext_pydantic_ai/capability.py Implements automatic context prep, optional capture, and flush hooks in the Pydantic AI capability lifecycle.
integrations/bub/src/powercontext_bub/plugin.py Switches Bub capture rendering to the shared capture helper.
integrations/bub/pyproject.toml Bumps Bub integration dependency to powercontext[client]>=0.0.2.
e2e/bub/uv.lock Updates lockfile to reflect the powercontext[client]>=0.0.2 requirement.
docs/en/docs/reference/interfaces.md Documents the new Pydantic AI adapter as a supported interface.
docs/zh/docs/reference/interfaces.md Documents the new Pydantic AI adapter as a supported interface (ZH).
docs/en/docs/how-to/configure-pydantic-ai.md Adds end-user setup/configuration documentation (EN).
docs/zh/docs/how-to/configure-pydantic-ai.md Adds end-user setup/configuration documentation (ZH).
tests/pydantic_ai_adapter/init.py Adds a dedicated test package for the adapter tests.
tests/pydantic_ai_adapter/fakes.py Adds a recording PowerContext client test double for adapter-boundary assertions.
tests/pydantic_ai_adapter/test_toolset.py Validates tool schemas/instructions/mapping, retry conversion, and per-run client lifecycle.
tests/pydantic_ai_adapter/test_settings_scope.py Validates settings/env behavior and scope derivation precedence/bounding.
tests/pydantic_ai_adapter/test_capability.py Validates per-run context injection rules and fail-open recall behavior.
tests/pydantic_ai_adapter/test_capture.py Validates capture opt-in, bounding/redaction, checkpoint flushing, and fail-open capture/flush behavior.
tests/e2e/test_pydantic_ai_chain.py Adds an end-to-end chain test using a real server lifecycle + SQLite to validate capture→flush→recall→search.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/powercontext/client/capture.py Outdated
Comment thread pyproject.toml
Comment thread integrations/pydantic-ai/src/powercontext_pydantic_ai/capability.py
Comment thread integrations/pydantic-ai/src/powercontext_pydantic_ai/capability.py
Comment thread integrations/pydantic-ai/src/powercontext_pydantic_ai/capability.py
@thunguo

thunguo commented Aug 23, 2026

Copy link
Copy Markdown
Contributor Author

@PsiACE This PR is ready for review, plz review it when you are free, thx.

if state.captured_position <= state.flushed_position:
return
try:
response = await self._toolset._require_client().flush_memory(FlushMemoryRequest(scope_id=state.scope_id))

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P1] checkpoint/final flush 不能保证追到本次捕获位置

这里每次只调用一次 flush_memory,但 Server 每次最多处理 source_window_limit 个 Source;当同一 scope 已有 backlog 时,返回的 current_cursor 仍可能小于 state.captured_position。使用真实 SQLite Server、source_window_limit=1 和两条 backlog 的探针中,本次 tool result 位于 position 5,checkpoint 与 final flush 后 cursor 只到 1、2,下一次 model request 看不到该结果;继续手工 flush 到 5 后才可召回。这会破坏 checkpoint 的 read-your-write 语义。建议在 deadline/max-calls/no-progress 约束下循环,直到 cursor 到达本次捕获位置,并补一个返回 partial cursor 的回归测试。


if isinstance(value, Mapping):
return {
str(key): REDACTED if is_sensitive_key(str(key)) else sanitize_capture_value(item)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P1] 当前 sanitizer 会原样持久化常见凭据形态

这里的 key 归一化无法识别 camelCase apiKey(会变成 apikey,但规则只含 api_key);同时非 Mapping 的字符串会原样返回,而 locked Pydantic AI 2.29 的 ToolCallPart.argsstr | dict | None,OpenAI adapter 会直接传入 JSON 字符串。探针确认 {"apiKey":"..."} 和字符串形式的 {"api_key":"..."} 都保留了 synthetic secret。capture 会持久化 tool arguments/results,这会绕过文档承诺的 credential redaction。建议覆盖 camelCase/compact aliases,并对结构化 JSON 参数使用 args_as_dict() 或安全解析后递归脱敏,补两种形态的回归测试。

run_id=ctx.run_id,
conversation_id=ctx.conversation_id,
)
return replace(request_context, messages=[context_request, *request_context.messages])

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P1] 新 run 应替换旧的 PowerContext context

这里直接把新 context 前置到完整 message_history,旧 run 注入的 CONTEXT_MARKER 消息不会被移除。连续三次 agent.run(..., message_history=previous.all_messages()) 的公开路径探针得到 marker 数 [1, 2, 3];第三轮同时携带 context-1、context-2、context-3,既让陈旧 system context 继续影响模型,也会按每轮最多 8KB 线性膨胀历史。建议在插入当前 run context 前过滤或替换旧的 PowerContext-marked request,保证复用历史时始终只有一个当前 context,并增加多 run 回归测试。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: Pydantic AI framework integration

3 participants