Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
aa3c506
chore(deps): migrate @mariozechner/pi-ai to maintained @earendil-work…
TONresistor Jun 19, 2026
ceb09d6
feat(models): add Claude Opus 4.8
TONresistor Jun 19, 2026
b363fe0
chore(cleanup): remove dead code
TONresistor Jun 26, 2026
a83f51a
refactor(dedup): share row mappers and media classification
TONresistor Jun 26, 2026
558705f
refactor(hooks): share per-hook execution in runner
TONresistor Jun 26, 2026
7994346
refactor(telegram-tools): drop dead named re-exports
TONresistor Jun 26, 2026
ecd6690
refactor(tools): remove redundant withToolErrors wrapper
TONresistor Jun 26, 2026
442d26c
refactor(sdk): dedupe jetton transfer and node-cache invalidation
TONresistor Jun 26, 2026
6bc287f
fix(tools): enforce dm-only/group-only channel scope
TONresistor Jun 26, 2026
e8abfd7
refactor(startup): break startAgent god-method into named phases
TONresistor Jun 26, 2026
208b02a
feat(deals): remove the deals trading module
TONresistor Jun 26, 2026
1aac963
fix(tools): enforce minimum access floors
TONresistor Jul 9, 2026
9c96501
fix(tasks): preserve scheduled task authority
TONresistor Jul 9, 2026
7c20f62
fix(finance): require explicit action approval
TONresistor Jul 9, 2026
d98238a
fix(runtime): keep side-effect operations serialized
TONresistor Jul 9, 2026
5f967e0
fix(finance): bind gift purchase approval to price
TONresistor Jul 9, 2026
a17b3f9
fix(tools): protect owner-private reads
TONresistor Jul 9, 2026
e1a20db
fix(mcp): cancel timed-out tool requests
TONresistor Jul 9, 2026
cff427b
fix(mcp): treat remote tools as untrusted actions
TONresistor Jul 9, 2026
93b26b1
feat(codex): support GPT-5.6 models
TONresistor Jul 10, 2026
e29d39a
fix(security): restrict external action tools
TONresistor Jul 10, 2026
81385cf
fix(mcp): bound stalled action calls
TONresistor Jul 10, 2026
18e2694
fix(workspace): reject parent symlink escapes
TONresistor Jul 10, 2026
b282731
fix(exec): enforce dedicated sender allowlist
TONresistor Jul 10, 2026
7d41524
fix(telegram): preserve send confirmations
TONresistor Jul 10, 2026
d3478ee
fix(plugins): wire bot inline runtime
TONresistor Jul 10, 2026
0747679
fix(logging): redact sensitive runtime data
TONresistor Jul 10, 2026
f434d7a
fix(runtime): align supported Node versions
TONresistor Jul 10, 2026
415aee5
fix(ton-proxy): harden process lifecycle
TONresistor Jul 10, 2026
c8598a0
feat(providers): add validated Grok Build support
TONresistor Jul 10, 2026
a59383c
fix(codex): gate unavailable Luna model
TONresistor Jul 10, 2026
31ad001
fix(telegram): prevent self-replies and duplicate sends
TONresistor Jul 10, 2026
09e1eea
fix(product): remove stale deals surfaces
TONresistor Jul 10, 2026
e7bfc2c
fix(doctor): inspect the actual workspace soul
TONresistor Jul 10, 2026
5e4e3da
fix(deps): pin patched esbuild
TONresistor Jul 10, 2026
c60704f
fix(web): use eval-free Lottie player
TONresistor Jul 10, 2026
4efd5b7
ci: batch Telegram push notifications
TONresistor Jul 10, 2026
9b392af
refactor(quality): remove dead code and centralize basics
TONresistor Jul 10, 2026
b27d3bd
refactor(providers): centralize model request policy
TONresistor Jul 10, 2026
7d014bd
refactor(dns): share ownership-safe mutations
TONresistor Jul 10, 2026
5f72c70
refactor(dex): centralize quote simulation
TONresistor Jul 10, 2026
cea0689
refactor(webui): share contracts and error responses
TONresistor Jul 10, 2026
b010005
refactor(sdk): split public types by domain
TONresistor Jul 10, 2026
7c5055c
refactor(web): split API client responsibilities
TONresistor Jul 10, 2026
b363f34
refactor(onboard): separate setup workflows
TONresistor Jul 10, 2026
2e705fb
refactor(app): extract runtime boundaries
TONresistor Jul 10, 2026
c06cb19
refactor(agent): extract loop services
TONresistor Jul 10, 2026
67eefe0
fix(refactor): refresh provider config
TONresistor Jul 10, 2026
9e2395f
fix(sdk): isolate plugin database contexts
TONresistor Jul 10, 2026
490fcea
feat(sdk): align v2 public contracts
TONresistor Jul 10, 2026
6d4fc2d
ci(sdk): verify publishable package contract
TONresistor Jul 10, 2026
41d6dbe
fix(sdk): require approval for external actions
TONresistor Jul 10, 2026
3d49843
refactor(sdk): harden TON DEX and DNS adapters
TONresistor Jul 10, 2026
a5c42fb
feat(sdk): enforce v2 capability boundaries
TONresistor Jul 10, 2026
88fa7dc
refactor(sdk): split TON analytics services
TONresistor Jul 10, 2026
c96ae43
fix(sdk): close review security gaps
TONresistor Jul 10, 2026
0bf0895
fix(telegram): report provider failures
TONresistor Jul 10, 2026
a9586d5
feat(sdk): add safe inline and highload brokers
TONresistor Jul 11, 2026
21c05df
chore(release): prepare v0.10.0
TONresistor Jul 11, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
105 changes: 58 additions & 47 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,21 @@ jobs:

- uses: actions/setup-node@v4
with:
node-version: 20
node-version-file: .nvmrc
cache: npm

- name: Install dependencies
run: npm ci

- name: Verify runtime contract
run: npm run check:runtime

- name: Build SDK workspace
run: npm run build -w packages/sdk

- name: Verify SDK package contract
run: node scripts/check-sdk-package.mjs

- name: Type check
run: npm run typecheck

Expand Down Expand Up @@ -62,7 +68,7 @@ jobs:
timeout-minutes: 25
strategy:
matrix:
node-version: [20, 22]
node-version: ["22.22.2", "24.15.0"]
steps:
- uses: actions/checkout@v4

Expand Down Expand Up @@ -90,16 +96,16 @@ jobs:
- name: Test with coverage
run: npm run test:coverage

- name: Enforce SDK coverage
run: npm run test:sdk:coverage

- name: CLI smoke test
run: node dist/cli/index.js --help

# ---- Telegram notification (after the full CI passes, pushes only) ----
# dev : one message PER COMMIT, prefixed [DEV], paced 1/sec.
# main : one clean summary of how many stable commits were merged.
# Both walk the push range (before..after), not just the HEAD commit.
# ---- Telegram notification (one summary per push, pushes only) ----
notify:
needs: [checks, test]
if: github.event_name == 'push'
if: always() && github.event_name == 'push'
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
Expand All @@ -111,33 +117,22 @@ jobs:
env:
TG_TOKEN: ${{ secrets.TELEGRAM_BOT_TOKEN }}
TG_CHAT: ${{ secrets.TELEGRAM_CHAT_ID }}
REPO: ${{ github.repository }}
BRANCH: ${{ github.ref_name }}
BEFORE: ${{ github.event.before }}
AFTER: ${{ github.sha }}
BEFORE_SHA: ${{ github.event.before }}
AFTER_SHA: ${{ github.event.after }}
CHECKS_RESULT: ${{ needs.checks.result }}
TEST_RESULT: ${{ needs.test.result }}
run: |
set -uo pipefail
ZERO=0000000000000000000000000000000000000000

# Resolve the commits in this push, oldest -> newest (merge commits excluded).
# Fallbacks (first push / force-push / unknown before) -> HEAD only.
if [ "$BEFORE" = "$ZERO" ] \
|| ! git cat-file -e "${BEFORE}^{commit}" 2>/dev/null \
|| ! git merge-base --is-ancestor "$BEFORE" "$AFTER" 2>/dev/null; then
SHAS=$(git log -1 --format=%H "$AFTER")
RANGE_OK=0
else
SHAS=$(git log --reverse --no-merges --format=%H "${BEFORE}..${AFTER}")
RANGE_OK=1
fi
NULL_SHA="0000000000000000000000000000000000000000"

COUNT=$(printf '%s\n' "$SHAS" | grep -c . || true)
if [ "$COUNT" -eq 0 ]; then echo "Nothing to notify"; exit 0; fi
if [ -z "$TG_TOKEN" ] || [ -z "$TG_CHAT" ]; then
echo "Telegram secrets not configured, skipping"
exit 0
fi

esc() { printf '%s' "$1" | sed -e 's/&/\&amp;/g' -e 's/</\&lt;/g' -e 's/>/\&gt;/g'; }
# Send one message, retrying until Telegram accepts it. IMPORTANT: no
# curl --fail here — on a 429 we must READ the body to get retry_after;
# --fail discards it, which silently drops rate-limited messages.
# Send one message, retrying until Telegram accepts it. Do not use
# curl --fail: a 429 body contains the retry_after value we need.
send() {
local text="$1" attempt resp ra
for attempt in 1 2 3 4 5 6; do
Expand All @@ -155,26 +150,42 @@ jobs:
return 1
}

if [ "$BRANCH" = "main" ]; then
# Clean summary: number of stable commits merged to main.
noun="commits"; [ "$COUNT" -eq 1 ] && noun="commit"
if [ "$RANGE_OK" = 1 ]; then
link="https://github.com/${REPO}/compare/${BEFORE}...${AFTER}"
REPO_URL="${{ github.server_url }}/${{ github.repository }}"

# One summary notification per push (avoid per-commit spam).
if [ -n "$BRANCH" ]; then
if [ "$BEFORE_SHA" = "$NULL_SHA" ] || ! git merge-base --is-ancestor "$BEFORE_SHA" "$AFTER_SHA" 2>/dev/null; then
COUNT=$(git rev-list --count "$AFTER_SHA")
RANGE="$AFTER_SHA"
URL="$REPO_URL/commits/$BRANCH"
else
COUNT=$(git rev-list --count "$BEFORE_SHA..$AFTER_SHA")
RANGE="$BEFORE_SHA..$AFTER_SHA"
URL="$REPO_URL/compare/$BEFORE_SHA...$AFTER_SHA"
fi
NOUN=commits; [ "$COUNT" = "1" ] && NOUN=commit
REPO_NAME=${REPO_URL##*/}
LABEL=$(printf '%s' "$BRANCH" | tr '[:lower:]' '[:upper:]')
TEXT="<b>[$LABEL] $REPO_NAME</b>"
if [ "$CHECKS_RESULT" = "success" ] && [ "$TEST_RESULT" = "success" ]; then
printf -v TEXT '%s\n%s %s pushed to %s' "$TEXT" "$COUNT" "$NOUN" "$BRANCH"
else
link="https://github.com/${REPO}/commit/${AFTER}"
printf -v TEXT '%s\nCI failed on %s (%s %s)' "$TEXT" "$BRANCH" "$COUNT" "$NOUN"
fi
send "🟢 <b>${COUNT}</b> stable ${noun} merged to <b>main</b>"$'\n'"<a href=\"${link}\">View changes</a>"
else
# Per-commit feed for dev (and any other non-main branch), [DEV] prefixed.
tag="[${BRANCH^^}]"

# Commit titles (HTML-escaped), oldest first, capped to avoid huge messages.
MAX=50
TITLES=$(git log --reverse --max-count="$MAX" --pretty=format:'%s' "$RANGE" \
| sed -e 's/&/\&amp;/g' -e 's/</\&lt;/g' -e 's/>/\&gt;/g')
if [ "$COUNT" -gt 1 ]; then
send "📦 <b>${COUNT}</b> commits pushed to <b>${BRANCH}</b>"
sleep 1
if [ "$COUNT" -gt "$MAX" ]; then
printf -v TITLES '%s\n… and %s more' "$TITLES" "$((COUNT - MAX))"
fi
# Multiple commits: collapse the title list into an expandable quote.
printf -v TEXT '%s\n\n<blockquote expandable>%s</blockquote>' "$TEXT" "$TITLES"
elif [ -n "$TITLES" ]; then
printf -v TEXT '%s\n\n<blockquote>%s</blockquote>' "$TEXT" "$TITLES"
fi
for sha in $SHAS; do
title=$(esc "$(git log -1 --format=%s "$sha")")
url="https://github.com/${REPO}/commit/${sha}"
send "${tag} <b>${title}</b>"$'\n'"<a href=\"${url}\">${sha:0:7}</a>"
sleep 1
done
printf -v TEXT '%s\n\n<a href="%s">View commits</a>' "$TEXT" "$URL"
send "$TEXT"
fi
14 changes: 9 additions & 5 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:

- uses: actions/setup-node@v4
with:
node-version: 20
node-version-file: .nvmrc
cache: npm
cache-dependency-path: |
package-lock.json
Expand All @@ -27,13 +27,17 @@ jobs:
- run: npm ci
- run: cd web && npm ci
- run: npm run build -w packages/sdk
- run: node scripts/check-sdk-package.mjs
- run: npm run typecheck
- run: npm run build
- run: node dist/cli/index.js --help

- name: Run tests
run: npx vitest run

- name: Enforce SDK coverage
run: npm run test:sdk:coverage

- uses: actions/upload-artifact@v4
with:
name: dist
Expand All @@ -52,7 +56,7 @@ jobs:

- uses: actions/setup-node@v4
with:
node-version: 20
node-version-file: .nvmrc
registry-url: https://registry.npmjs.org
cache: npm
cache-dependency-path: |
Expand Down Expand Up @@ -100,7 +104,7 @@ jobs:

- uses: actions/setup-node@v4
with:
node-version: 20
node-version-file: .nvmrc
registry-url: https://registry.npmjs.org
cache: npm

Expand All @@ -117,7 +121,7 @@ jobs:
echo "publish=false" >> "$GITHUB_OUTPUT"
fi

- name: Install root deps (for @types/node hoisting)
- name: Install dependencies
if: steps.check.outputs.publish == 'true'
run: npm ci

Expand Down Expand Up @@ -167,7 +171,7 @@ jobs:

# ---- GitHub Release ----
create-release:
needs: [publish-npm]
needs: [publish-npm, publish-sdk, publish-docker]
runs-on: ubuntu-latest
timeout-minutes: 10
permissions:
Expand Down
1 change: 1 addition & 0 deletions .npmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
engine-strict=true
2 changes: 1 addition & 1 deletion .nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
20
22.22.2
41 changes: 40 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,38 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

## [0.10.0] - 2026-07-11

### Added

- **GPT-5.6 Codex support** with Sol and Terra model resolution. Luna support is available only behind `TELETON_ENABLE_CODEX_LUNA=true` for controlled backend revalidation.
- **Validated Grok Build provider** with CLI authentication and runtime checks.
- **Claude Opus 4.8** in the shared model catalog.
- **Plugin SDK 2.1** with typed capability contracts, protected low-level TON sends, get-method execution, DeDust/STON.fi brokers, inline-bot operations, Highload Wallet support, isolated storage/secrets/database access, and explicit approval metadata for external actions.
- SDK package verification, coverage enforcement, and independent npm publication through the release workflow.

### Changed

- Migrated the LLM client from deprecated `@mariozechner/pi-ai` to maintained `@earendil-works/pi-ai`.
- Refactored the agent loop, application startup, onboarding, WebUI contracts, provider policy, DEX/DNS adapters, and SDK type surface into smaller shared modules.
- **Breaking:** raised the supported runtime baseline to Node.js `^22.22.2`, `^24.15.0`, or `>=26.0.0`.
- **Breaking:** removed the obsolete Deals trading module and its stale CLI/WebUI surfaces.
- Plugin execution now enforces SDK capability boundaries, channel scopes, minimum access floors, creator authority for scheduled tasks, and approval gates for external actions.
- CI Telegram notifications now batch every pushed commit into one expandable message.

### Fixed

- Provider quota and runtime failures now produce a clear Telegram error instead of leaving the user without a response.
- Prevented Telegram self-replies, duplicate sends, and false send confirmations; restored bot inline runtime wiring.
- Serialized side-effect operations and bounded stalled MCP/tool calls without retrying non-cancellable financial actions.
- Hardened workspace symlink containment, exec sender allowlists, plugin databases, private reads, log redaction, TON Proxy lifecycle, DEX/DNS transactions, and remote MCP tool trust.
- Bound gift purchases to the approved live price and protected owner-only financial data.
- Replaced eval-based Lottie rendering and pinned patched dependency versions.

### Removed

- Dead helpers, exports, row/media duplicates, and the redundant tool-error wrapper.

## [0.9.0] - 2026-06-19

### Added
Expand Down Expand Up @@ -438,7 +470,14 @@ Git history rewritten to fix commit attribution (email update from `tonresistor@
- Professional distribution (npm, Docker, CI/CD)
- Pre-commit hooks and linting infrastructure

[Unreleased]: https://github.com/TONresistor/teleton-agent/compare/v0.8.1...HEAD
[Unreleased]: https://github.com/TONresistor/teleton-agent/compare/v0.10.0...HEAD
[0.10.0]: https://github.com/TONresistor/teleton-agent/compare/v0.9.0...v0.10.0
[0.9.0]: https://github.com/TONresistor/teleton-agent/compare/v0.8.6...v0.9.0
[0.8.6]: https://github.com/TONresistor/teleton-agent/compare/v0.8.5...v0.8.6
[0.8.5]: https://github.com/TONresistor/teleton-agent/compare/v0.8.4...v0.8.5
[0.8.4]: https://github.com/TONresistor/teleton-agent/compare/v0.8.3...v0.8.4
[0.8.3]: https://github.com/TONresistor/teleton-agent/compare/v0.8.2...v0.8.3
[0.8.2]: https://github.com/TONresistor/teleton-agent/compare/v0.8.1...v0.8.2
[0.8.1]: https://github.com/TONresistor/teleton-agent/compare/v0.8.0...v0.8.1
[0.8.0]: https://github.com/TONresistor/teleton-agent/compare/v0.7.5...v0.8.0
[0.7.5]: https://github.com/TONresistor/teleton-agent/compare/v0.7.4...v0.7.5
Expand Down
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ This starts the agent in watch mode with automatic restarts on file changes.

### Prerequisites

- **Node.js 20.0.0+** ([download](https://nodejs.org/))
- **Node.js 22.22.2+ LTS** ([download](https://nodejs.org/)); Node 24 requires 24.15.0+
- **npm 9+** (ships with Node.js)
- An LLM API key from any [supported provider](README.md#supported-providers) (Anthropic, OpenAI, Google, xAI, Groq, OpenRouter, Mistral, and more)
- Telegram API credentials from [my.telegram.org/apps](https://my.telegram.org/apps)
Expand Down
4 changes: 2 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# ---- Build stage ----
FROM node:20-slim AS build
FROM node:22.22.2-slim AS build

WORKDIR /app

Expand Down Expand Up @@ -30,7 +30,7 @@ RUN cd web && npm ci
RUN npm run build

# ---- Runtime stage ----
FROM node:20-slim
FROM node:22.22.2-slim

WORKDIR /app

Expand Down
Loading
Loading