Metadata-Version: 2.4
Name: aidialog
Version: 0.0.5
Summary: Read, search, edit, and persist AI dialogs stored as Jupyter notebooks
Author-email: Jeremy Howard <github@jhoward.fastmail.fm>
License: Apache-2.0
Project-URL: Repository, https://github.com/AnswerDotAI/aidialog
Project-URL: Documentation, https://AnswerDotAI.github.io/aidialog/
Keywords: nbdev
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: fastcore>=2.1.13
Provides-Extra: dev
Requires-Dist: exhash; extra == "dev"
Requires-Dist: nbformat; extra == "dev"
Dynamic: license-file

# aidialog


<!-- WARNING: THIS FILE WAS AUTOGENERATED! DO NOT EDIT! -->

`aidialog` provides the [`Dialog`](https://AnswerDotAI.github.io/aidialog/dialog.html#dialog)/[`Message`](https://AnswerDotAI.github.io/aidialog/dialog.html#message) model used by solveit and the fastai AI tooling ecosystem. An AI dialog is a Jupyter notebook whose cells are messages: notes, runnable code, and prompts with replies. Five modules build on each other:

- `aidialog.msg_parts`: the canonical [`Msg`](https://AnswerDotAI.github.io/aidialog/msg_parts.html#msg)/[`Part`](https://AnswerDotAI.github.io/aidialog/msg_parts.html#part) chat message model and its wire text form
- `aidialog.dialog`: the core [`Dialog`](https://AnswerDotAI.github.io/aidialog/dialog.html#dialog)/[`Message`](https://AnswerDotAI.github.io/aidialog/dialog.html#message) model, including plain-text rendering of Jupyter outputs
- `aidialog.ipynb`: reading and writing dialogs as `.ipynb` files
- `aidialog.hist`: conversions between dialogs, chat histories, and formatted replies
- `aidialog.dlgskill`: search and editing tools for dialogs and notebooks, registered as a pyskill

Provider session files (Claude Code transcripts, Codex rollouts) and conversation compaction live in [llmsurgery](https://github.com/AnswerDotAI/llmsurgery).

## The theory

A dialog is a conversation between a human, an AI, and an interpreter. Each message type addresses one of them and expects a certain kind of answer:

- A **prompt** asks the AI a question and holds its reply.
- A **code** message gives the interpreter source and holds its outputs.
- A **note** is read by everyone and answered by nobody.
- A **raw** message addresses no one. It is inert matter the conversation carries along.

A reply may itself contain runnable code with results, so a whole dialog can live inside one message. [`reply2dlg`](https://AnswerDotAI.github.io/aidialog/hist.html#reply2dlg) opens a reply up as a dialog and [`dlg2reply`](https://AnswerDotAI.github.io/aidialog/hist.html#dlg2reply) puts it back.

Dialogs and Jupyter notebooks both serialize to the ipynb format, but they are not the same thing. A notebook has cells. A dialog has messages. Messages can be *prompts*, which notebooks cannot express, and they make structure explicit that notebooks leave implicit. E.g a heading opens a section that runs to the next heading of the same level; an export directive marks the code that belongs to a module. The shared file format means the same tools read both. The word tells you which layer you are on. File-level tools such as `fastcore.nbio` and `exhash` speak of cells and notebooks. Everything in this library speaks of messages and dialogs.

The [`Dialog`](https://AnswerDotAI.github.io/aidialog/dialog.html#dialog) is the center of the library. Everything else is a projection of it. A storage projection must preserve everything that means something. What it does not understand it carries verbatim in metadata, and what is broken it heals rather than rejects. A transmission projection normalizes on purpose, and what it drops is written into its contract. A display projection only goes one way. The rule is to convert in, edit at the center, and project out. The function names say the same thing. Every converter has `dlg` on exactly one side.

| projection | contract | in | out |
|----|----|----|----|
| ipynb file | storage, pragmatically lossless | [`read_ipynb`](https://AnswerDotAI.github.io/aidialog/ipynb.html#read_ipynb) | [`write_ipynb`](https://AnswerDotAI.github.io/aidialog/ipynb.html#write_ipynb) |
| Claude Code session | storage | `sess2dlg` | `dlg2sess` |
| Codex thread | storage (write-only so far) |  | `dlg2thread` |
| canonical chat ([`Msg`](https://AnswerDotAI.github.io/aidialog/msg_parts.html#msg)/[`Part`](https://AnswerDotAI.github.io/aidialog/msg_parts.html#part)) | transmission, normalizing | [`chat2dlg`](https://AnswerDotAI.github.io/aidialog/hist.html#chat2dlg) | [`dlg2chat`](https://AnswerDotAI.github.io/aidialog/hist.html#dlg2chat) |
| hist (live call input) | transmission, one-way |  | [`dlg2hist`](https://AnswerDotAI.github.io/aidialog/hist.html#dlg2hist) |
| a prompt’s reply | self-similar | [`reply2dlg`](https://AnswerDotAI.github.io/aidialog/hist.html#reply2dlg) | [`dlg2reply`](https://AnswerDotAI.github.io/aidialog/hist.html#dlg2reply) |
| XML views | display, one-way |  | [`view_dlg`](https://AnswerDotAI.github.io/aidialog/dlgskill.html#view_dlg), [`msg2xml`](https://AnswerDotAI.github.io/aidialog/dlgskill.html#msg2xml) |

The session codecs (in [llmsurgery](https://github.com/AnswerDotAI/llmsurgery)) route through chat on their way to the wire: ant’s `dlg2msgs` and oai’s `dlg2items` are each `denorm_msgs(dlg2chat(...))`.

## Usage

### Installation

Install latest from the GitHub [repository](https://github.com/AnswerDotAI/aidialog):

``` sh
$ pip install git+https://github.com/AnswerDotAI/aidialog.git
```

or from [pypi](https://pypi.org/project/aidialog/):

``` sh
$ pip install aidialog
```

### Documentation

Documentation can be found hosted on this GitHub [repository](https://github.com/AnswerDotAI/aidialog)’s [pages](https://AnswerDotAI.github.io/aidialog/).

## How to use

A quick taste - create a dialog, add a message, and view it as concise XML:

``` python
from aidialog.dlgskill import *
import tempfile

p = tempfile.mkdtemp() + '/demo.ipynb'
create_dlg(p, '## A tiny dialog', 'note')
add_msg('6*7', after=find_msgs(dlg=p)[0].id, dlg=p)
view_dlg(p)
```

    <dialog name="demo"><markdown id="470ae519">## A tiny dialog</markdown><code id="c836ce0c">6*7</code></dialog>
