Skip to content
Closed
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
eb13c20
chore: establish Python parity baseline
rayrayraykk Sep 1, 2026
ebb99fd
fix: resolve npm executable on Windows
rayrayraykk Sep 1, 2026
427b6de
fix: execute npm through the Windows shell
rayrayraykk Sep 1, 2026
7323933
feat: align core foundation contracts
rayrayraykk Sep 1, 2026
f211989
feat: align message and event contracts
rayrayraykk Sep 1, 2026
311cffa
feat: implement Python-compatible agent state
rayrayraykk Sep 1, 2026
eac64d0
feat: implement Python-compatible permission engine
rayrayraykk Sep 1, 2026
0e972c4
feat: align tool skill and mcp layers with Python
rayrayraykk Sep 1, 2026
a69b8bc
feat: align model contracts and formatters with Python
rayrayraykk Sep 1, 2026
94e16c2
feat: align chat providers with Python
rayrayraykk Sep 1, 2026
072f897
feat: align embedding and tts with Python
rayrayraykk Sep 1, 2026
0251b82
feat: align agent core and middleware hooks with Python
rayrayraykk Sep 1, 2026
72da8a0
feat: align tracing middleware with Python
rayrayraykk Sep 1, 2026
a2b255a
feat: align local workspace with Python
rayrayraykk Sep 1, 2026
52106ba
feat: align sandbox gateway and bubblewrap workspace with Python
rayrayraykk Sep 1, 2026
dff29ef
feat: align Docker workspace with Python
rayrayraykk Sep 1, 2026
48458b4
feat: align Apple Container workspace with Python
rayrayraykk Sep 1, 2026
cbd2184
feat: align E2B workspace with Python
rayrayraykk Sep 1, 2026
01fb109
feat: align Daytona workspace with Python
rayrayraykk Sep 1, 2026
e6fb887
feat: align Kubernetes workspace with Python
rayrayraykk Sep 1, 2026
8698a4f
feat: align OpenSandbox workspace with Python
rayrayraykk Sep 1, 2026
51c51e4
feat: align RAG documents chunkers and parsers with Python
rayrayraykk Sep 1, 2026
4156b2e
feat: align vector stores with Python
rayrayraykk Sep 1, 2026
d3e4304
feat: align knowledge base with Python
rayrayraykk Sep 1, 2026
ae18be7
feat: align RAG middleware with Python
rayrayraykk Sep 1, 2026
f85a2b4
feat: align agentic memory middleware with Python
rayrayraykk Sep 1, 2026
4bbf829
feat: align mem0 memory middleware with Python
rayrayraykk Sep 1, 2026
3b373d9
feat: align ReMe memory middleware with Python
rayrayraykk Sep 1, 2026
4990d71
feat: align pipeline and console with Python
rayrayraykk Sep 1, 2026
39212d5
feat(service): add storage records and memory contract
rayrayraykk Sep 1, 2026
01ed949
feat(service): add redis storage adapter
rayrayraykk Sep 1, 2026
3175e22
feat(service): add transactional sql storage
rayrayraykk Sep 1, 2026
29ae8b4
test(service): expand storage parity contract
rayrayraykk Sep 1, 2026
b18c65e
feat(service): add access policy and message bus
rayrayraykk Sep 1, 2026
a53b2a4
feat(service): add workspace manager foundations
rayrayraykk Sep 1, 2026
b3e8a2f
feat(service): add remote workspace managers
rayrayraykk Sep 1, 2026
ce2dc18
feat(service): align runtime managers and scheduler
rayrayraykk Sep 1, 2026
c37adf1
feat(service): align access session and workspace services
rayrayraykk Sep 1, 2026
a018765
feat(service): align knowledge indexing services
rayrayraykk Sep 1, 2026
452c7de
feat(service): align chat toolkit and team runtime
rayrayraykk Sep 1, 2026
d3f47bb
feat(service): add app composition and protocol runtime
rayrayraykk Sep 1, 2026
ce7c459
ci(service): verify runtime across packages
rayrayraykk Sep 1, 2026
8546449
feat(service): add registry hubs
rayrayraykk Sep 1, 2026
c9ddcb5
feat(service): add channel runtime
rayrayraykk Sep 1, 2026
b2e5f55
feat(service): add channel platform adapters
rayrayraykk Sep 1, 2026
a5437f3
feat(service): add web-standard HTTP routes
rayrayraykk Sep 1, 2026
8001333
feat(service): complete Python-compatible HTTP surface
rayrayraykk Sep 1, 2026
92bd172
feat(desktop): adopt shared service runtime
rayrayraykk Sep 1, 2026
fa8e4e5
feat(agent): add explicit context compression tool
rayrayraykk Sep 1, 2026
88b318b
feat(channel): add interactive credential binding
rayrayraykk Sep 1, 2026
18aa8ad
feat(parity): finalize latest Python baseline
rayrayraykk Sep 1, 2026
f45ca71
ci: raise heap limit for package builds
rayrayraykk Sep 1, 2026
501ec03
ci: install ripgrep for cross-platform tests
rayrayraykk Sep 1, 2026
298068c
test: omit optional providers from package smoke
rayrayraykk Sep 1, 2026
13f1cb0
test(mcp): stabilize stdio integration across platforms
rayrayraykk Sep 1, 2026
759c68e
fix: support native paths across platforms
rayrayraykk Sep 1, 2026
1651e8b
ci: rebuild sqlite with test node runtime
rayrayraykk Sep 1, 2026
d666ac3
ci: scope sqlite rebuild to core
rayrayraykk Sep 1, 2026
ad8f0b5
ci: use supported Windows native toolchain
rayrayraykk Sep 1, 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
  •  
  •  
  •  
77 changes: 65 additions & 12 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,32 @@ on:
- main

jobs:
parity-manifest:
runs-on: ubuntu-latest
steps:
- name: Checkout TypeScript repository
uses: actions/checkout@v4

- name: Checkout pinned Python baseline
uses: actions/checkout@v4
with:
repository: agentscope-ai/agentscope
ref: 61cdeae4ffe63182f3343229aa6fbd868e30b0c5
path: python-baseline

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 20.x

- name: Test parity tooling
run: node --test scripts/parity/*.test.mjs

- name: Verify parity manifest against Python
run: >-
node scripts/parity/check-manifest.mjs
--python-root python-baseline

lint:
runs-on: ubuntu-latest
steps:
Expand All @@ -32,6 +58,9 @@ jobs:
- name: Run linter and formatter
run: pnpm run format

- name: Verify formatting produced no changes
run: git diff --exit-code

check-i18n:
runs-on: ubuntu-latest
steps:
Expand All @@ -52,7 +81,7 @@ jobs:

strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
os: [ubuntu-latest, macos-latest, windows-2022]
node-version: [20.x]

steps:
Expand All @@ -70,31 +99,55 @@ jobs:
node-version: ${{ matrix.node-version }}
cache: 'pnpm'

- name: Install ripgrep on Linux
if: runner.os == 'Linux'
run: sudo apt-get update && sudo apt-get install --yes ripgrep

- name: Install ripgrep on macOS
if: runner.os == 'macOS'
run: brew install ripgrep

- name: Install ripgrep on Windows
if: runner.os == 'Windows'
run: choco install ripgrep --yes --no-progress

- name: Install dependencies
run: pnpm install --frozen-lockfile

- name: Build agentscope package
run: pnpm run build:agentscope
env:
NODE_OPTIONS: --max-old-space-size=8192

- name: Type-check AgentScope service
run: pnpm --filter @agentscope-ai/agentscope-service typecheck

- name: Build AgentScope service package
run: pnpm run build:service
env:
NODE_OPTIONS: --max-old-space-size=8192

- name: Test package installation
shell: bash
run: |
cd packages/agentscope
npm pack
TARBALL=$(ls agentscope-ai-agentscope-*.tgz)
mkdir -p ../../test-install
cd ../../test-install
npm init -y
npm install "../packages/agentscope/$TARBALL"
node -e "const { Agent } = require('@agentscope-ai/agentscope/agent'); console.log('CJS import successful:', typeof Agent === 'function');"
node --input-type=module -e "import { Agent } from '@agentscope-ai/agentscope/agent'; console.log('ESM import successful:', typeof Agent === 'function');"
run: pnpm run test:package

- name: Build Desktop app
run: pnpm run build:desktop

- name: Rebuild SQLite native module for Node tests
run: >-
npx --yes pnpm@9.15.9
--filter @agentscope-ai/agentscope
rebuild better-sqlite3

- name: Run Desktop runtime tests
run: pnpm --filter @agentscope-ai/desktop test

- name: Run unit tests
run: pnpm run test:agentscope

- name: Run service unit tests
run: pnpm run test:service

- name: Upload test coverage
uses: actions/upload-artifact@v4
with:
Expand Down
9 changes: 5 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
</a>
<a href="https://pypi.org/project/agentscope/">
<img
src="https://img.shields.io/badge/node-18.0.0+-blue?logo=node.js"
src="https://img.shields.io/badge/node-20.0.0+-blue?logo=node.js"
alt="npm"
/>
</a>
Expand Down Expand Up @@ -43,8 +43,8 @@ rather than constraining them with strict prompts and opinionated orchestrations

## Requirements

- **Node.js**: 18.0.0 or higher (20.x recommended)
- **Package Manager**: pnpm 8.0.0+ (recommended) or npm
- **Node.js**: 20.0.0 or higher
- **Package Manager**: pnpm 9.0.0+ (recommended) or npm

## Features

Expand Down Expand Up @@ -121,7 +121,8 @@ for await (const event of agent.replyStream({})) {
This is a monorepo containing:

- `packages/agentscope`: Core AgentScope library
- `app/friday`: Example Electron application built with AgentScope
- `packages/agentscope-service`: Node.js Agent Service runtime
- `apps/desktop`: Electron desktop application built with AgentScope

## License

Expand Down
7 changes: 6 additions & 1 deletion apps/desktop/electron.vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,12 @@ export default defineConfig({
},
build: {
rollupOptions: {
external: ['@agentscope-ai/agentscope', /^@agentscope-ai\/agentscope\/.*/],
external: [
'@agentscope-ai/agentscope',
/^@agentscope-ai\/agentscope\/.*/,
'@agentscope-ai/agentscope-service',
/^@agentscope-ai\/agentscope-service\/.*/,
],
},
},
},
Expand Down
15 changes: 15 additions & 0 deletions apps/desktop/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
const { createDefaultPreset } = require('ts-jest');

const tsJestTransform = createDefaultPreset({
tsconfig: 'tsconfig.node.json',
}).transform;

/** @type {import('jest').Config} */
module.exports = {
testEnvironment: 'node',
testMatch: ['<rootDir>/test/**/*.test.ts'],
transform: tsJestTransform,
moduleNameMapper: {
'^@shared/(.*)$': '<rootDir>/src/shared/$1',
},
};
5 changes: 5 additions & 0 deletions apps/desktop/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"scripts": {
"format": "prettier --write .",
"lint": "eslint --cache .",
"test": "jest --runInBand",
"typecheck:node": "tsc --noEmit -p tsconfig.node.json --composite false",
"typecheck:web": "tsc --noEmit -p tsconfig.web.json --composite false",
"typecheck": "pnpm run typecheck:node && pnpm run typecheck:web",
Expand All @@ -22,6 +23,7 @@
},
"dependencies": {
"@agentscope-ai/agentscope": "workspace:*",
"@agentscope-ai/agentscope-service": "workspace:*",
"@electron-toolkit/preload": "^3.0.2",
"@electron-toolkit/utils": "^4.0.0",
"@milkdown/components": "^7.19.0",
Expand Down Expand Up @@ -70,6 +72,7 @@
"@tailwindcss/typography": "^0.5.19",
"@types/mime-types": "^3.0.1",
"@types/node": "^22.19.11",
"@types/jest": "^30.0.0",
"@types/node-cron": "^3.0.11",
"@types/react": "^19.2.7",
"@types/react-dom": "^19.2.3",
Expand All @@ -81,10 +84,12 @@
"eslint-plugin-react": "^7.37.5",
"eslint-plugin-react-hooks": "^7.0.1",
"eslint-plugin-react-refresh": "^0.4.24",
"jest": "^30.2.0",
"prettier": "^3.7.4",
"react": "^19.2.1",
"react-dom": "^19.2.1",
"typescript": "^5.9.3",
"ts-jest": "^29.4.6",
"vite": "^7.2.6"
}
}
31 changes: 0 additions & 31 deletions apps/desktop/src/main/agent/index.ts

This file was deleted.

12 changes: 9 additions & 3 deletions apps/desktop/src/main/config/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,15 +68,21 @@ export function setConfig(updates: Partial<Config>): Config {
* Register IPC handlers for configuration management
*
* @param ipcMain - The Electron IPC main instance
* @param onChange - Optional callback after configuration persistence
*/
export function registerConfigHandlers(ipcMain: IpcMain): void {
export function registerConfigHandlers(
ipcMain: IpcMain,
onChange?: (config: Config) => Promise<void>
): void {
initConfig();

ipcMain.handle('config:get', () => {
return getConfig();
});

ipcMain.handle('config:set', (_event, updates: Partial<Config>) => {
return setConfig(updates);
ipcMain.handle('config:set', async (_event, updates: Partial<Config>) => {
const config = setConfig(updates);
await onChange?.(config);
return config;
});
}
33 changes: 20 additions & 13 deletions apps/desktop/src/main/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@ import { join } from 'path';
import { electronApp, optimizer, is } from '@electron-toolkit/utils';
import { app, shell, BrowserWindow, ipcMain, Tray, Menu, nativeImage, dialog } from 'electron';

import { registerConfigHandlers } from './config';
import { shutdownScheduler } from './scheduler';
import { getConfig, registerConfigHandlers } from './config';
import { DesktopServiceRuntime } from './runtime';
import { registerChatHandlers } from './services/chatService';
import { registerDocumentHandlers } from './services/documentService';
import { registerMcpHandlers } from './services/mcpHandlers';
import { mcpShutdownAll } from './services/mcpService';
import { registerScheduleHandlers } from './services/scheduleService';
import { registerSkillHandlers } from './services/skillHandlers';
import { ensureDirectories } from './storage';
import { PATHS } from './storage/paths';
import icon from '../../resources/icon.png?asset';

interface AppWithQuitting extends Electron.App {
Expand All @@ -21,6 +21,7 @@ interface AppWithQuitting extends Electron.App {
(app as AppWithQuitting).isQuitting = false;

let tray: Tray | null = null;
let serviceRuntime: DesktopServiceRuntime | null = null;

/**
* Create system tray icon with menu for the application
Expand Down Expand Up @@ -140,19 +141,25 @@ app.whenReady().then(async () => {
});

// Ensure storage directories exist
ensureDirectories();

// Register IPC handlers for each module (except those needing webContents)
registerConfigHandlers(ipcMain);
registerMcpHandlers(ipcMain);
registerSkillHandlers(ipcMain);
await ensureDirectories();

serviceRuntime = await new DesktopServiceRuntime({ dataDirectory: PATHS.root }).open();
await serviceRuntime.syncConfig(getConfig());
await serviceRuntime.migrateLegacyChats();
await serviceRuntime.migrateLegacyMCPs();
await serviceRuntime.migrateLegacySchedules();
await serviceRuntime.migrateLegacySkills();
await serviceRuntime.migrateLegacyDocuments();
registerConfigHandlers(ipcMain, config => serviceRuntime!.syncConfig(config));
registerMcpHandlers(ipcMain, serviceRuntime);
registerSkillHandlers(ipcMain, serviceRuntime);

const mainWindow = createWindow();

// Register handlers that need webContents
registerDocumentHandlers(ipcMain, mainWindow.webContents);
registerChatHandlers(ipcMain, mainWindow.webContents);
await registerScheduleHandlers(ipcMain, mainWindow.webContents);
registerDocumentHandlers(ipcMain, mainWindow.webContents, serviceRuntime);
registerChatHandlers(ipcMain, mainWindow.webContents, serviceRuntime);
registerScheduleHandlers(ipcMain, mainWindow.webContents, serviceRuntime);

createTray(mainWindow);

Expand All @@ -168,7 +175,7 @@ app.whenReady().then(async () => {

app.on('before-quit', async () => {
(app as AppWithQuitting).isQuitting = true;
await Promise.allSettled([shutdownScheduler(), mcpShutdownAll()]);
await Promise.allSettled([serviceRuntime?.close()]);
});

// Don't quit when all windows are closed (hidden to tray)
Expand Down
3 changes: 3 additions & 0 deletions apps/desktop/src/main/runtime/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export { DesktopServiceRuntime } from './service-runtime';
export type { DesktopServiceRuntimeOptions } from './service-runtime';
export type { DesktopScheduleEvent } from './service-runtime';
Loading
Loading