Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
94 commits
Select commit Hold shift + click to select a range
b90aa67
feat: design ACP AgentSession kernel
ngoclam9415 Jul 16, 2026
b699d0f
docs: revise ACP AgentSession architecture
ngoclam9415 Jul 16, 2026
d0e7a98
docs: approve ACP AgentSession design
ngoclam9415 Jul 16, 2026
6613043
feat: define session journal facts and protected state
ngoclam9415 Jul 16, 2026
ec16753
feat: add sqlite and postgres session journals
ngoclam9415 Jul 16, 2026
8565f3c
feat: project journal conversation and host events
ngoclam9415 Jul 16, 2026
650b21f
feat: add durable text AgentSession
ngoclam9415 Jul 16, 2026
2de5c60
feat: migrate timelines into session journals
ngoclam9415 Jul 16, 2026
ccacdb8
feat: expose Dana over ACP stdio
ngoclam9415 Jul 16, 2026
69c6cb9
feat: cut over durable ACP conversation
ngoclam9415 Jul 16, 2026
d6c0abc
docs: add D1 briefing and manual test scripts
ngoclam9415 Jul 17, 2026
78163bf
chore: gitignore local v2 planning notes
ngoclam9415 Jul 28, 2026
afccf6c
feat: add event bus substrate (S1)
ngoclam9415 Jul 28, 2026
64c2fbe
chore: gitignore local agent tool dirs and scratch
ngoclam9415 Jul 28, 2026
fa3d347
fix: un-ignore tests/unit/core/guard (project test source, not scratch)
ngoclam9415 Jul 28, 2026
f4bab56
fix: cache native tool schemas to avoid RecursionError on long sessions
ngoclam9415 Jul 28, 2026
7f5d700
test: add llm guard live test
ngoclam9415 Jul 28, 2026
3f156f7
feat: add tool execution engine + permission policy (S3)
ngoclam9415 Jul 28, 2026
ba66c41
feat: wire EventBus into STAR loop (S2)
ngoclam9415 Jul 29, 2026
551eb8c
feat: extension auto-discovery + hot reload (S4)
ngoclam9415 Jul 29, 2026
7d2b236
docs: how to extend Dana (v2.0 extensibility backbone)
ngoclam9415 Jul 29, 2026
c188001
Merge pull request #28 from aitomatic/feat/extensibility-backbone
ngoclam9415 Aug 2, 2026
41e4285
feat(D3): add Operations model, effect metadata, and hard-deny-wins p…
ngoclam9415 Aug 3, 2026
1581eee
feat(D2): add Tool Execution Engine with cooperative latency and isol…
ngoclam9415 Aug 3, 2026
81f6167
fix(D2): cancellation race in isolated worker path, check-then-act ra…
ngoclam9415 Aug 3, 2026
946287a
feat(D2): add cancellation trees and kill escalation
ngoclam9415 Aug 3, 2026
1df159b
feat(D2): add Durable Jobs with cascade/detach
ngoclam9415 Aug 3, 2026
8fceca1
feat(D3): add Permission Modes and grant store
ngoclam9415 Aug 3, 2026
d5d68b8
feat(D3): add PolicyEvaluator, populate affected_locations, fix locat…
ngoclam9415 Aug 3, 2026
89ba184
feat(D2): extend ACP translation with tool states
ngoclam9415 Aug 3, 2026
8bb29d7
feat(D3): add ACP permission adapter, Policy Preflight, and mode stat…
ngoclam9415 Aug 4, 2026
577fc5f
feat(D3): add session/request_permission handler, wire PolicyEvaluato…
ngoclam9415 Aug 4, 2026
f15c829
feat(D5): MCP handshake, tools/list discovery, and schema conversion
ngoclam9415 Aug 4, 2026
c6c1698
feat(D5): stdio and HTTP MCP transport adapters
ngoclam9415 Aug 4, 2026
8a868ea
feat(D5): remove ad hoc MCP clients after official-protocol parity
ngoclam9415 Aug 4, 2026
6c27a10
feat(D4): add ACP model state, provider-neutral Conversation View, pr…
ngoclam9415 Aug 4, 2026
5267ea9
feat(mcp): D5 catalog adapter, namespaced identity, leases, and config
ngoclam9415 Aug 4, 2026
ef0d5e2
feat(d6): content normalization, MIME/size checks, and artifact store
ngoclam9415 Aug 4, 2026
cc976fe
test(d6): add edge case tests for content normalization and artifact …
ngoclam9415 Aug 4, 2026
7a1662f
fix(D6): schema migration v1→v2, reject embedded_resource path, remov…
ngoclam9415 Aug 4, 2026
33626f2
feat(D5): add MCP execution adapter, cancellation tracker, restore ha…
ngoclam9415 Aug 5, 2026
4c5db0f
feat(D6): add multimodal Conversation View blocks, ACP attachment con…
ngoclam9415 Aug 5, 2026
75fec8b
fix(D5): route MCP tools through remote adapter in execute/execute_as…
ngoclam9415 Aug 5, 2026
220fa9a
feat(D6): add provider capability validation and content_blocks suppo…
ngoclam9415 Aug 5, 2026
849b84e
feat(D2,D4): commit Sprint 2 residue before Sprint 3 kickoff
ngoclam9415 Aug 7, 2026
feaa043
feat(D7.1,D7.2): dana-code on AgentSession — async REPL + HostEvent b…
ngoclam9415 Aug 7, 2026
79df951
fix(D7): Wave 1 review polish — Ctrl-C teardown, factory defaults, ho…
ngoclam9415 Aug 10, 2026
4a43e27
fix(D7.1): close journal repo on REPL exit — fixes shutdown hang
ngoclam9415 Aug 10, 2026
d6b73d6
fix(D7.1): default_agent_factory must not pass llm_provider/model — f…
ngoclam9415 Aug 10, 2026
d79d469
fix(D7.2): suppress duplicate user-message echo in interactive REPL
ngoclam9415 Aug 10, 2026
c555fc3
fix(D7.1): remove redundant _current_version reach-in (M1)
ngoclam9415 Aug 10, 2026
77ab2a8
fix(D7): add AgentSession accessors + fix ACP policy import (shared i…
ngoclam9415 Aug 10, 2026
3061fa5
feat(D7.3): CLI capability inheritance — permissions, slash commands,…
ngoclam9415 Aug 10, 2026
9932c03
refactor(D7): move normalized_blocks_to_text_blocks to shared content…
ngoclam9415 Aug 10, 2026
ddaee9b
feat(D7.3): multimodal input (AC #5) + journal MODEL_CHANGED (M2)
ngoclam9415 Aug 10, 2026
d652826
fix(D7): default_agent_factory builds DanaCodingAgent (coding-assista…
ngoclam9415 Aug 10, 2026
f25fde3
fix(D7): AgentSession.prompt drives the streaming STAR loop (aquery_s…
ngoclam9415 Aug 10, 2026
2ab6b8e
test(D7.4): dana-code <-> dana-acp parity smoke (host-event stream eq…
ngoclam9415 Aug 11, 2026
31c31a1
fix(D7.5): ACP request_permission outcome schema + flip D7.4 permissi…
ngoclam9415 Aug 11, 2026
b5f443d
feat(D7.5): MCP tools reachable from a host turn via single-dispatch …
ngoclam9415 Aug 11, 2026
d04ad5d
feat(D7.6): native-tool catalog for policy classification + re-enable…
ngoclam9415 Aug 13, 2026
1a95323
fix(D7.6): hard-policy gaps — bash rm -rf rule keys off bash__execute…
ngoclam9415 Aug 13, 2026
5c47915
feat(D7): interactive NEEDS_PROMPT prompt in the CLI turn (follow-up 3)
ngoclam9415 Aug 13, 2026
a5316db
feat(D7): per-tool MCP UX + per-MCP policy (Approach A2)
ngoclam9415 Aug 13, 2026
9d55a26
D8(tests): close foreign-env test leak — pytest/ruff into uv dev grou…
ngoclam9415 Aug 31, 2026
f5f8a70
D8(tests): --continue-on-collection-errors on make test/test-unit so …
ngoclam9415 Aug 31, 2026
50434bb
D8(tests): declare license = MIT (PEP 639 SPDX expression) in [project]
ngoclam9415 Aug 31, 2026
558cb2d
D8(tests): align test_reap_child_pids with D5 TERM-then-KILL escalation
ngoclam9415 Aug 31, 2026
b194ee6
D8(getattr): remove STARAgent magic __getattr__ dispatch
ngoclam9415 Aug 31, 2026
49e8346
D8(getattr): migrate test off phantom _prompt_engineer attr (was magi…
ngoclam9415 Aug 31, 2026
4b2f253
D8(getattr): regression tests for AttributeError on unknown attrs + d…
ngoclam9415 Aug 31, 2026
967204d
D8(getattr): address review findings
ngoclam9415 Aug 31, 2026
3dafe8e
D8(skills): invert greedy default to opt-in via DANA_CLAUDE_SKILLS=1
ngoclam9415 Aug 31, 2026
e156848
D8(skills): gate ClaudeCodeSkills registration on DANA_CLAUDE_SKILLS=1
ngoclam9415 Aug 31, 2026
fb89b11
D8(skills): tests for opt-in gate
ngoclam9415 Aug 31, 2026
6778113
D8(cli): lazy log-dir resolution in LLMDebugLogger (no import-time mk…
ngoclam9415 Aug 31, 2026
7fbea89
D8(cli): argparse help/version layer for all entrypoints
ngoclam9415 Aug 31, 2026
92c29d2
D8(cli): subprocess smoke tests for --help/--version/bogus-flag/bare/…
ngoclam9415 Aug 31, 2026
9a9824e
D8(session): flat re-exports — AgentSession, TextBlock, FactType, Jou…
ngoclam9415 Aug 31, 2026
8f5b3de
D8(session): AgentSession.create() convenience constructor — journal+…
ngoclam9415 Aug 31, 2026
c6bf371
D8(session): reconcile timeline persistence id with journal session i…
ngoclam9415 Aug 31, 2026
1d72760
D8(session): docs/examples/host_hello.py — 17-line host, create() -> …
ngoclam9415 Aug 31, 2026
68e33ec
D8(session): tests — flat imports, create() defaults/explicit, idempo…
ngoclam9415 Aug 31, 2026
1561100
D8(session): host_hello accepts DANA_MOCK_LLM=true (Makefile conventi…
ngoclam9415 Aug 31, 2026
d2fbbfa
D8(readme): rewrite README against verified API
ngoclam9415 Aug 31, 2026
f68f65f
D8(readme): add MIT LICENSE at repo root
ngoclam9415 Aug 31, 2026
9cdb88b
D8(readme): document DANA_CONFIG_PATH as the config override; fix mod…
ngoclam9415 Aug 31, 2026
751219d
D8(pypi): rename distribution to dana-agent; update dist-name lookups
ngoclam9415 Aug 31, 2026
0e1a1c0
D8(pypi): bump build-system setuptools floor to >=77
ngoclam9415 Aug 31, 2026
6e4967d
D8(pypi): add tag-triggered PyPI publish workflow (trusted publishing)
ngoclam9415 Aug 31, 2026
e58faf9
D8(pypi): offer pip install dana-agent in README Installation
ngoclam9415 Aug 31, 2026
5d6682f
chore(D8): doc-sweep — dana-agent install names, real streaming API i…
ngoclam9415 Aug 31, 2026
bdb977d
ci(D8): postgres service for journal contract tests + pin uv to matri…
ngoclam9415 Sep 3, 2026
62e54e8
ci(D8): two-lane CI — postgres contract only on PRs to master
ngoclam9415 Sep 3, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 63 additions & 1 deletion .github/workflows/pr-lint-and-test.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Lint + test on pull requests to protected branches
# Skips live and deep tests — those require API keys and run locally
#
# Two lanes:
# * PRs to develop + manual dispatch → fast lane, no postgres service,
# postgres parametrizations deselected (-k "not postgres")
# * PRs to master → full lane, real postgres:16 service,
# session-journal contract exercised against both backends

name: PR Lint & Test

Expand All @@ -10,6 +16,8 @@ on:

jobs:
lint-and-test:
# Fast lane: everything except PRs into master
if: github.event_name != 'pull_request' || github.base_ref != 'master'
runs-on: ubuntu-latest
strategy:
matrix:
Expand All @@ -22,6 +30,59 @@ jobs:
uses: astral-sh/setup-uv@v6
with:
enable-cache: true
# Pin uv to the matrix python — otherwise uv resolves its own
# interpreter and the "(3.12)" job name lies about what ran.
python-version: ${{ matrix.python-version }}

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}

- name: Install dependencies
run: uv sync --extra dev

- name: Lint
run: uv run ruff check dana/

- name: Run tests (no live, no deep, no postgres)
env:
DANA_MOCK_LLM: "true"
DANA_USE_REAL_LLM: "false"
# No postgres service on this lane — deselect the [postgres]
# parametrizations so they skip-by-selection instead of failing
# their CI=true-without-DSN contract check.
run: uv run pytest tests/ -m "not live and not deep" -k "not postgres" -v --maxfail=10 --tb=short --durations=10

lint-and-test-postgres:
# Full lane: only PRs into master get the real-database contract
if: github.event_name == 'pull_request' && github.base_ref == 'master'
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.12"]

services:
postgres:
image: postgres:16
env:
POSTGRES_PASSWORD: postgres
ports:
- 5432:5432
options: >-
--health-cmd "pg_isready -U postgres"
--health-interval 5s
--health-timeout 5s
--health-retries 10

steps:
- uses: actions/checkout@v4

- name: Install uv
uses: astral-sh/setup-uv@v6
with:
enable-cache: true
python-version: ${{ matrix.python-version }}

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
Expand All @@ -34,8 +95,9 @@ jobs:
- name: Lint
run: uv run ruff check dana/

- name: Run tests (no live, no deep)
- name: Run tests (no live, no deep, with postgres contract)
env:
DANA_MOCK_LLM: "true"
DANA_USE_REAL_LLM: "false"
DANA_TEST_POSTGRES_DSN: postgresql://postgres:postgres@localhost:5432/postgres
run: uv run pytest tests/ -m "not live and not deep" -v --maxfail=10 --tb=short --durations=10
96 changes: 96 additions & 0 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
# Publish dana-agent to PyPI on v* tags.
#
# Trigger chain: merge develop → master makes release-on-merge-to-master.yml
# push a `v{version}` tag (version read from pyproject.toml); that tag
# triggers this workflow, which builds sdist+wheel, verifies the tag matches
# the pyproject version, and uploads via PyPI Trusted Publishing (OIDC) —
# no API tokens stored as secrets.
#
# ONE-TIME MAINTAINER STEP (required before the first real upload):
# On pypi.org, add a Trusted Publisher for this repo — project "dana-agent",
# owner aitomatic, repository dana-runtime, workflow publish.yml,
# environment "pypi". Repeat on test.pypi.org with environment "testpypi"
# if the dry-run target is used. Until then the upload step fails with a
# trusted-publisher error (builds and checks still pass).
#
# Manual dry-runs: Actions → Publish to PyPI → Run workflow.
# - dry_run=true (default): build + twine check only, no upload.
# - testpypi=true: upload to test.pypi.org instead of pypi.org.

name: Publish to PyPI

on:
push:
tags: ["v*"]
workflow_dispatch:
inputs:
testpypi:
description: "Upload to test.pypi.org instead of pypi.org"
type: boolean
default: false
dry_run:
description: "Build and check artifacts without uploading"
type: boolean
default: true

permissions:
contents: read

jobs:
publish:
runs-on: ubuntu-latest
# Tag push → production. Manual run → testpypi environment (only used
# when actually uploading; dry runs skip the upload step).
environment: ${{ github.event_name == 'push' && 'pypi' || 'testpypi' }}
permissions:
id-token: write # PyPI Trusted Publishing (OIDC)

steps:
- name: Checkout
uses: actions/checkout@v4

- name: Install uv
uses: astral-sh/setup-uv@v6

- name: Read version from pyproject.toml
id: version
run: |
VERSION=$(grep -m1 '^version' pyproject.toml | sed 's/.*"\(.*\)"/\1/')
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
echo "Version: $VERSION"

- name: Verify tag matches pyproject version
if: github.event_name == 'push'
run: |
TAG="${GITHUB_REF_NAME}"
EXPECTED="v${{ steps.version.outputs.version }}"
if [ "$TAG" != "$EXPECTED" ]; then
echo "Tag $TAG does not match pyproject version $EXPECTED"
exit 1
fi
echo "Tag $TAG matches pyproject version $EXPECTED"

- name: Build sdist and wheel
run: |
rm -rf dist
uv build
ls -la dist/

- name: Check metadata (twine check)
run: uvx twine check dist/*

- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: dana-agent-${{ steps.version.outputs.version }}
path: dist/*

- name: Publish to PyPI
if: github.event_name == 'push' || inputs.testpypi
uses: pypa/gh-action-pypi-publish@release/v1
with:
repository-url: "${{ inputs.testpypi && 'https://test.pypi.org/legacy/' || '' }}"

- name: Publish skipped (dry run)
if: github.event_name != 'push' && !inputs.testpypi
run: echo 'Dry run — artifacts built and checked, no upload performed'
11 changes: 10 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,16 @@ data/
plans/
.repomixignore
AGENTS.md
CLAUDE.md
/sprint/
/v2/
# agent tool dirs / local scratch (NOT project source — analogous to .claude/.opencode)
.agents/
.codegraph/
.codex/
.superpowers/
memories/
release-manifest.json
repomix-output.xml

.DS_Store
.DS_Store.worktree/
88 changes: 0 additions & 88 deletions CLAUDE.md

This file was deleted.

87 changes: 87 additions & 0 deletions CONTEXT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
# Dana Agent Runtime

Dana runs stateful STAR agent conversations across terminal, ACP, and future hosts while preserving one coherent record of each session.

## Session History

**Session Journal**:
The sole durable authority for the ordered facts produced during one agent session. Facts remain available until explicit session deletion; large payloads may be retained separately as referenced artifacts.
_Avoid_: Timeline, execution log, transcript

**Owner Scope**:
The immutable tenant or principal scope that owns a Session Journal and its artifacts. Every session operation remains within this scope, including forks and projections.
_Avoid_: User field, optional tenant filter

**Journal Fact**:
An immutable, typed, and ordered statement about session activity. Content streams use bounded facts and an explicit final fact rather than treating each token as durable history.
_Avoid_: Event, log line, token delta

**Conversation View**:
The model-facing projection of a Session Journal, including the active compression checkpoint and retained recent conversation.
_Avoid_: Timeline snapshot, chat history

**Thought Summary**:
A sanitized reasoning update intentionally safe for host display and durable session history. It is distinct from hidden model reasoning and provider replay state.
_Avoid_: Chain of thought, raw reasoning

**Provider Replay State**:
Protected model-provider material required to continue a conversation faithfully. It is not host-visible session history or an ordinary Journal Fact.
_Avoid_: Thought, trace, reasoning log

**Compression Checkpoint**:
A typed, immutable Session Journal fact containing a summarized Conversation View for an exact committed sequence range. It records its projection version and provenance without replacing the facts it summarizes.
_Avoid_: Compact session, summary message

**Interrupted Turn**:
A turn that started but has no terminal Journal Fact. Partial output remains visible to hosts, while unfinished tool outcomes remain unknown and the Conversation View does not treat the partial answer as complete.
_Avoid_: Failed turn, cancelled turn

**Committed Turn**:
A turn closed by exactly one terminal Journal Fact. Only committed turn boundaries are valid fork points.
_Avoid_: Completed request

**Session Fork**:
A new Session Journal that inherits conversation history through an immutable reference to a parent session's committed turn. Parent facts are not copied into the child journal.
_Avoid_: Session copy, cloned transcript

## Tool Execution

**Tool Catalog**:
The versioned set of tools available to one session. A turn uses one immutable catalog version for both model presentation and invocation resolution.
_Avoid_: Global registry, tool list

**Tool Identity**:
The stable, provider-neutral identity of a tool within its source. Model-provider aliases and user-facing names may vary without changing journal or policy identity.
_Avoid_: Function name, display name, provider alias

**Operation**:
A normalized request to invoke a tool, described by its effects, validated arguments, and affected locations. Permission policy evaluates Operations rather than provider aliases or hard-coded tool names.
_Avoid_: Tool call dictionary, command

**Permission Mode**:
A session setting that controls when an otherwise permitted Operation requires user confirmation. Permission Modes never override hard policy.
_Avoid_: Security level, sandbox mode

**Policy Grant**:
A durable, revocable rule that allows or rejects matching Operations within an explicit Owner Scope, workspace, Tool Identity, effect, and location scope. Hard policy always overrides an allow grant.
_Avoid_: Remembered click, permission history, global wildcard

**Policy Preflight**:
A non-authorizing check that compares a workflow's declared Operations with hard policy and Policy Grants before execution. Dynamic Operations remain subject to invocation-time enforcement.
_Avoid_: Permission bypass, automatic approval

**Tool Execution Engine**:
The session-owned module that authorizes, runs, cancels, and terminalizes every tool invocation while recording its ordered Journal Facts.
_Avoid_: Tool wrapper, direct dispatch

**Cancellation Capability**:
A Tool Catalog declaration of how an invocation acknowledges cancellation. Cooperative thread tools declare and verify a maximum cancellation latency; hard cancellation requires a killable worker or acknowledged remote cancellation.
_Avoid_: Thread kill, best-effort stop

**Durable Job**:
Background work that has accepted ownership independently of its originating turn, with its own journal identity and cancellation handle. Work remains part of the parent cancellation tree until this handoff completes.
_Avoid_: Detached thread, fire-and-forget task

**MCP Lease**:
A session's scoped right to use one validated MCP server configuration and credential scope. Connection pooling is an internal optimization and does not change session ownership or tool visibility.
_Avoid_: Global MCP registration, shared server object
Loading
Loading