Skip to content
J-X0-cloudPublic

About

Marketing site and demo funnel for an AI close agent that answers from a company's own ledger and policies

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

Closewell

The AI close agent for finance teams: reconciliations, journal entries and ledger answers, grounded in your own books and cited every time.

Live demo: https://www.freelancerportfoliohub.com/jameslee/projects/closewell/index.html

Preview

Overview

This repository holds the Closewell marketing site and the agent service behind its Ledger Q&A and close workflows. The site walks a finance team from "what is it" to "book a demo", with separate paths for CFOs and controllers. The product mockups (policy workflow card, close run, policy library, cited ledger answers) are rendered from typed data in HTML and inline SVG rather than screenshots, so copy and examples can change without design work.

The agent service (agent/) is a Python FastAPI app that answers only from the company's ledger and written policies. It keeps a double-entry ledger model, matches bank lines to invoices, proposes and validates journal entries for approval, retrieves policy sections and ledger records with BM25, and streams its answer with the entries and policy sections it relied on. The Next.js site calls it server-side over HTTP.

Features

  • Four routes: homepage, Platform, For Controllers and Book a demo, each section backed by typed content in lib/data
  • Interactive mockups: rotating policy workflow (Cash / Accrual / Revenue), before/after close board with reviewer sign-off, six-tab capability explorer, four-step How it works walkthrough
  • Double-entry ledger model: accounts with normal balances, signed GL lines, balanced journal entries with reversals, trial balance, and approval-gated posting
  • Bank-to-ledger reconciliation: matches receipts to open invoices by remittance reference, exact amount or the best many-to-one invoice set, with fuzzy payer names as a fallback
    • Applies SHORT-PAY-01: small shortfalls close to 6150, larger ones and overpayments go to the Controller
    • Batch runs apply each invoice to at most one receipt and flag ambiguous exact fits
  • Journal entry proposals: cash application and short-pay write-offs from reconciliation, Day-1 accrual reversals, prepaid reclassifications with amortization schedules, and FLUX-01 flux review; every proposal is validated as balanced before it is returned
  • Grounded close agent: streaming /agent endpoint with a manual tool-use loop
    • getLedgerEntries, matchTransactions, draftJournalEntry, citePolicy, explainFlux, proposeJournalEntries tools with pydantic-validated inputs
    • Pluggable model interface: Claude through the Anthropic SDK, or a deterministic offline model when no API key is set
    • Drafts never post; anything outside policy is routed to the named reviewer
  • Cited ledger Q&A: /qa retrieves policy sections, GL lines, bank lines, invoices and account summaries with BM25 and drops any citation that was not retrieved
  • Qualified demo requests: the form submits through a server action to the service, which validates it, scores the lead by close length, ERP and role, and forwards it to a CRM webhook
  • Accessible by default: native <details> FAQ, labelled form controls and radio chips, reduced-motion support, and pages that render fully without JavaScript

Tech stack

Area Choice
Site Next.js 15 (App Router), React 19, TypeScript (strict)
Styling Hand-written CSS with design tokens, next/font/local
Service Python 3.12, FastAPI, pydantic v2, uvicorn
AI anthropic Python SDK (Claude Opus 5, adaptive thinking), offline fallback model
Retrieval Okapi BM25 over policy sections and ledger records
Tooling uv, pytest, ruff; ESLint (flat config), Prettier, pnpm
Deploy Dockerfile + railway.json for the service

Getting started

Run the agent service and the site in two terminals.

# 1. Agent service (http://localhost:8000)
cd agent
uv sync
uv run python -m closewell_agent      # set ANTHROPIC_API_KEY to use Claude; offline model otherwise

# 2. Site (http://localhost:3000)
pnpm install
cp .env.example .env.local            # API_URL points at the service
pnpm dev

Open http://localhost:3000. The interactive API docs for the service are at http://localhost:8000/docs.

Tests

cd agent
uv run pytest            # domain, reconciliation, journal, retrieval, agent and API tests
uv run ruff check .

Environment variables

Site (.env.local):

Variable Required Description
API_URL Yes Base URL of the agent service, used server-side only
NEXT_PUBLIC_SITE_URL No Canonical URL for metadata and the sitemap

Agent service (see agent/.env.example):

Variable Required Description
ANTHROPIC_API_KEY No Enables Claude; without it the deterministic offline model answers
ANTHROPIC_MODEL No Model id, defaults to claude-opus-5
LLM_PROVIDER No auto (default), anthropic or offline
AGENT_MAX_TURNS No Tool-use turns per request, defaults to 8
DEMO_WEBHOOK_URL No CRM webhook for demo requests; logged locally when unset
CORS_ORIGINS No Comma-separated browser origins, defaults to http://localhost:3000
PORT No Port to listen on, defaults to 8000

Calling the agent

curl -N http://localhost:8000/agent \
  -H 'content-type: application/json' \
  -d '{"messages":[{"role":"user","content":"Why did cloud infra rise in September?"}],"context":{"period":"2026-09"}}'

The response is newline-delimited JSON: text deltas, tool_call / tool_result activity, citation events and a final done.

Service endpoints

Method Path Description
GET /health Status and the active model
GET /accounts Chart of accounts
GET /ledger/entries GL lines filtered by account, period, counterparty, entity
GET /ledger/trial-balance Trial balance up to a period
GET /ledger/flux Period-over-period movements under FLUX-01
GET /bank-lines, /invoices Unreconciled bank lines and open invoices
GET /policies, /policies/{id}, /policies/search Policy library and section search
POST /reconciliation/match Match bank lines to open invoices
POST /journal/validate Check journal lines for balance and known accounts
POST /journal/drafts Draft an entry for approval
GET /journal/proposals Proposed close entries for a period
POST /qa Cited answer from retrieved ledger and policy passages
POST /agent Streaming close agent (NDJSON)
POST /demo-requests Validate, qualify and forward a demo request

Deploying the service

agent/Dockerfile builds the service with uv and serves it on $PORT. On Railway, point a service at this repository with the root directory set to agent; agent/railway.json selects the Dockerfile and the /health check. Set API_URL on the site to the service's URL.

Project structure

.
├── agent/                      # Python agent service
│   ├── src/closewell_agent/
│   │   ├── ledger/             # accounts, GL lines, journal entries, ledger store, policies
│   │   ├── reconciliation/     # remittance references, invoice sets, matcher
│   │   ├── journal/            # drafting, proposal engine, flux review
│   │   ├── retrieval/          # tokenizer, ledger documents, BM25 index
│   │   ├── llm/                # model interface, Anthropic client, offline model
│   │   ├── qa/                 # cited ledger Q&A
│   │   ├── agent/              # tools, prompts, run loop, NDJSON events
│   │   ├── leads/              # demo request validation, scoring, delivery
│   │   ├── api/                # FastAPI app and routes
│   │   └── fixtures/           # sample company ledger and policies (JSON)
│   ├── tests/
│   ├── Dockerfile
│   └── pyproject.toml
├── app/
│   ├── controllers/    # For Controllers page
│   ├── get-started/    # Book a demo page and its server action
│   ├── platform/       # Platform page
│   ├── globals.css     # tokens, primitives, mockups, sections
│   ├── layout.tsx
│   └── page.tsx        # homepage
├── components/
│   ├── brand/          # logo mark
│   ├── capabilities/   # capability tabs and previews
│   ├── controller/     # For Controllers sections
│   ├── demo/           # demo intro and form
│   ├── home/           # hero workflow card, shift board, how it works…
│   ├── layout/         # header, footer, backdrop
│   ├── platform/       # Platform sections
│   ├── sections/       # shared sections (roles, security, FAQ, CTA)
│   └── ui/             # Button, Badge, Card, Avatar, Icon, Sparkline…
├── lib/
│   ├── api.ts          # server-side client for the agent service
│   └── data/           # typed page content
├── public/             # fonts and images
└── types/              # content and demo-request types

Scripts

Script Description
pnpm dev Start the site dev server
pnpm build Production build of the site
pnpm start Serve the production build
pnpm lint ESLint
pnpm typecheck TypeScript, no emit
pnpm format Prettier
uv run python -m closewell_agent Start the agent service (in agent/)
uv run pytest Agent service tests (in agent/)
uv run ruff check . Lint the agent service (in agent/)

About

Marketing site and demo funnel for an AI close agent that answers from a company's own ledger and policies

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages