Honcho 2.1.0 "ROTE" deriver#160
Conversation
chore: refactor repo
WalkthroughThis update introduces a major architectural refactor of the codebase, modularizing core logic for deriver, dialectic, CRUD operations, and file uploads. It removes legacy agent and theory-of-mind modules, adds robust file upload and chunking support, overhauls configuration management, and updates both Python and TypeScript SDKs and APIs to use session-scoped messaging and single-query endpoints. Changes
Sequence Diagram(s)sequenceDiagram
participant Client
participant API
participant CRUD
participant Deriver
participant Dialectic
participant EmbeddingStore
participant DB
Client->>API: POST /sessions/{session_id}/messages/upload (file, peer_id)
API->>API: Validate and chunk file
API->>CRUD: create_messages (session, peer, chunks)
CRUD->>DB: Insert messages
API->>Deriver: enqueue(messages)
Deriver->>DB: Queue message processing tasks
Client->>API: POST /peers/{peer_id}/chat (query, session_id, target)
API->>Dialectic: chat(workspace, peer, target, session, query)
Dialectic->>CRUD: get_working_representation
Dialectic->>EmbeddingStore: get_observations (semantic search)
Dialectic->>Dialectic: dialectic_call/stream (LLM)
Dialectic->>API: Return response
API->>Client: Return chat result or stream
Possibly related PRs
Suggested reviewers
Poem
✨ Finishing Touches
🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Actionable comments posted: 76
🔭 Outside diff range comments (8)
src/deriver/__main__.py (1)
8-18: Swap
Since the project already usesstructlog/logging, substitute-import asyncio +import asyncio +import logging @@ -if __name__ == "__main__": - print("[DERIVER] Starting deriver queue processor") +logger = logging.getLogger("deriver.main") + +if __name__ == "__main__": + logger.info("Starting deriver queue processor") @@ - print("[DERIVER] Running main loop") + logger.info("Running main loop") @@ - except KeyboardInterrupt: - print("[DERIVER] Shutdown initiated via KeyboardInterrupt") - except Exception as e: - print(f"[DERIVER] Error in main process: {str(e)}") + except KeyboardInterrupt: + logger.info("Shutdown initiated via KeyboardInterrupt") + except Exception as e: + logger.exception("Error in main process", exc_info=e) @@ - print("[DERIVER] Deriver process exiting") + logger.info("Deriver process exiting")sdks/python/src/honcho/__init__.py (1)
49-49: Version constant not bumpedChangelog advertises
1.2.0, but__version__remains1.0.0. Align these to prevent downstream tooling (pip, packaging, SDK consumers) from mis-identifying the release.-__version__ = "1.0.0" +__version__ = "1.2.0"sdks/python/src/honcho/utils/file_upload.py (1)
69-76: Consider error handling for file operations and memory usageThe function should handle potential I/O errors when reading files and consider memory implications for large files.
def prepare_file_for_upload( file: tuple[str, bytes, str] | tuple[str, IOBase, str] | IOBase, ) -> tuple[str, bytes, str]: """ Prepare a file for upload by normalizing and reading its content. Args: file: File to prepare. Can be: - a file object (must have .name and .read()) - a tuple (filename, bytes, content_type) - a tuple (filename, fileobj, content_type) Returns: A tuple of (filename, content_bytes, content_type) ready for API upload Raises: ValueError: If the file input format is not supported + IOError: If the file cannot be read """ normalized_file = normalize_file_input(file) - # Read the file content - normalized_file[1].seek(0) # Reset file position - content_bytes = normalized_file[1].read() + # Read the file content with error handling + try: + normalized_file[1].seek(0) # Reset file position + content_bytes = normalized_file[1].read() + if not isinstance(content_bytes, bytes): + content_bytes = content_bytes.encode('utf-8') + except Exception as e: + raise IOError(f"Failed to read file content: {str(e)}") from e return (normalized_file[0], content_bytes, normalized_file[2])For production use with potentially large files, consider implementing chunked file reading or streaming uploads to avoid memory issues. The current implementation loads entire files into memory which could cause problems with files larger than available RAM.
src/deriver/logging.py (1)
226-256: Simplify conditional logic and use f-string conversion flags.The function works correctly but can be improved based on static analysis hints.
def _extract_observation_text(obs: ObservationType) -> str: """Extract text content from various observation types, including premises.""" if isinstance(obs, str): return obs - elif isinstance(obs, dict): + if isinstance(obs, dict): # Handle dict-based structured observations first if "conclusion" in obs: conclusion: str = str(obs["conclusion"]) premises: list[Any] = list(obs.get("premises", [])) if premises: - premises_text = "\n" + "\n".join(f" - {str(p)}" for p in premises) + premises_text = "\n" + "\n".join(f" - {p!s}" for p in premises) return f"{conclusion}{premises_text}" return conclusion return str(obs.get("content", obs)) - else: - # Handle object-based observations - # Use Any type for this branch since we're doing dynamic attribute checking - obj: Any = obs - if hasattr(obj, "conclusion"): - conclusion = str(obj.conclusion) - if hasattr(obj, "premises") and obj.premises: - premises_text = "\n" + "\n".join( - f" - {str(p)}" for p in obj.premises - ) - return f"{conclusion}{premises_text}" - return conclusion - elif hasattr(obj, "content"): - return str(obj.content) - else: - return str(obj) + # Handle object-based observations + # Use Any type for this branch since we're doing dynamic attribute checking + obj: Any = obs + if hasattr(obj, "conclusion"): + conclusion = str(obj.conclusion) + if hasattr(obj, "premises") and obj.premises: + premises_text = "\n" + "\n".join( + f" - {p!s}" for p in obj.premises + ) + return f"{conclusion}{premises_text}" + return conclusion + if hasattr(obj, "content"): + return str(obj.content) + return str(obj)src/deriver/consumer.py (1)
21-59: Add return type annotation.The function is missing a return type annotation.
-async def process_item(db: AsyncSession, payload: dict[str, Any]): +async def process_item(db: AsyncSession, payload: dict[str, Any]) -> None:src/crud/representation.py (1)
231-233: Consider a more robust naming scheme.The simple underscore concatenation could cause issues if peer names contain underscores. Consider using a delimiter that's less likely to appear in names or encoding the names.
def construct_collection_name(*, observer: str, observed: str) -> str: - return f"{observer}_{observed}" + # Use a delimiter less likely to appear in names + return f"{observer}:::{observed}"src/crud/message.py (1)
275-411: Consider breaking down the complex search function.While the implementation correctly handles multiple search strategies (semantic, full-text, exact match), the function complexity (11) exceeds recommended limits. Consider extracting search strategy implementations into separate helper functions:
async def _semantic_search_query(workspace_name: str, query: str, embedding_query: list[float], session_name: str | None, peer_name: str | None) -> Select: # Semantic search logic async def _fulltext_search_query(workspace_name: str, query: str, session_name: str | None, peer_name: str | None) -> Select: # Full-text search logic async def _exact_match_query(workspace_name: str, query: str, session_name: str | None, peer_name: str | None) -> Select: # Exact match logicThis would improve maintainability and testability while reducing cognitive load.
Would you like me to help refactor this into smaller, more focused functions?
src/deriver/deriver.py (1)
541-632: Fix timezone-naive datetime usage.Line 579 uses
datetime.datetime.now()without timezone, which could cause issues:- "created_at": datetime.datetime.now().isoformat(), + "created_at": datetime.datetime.now(datetime.timezone.utc).isoformat(),The rest of the implementation correctly handles different storage scenarios (session vs global) and uses PostgreSQL JSON operators appropriately.
There was a problem hiding this comment.
Actionable comments posted: 3
🔭 Outside diff range comments (2)
sdks/typescript/__tests__/client.test.ts (2)
6-22: Mock may break consumers that use named exports from@honcho-ai/core
jest.mock('@honcho-ai/core', () => jest.fn() …)replaces the entire module with a single default-exported mock constructor.
If any source under test later switches toimport { X } from '@honcho-ai/core'the tests will silently start returningundefined, making failures hard to diagnose.-jest.mock('@honcho-ai/core', () => { - return jest.fn().mockImplementation(() => ({ … })); -}); +jest.mock('@honcho-ai/core', () => ({ + __esModule: true, + default: jest.fn().mockImplementation(() => ({ … })), +}));Adding
__esModule: trueand exportingdefaultpreserves named-export look-ups while keeping current behaviour intact.
55-68: Preserve pre-existing env-vars when mutatingprocess.envThe test overwrites
HONCHO_*variables and then deletes them.
If a dev runs the suite with genuine values in their shell these will be lost for subsequent tests.- process.env.HONCHO_WORKSPACE_ID = 'env-workspace'; + const { HONCHO_WORKSPACE_ID, HONCHO_API_KEY, HONCHO_URL } = process.env; + process.env.HONCHO_WORKSPACE_ID = 'env-workspace'; … - delete process.env.HONCHO_WORKSPACE_ID; - delete process.env.HONCHO_API_KEY; - delete process.env.HONCHO_URL; + Object.assign(process.env, { + HONCHO_WORKSPACE_ID, + HONCHO_API_KEY, + HONCHO_URL, + });A small helper (e.g.
withEnv) can DRY this across tests.
♻️ Duplicate comments (1)
sdks/typescript/package.json (1)
21-21: Exact version pinning aligns with user preference.Based on the retrieved learnings, the user prefers exact version pinning for dependencies in the TypeScript SDK package.json rather than using semver ranges. This change from "^1.1.0" to "1.2.0" is consistent with that preference.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (7)
sdks/python/pyproject.toml(1 hunks)sdks/typescript/__tests__/client.test.ts(18 hunks)sdks/typescript/__tests__/integration.test.ts(3 hunks)sdks/typescript/__tests__/peer.test.ts(23 hunks)sdks/typescript/__tests__/session.test.ts(34 hunks)sdks/typescript/package.json(2 hunks)sdks/typescript/src/pagination.ts(2 hunks)
🧰 Additional context used
🧠 Learnings (4)
sdks/typescript/package.json (1)
Learnt from: dr-frmr
PR: plastic-labs/honcho#160
File: sdks/typescript/package.json:21-22
Timestamp: 2025-07-16T21:28:04.477Z
Learning: The user dr-frmr prefers exact version pinning for dependencies in the TypeScript SDK package.json rather than using semver ranges, indicating they want explicit control over dependency updates.
sdks/python/pyproject.toml (1)
Learnt from: VVoruganti
PR: plastic-labs/honcho#115
File: README.md:393-396
Timestamp: 2025-05-29T16:27:13.808Z
Learning: CONTRIBUTING.md exists at the repository root in the Honcho project and contains a comprehensive contributing guide. Automated verification scripts can sometimes fail to detect existing files, so manual verification may be needed when users dispute automated findings.
sdks/typescript/__tests__/client.test.ts (1)
Learnt from: Rajat-Ahuja1997
PR: plastic-labs/honcho#131
File: src/crud.py:503-505
Timestamp: 2025-06-18T14:50:59.967Z
Learning: The Honcho project prefers upsert behavior for update operations across all resources (sessions, peers, workspaces). Update operations should create the resource if it doesn't exist rather than failing fast. This is an explicit design decision that differs from typical REST semantics but provides a more forgiving API experience.
sdks/typescript/__tests__/session.test.ts (1)
Learnt from: dr-frmr
PR: plastic-labs/honcho#131
File: src/routers/sessions.py:206-213
Timestamp: 2025-06-18T20:42:06.458Z
Learning: The `get_or_create_session` function in this codebase is designed to handle both session creation and adding peers to existing sessions. When called with peers, it will add those peers to an existing session rather than creating a duplicate session.
🧬 Code Graph Analysis (1)
sdks/typescript/__tests__/client.test.ts (3)
sdks/python/src/honcho/client.py (2)
Honcho(20-405)peer(123-154)sdks/typescript/src/client.ts (2)
Honcho(10-217)peer(43-48)sdks/typescript/src/pagination.ts (1)
Page(5-77)
🔇 Additional comments (12)
sdks/typescript/package.json (1)
3-3: Version bump looks correct for the 1.2.0 release.The version increment from 1.1.0 to 1.2.0 aligns with the major feature additions and API changes documented in the PR summary.
sdks/typescript/src/pagination.ts (1)
43-43: Defaults removal in pagination getters is intentional and well-testedUnit tests in
__tests__/pagination.test.tsexplicitly assert thatsize,total, andhasNextPagereturnundefinedwhen those fields are missing, and integration tests validate correct behavior when the API provides values. No fallback defaults (0orfalse) are needed.This change is safe and covered by tests—no further action required.
sdks/typescript/__tests__/integration.test.ts (3)
141-141: API parameter update aligns with dialectic chat endpoint changes.The change from
queriestoqueryreflects the updated dialectic chat endpoint that now accepts a single query string instead of multiple queries, as documented in the PR summary.
232-232: Search parameter structure updated correctly.The workspace search now expects a structured object with a
bodykey instead of a raw string, aligning with the API changes.
252-252: Session search parameter structure updated correctly.The session search now expects a structured object with a
querykey instead of a raw string, consistent with the API standardization.sdks/typescript/__tests__/peer.test.ts (3)
23-26: Mock workspace methods added to support existing tests.The addition of workspace mock methods (
getOrCreate,update,list,search) ensures test compatibility with the expanded workspace API surface.
69-69: Chat method parameter updated consistently.All chat method tests now use
queryinstead ofqueries, reflecting the dialectic chat endpoint update to accept a single query string.Also applies to: 100-100, 114-114, 127-127, 140-140, 158-158
350-350: Search parameter structure updated correctly.The search tests now use
{ query: 'hello' }instead of{ body: 'hello' }, aligning with the standardized search parameter structure.Also applies to: 394-394
sdks/typescript/__tests__/session.test.ts (2)
30-33: Mock workspace methods added for test compatibility.The addition of workspace mock methods ensures existing session tests continue to work with the expanded workspace API.
581-581: Search parameter structure updated correctly.The session search test now uses
{ query: 'hello' }instead of{ body: 'hello' }, consistent with the standardized search parameter structure across the API.sdks/typescript/__tests__/client.test.ts (2)
333-337: Search argument wrapped in{ body }– matches implementationThe expectation now mirrors the updated SDK signature; looks correct and keeps the test meaningful.
373-377: Complex-query test validates escaping/forwarding correctlyGood to see edge-case coverage for special characters.
There was a problem hiding this comment.
Actionable comments posted: 9
♻️ Duplicate comments (16)
docs/v2/guides/dialectic-endpoint.mdx (1)
17-17: Fix double space formatting issueThere's an extra space before the "## Prerequisites" heading which can break some Markdown renderers.
-This chat interface is exposed via the `peer.chat()` endpoint. It accepts a string query. Below is some example code on how this works. +This chat interface is exposed via the `peer.chat()` endpoint. It accepts a string query. Below is some example code on how this works.sdks/python/examples/multi_user_representations.py (1)
32-32: Replace hardcoded sleep with proper deriver pollingThe hardcoded 5-second sleep is not reliable for ensuring message processing completion. The script already demonstrates proper deriver polling later - consider using it consistently.
-time.sleep(5) +print("waiting for initial messages to be processed") +deriver_status = honcho.poll_deriver_status() +print("deriver status:", deriver_status)docs/v2/guides/file-uploads.mdx (1)
220-232: Note inconsistency in example codeThe
upload_documentfunction shows parameters (content,metadata) that aren't mentioned in the API documentation section. This may confuse users about the actual API surface.Verify that the example code matches the actual API. If
contentandmetadataparameters are supported, they should be documented in the "Upload Parameters" section.src/crud/peer.py (3)
107-109: Improve exception message handlingThe exception message is constructed inline, which goes against best practices for exception handling.
raise ResourceNotFoundException( - f"Peer {peer.name} not found in workspace {workspace_name}" + f"Peer {peer.name} not found in workspace {workspace_name}", )Consider using a shorter message or defining it as a constant if used frequently.
118-120: Remove unnecessary assignment before returnThe assignment to
stmtbefore returning is unnecessary as flagged by static analysis.stmt = apply_filter(stmt, models.Peer, filters) - return stmt.order_by(models.Peer.created_at) + return apply_filter(stmt, models.Peer, filters).order_by(models.Peer.created_at)
156-156: Use proper logging formatReplace f-string with proper logging format for better performance and consistency.
- logger.info(f"Peer {peer_name} updated successfully") + logger.info("Peer %s updated successfully", peer_name)src/utils/shared_models.py (1)
150-150: Use timezone-aware datetime for consistency.Using
datetime.now()without timezone can lead to ambiguity in distributed systems. Consider using UTC timestamps.- created_at=datetime.now(), + created_at=datetime.now(datetime.timezone.utc),Also add the import:
-from datetime import datetime +from datetime import datetimeAlso applies to: 172-172
src/dialectic/chat.py (1)
43-43: Add return type annotations for public functions.The decorated functions should have explicit return type annotations for better type safety.
async def dialectic_call( query: str, working_representation: str, additional_context: str | None, peer_name: str, -): +) -> Any: # The actual return type depends on the LLM response structureasync def dialectic_stream( query: str, working_representation: str, additional_context: str | None, peer_name: str, -): +) -> Any: # The actual return type depends on the LLM stream structureConsider defining a more specific return type based on the actual LLM response structure.
Also applies to: 92-92
src/utils/files.py (2)
222-222: Add context to FileProcessingError.The error should provide more information about what went wrong.
- raise FileProcessingError() + raise FileProcessingError("No messages could be generated from the uploaded file")
56-60: Move import to module level.The
jsonimport should be at the module level for consistency and to avoid repeated imports.Move the import to the top of the file:
+import json import logging from io import BytesIOAnd remove it from the method:
async def extract_text(self, content: bytes) -> str: - import json - data = json.loads(content.decode("utf-8"))src/utils/formatting.py (4)
65-93: Consider adding type guards for better type safety.The function handles multiple input types well, but the complex casting on line 87 with
pyright: ignoresuggests type complexity that could be improved with proper type guards.Also, add missing trailing comma:
return format_structured_observation( - observation.conclusion, observation.premises + observation.conclusion, observation.premises, )
111-114: Remove unnecessaryelseafterreturn.The
elseblock is unnecessary since the previous condition returns.if current_time and current_time != "unknown": return f"{current_time} {speaker}: {new_turn}" - else: - return f"{speaker}: {new_turn}" + return f"{speaker}: {new_turn}"
183-200: Refactor to remove unnecessaryelifandelseafterreturn.The conditional structure can be simplified since each branch returns.
if isinstance(dt, datetime): # It's a datetime object return dt.strftime("%Y-%m-%d %H:%M:%S") - elif isinstance(dt, str): + if isinstance(dt, str): # It's a string - try to parse it first try: # Handle ISO format strings if "T" in dt: parsed_dt = datetime.fromisoformat(dt.replace("Z", "+00:00")) return parsed_dt.strftime("%Y-%m-%d %H:%M:%S") - else: - # Already in simple format - return dt + # Already in simple format + return dt except ValueError: # If parsing fails, return as-is return dt - else: - # Fallback - return str(dt) + # Fallback + return str(dt)
233-236: Remove unnecessaryelsein helper function.The else block after return is not needed.
if isinstance(context, ReasoningResponse): # It's a ReasoningResponse object return getattr(context, level, []) - else: - # It's a dict - return context.get(level, []) + # It's a dict + return context.get(level, [])src/utils/logging.py (2)
248-314: Refactor complex evidence formatting logic.This function has high complexity (13 > 10). The evidence formatting section could be extracted into separate helper functions.
Extract the evidence formatting logic into separate functions:
def _format_evidence_section( evidence_ids: list[str], evidence_links: dict[str, str] | None, evidence_text_map: dict[str, Any] | None, ) -> list[str]: """Format evidence section with links and text previews.""" lines = [] for ev in evidence_ids: text_part = _get_evidence_text_preview(ev, evidence_text_map) bullet = f"* {ev}{text_part}" if isinstance(evidence_links, dict) and ev in evidence_links: bullet = f"* [{ev}{text_part}]({evidence_links[ev]})" lines.append(bullet) return lines def _get_evidence_text_preview( ev_id: str, evidence_text_map: dict[str, Any] | None ) -> str: """Get truncated text preview for evidence.""" if not isinstance(evidence_text_map, dict): return "" raw_txt = evidence_text_map.get(ev_id, "") try: txt = str(raw_txt) if raw_txt else "" except (TypeError, ValueError): txt = "" if txt: from textwrap import shorten return f' – "{shorten(txt, width=60, placeholder="...")}"' return ""
8-8: Move inline imports to module level.Inline imports should be moved to the top of the file for better performance and consistency with coding guidelines.
Move these imports to the top of the file after line 8:
from typing import cast(line 282-283)The
from textwrap import shortenimport on line 8 is already at module level, so line 292 can be removed.Also applies to: 282-283, 292-292
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
⛔ Files ignored due to path filters (1)
sdks/typescript/package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (13)
docs/changelog/compatibility-guide.mdx(2 hunks)docs/v2/guides/dialectic-endpoint.mdx(1 hunks)docs/v2/guides/file-uploads.mdx(1 hunks)sdks/python/examples/multi_user_representations.py(1 hunks)sdks/typescript/src/client.ts(1 hunks)sdks/typescript/src/session.ts(1 hunks)src/crud/peer.py(1 hunks)src/dialectic/chat.py(1 hunks)src/utils/__init__.py(0 hunks)src/utils/files.py(1 hunks)src/utils/formatting.py(1 hunks)src/utils/logging.py(1 hunks)src/utils/shared_models.py(1 hunks)
💤 Files with no reviewable changes (1)
- src/utils/init.py
🧰 Additional context used
📓 Path-based instructions (1)
src/**/*.py
Instructions used from:
Sources:
📄 CodeRabbit Inference Engine
- CLAUDE.md
🧠 Learnings (5)
docs/changelog/compatibility-guide.mdx (1)
Learnt from: Rajat-Ahuja1997
PR: plastic-labs/honcho#131
File: src/crud.py:503-505
Timestamp: 2025-06-18T14:50:59.967Z
Learning: The Honcho project prefers upsert behavior for update operations across all resources (sessions, peers, workspaces). Update operations should create the resource if it doesn't exist rather than failing fast. This is an explicit design decision that differs from typical REST semantics but provides a more forgiving API experience.
sdks/python/examples/multi_user_representations.py (3)
Learnt from: dr-frmr
PR: plastic-labs/honcho#131
File: src/routers/sessions.py:206-213
Timestamp: 2025-06-18T20:42:06.458Z
Learning: The `get_or_create_session` function in this codebase is designed to handle both session creation and adding peers to existing sessions. When called with peers, it will add those peers to an existing session rather than creating a duplicate session.
Learnt from: Rajat-Ahuja1997
PR: plastic-labs/honcho#144
File: tests/integration/test_message_embeddings.py:128-187
Timestamp: 2025-06-26T18:35:46.478Z
Learning: The honcho repository does not use trailing commas in function signatures, function calls, or object instantiation. This is consistently applied across the entire codebase including test files, and reviews should not suggest adding trailing commas.
Learnt from: Rajat-Ahuja1997
PR: plastic-labs/honcho#131
File: src/crud.py:503-505
Timestamp: 2025-06-18T14:50:59.967Z
Learning: The Honcho project prefers upsert behavior for update operations across all resources (sessions, peers, workspaces). Update operations should create the resource if it doesn't exist rather than failing fast. This is an explicit design decision that differs from typical REST semantics but provides a more forgiving API experience.
docs/v2/guides/file-uploads.mdx (1)
Learnt from: VVoruganti
PR: plastic-labs/honcho#115
File: README.md:393-396
Timestamp: 2025-05-29T16:27:13.808Z
Learning: CONTRIBUTING.md exists at the repository root in the Honcho project and contains a comprehensive contributing guide. Automated verification scripts can sometimes fail to detect existing files, so manual verification may be needed when users dispute automated findings.
src/crud/peer.py (7)
Learnt from: dr-frmr
PR: plastic-labs/honcho#131
File: src/routers/sessions.py:206-213
Timestamp: 2025-06-18T20:42:06.458Z
Learning: The `get_or_create_session` function in this codebase is designed to handle both session creation and adding peers to existing sessions. When called with peers, it will add those peers to an existing session rather than creating a duplicate session.
Learnt from: Rajat-Ahuja1997
PR: plastic-labs/honcho#131
File: migrations/versions/d429de0e5338_adopt_peer_paradigm.py:918-942
Timestamp: 2025-06-19T14:32:02.934Z
Learning: The queue and active_queue_sessions tables in the migration script `migrations/versions/d429de0e5338_adopt_peer_paradigm.py` are expected to remain small, so per-row updates are acceptable and performance optimizations like set-based updates are not necessary.
Learnt from: Rajat-Ahuja1997
PR: plastic-labs/honcho#131
File: migrations/versions/d429de0e5338_adopt_peer_paradigm.py:188-194
Timestamp: 2025-06-18T15:58:51.202Z
Learning: In the migration file `migrations/versions/d429de0e5338_adopt_peer_paradigm.py`, the team has explicitly decided to accept SQL injection risks from f-string interpolation of schema names, despite the security concerns around DDL injection via the DATABASE_SCHEMA environment variable.
Learnt from: CR
PR: plastic-labs/honcho#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-30T19:10:56.136Z
Learning: Applies to src/models.py : Feature flags on workspace, peer, and session levels
Learnt from: Rajat-Ahuja1997
PR: plastic-labs/honcho#131
File: migrations/versions/d429de0e5338_adopt_peer_paradigm.py:36-77
Timestamp: 2025-06-19T14:07:32.309Z
Learning: The migration script `migrations/versions/d429de0e5338_adopt_peer_paradigm.py` properly handles foreign key constraints during table updates by explicitly dropping foreign key constraints before making schema changes, preventing constraint violations during the migration process.
Learnt from: Rajat-Ahuja1997
PR: plastic-labs/honcho#131
File: src/crud.py:374-377
Timestamp: 2025-06-18T21:24:55.907Z
Learning: The codebase uses a layered error handling approach where the CRUD layer raises ValueError for business rule violations (like peer limits), and the API layer catches these ValueError exceptions and translates them to appropriate domain-specific exceptions (ValidationException for validation errors, ResourceNotFoundException for missing resources). This provides clean separation of concerns between business logic and HTTP semantics.
Learnt from: CR
PR: plastic-labs/honcho#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-30T19:10:56.136Z
Learning: Applies to src/**/*.py : Use specific exception types (ResourceNotFoundException, ValidationException, etc.)
src/utils/logging.py (3)
Learnt from: CR
PR: plastic-labs/honcho#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-30T19:10:56.136Z
Learning: Applies to src/**/*.py : Proper logging with context instead of print statements
Learnt from: dr-frmr
PR: plastic-labs/honcho#142
File: tests/sdk/conftest.py:17-18
Timestamp: 2025-06-26T20:57:43.067Z
Learning: In test configuration files, when sys.path modifications are required to make modules discoverable (like adding SDK source paths), the subsequent imports must use # noqa: E402 directives to suppress "module level import not at top of file" warnings. This is a necessary pattern when imports depend on runtime path modifications.
Learnt from: CR
PR: plastic-labs/honcho#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-30T19:10:56.136Z
Learning: Applies to src/**/*.py : Line length: 88 chars (Black compatible)
🧬 Code Graph Analysis (1)
src/crud/peer.py (5)
src/exceptions.py (1)
ResourceNotFoundException(21-25)src/utils/filter.py (1)
apply_filter(50-97)src/schemas.py (4)
PeerCreate(58-66)Peer(78-89)PeerUpdate(73-75)Session(209-221)src/models.py (3)
Peer(103-134)Session(138-168)SessionPeer(404-414)src/routers/peers.py (3)
get_peers(36-53)update_peer(97-107)get_sessions_for_peer(117-140)
🪛 LanguageTool
docs/v2/guides/dialectic-endpoint.mdx
[grammar] ~17-~17: Use correct spacing
Context: ... Below is some example code on how this works. ## Prerequisites ```python Pyt...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
docs/changelog/compatibility-guide.mdx
[grammar] ~11-~11: Use correct spacing
Context: ...on Compatibility ### Honcho API v2.1.0 (Current) Compatible Version: v1.2.0 Install with: bash npm install @honcho-ai/sdk@1.2.0 Compatible Version: v1.2.0 Install with: bash pip install honcho-ai==1.2.0 ### Honcho API v2.0.5 ...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~33-~33: Use correct spacing
Context: ... ### Honcho API v2.0.5 Compatible Version: v1.1.0 Install with: bash npm install @honcho-ai/sdk@1.1.0 Compatible Version: v1.1.0 Install with: bash pip install honcho-ai==1.1.0 ## Version Compatibility Table | Honcho AP...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
docs/v2/guides/file-uploads.mdx
[grammar] ~7-~7: Use correct spacing
Context: ...art of your peer's knowledge or session context. This feature is perfect for ingesting do...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~9-~9: Use correct spacing
Context: ...u want your AI agents to understand and reference. ## How It Works When you upload a file, Ho...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~11-~11: Use correct spacing
Context: ...to understand and reference. ## How It Works When you upload a file, Honcho: 1. **Ex...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~13-~13: There might be a mistake here.
Context: ...# How It Works When you upload a file, Honcho: 1. Extracts text from the file using spe...
(QB_NEW_EN_OTHER)
[grammar] ~15-~15: There might be a mistake here.
Context: ...ng specialized processors based on file type 2. Creates messages with the extracted co...
(QB_NEW_EN_OTHER)
[grammar] ~16-~16: There might be a mistake here.
Context: ... limits (messages are limited to 50,000 characters) 3. Queues processing for background analy...
(QB_NEW_EN_OTHER)
[grammar] ~17-~17: There might be a mistake here.
Context: ...s and insight derivation like any other message The file content becomes part of the pee...
(QB_NEW_EN_OTHER)
[grammar] ~19-~19: Use correct spacing
Context: ...or natural language queries and context retrieval. ## Supported File Types Honcho currently s...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~21-~21: Use correct spacing
Context: ...d context retrieval. ## Supported File Types Honcho currently supports the following ...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~23-~23: There might be a mistake here.
Context: ...s the following file types with more to come: - PDF files (application/pdf) - Text ...
(QB_NEW_EN_OTHER)
[grammar] ~25-~25: There might be a problem here.
Context: ...es with more to come: - PDF files (application/pdf) - Text extraction with page numbers - **Text f...
(QB_NEW_EN_MERGED_MATCH)
[grammar] ~26-~26: There might be a mistake here.
Context: ...ion with page numbers - Text files (text/*) - Plain text, markdown, code files, e...
(QB_NEW_EN_OTHER)
[grammar] ~26-~26: Use hyphens correctly
Context: ...ge numbers - Text files (text/*) - Plain text, markdown, code files, etc. - **JS...
(QB_NEW_EN_OTHER_ERROR_IDS_29)
[grammar] ~27-~27: There might be a mistake here.
Context: ...own, code files, etc. - JSON files (application/json) - Structured data converted to readab...
(QB_NEW_EN_OTHER)
[grammar] ~27-~27: Use hyphens correctly
Context: ... - JSON files (application/json) - Structured data converted to readable format <Not...
(QB_NEW_EN_OTHER_ERROR_IDS_29)
[grammar] ~27-~27: Use correct spacing
Context: ...- Structured data converted to readable format Files are processed in memory and not stored on disk. Only the extracted text content is preserved in Honcho's message system. ## Basic Usage ### Upload a Single File <...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~33-~33: Use correct spacing
Context: ...cho's message system. ## Basic Usage ### Upload a Single File ```pyt...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~35-~35: Use correct spacing
Context: ...e> ## Basic Usage ### Upload a Single File ```python Python from honcho import Honcho # Initialize client honcho = Honcho() # C...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~41-~41: There might be a mistake here.
Context: ...from honcho import Honcho # Initialize client honcho = Honcho() # Create session and ...
(QB_NEW_EN_OTHER)
[grammar] ~42-~42: Use correct spacing
Context: ...rt Honcho # Initialize client honcho = Honcho() # Create session and peer session = honcho...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~44-~44: There might be a mistake here.
Context: ...honcho = Honcho() # Create session and peer session = honcho.session("research-sessi...
(QB_NEW_EN_OTHER)
[grammar] ~46-~46: Use correct spacing
Context: ...ncho.session("research-session") user = honcho.peer("researcher") # Upload a PDF to a session with open("res...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~49-~49: Use correct spacing
Context: ...ith open("research_paper.pdf", "rb") as file: messages = session.upload_file( file=fil...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~50-~50:
Context: ...per.pdf", "rb") as file: messages = session.upload_file( file=file, peer_id=user.id, ) print(f...
(QB_NEW_EN_OTHER_ERROR_IDS_)
[grammar] ~52-~52: Use correct spacing
Context: ...upload_file( file=file, peer_id=user.id, ) print(f"Created {len(messages)} messag...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~55-~55: Use correct spacing
Context: ...eated {len(messages)} messages from the PDF") typescript TypeScript import { Honcho } from "@honcho-ai/sdk"; import fs from "fs"; // Initialize client const honcho = new Honcho({}); // Create session and peer const session = honcho.session("research-session"); const user = honcho.peer("researcher"); // Upload a PDF to a session const fileStream = fs.createReadStream("research_paper.pdf"); const messages = await session.uploadFile({ file: fileStream, peerId: user.id, }); console.log(Created ${messages.length} messages from the PDF); ``` ### Upload to Peer's Global Representation ...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~80-~80: Use correct spacing
Context: ...CodeGroup> ### Upload to Peer's Global Representation ```python Python # Upload files directly to a peer's global representation with open("personal_notes.pdf", "rb") as file: messages = user.upload_file( file=file, ) print(f"Added {len(messages)} messages t...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~90-~90: Use correct spacing
Context: ...ssages)} messages to {user.id}'s global representation") typescript TypeScript // Upload files directly to a peer's global representation const fileStream = fs.createReadStream("personal_notes.pdf"); const messages = await user.uploadFile({ file: fileStream, }); console.log(Added ${messages.length} messages to ${user.id}'s global representation); ``` ## Upload Parameters The upload methods ac...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~104-~104: Use correct spacing
Context: ...entation`); ``` ## Upload Parameters The upload methods accept the following ...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~106-~106: There might be a mistake here.
Context: ...The upload methods accept the following parameters: | Parameter | Type | Required | Descrip...
(QB_NEW_EN_OTHER)
[grammar] ~111-~111: There might be a mistake here.
Context: ...sion only | ID of the peer creating the messages | ## File Processing Details ### Text Extra...
(QB_NEW_EN_OTHER)
[grammar] ~113-~113: Use correct spacing
Context: ...ting the messages | ## File Processing Details ### Text Extraction PDF Files: Text is ...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~115-~115: Use correct spacing
Context: ...| ## File Processing Details ### Text Extraction PDF Files: Text is extracted page by p...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~117-~117: There might be a mistake here.
Context: ...xtracted page by page with page numbers preserved: [Page 1] Introduction This document provides... [Page 2] Methodology Our approach involves... Text Files: Content is decod...
(QB_NEW_EN_OTHER)
[grammar] ~128-~128: There might be a mistake here.
Context: ...odology Our approach involves... ``` Text Files: Content is decoded using UTF-8...
(QB_NEW_EN_OTHER)
[grammar] ~128-~128: Use correct spacing
Context: ...g UTF-8, UTF-16, or Latin-1 encoding as needed. JSON Files: Structured data is convert...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~130-~130: Use correct spacing
Context: ... Structured data is converted to string format. ### Chunking Strategy Large files are autom...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~132-~132: Use correct spacing
Context: ...nverted to string format. ### Chunking Strategy Large files are automatically split into...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~134-~134: There might be a mistake here.
Context: ...seeks to break at natural boundaries if present: 1. Paragraph breaks (\n\n) 2. Line break...
(QB_NEW_EN_OTHER)
[grammar] ~139-~139: Use correct spacing
Context: ...ence endings (. ) 4. Word boundaries ( ) Each chunk becomes a separate message, m...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~141-~141: Use correct spacing
Context: ...sage, maintaining the original document structure. ## Querying Uploaded Content Once files ar...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~143-~143: Use correct spacing
Context: ...cument structure. ## Querying Uploaded Content Once files are uploaded, you can query t...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~145-~145: There might be a mistake here.
Context: ...content using Honcho's natural language interface: ```python Python # Query what was learned from the uploaded documents response = user.chat("What are the key findings from the research papers I uploaded?") print(response) # Ask about specific documents resp...
(QB_NEW_EN_OTHER)
[grammar] ~153-~153: There might be a mistake here.
Context: ...) print(response) # Ask about specific documents response = user.chat("What does the quar...
(QB_NEW_EN_OTHER)
[grammar] ~154-~154: Use correct spacing
Context: ...erly report say about revenue growth?") print(response) # Get context from the uploaded documents ...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~157-~157: There might be a mistake here.
Context: ...ext from the uploaded documents for LLM integration context = session.get_context(tokens=300...
(QB_NEW_EN_OTHER)
[grammar] ~159-~159: Use correct spacing
Context: ...ion.get_context(tokens=3000) messages = context.to_openai(assistant=assistant) typescript TypeScript // Query what was learned from the uploaded documents const response = await user.chat("What are the key findings from the research papers I uploaded?"); console.log(response); // Ask about specific documents const response2 = await user.chat("What does the quarterly report say about revenue growth?"); console.log(response2); // Get context from the uploaded documents for LLM integration const context = await session.getContext({ tokens: 3000 }); const messages = context.toOpenAI(assistant); ``` ## Error Handling ### Unsupported File Typ...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~177-~177: Use correct spacing
Context: ...(assistant); ``` ## Error Handling ### Unsupported File Types Files with unsup...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~179-~179: Use correct spacing
Context: ...## Error Handling ### Unsupported File Types Files with unsupported content types wil...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~181-~181: There might be a mistake here.
Context: ...unsupported content types will raise an exception: python try: messages = session.upload_file( file=open("image.jpg", "rb"), peer_id=user.id ) except Exception as e: print(f"Upload failed: {e}") # Error: "Could not process file image.jpg: Unsupported file type: image/jpeg" ### Missing Required Fields Ses...
(QB_NEW_EN_OTHER)
[grammar] ~194-~194: Use correct spacing
Context: ...: image/jpeg" ``` ### Missing Required Fields Session uploads require a peer_id para...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~196-~196: There might be a mistake here.
Context: ...ds Session uploads require a peer_id parameter: python # This will fail for session uploads try: messages = session.upload_file(file=file) # Missing peer_id except ValueError as e: print(f"Validation error: {e}") ## Complete Example: Document Anal...
(QB_NEW_EN_OTHER)
[grammar] ~206-~206: Use correct spacing
Context: ... ## Complete Example: Document Analysis Assistant Here's a complete example of building a ...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~208-~208: There might be a mistake here.
Context: ...example of building a document analysis assistant: ```python Python from honcho import Honcho # Initialize honcho = Honcho() sessio...
(QB_NEW_EN_OTHER)
[grammar] ~218-~218: Use correct spacing
Context: ...er = honcho.peer("analyst") assistant = honcho.peer("analysis-bot") def upload_document(file_path, descripti...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~221-~221: There might be a mistake here.
Context: ... """Upload a document and add it to the session""" with open(file_path, "rb") as fi...
(QB_NEW_EN_OTHER)
[grammar] ~227-~227: Use correct spacing
Context: ... peer_id=user.id, ) return messages def analyze_documents(): """Get AI a...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~230-~230: There might be a mistake here.
Context: ...s(): """Get AI analysis of uploaded documents""" context = session.get_context(to...
(QB_NEW_EN_OTHER)
[grammar] ~232-~232: Use correct spacing
Context: ...get_context(tokens=4000) messages = context.to_openai(assistant=assistant) # Add analysis request messages.append({ "role": "user", "content": "Please analyze all the documents I've uploaded and provide a comprehensive summary of the key findings, trends, and recommendations." }) # Call OpenAI (or your preferred LLM) # response = openai.chat.completions.create(model="gpt-4", messages=messages) # return response.choices[0].message.content return "Analysis would be generated here" # Upload multiple documents documents = [ ...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~246-~246: There might be a mistake here.
Context: ...d be generated here" # Upload multiple documents documents = [ ("quarterly_report.pdf...
(QB_NEW_EN_OTHER)
[grammar] ~250-~250: Use correct spacing
Context: ...Product Development Roadmap 2024-2025") ] for file_path, description in documents:...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~255-~255: Use correct spacing
Context: ...d {file_path}: {len(messages)} messages created") # Get AI analysis analysis = analyze_docum...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~257-~257: There might be a mistake here.
Context: ...messages)} messages created") # Get AI analysis analysis = analyze_documents() print("Do...
(QB_NEW_EN_OTHER)
[grammar] ~259-~259: Use correct spacing
Context: ...documents() print("Document Analysis:", analysis) typescript TypeScript import { Honcho } from "@honcho-ai/sdk"; import fs from "fs"; // Initialize const honcho = new Honcho({}); const session = honcho.session("document-analysis"); const user = honcho.peer("analyst"); const assistant = honcho.peer("analysis-bot"); async function uploadDocument(filePath: string, description: string) { const fileStream = fs.createReadStream(filePath); const messages = await session.uploadFile({ file: fileStream, peerId: user.id, }); return messages; } async function analyzeDocuments() { const context = await session.getContext({ tokens: 4000 }); const messages = context.toOpenAI(assistant); // Add analysis request messages.push({ role: "user", content: "Please analyze all the documents I've uploaded and provide a comprehensive summary of the key findings, trends, and recommendations." }); // Call OpenAI (or your preferred LLM) // const response = await openai.chat.completions.create({ model: "gpt-4", messages }); // return response.choices[0].message.content; return "Analysis would be generated here"; } // Upload multiple documents const documents = [ ["quarterly_report.pdf", "Q3 2024 Quarterly Financial Report"], ["market_research.pdf", "Market Analysis and Competitive Landscape"], ["product_roadmap.pdf", "Product Development Roadmap 2024-2025"] ]; for (const [filePath, description] of documents) { const messages = await uploadDocument(filePath, description); console.log(Uploaded ${filePath}: ${messages.length} messages created); } // Get AI analysis const analysis = await analyzeDocuments(); console.log("Document Analysis:", analysis); ``` ## Error Handling - **Always wrap uploads ...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~316-~316: Use correct spacing
Context: ..., analysis); ``` ## Error Handling - *Always wrap uploads in try-catch blocks...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~318-~318: There might be a mistake here.
Context: ... in try-catch blocks** for robust error handling - Validate file types before upload to a...
(QB_NEW_EN_OTHER)
[grammar] ~319-~319: There might be a mistake here.
Context: ...pes** before upload to avoid processing errors - Handle large files gracefully with pro...
(QB_NEW_EN_OTHER)
[grammar] ~320-~320: There might be a mistake here.
Context: ... large files gracefully** with progress indicators - Implement retry logic for network fail...
(QB_NEW_EN_OTHER)
[grammar] ~321-~321: Use a period to end declarative sentences
Context: ...- Implement retry logic for network failures
(QB_NEW_EN_OTHER_ERROR_IDS_25)
🪛 Ruff (0.12.2)
sdks/python/examples/multi_user_representations.py
20-20: Trailing comma missing
Add trailing comma
(COM812)
40-40: Trailing comma missing
Add trailing comma
(COM812)
45-45: Trailing comma missing
Add trailing comma
(COM812)
48-48: Trailing comma missing
Add trailing comma
(COM812)
66-66: Trailing comma missing
Add trailing comma
(COM812)
69-69: Trailing comma missing
Add trailing comma
(COM812)
74-74: Trailing comma missing
Add trailing comma
(COM812)
77-77: Trailing comma missing
Add trailing comma
(COM812)
src/crud/peer.py
107-109: Avoid specifying long messages outside the exception class
(TRY003)
108-108: Trailing comma missing
Add trailing comma
(COM812)
124-124: Trailing comma missing
Add trailing comma
(COM812)
145-145: Trailing comma missing
Add trailing comma
(COM812)
156-156: Logging statement uses f-string
(G004)
src/dialectic/chat.py
43-43: Missing return type annotation for public function dialectic_call
(ANN201)
63-63: Trailing comma missing
Add trailing comma
(COM812)
92-92: Missing return type annotation for public function dialectic_stream
(ANN201)
112-112: Trailing comma missing
Add trailing comma
(COM812)
164-164: Trailing comma missing
Add trailing comma
(COM812)
166-166: Logging statement uses f-string
(G004)
177-177: Trailing comma missing
Add trailing comma
(COM812)
183-183: Logging statement uses f-string
(G004)
198-198: Trailing comma missing
Add trailing comma
(COM812)
209-209: Logging statement uses f-string
(G004)
209-209: Trailing comma missing
Add trailing comma
(COM812)
220-220: Trailing comma missing
Add trailing comma
(COM812)
231-231: Logging statement uses f-string
(G004)
231-231: Trailing comma missing
Add trailing comma
(COM812)
237-237: Trailing comma missing
Add trailing comma
(COM812)
241-241: Trailing comma missing
Add trailing comma
(COM812)
244-244: Logging statement uses f-string
(G004)
src/utils/formatting.py
65-65: Dynamically typed expressions (typing.Any) are disallowed in observation
(ANN401)
70-70: Trailing comma missing
Add trailing comma
(COM812)
96-96: Trailing comma missing
Add trailing comma
(COM812)
171-171: Dynamically typed expressions (typing.Any) are disallowed in dt
(ANN401)
194-194: Consider moving this statement to an else block
(TRY300)
213-213: Trailing comma missing
Add trailing comma
(COM812)
229-229: Trailing comma missing
Add trailing comma
(COM812)
239-239: Trailing comma missing
Add trailing comma
(COM812)
src/utils/shared_models.py
61-61: Trailing comma missing
Add trailing comma
(COM812)
64-64: Trailing comma missing
Add trailing comma
(COM812)
78-78: Trailing comma missing
Add trailing comma
(COM812)
85-85: Trailing comma missing
Add trailing comma
(COM812)
150-150: datetime.datetime.now() called without a tz argument
(DTZ005)
158-158: Trailing comma missing
Add trailing comma
(COM812)
172-172: datetime.datetime.now() called without a tz argument
(DTZ005)
183-183: Trailing comma missing
Add trailing comma
(COM812)
src/utils/files.py
48-48: Avoid specifying long messages outside the exception class
(TRY003)
64-64: Missing return type annotation for special method __init__
Add return type annotation: None
(ANN204)
81-83: Avoid specifying long messages outside the exception class
(TRY003)
82-82: Trailing comma missing
Add trailing comma
(COM812)
140-140: Trailing comma missing
Add trailing comma
(COM812)
149-149: Trailing comma missing
Add trailing comma
(COM812)
150-150: Trailing comma missing
Add trailing comma
(COM812)
218-218: Trailing comma missing
Add trailing comma
(COM812)
222-222: Unnecessary parentheses on raised exception
Remove unnecessary parentheses
(RSE102)
src/utils/logging.py
50-50: Use explicit conversion flag
Replace with conversion flag
(RUF010)
79-79: Trailing comma missing
Add trailing comma
(COM812)
98-98: Boolean-typed positional argument in function definition
(FBT001)
98-98: Boolean default positional argument in function definition
(FBT002)
110-110: Trailing comma missing
Add trailing comma
(COM812)
172-172: Trailing comma missing
Add trailing comma
(COM812)
201-201: Trailing comma missing
Add trailing comma
(COM812)
213-213: Trailing comma missing
Add trailing comma
(COM812)
231-231: Trailing comma missing
Add trailing comma
(COM812)
249-249: format_question_eval_input is too complex (13 > 10)
(C901)
266-266: Trailing comma missing
Add trailing comma
(COM812)
305-305: Trailing comma missing
Add trailing comma
(COM812)
334-334: Trailing comma missing
Add trailing comma
(COM812)
339-339: Trailing comma missing
Add trailing comma
(COM812)
390-390: Trailing comma missing
Add trailing comma
(COM812)
400-400: Trailing comma missing
Add trailing comma
(COM812)
423-423: Boolean-typed positional argument in function definition
(FBT001)
423-423: Boolean default positional argument in function definition
(FBT002)
434-434: Trailing comma missing
Add trailing comma
(COM812)
545-545: Dynamically typed expressions (typing.Any) are disallowed in processing_result
(ANN401)
545-545: Trailing comma missing
Add trailing comma
(COM812)
551-551: Use explicit conversion flag
Replace with conversion flag
(RUF010)
555-555: Trailing comma missing
Add trailing comma
(COM812)
🔇 Additional comments (18)
docs/changelog/compatibility-guide.mdx (1)
11-32: Version update and SDK compatibility documented correctlyThe addition of Honcho API v2.1.0 as the current version with SDK v1.2.0 compatibility is properly documented and structured.
sdks/typescript/src/session.ts (1)
224-262: File upload method implementation is functionally correctThe
uploadFilemethod correctly implements file upload functionality with proper parameter structure. The method uses the correctfileparameter name and handles the file data appropriately.Note: Past review comments about type safety improvements (using specific
Messagetypes instead ofany[]and removingas anycasting) could still be addressed for better type safety, but the current implementation is functional and correct.sdks/python/examples/multi_user_representations.py (1)
1-84: Excellent demonstration of multi-user session managementThis example effectively demonstrates the new session-scoped messaging and dialectic query capabilities. The script clearly shows how different session contexts affect peer representations and responses.
sdks/typescript/src/client.ts (2)
120-154: Well-implemented deriver status methodThe
getDeriverStatusmethod provides a clean interface for checking deriver processing status with proper parameter handling and response mapping.
156-214: Robust polling implementation with comprehensive timeout handlingThe
pollDeriverStatusmethod demonstrates excellent polling patterns with adaptive sleep timing, proper timeout handling, and informative error messages. The logic correctly estimates sleep duration based on work units and prevents infinite loops.The past review suggestions about making work unit processing time configurable and correcting return type fields are still valid improvements but don't impact the method's functionality.
src/crud/peer.py (3)
14-74: Well-structured batch operationThe implementation efficiently handles both retrieval and creation of peers in a single transaction, with proper metadata and configuration updates for existing peers.
160-192: Clean implementation of peer-session relationship queryThe function correctly handles the many-to-many relationship through the session_peers table with proper filtering and ordering.
143-147: Ignore create-on-update concern for update_peerThe use of
get_or_create_peerswithinupdate_peeris intentional: Honcho’s API employs upsert semantics for all update operations, creating the resource if it doesn’t exist rather than failing fast. No change is required here.Likely an incorrect or invalid review comment.
src/utils/shared_models.py (1)
14-194: Well-designed reasoning modelsThe models provide a clean, type-safe structure for handling reasoning observations with clear separation between explicit and deductive reasoning. The helper methods in
ObservationContextandUnifiedObservationfacilitate easy conversion and manipulation of observation data.src/dialectic/chat.py (1)
129-247: Well-structured context retrieval logicThe
chatfunction effectively handles the complex logic for different query scopes (session/global) and target scenarios with clear documentation of each case. The separation between working representation and additional context retrieval is appropriate.src/utils/files.py (2)
18-92: Excellent extensible file processing architectureThe use of Protocol pattern for file processors makes the system easily extensible for new file types. The implementation properly handles different file formats with appropriate error handling.
94-122: Smart text chunking implementationThe chunking logic intelligently attempts to break at natural boundaries (paragraphs, sentences, words) rather than arbitrarily splitting text, which preserves context and readability.
src/utils/formatting.py (4)
1-29: Well-structured module setup with proper typing.The imports, Protocol definition, and constants are appropriately organized. Good use of runtime_checkable Protocol for duck typing support.
31-63: Clean formatting utility functions.Both functions are well-implemented with clear logic and proper documentation.
116-169: Well-implemented context formatting function.The function properly handles both ReasoningResponse objects and dictionaries, with good structure and edge case handling.
202-209: Simple and effective normalization function.The function correctly normalizes observations for comparison using consistent logic.
src/utils/logging.py (2)
1-22: Well-organized imports and utility function.Good module structure with proper imports at the top level and a simple, effective truncation utility.
110-110: Add missing trailing commas.{"Stream Mode": "Yes" if stream else "No"}, - ) + ), )"Created At": created_at_str or "Not specified", - }, + }, )f"\n{format_dict_as_markdown(storage_metrics, '💾 Storage Metrics')}" - ) + )Also applies to: 172-172, 201-201
⛔ Skipped due to learnings
Learnt from: Rajat-Ahuja1997 PR: plastic-labs/honcho#144 File: tests/integration/test_message_embeddings.py:128-187 Timestamp: 2025-06-26T18:35:46.478Z Learning: The honcho repository does not use trailing commas in function signatures, function calls, or object instantiation. This is consistently applied across the entire codebase including test files, and reviews should not suggest adding trailing commas.
There was a problem hiding this comment.
Actionable comments posted: 3
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (1)
src/dialectic/utils.py(1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
src/**/*.py
Instructions used from:
Sources:
📄 CodeRabbit Inference Engine
- CLAUDE.md
🧠 Learnings (1)
src/dialectic/utils.py (2)
Learnt from: CR
PR: plastic-labs/honcho#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-30T19:10:56.136Z
Learning: Applies to src/**/*.py : Explicit error handling with appropriate exception types
Learnt from: CR
PR: plastic-labs/honcho#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-30T19:10:56.136Z
Learning: Applies to src/**/*.py : Use specific exception types (ResourceNotFoundException, ValidationException, etc.)
🪛 Ruff (0.12.2)
src/dialectic/utils.py
101-101: Trailing comma missing
Add trailing comma
(COM812)
105-105: Trailing comma missing
Add trailing comma
(COM812)
112-112: Trailing comma missing
Add trailing comma
(COM812)
117-117: Trailing comma missing
Add trailing comma
(COM812)
136-136: Logging statement uses f-string
(G004)
136-136: Trailing comma missing
Add trailing comma
(COM812)
143-143: Trailing comma missing
Add trailing comma
(COM812)
180-180: _format_observations is too complex (14 > 10)
(C901)
181-181: Trailing comma missing
Add trailing comma
(COM812)
247-247: Trailing comma missing
Add trailing comma
(COM812)
263-263: Missing return type annotation for public function generate_semantic_queries
(ANN201)
269-269: Trailing comma missing
Add trailing comma
(COM812)
277-277: Trailing comma missing
Add trailing comma
(COM812)
284-284: Trailing comma missing
Add trailing comma
(COM812)
298-298: Trailing comma missing
Add trailing comma
(COM812)
305-305: Trailing comma missing
Add trailing comma
(COM812)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: test
There was a problem hiding this comment.
Actionable comments posted: 1
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (1)
tests/conftest.py(5 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
tests/**/*.py
Instructions used from:
Sources:
📄 CodeRabbit Inference Engine
- CLAUDE.md
tests/conftest.py
Instructions used from:
Sources:
📄 CodeRabbit Inference Engine
- CLAUDE.md
🧠 Learnings (1)
tests/conftest.py (3)
Learnt from: CR
PR: plastic-labs/honcho#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-30T19:10:56.136Z
Learning: Applies to tests/conftest.py : Fixtures should be defined in tests/conftest.py
Learnt from: CR
PR: plastic-labs/honcho#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-30T19:10:56.136Z
Learning: Applies to tests/**/*.py : Tests in pytest with fixtures in tests/conftest.py
Learnt from: CR
PR: plastic-labs/honcho#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-30T19:10:56.136Z
Learning: Applies to src/models.py : Feature flags on workspace, peer, and session levels
🧬 Code Graph Analysis (1)
tests/conftest.py (1)
src/utils/shared_models.py (2)
DeductiveObservation(41-48)SemanticQueries(179-184)
🪛 Ruff (0.12.2)
tests/conftest.py
318-318: Trailing comma missing
Add trailing comma
(COM812)
321-321: Trailing comma missing
Add trailing comma
(COM812)
324-324: Trailing comma missing
Add trailing comma
(COM812)
327-327: Trailing comma missing
Add trailing comma
(COM812)
330-330: Trailing comma missing
Add trailing comma
(COM812)
333-333: Trailing comma missing
Add trailing comma
(COM812)
350-350: Trailing comma missing
Add trailing comma
(COM812)
367-367: Trailing comma missing
Add trailing comma
(COM812)
🔇 Additional comments (6)
tests/conftest.py (6)
1-2: Import changes look good.The addition of
Callableis properly used in themock_langfusefixture, and the reordering of imports maintains functionality.Also applies to: 29-29
192-194: Good simplification of the function.The single-line return statement is cleaner and maintains the same functionality.
291-292: Patch target updates align with module restructuring.The migration from
src.crud.embedding_clienttosrc.embedding_client.embedding_clientcorrectly reflects the architectural changes.
336-357: Well-structured mock implementation.The critical analysis mock correctly uses the
DeductiveObservationmodel and includes the_response.thinkingattribute, properly matching the expected interface of the actual implementation.
370-377: Fixture return dictionary properly updated.The yield dictionary correctly includes all the refactored mock functions with appropriate key names matching the new architecture.
318-335: Fix trailing commas for consistency.Add trailing commas to maintain consistent code style:
patch( - "src.utils.summarizer.create_short_summary", new_callable=AsyncMock + "src.utils.summarizer.create_short_summary", new_callable=AsyncMock, ) as mock_short_summary, patch( - "src.utils.summarizer.create_long_summary", new_callable=AsyncMock + "src.utils.summarizer.create_long_summary", new_callable=AsyncMock, ) as mock_long_summary, patch( - "src.deriver.deriver.critical_analysis_call", new_callable=AsyncMock + "src.deriver.deriver.critical_analysis_call", new_callable=AsyncMock, ) as mock_critical_analysis, patch( - "src.dialectic.chat.dialectic_call", new_callable=AsyncMock + "src.dialectic.chat.dialectic_call", new_callable=AsyncMock, ) as mock_dialectic_call, patch( - "src.dialectic.chat.dialectic_stream", new_callable=AsyncMock + "src.dialectic.chat.dialectic_stream", new_callable=AsyncMock, ) as mock_dialectic_stream, patch( - "src.dialectic.utils.generate_semantic_queries", new_callable=AsyncMock + "src.dialectic.utils.generate_semantic_queries", new_callable=AsyncMock, ) as mock_semantic_queries,⛔ Skipped due to learnings
Learnt from: Rajat-Ahuja1997 PR: plastic-labs/honcho#144 File: tests/integration/test_message_embeddings.py:128-187 Timestamp: 2025-06-26T18:35:46.478Z Learning: The honcho repository does not use trailing commas in function signatures, function calls, or object instantiation. This is consistently applied across the entire codebase including test files, and reviews should not suggest adding trailing commas.
|
|
||
| # Mock semantic query generation | ||
| mock_semantic_queries.return_value = SemanticQueries( | ||
| queries=["test query 1", "test query 2"] | ||
| ) |
There was a problem hiding this comment.
🧹 Nitpick (assertive)
Semantic queries mock correctly uses the new model.
The update to return a SemanticQueries object aligns with the API changes. Consider adding a trailing comma after line 367 for consistency.
mock_semantic_queries.return_value = SemanticQueries(
- queries=["test query 1", "test query 2"]
+ queries=["test query 1", "test query 2"],
)📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| # Mock semantic query generation | |
| mock_semantic_queries.return_value = SemanticQueries( | |
| queries=["test query 1", "test query 2"] | |
| ) | |
| # Mock semantic query generation | |
| mock_semantic_queries.return_value = SemanticQueries( | |
| queries=["test query 1", "test query 2"], | |
| ) |
🧰 Tools
🪛 Ruff (0.12.2)
367-367: Trailing comma missing
Add trailing comma
(COM812)
🤖 Prompt for AI Agents
In tests/conftest.py around lines 364 to 368, add a trailing comma after the
last item in the SemanticQueries instantiation on line 367 to maintain
consistency and adhere to style guidelines.
* feat: update SDKs to core 1.2.0 * feat: 2.1.0 introduce ROTE deriver/dialectic chore: refactor repo * fix: get typescript sdk tests working again, bump version numbers * chore: cleanup * chore: update unit test provider config * fix: remove "backup" query gen * fix: remove old utils from conftest
Summary by CodeRabbit
New Features
Bug Fixes
Refactor
Documentation
Tests
Chores