Skip to content

feat(ask): AIChat SDK — programmatic LLM chat with session management - #58

Merged
genesiscz merged 16 commits into
masterfrom
feat/ai-chat-sdk
Feb 26, 2026
Merged

genesiscz merged 16 commits into
masterfrom
feat/ai-chat-sdk

Conversation

@genesiscz

Copy link
Copy Markdown
Owner

Summary

  • Extracts the ask tool's core into AIChat — a programmatic, provider-agnostic LLM chat class
  • Fixes telegram stdout leakage by replacing subprocess runTool() with in-process AIChat({ logLevel: "silent" })
  • CLI single-message mode refactored to use AIChat (eliminates process.stdout.write monkey-patch hack)

New Components

File Purpose
src/ask/AIChat.ts Main class — constructor, send(), stream(), static discovery methods
src/ask/lib/types.ts All AIChat interfaces (AIChatOptions, SendOptions, ChatResponse, SessionEntry, etc.)
src/ask/lib/ChatEvent.ts Single event class with type guards (.isText(), .isDone(), etc.) and factories
src/ask/lib/ChatTurn.ts Dual PromiseLike<ChatResponse> + AsyncIterable<ChatEvent> — await or stream
src/ask/lib/ChatLog.ts In-memory log capture with cursor-based getUnseen() — never writes to stdout
src/ask/lib/ChatSession.ts Session data class with add(), getHistory(), toMessages(), filtering, export
src/ask/lib/ChatSessionManager.ts JSONL persistence — create(), save(), load(), list(), delete()
src/ask/index.lib.ts Barrel export for programmatic use

Usage

// Programmatic (telegram, scripts)
const chat = new AIChat({ provider: "openai", model: "gpt-4o-mini", logLevel: "silent" });
const response = await chat.send("Hello!");

// Streaming
for await (const event of chat.send("Tell me a story")) {
  if (event.isText()) process.stdout.write(event.text);
  if (event.isDone()) console.log(`Cost: $${event.response.cost}`);
}

// With session persistence
const chat = new AIChat({
  provider: "anthropic", model: "claude-sonnet-4-6",
  session: { id: "my-session", autoSave: true },
});

Test plan

  • 40 unit tests pass across 5 test files (ChatEvent, ChatLog, ChatSession, ChatSessionManager, ChatTurn)
  • Type-check passes with no new errors
  • Manual: tools ask -p openai -m gpt-4o-mini --raw "hello" — only response on stdout
  • Manual: tools telegram listen — verify no log leakage in responses

Copilot AI review requested due to automatic review settings February 25, 2026 22:06
@genesiscz

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Feb 25, 2026 •

Copy link
Copy Markdown
Contributor

Warning

Rate limit exceeded

@genesiscz has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 13 minutes and 10 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 1d5bdcb and 5ebe1db.

📒 Files selected for processing (21)
  • .claude/plans/2026-02-25-AskLibrary.md
  • .claude/plans/future/2026-03/2026-02-26-AIChat-Tools.md
  • .codex/config.toml
  • src/ask/AIChat.ts
  • src/ask/chat/ChatEngine.ts
  • src/ask/docs/claude-agent-sdk/overview.md
  • src/ask/docs/claude-agent-sdk/typescript-sdk.md
  • src/ask/index.lib.ts
  • src/ask/index.ts
  • src/ask/lib/ChatEvent.ts
  • src/ask/lib/ChatLog.ts
  • src/ask/lib/ChatSession.ts
  • src/ask/lib/ChatSessionManager.ts
  • src/ask/lib/ChatTurn.ts
  • src/ask/lib/__tests__/ChatEvent.test.ts
  • src/ask/lib/__tests__/ChatLog.test.ts
  • src/ask/lib/__tests__/ChatSession.test.ts
  • src/ask/lib/__tests__/ChatSessionManager.test.ts
  • src/ask/lib/__tests__/ChatTurn.test.ts
  • src/ask/lib/types.ts
  • src/telegram/lib/actions/ask.ts
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/ai-chat-sdk

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai

coderabbitai Bot commented Feb 25, 2026

Copy link
Copy Markdown
Contributor
✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@gemini-code-assist

Copy link
Copy Markdown
Contributor

Summary of Changes

Hello @genesiscz, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request introduces a foundational AIChat SDK, significantly enhancing how the application interacts with Large Language Models. The primary goal was to create a more robust, programmatic, and provider-agnostic interface for LLM communication, which includes sophisticated session management and persistence. This refactoring also directly addresses and resolves critical stdout leakage issues previously experienced in the Telegram integration and streamlines the CLI's LLM interaction by moving to an in-process approach, replacing less efficient and problematic subprocess calls.

Highlights

  • AIChat SDK Introduction: A new AIChat SDK has been introduced, providing a programmatic, provider-agnostic class for interacting with Large Language Models (LLMs) and managing chat sessions.
  • Stdout Leakage Fix: The issue of stdout leakage in the Telegram integration has been resolved by replacing subprocess runTool() calls with in-process AIChat({ logLevel: "silent" }).
  • CLI Refactoring: The CLI's single-message mode has been refactored to utilize the new AIChat class, eliminating previous monkey-patching of process.stdout.write.
  • Session Management: Comprehensive session management with persistence capabilities has been implemented, allowing chat history to be saved and loaded.
  • Streamable and Awaitable Responses: A new ChatTurn class enables chat responses to be both awaitable (for buffered results) and async iterable (for streaming events).

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Changelog
  • src/ask/AIChat.ts
    • Added the core AIChat class, providing a programmatic interface for LLM interactions, session management, and configuration.
  • src/ask/chat/ChatEngine.ts
    • Updated sendMessage method to accept onChunk and onThinking callbacks, allowing external handling of streaming output instead of direct process.stdout.write.
  • src/ask/index.lib.ts
    • Added a new barrel export file to expose the AIChat SDK components for programmatic use.
  • src/ask/index.ts
    • Refactored the ASKTool to utilize the new AIChat class for single-message mode, removing the process.stdout.write monkey-patch and direct ChatEngine usage.
  • src/ask/lib/ChatEvent.ts
    • Added a new ChatEvent class to standardize event types and provide type guards for streaming chat responses.
  • src/ask/lib/ChatLog.ts
    • Added a new ChatLog class for capturing and managing in-memory logs with configurable levels and cursor-based retrieval.
  • src/ask/lib/ChatSession.ts
    • Added a new ChatSession class to manage conversation history, including adding entries, filtering, and exporting in various formats.
  • src/ask/lib/ChatSessionManager.ts
    • Added a new ChatSessionManager class responsible for persisting and loading ChatSession data to and from JSONL files.
  • src/ask/lib/ChatTurn.ts
    • Added a new ChatTurn class that makes chat responses both awaitable (for buffered results) and async iterable (for streaming events).
  • src/ask/lib/types.ts
    • Added new TypeScript type definitions for AIChatOptions, ChatResponse, SessionEntry, LogLevel, and other related interfaces.
  • src/telegram/lib/actions/ask.ts
    • Updated the handleAsk action to use the new AIChat SDK, enabling in-process LLM interaction and session persistence for Telegram contacts, and removing the runTool subprocess call.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution. ↩

@gemini-code-assist gemini-code-assist Bot 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.

Code Review

This pull request introduces a well-designed AIChat SDK, which is a fantastic abstraction for programmatic LLM interaction and session management. The refactoring of the CLI and Telegram bot to use this new SDK is a significant improvement, particularly the fix for the stdout leakage in the Telegram integration. The new library components are thoughtfully created and come with a good set of tests.

My review includes a few points for consideration:

  • A high-severity issue regarding the streaming implementation in AIChat, which currently buffers the entire response instead of streaming text chunks. This could be misleading for SDK consumers.
  • A couple of medium-severity suggestions to improve code safety by removing non-null assertions.

Overall, this is a very strong contribution that builds a solid foundation for using the AI capabilities programmatically.

Comment thread src/ask/AIChat.ts Outdated
Comment thread src/ask/AIChat.ts Outdated
Comment thread src/ask/AIChat.ts Outdated

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

This PR introduces AIChat, a programmatic SDK for LLM chat with session management, extracting core functionality from the ask CLI tool. It addresses stdout leakage issues in the telegram bot by replacing subprocess-based tool invocation with direct in-process API calls using AIChat with silent logging.

Changes:

  • New AIChat SDK providing provider-agnostic LLM chat with automatic session persistence
  • Telegram integration refactored to use AIChat instances (one per contact) with persistent sessions
  • CLI single-message mode refactored to use AIChat, eliminating stdout monkey-patching

Reviewed changes

Copilot reviewed 16 out of 16 changed files in this pull request and generated 10 comments.

Show a summary per file
File Description
src/telegram/lib/actions/ask.ts Replaced subprocess runTool() with cached AIChat instances per contact, enabling silent mode to fix stdout leakage
src/ask/lib/types.ts New TypeScript interfaces for AIChat, session entries, events, and configuration options
src/ask/lib/__tests__/*.test.ts Unit tests for ChatEvent, ChatLog, ChatSession, ChatSessionManager, and ChatTurn (40 tests)
src/ask/lib/ChatTurn.ts Dual PromiseLike/AsyncIterable class for streaming or buffered LLM responses
src/ask/lib/ChatSessionManager.ts JSONL-based session persistence with create, save, load, list, and delete operations
src/ask/lib/ChatSession.ts In-memory session data management with history filtering, export, and statistics
src/ask/lib/ChatLog.ts Internal log capture with cursor-based unseen tracking, never writes to stdout
src/ask/lib/ChatEvent.ts Event types with type guards for text, thinking, tool calls, and completion
src/ask/AIChat.ts Main SDK class with provider resolution, session management, and message sending
src/ask/index.ts CLI refactored to use AIChat in both raw and streaming modes
src/ask/index.lib.ts Barrel export for programmatic SDK usage
src/ask/chat/ChatEngine.ts Added callback support for onChunk and onThinking to prevent stdout writes

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/ask/lib/ChatSessionManager.ts
Comment thread src/ask/AIChat.ts
Comment thread src/telegram/lib/actions/ask.ts
Comment thread src/telegram/lib/actions/ask.ts Outdated
Comment thread src/ask/AIChat.ts Outdated
Comment thread src/ask/AIChat.ts Outdated
Comment thread src/ask/AIChat.ts Outdated
Comment thread src/ask/AIChat.ts
Comment thread src/telegram/lib/actions/ask.ts Outdated
Comment thread src/ask/lib/ChatTurn.ts
- Fix duplicate API calls when ChatTurn is awaited then iterated
- Implement true streaming via ReadableStream bridge
- Remove non-null assertions in getProviders/getModels
- Add sessionId validation to prevent path traversal
- Add conflict detection for resume + session.id
- Fix telegram config-change detection with cache key
- Fix telegram history injection to use session context
- Document system prompt rebuild and engine mutation behavior
@genesiscz

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@genesiscz

Copy link
Copy Markdown
Owner Author

/gemini review

@coderabbitai

coderabbitai Bot commented Feb 25, 2026

Copy link
Copy Markdown
Contributor
✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@gemini-code-assist gemini-code-assist Bot 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.

Code Review

This pull request introduces a significant and well-structured AIChat SDK for programmatic LLM interaction, which is a great improvement. The refactoring successfully removes the stdout monkey-patching in the CLI and the subprocess execution in the Telegram tool, enhancing robustness and maintainability. The new components like ChatTurn, ChatSession, and ChatEvent provide a clean and powerful API. I've identified a few issues, primarily related to context handling, an ineffective override, and some areas for performance and correctness improvements. Addressing these will make the new SDK even more solid.

Comment thread src/ask/AIChat.ts
Comment thread src/telegram/lib/actions/ask.ts
Comment thread src/ask/AIChat.ts
Comment thread src/ask/chat/ChatEngine.ts
Comment thread src/ask/lib/ChatSession.ts
Comment thread src/ask/lib/ChatSessionManager.ts
genesiscz and others added 4 commits February 26, 2026 00:36
_getEngine now snapshots config before applying overrides and restores
it in a finally block, preventing state leakage across send() calls.
@genesiscz
genesiscz merged commit 2a1e289 into master Feb 26, 2026
1 of 2 checks passed
@genesiscz
genesiscz deleted the feat/ai-chat-sdk branch February 26, 2026 02:37
genesiscz added a commit that referenced this pull request Apr 20, 2026
Root README now covers every user-facing src/* tool. Added 33 new
Tool Details entries (#26–#58) and three new category sections
(macOS & System, Productivity & Automation, Shell & Infrastructure)
for tools that don't fit the existing categories.

Wrote fresh per-tool READMEs for the 31 tools that lacked one,
using the same robust style as src/watch/, src/ask/, src/azure-devops/
(badge row, tagline, feature table, quick-start, options table,
scenario-driven examples). Every tool that calls
handleReadmeFlag(import.meta.url) now renders real docs via
`tools <name> --readme`.

Skipped: `t3chat-length` (self-declared @internal), and tools that
already had both a root entry and a per-tool README (watch,
har-analyzer, ask, automate, azure-devops, mcp-manager, etc.).

Bump to 1.0.26.
genesiscz added a commit that referenced this pull request Apr 20, 2026
Add 31 per-tool READMEs using the same robust template as
src/watch/, src/ask/, src/azure-devops/ (badge row, tagline,
feature table, quick-start, options, scenario examples). Every tool
that calls handleReadmeFlag() now renders real docs via
\`tools <name> --readme\`.

Root README gains 33 Tool Details entries (#26-#58) and three new
category sections (macOS & System, Productivity & Automation,
Shell & Infrastructure) for tools that didn't fit the existing
buckets. Also add the external skill workspace pulled in by the
plugin runtime (.agents/, .claude/skills/, skills-lock.json).

Plugin version bumped to 1.0.26.
genesiscz added a commit that referenced this pull request Apr 20, 2026
Add 31 per-tool READMEs using the same robust template as
src/watch/, src/ask/, src/azure-devops/ (badge row, tagline,
feature table, quick-start, options, scenario examples). Every tool
that calls handleReadmeFlag() now renders real docs via
\`tools <name> --readme\`.

Root README gains 33 Tool Details entries (#26-#58) and three new
category sections (macOS & System, Productivity & Automation,
Shell & Infrastructure) for tools that didn't fit the existing
buckets. Also add the external skill workspace pulled in by the
plugin runtime (.agents/, .claude/skills/, skills-lock.json).

Plugin version bumped to 1.0.26.
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.

2 participants