Skip to content

Split ai-chat into an abstract base with ai-chat-native and ai-chat-pty subtypes #3446

Closed

Description

@malibio

Overview

Restructure ai-chat into an abstract base with two core subtypes, ai-chat-native (NodeSpace's agent loop; local inference or BYO-Key) and ai-chat-pty (an external agent in a terminal). The AI-chat types are defined once in nodespace-types (ADR-088 §1–§2, ADR-086 §1). ai-chat-acp is named but not created until ACP is implemented.

Problem Statement

  • One concrete ai-chat type covers different shapes, with provider ∈ native | openai-compat | pty. Every mode-specific field is optional, so nothing can be required, and a native chat can carry a transcript.
  • Two definitions. AiChatNode and its sub-types exist in packages/nodespace-types/src/ai_chat.rs and again in packages/core/src/models/ai_chat_node.rs.
  • Capture keys (packages/daemon/src/services/capture_service.rs):
    • They use a capture: prefix, a misapplied ADR-063 extension prefix; these are core's own fields.
    • Four keys are undeclared (capture:agent_type, capture:started_at, capture:ended_at, capture:exit_code).
    • started_at and ended_at duplicate created_at and last_active.
    • The keys are written through update_node_unchecked, which skips validation.
  • session_status uses archived for "ended". Capture writes it, and the PTY viewer reads it (ai-chat-pty-session.svelte).
  • model does two jobs. It holds the model id for native chats and the harness name for PTY chats (ai-chat-default-model.ts).

Proposed Solution

  1. ai-chat becomes abstract, with base fields content (title), agent (nodespace, claude, codex, …), model (optional), summary (optional prose) and last_active. Base rules, inherited by every subtype: not embedded; no inbound references; local_only handling; children: any; it owns nodespace:// link decoration.
  2. ai-chat-native owns provider (native | openai-compat), turn_status, context_tokens, and (for now) the existing messages[]. Message nodes are a separate issue.
  3. ai-chat-pty owns session_status (active | ended), session_id (local_only), transcript (local_only) and exit_code. Capture writes these bare names and summary, through the validated update. started_at, ended_at and agent_type go (agent is on the base).
  4. One definition of each AI-chat type in nodespace-types; delete core's copies.
  5. Frontend: a plugin and viewer per subtype (the existing native and PTY viewers); the AI Chats list queries the base type and so gets both subtypes.
  6. No migration: reset the database.

Architecture Impact

Implements decisions/088-ai-chat-subtypes-and-message-nodes.md §1–§2 (nodespace-docs), which supersedes ADR-034 in part and ADR-061 §6's capture: names. It uses ADR-086 §6 (abstract types) and §5 (composed rules). Update architecture/ai-chat-node.md in the same PR.

Acceptance Criteria

  • ai-chat is abstract: creating one directly is refused; ai-chat-native and ai-chat-pty are core subtypes with their own typed structs (tests)
  • A query for ai-chat returns both subtypes, and the AI Chats sidebar lists both (tests)
  • Capture writes bare session_id, transcript, summary, exit_code and session_status: ended through the validated update; no capture: key, started_at or ended_at is written (test)
  • session_status is active | ended; the PTY viewer reads ended
  • agent holds the harness or nodespace; model holds only a model id
  • No AI-chat type is defined in packages/core/src/models/ai_chat_node.rs
  • Follows development/node-type-sequence.md; the node-types.md AI-chat sheets updated in the same PR
  • bun run test:changed passes; bun run quality:fix clean

Technical Specifications

Reference Files

  • packages/core/src/models/core_schemas.rs (ai-chat schema), packages/core/src/models/ai_chat_node.rs
  • packages/nodespace-types/src/ai_chat.rs
  • packages/core/src/behaviors/mod.rs (AiChatNodeBehavior)
  • packages/daemon/src/services/capture_service.rs, packages/daemon/src/services/agent_session_service.rs
  • packages/desktop-app/src/lib/components/viewers/ai-chat-node-viewer.svelte, ai-chat-pty-session.svelte, ai-chat-model-selector.svelte
  • packages/desktop-app/src/lib/services/ai-chat-default-model.ts, packages/desktop-app/src/lib/stores/ai-chats.svelte.ts, packages/desktop-app/src/lib/types/ai-chat-node.ts

Dependencies

Related Issues

Non-Goals

  • Message nodes (separate issue)
  • PTY resume, and a real derived summary (open items in ADR-088)
  • ACP support

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions