Skip to content

ChatStream moves to a light module so chat()'s type hints resolve at runtime - #471

Merged
rejojer merged 4 commits into
mainfrom
fix/chat-stream-module
Sep 3, 2026
Merged

ChatStream moves to a light module so chat()'s type hints resolve at runtime#471
rejojer merged 4 commits into
mainfrom
fix/chat-stream-module

Conversation

@rejojer

@rejojer rejojer commented Sep 3, 2026

Copy link
Copy Markdown
Member

ChatStream was importable in client.py only under TYPE_CHECKING (a real import would have dragged local_chat's asyncio stack into import pageindex), which left chat()'s return annotation a dangling string: typing.get_type_hints(PageIndexClient.chat) raised NameError, and so did anything that introspects signatures. agents.function_tool(client.chat) died on it before looking at a single parameter.

The class touches neither asyncio nor the agent frameworks, so it moves to pageindex/chat_stream.py; client.py imports it for real, and the package exports it directly instead of lazily. import pageindex still leaves local_chat unloaded, and import cost is unchanged.

A review of the first commit found the move's own guards thinner than they looked, fixed in the second:

  • chat_stream.py had no from __future__ import annotations, unlike every sibling module, so its -> "ChatStream" quotes were load-bearing: unquoting them — the very edit this move makes in client.py — broke import pageindex outright.
  • The import in client.py is the whole fix and reads like a typing-only one, so a comment says why it must stay real.
  • The lazy-import test's denylist named no framework, so agents, litellm, openai or anthropic could join the eager path with a green suite — the cost this module was split out to avoid.
  • The type-hints walk had no floor, so it could silently stop covering anything, and nothing pinned pageindex.local_chat.ChatStream, the path the class shipped under in 0.2.11-0.2.14.
  • local_chat's module docstring still claimed the class.

Sits on the review view #457. The client.py hunk was merged by hand onto main's chat() signatures (#460), keeping main's TYPE_CHECKING import, which its runtime-only __getattr__ still uses.

Verification: 476 passed; whole suite with openai-agents blocked 370 passed / 106 skipped; pyright 0 on the touched files, package unchanged (236). The type-hints test is red on base (NameError), and all four new guards were mutation-checked red. Note function_tool(client.chat) also needs strict_mode=False: chat()'s object-typed parameters are what pageindex/integrations/openai_agents.py exists to work around, and that is unchanged here.

…ve at runtime

ChatStream was importable in client.py only under TYPE_CHECKING (a real
import would have dragged local_chat's asyncio stack into `import
pageindex`), which left chat()'s return annotation a dangling string:
typing.get_type_hints(PageIndexClient.chat) raised NameError, and so
did anything that introspects signatures — agents' function_tool
(client.chat) died on it before looking at a single parameter. The
class touches neither asyncio nor the agent frameworks, so it moves to
pageindex/chat_stream.py, client.py imports it for real, and the
package exports it directly instead of lazily. `import pageindex` still
leaves local_chat unloaded.

Claude-Session: https://claude.ai/code/session_01PYr9yG1FPQxKCA9m7ECQWY
Comment thread pageindex/client.py
extra_headers: Optional[dict[str, str]] = None,
extra_body: Optional[dict[str, Any]] = None,
) -> "ChatStream": ...
) -> ChatStream: ...
Comment thread pageindex/client.py
extra_headers: Optional[dict[str, str]] = None,
extra_body: Optional[dict[str, Any]] = None,
) -> Union[str, "ChatStream"]: ...
) -> Union[str, ChatStream]: ...
Comment thread pageindex/client.py
extra_headers: Optional[dict[str, str]] = None,
extra_body: Optional[dict[str, Any]] = None,
) -> Union[str, "ChatStream", dict[str, Any], Iterator[Any]]: ...
) -> Union[str, ChatStream, dict[str, Any], Iterator[Any]]: ...
rejojer added a commit that referenced this pull request Sep 3, 2026
…s, a guarded eager path, the old import path pinned

Review of #471 found the move's guards thinner than they look:

- chat_stream.py had no `from __future__ import annotations`, unlike
  every sibling module, which made its `-> "ChatStream"` quotes
  load-bearing: unquoting them — the very edit this move made in
  client.py, and what `ruff --select UP037 --fix` does — broke
  `import pageindex` outright.
- The import in client.py is the whole fix and reads like a
  typing-only one; a comment says why it must stay real.
- The lazy-import test's denylist named no framework, so agents,
  litellm, openai or anthropic could join the eager path with a green
  suite — the cost the module was split out to avoid.
- The type-hints walk had no floor, so it could silently stop covering
  anything, and nothing pinned `pageindex.local_chat.ChatStream`, the
  path the class shipped under in 0.2.11-0.2.14.
- local_chat's module docstring still claimed the class.

All four guards mutation-checked red.
…s, a guarded eager path, the old import path pinned

Review of #471 found the move's guards thinner than they look:

- chat_stream.py had no `from __future__ import annotations`, unlike
  every sibling module, which made its `-> "ChatStream"` quotes
  load-bearing: unquoting them — the very edit this move made in
  client.py, and what `ruff --select UP037 --fix` does — broke
  `import pageindex` outright.
- The import in client.py is the whole fix and reads like a
  typing-only one; a comment says why it must stay real.
- The lazy-import test's denylist named no framework, so agents,
  litellm, openai or anthropic could join the eager path with a green
  suite — the cost the module was split out to avoid.
- The type-hints walk had no floor, so it could silently stop covering
  anything, and nothing pinned `pageindex.local_chat.ChatStream`, the
  path the class shipped under in 0.2.11-0.2.14.
- local_chat's module docstring still claimed the class.

All four guards mutation-checked red.
method's hints must resolve, ChatStream included."""
import inspect
import typing
import pageindex
@rejojer
rejojer merged commit c8c8293 into main Sep 3, 2026
9 checks passed
@rejojer
rejojer deleted the fix/chat-stream-module branch September 3, 2026 10:19
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.

1 participant