编程式场景
编程式场景使用 TypeScript 编写,提供完整的编程能力和 UI 自定义能力。
项目结构
my-scenario/
├── scenario.json # 场景清单配置
├── package.json # 依赖管理
├── tsconfig.json # TypeScript 配置
├── src/
│ ├── index.ts # 入口文件(必填)
│ ├── tools/
│ │ ├── index.ts # 工具定义
│ │ └── my-tool.ts # 单个工具
│ ├── components/
│ │ ├── DashboardPanel.tsx
│ │ ├── SettingsPanel.tsx
│ │ └── Sidebar.tsx
│ ├── hooks/
│ │ └── useScenarioData.ts
│ └── utils/
│ └── helpers.ts
├── prompts/
│ └── system.md
└── assets/入口文件
入口文件(src/index.ts)必须默认导出一个符合 ScenarioModule 接口的对象。
完整示例
typescript
import type {
ScenarioModule,
ScenarioModuleContext,
ScenarioToolDefinition,
} from '@aweeclaw/scenario-sdk'
import { DashboardPanel } from './components/DashboardPanel.js'
import { SettingsPanel } from './components/SettingsPanel.js'
export default {
id: 'my-scenario',
version: '1.0.0',
// ========== 清单 ==========
getManifest() {
return {
id: 'my-scenario',
version: '1.0.0',
name: 'My Scenario',
nameZh: '我的场景',
description: 'A powerful scenario',
descriptionZh: '一个强大的场景',
author: 'developer',
icon: 'Package',
category: 'development',
tags: ['demo', 'example'],
minAppVersion: '1.0.0',
permissions: ['workspace:read', 'workspace:write', 'web:search'],
dependencies: [
{ scenarioId: 'base-utils', version: '>=1.0.0' },
],
}
},
// ========== 插件定义 ==========
getPlugin() {
return {
id: 'my-scenario',
name: 'My Scenario',
nameZh: '我的场景',
icon: 'Package',
description: 'A powerful scenario',
descriptionZh: '一个强大的场景',
version: '1.0.0',
author: 'developer',
category: 'development',
tags: ['demo', 'example'],
identity: {
systemPrompt: '你是一个专业的开发助手。',
systemPromptFile: 'prompts/system.md',
securityRules: '不要执行危险操作。',
conventions: '使用 TypeScript 最佳实践。',
workflow: '1. 分析需求\n2. 设计方案\n3. 实现代码\n4. 测试验证',
},
capabilities: {
toolPacks: ['code-analysis', 'git-operations'],
modes: [
{
id: 'chat',
name: 'Chat',
nameZh: '对话',
description: '标准对话模式',
},
{
id: 'agent',
name: 'Agent',
nameZh: '代理',
description: '自主代理模式',
},
],
contextTypes: [
{ type: 'file', name: 'File', nameZh: '文件', description: '文件上下文' },
{ type: 'code', name: 'Code', nameZh: '代码', description: '代码上下文' },
],
outputFormats: ['text', 'code', 'json', 'markdown'],
},
ui: {
layout: 'dashboard-centric',
panels: [
{
id: 'dashboard',
component: 'DashboardPanel',
region: 'primary',
defaultVisible: true,
resizable: true,
minWidth: 300,
maxWidth: 800,
},
{
id: 'settings',
component: 'SettingsPanel',
region: 'secondary',
defaultVisible: false,
resizable: true,
minWidth: 250,
maxWidth: 500,
},
{
id: 'chat',
component: 'ChatPanel',
region: 'auxiliary',
defaultVisible: true,
resizable: true,
minWidth: 300,
maxWidth: 600,
},
],
sidebarItems: [
{
id: 'dashboard',
icon: 'LayoutDashboard',
label: 'Dashboard',
labelZh: '仪表盘',
component: 'DashboardPanel',
position: 0,
},
{
id: 'settings',
icon: 'Settings',
label: 'Settings',
labelZh: '设置',
component: 'SettingsPanel',
position: 1,
},
{
id: 'explorer',
icon: 'Files',
label: 'Workspace',
labelZh: '工作区',
component: 'ExplorerView',
position: 2,
},
],
statusBarItems: [
{
id: 'status',
icon: 'Activity',
label: 'Status',
labelZh: '状态',
position: 0,
},
],
defaultSidePanel: 'dashboard',
welcomeMessage: 'Welcome! How can I help you today?',
welcomeMessageZh: '欢迎!今天我能帮你做什么?',
},
dataSources: {
workspace: true,
knowledgeBase: false,
externalApi: false,
},
}
},
// ========== 工具定义 ==========
getTools(): ScenarioToolDefinition[] {
return [
{
name: 'analyze_code',
definition: {
name: 'analyze_code',
description: 'Analyze code quality and provide suggestions',
descriptionZh: '分析代码质量并提供建议',
parameters: {
type: 'object',
properties: {
code: {
type: 'string',
description: 'Code to analyze',
descriptionZh: '要分析的代码',
},
language: {
type: 'string',
description: 'Programming language',
descriptionZh: '编程语言',
enum: ['typescript', 'javascript', 'python', 'java', 'go'],
},
},
required: ['code'],
},
},
executor: async (args, context) => {
const { code, language } = args
// 执行代码分析逻辑
const lines = code.split('\n').length
return {
success: true,
data: {
lines,
language: language || 'unknown',
suggestions: [],
},
}
},
},
]
},
// ========== 组件注册 ==========
getComponents() {
return {
DashboardPanel,
SettingsPanel,
}
},
// ========== 生命周期 ==========
async onActivate(context: ScenarioModuleContext) {
context.logger.info('场景已激活')
// 注册 IPC 处理器
context.registerIpcHandler('my-scenario:get-data', async (payload) => {
return { data: 'some data' }
})
// 发布数据
context.publishData('scenario:ready', {
scenarioId: 'my-scenario',
timestamp: Date.now(),
})
},
async onDeactivate(context: ScenarioModuleContext) {
context.logger.info('场景已停用')
// 清理资源
},
async onHealthCheck() {
return [
{ name: 'module', status: 'healthy', message: 'OK' },
]
},
} satisfies ScenarioModuleScenarioModule 接口
typescript
interface ScenarioModule {
id: string
version: string
getManifest(): ScenarioManifest
getPlugin(): ScenarioPlugin
getTools(): ScenarioToolDefinition[]
getComponents?(): ScenarioComponentRegistry
getIpcHandlers?(): ScenarioIpcHandler[]
onActivate?(context: ScenarioModuleContext): Promise<void>
onDeactivate?(context: ScenarioModuleContext): Promise<void>
onHealthCheck?(): Promise<ScenarioHealthCheck[]>
}共享依赖
编程式场景的 React、zustand 等依赖不打包进场景包,而是由客户端注入。
| 依赖 | 版本 |
|---|---|
| react | ^18.3.0 |
| react-dom | ^18.3.0 |
| react/jsx-runtime | ^18.3.0 |
| zustand | ^5.0.0 |
| lucide-react | ^0.562.0 |
在 scenario.json 中声明共享依赖:
json
{
"sharedDeps": {
"react": "^18.3.0",
"react-dom": "^18.3.0",
"zustand": "^5.0.0",
"lucide-react": "^0.562.0"
}
}
