Skip to content

Commit 902e1ce

Browse files
committed
feat: create moss agent as default
1 parent 76192df commit 902e1ce

File tree

18 files changed

+490
-114
lines changed

18 files changed

+490
-114
lines changed

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# 项目概述
22

3-
项目名为 `MOS-Shell` (Model-oriented Operating System Shell), 包含两个几个核心目标:
3+
项目名为 `MOS-Shell` (Model-oriented Operating System Shell), 包含几个核心目标:
44

55
1. `MOS`: 为 AI 大模型提供一个 "面向模型的操作系统", 可以将 跨设备/跨进程 的功能模块, 以 "树" 的形式提供给模型操作.
66
1. `Shell Runtime`: 为 AI Agent 提供一个持续运转的运行时 (Runtime), 联通所有功能模块 (称之为 Channel, 对标 python 的
@@ -12,6 +12,8 @@
1212

1313
目标是 AI 大模型作为大脑, 不仅可以思考, 还可以 实时/并行/有序 地操作包括 计算机/具身躯体 来进行交互.
1414

15+
更多设计思路请访问: [核心设计思想综述](https://ycnrlabqki3v.feishu.cn/wiki/QCKUwAX7tiUs4GkJTkLcMeWqneh)
16+
1517
MOS-Shell 是 Ghost In Shells (中文名: 灵枢) 项目创建的新交互范式架构, 是第二代 MOSS 架构 (完善了 ChannelApp 和
1618
Realtime-Actions 思想).
1719
第一代 MOSS 架构 (全代码驱动 + FunctionToken) 详见 [GhostOS](https://github.com/ghostInShells/ghostos)

examples/.workspace/configs/instructions/behaviors.md renamed to examples/.workspace/configs/moss_instructions/behaviors.md

File renamed without changes.

examples/.workspace/configs/instructions/persona.md renamed to examples/.workspace/configs/moss_instructions/persona.md

File renamed without changes.
Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
# from class: demo.linxu_demo.channels.no_ppt_channel:NoPPTConfig
21
ppt_list:
32
- dirname: example
43
description: 一个测试的ppt,介绍了人和AI的关系

examples/.workspace/configs/web.yaml

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
11
web_list:
2+
- id: "moss-repository"
3+
url: "https://github.com/GhostInShells/MOSShell"
4+
description: |-
5+
MOSShell 当前项目库 github 地址
26
- id: "moss-architecture-doc"
37
url: "https://ycnrlabqki3v.feishu.cn/wiki/QCKUwAX7tiUs4GkJTkLcMeWqneh"
48
description: "MOSS (模型可操作系统 - 流式代码解释器) 系统原理与应用综述"
@@ -14,25 +18,25 @@ web_list:
1418
- id: "ghostos-repository"
1519
url: "https://github.com/GhostInShells/ghostos"
1620
description: |-
17-
GhostOS 代码仓库地址,是用来做 ghost in shells 架构思想探索的验证库。
21+
GhostOS 代码仓库地址,是 2024 年用来做 ghost in shells 架构思想探索的验证库。目前已经终止迭代.
1822
- id: "moss-article"
1923
url: "https://arxiv.org/abs/2409.16120"
2024
description: |-
21-
这是我们24年研究 AI 通过全代码驱动系统的相关论文预印版
25+
这是我们24年研究 AI 通过全代码驱动系统的相关论文预印版. 是第一代 MOSS 架构思想. 现在是第二代.
2226
- id: "机械臂演示视频汇总"
2327
url: "https://ycnrlabqki3v.feishu.cn/wiki/FiOOwBKG0iSEONkGRKvcyDHOnaf"
2428
description: |-
25-
这里提供了我们 6dof jetarm 机械臂积累的展示视频
29+
这里提供了我们 6dof jetarm 机械臂积累的展示视频. 是当前 MOSShell 的展示视频之一.
2630
- id: "20年语音交互视频展示视频"
2731
url: "https://www.bilibili.com/video/BV1tK4y1a75B/?share_source=copy_web&vd_source=d16eb4aa121a670f02fa576471d30a41"
2832
description: |-
29-
朱明 20年项目中,通过微信语音控制网页,通过网页的小视频做对话式视频的案例
33+
ZhuMing 20年项目中,通过微信语音控制网页,通过网页的小视频做对话式视频的案例. 是 GhostInShells 项目理念起点的示例之一.
3034
- id: "20年语音交互控制网页游戏视频"
3135
url: "https://www.bilibili.com/video/BV1tK4y1a75B/?share_source=copy_web&vd_source=d16eb4aa121a670f02fa576471d30a41&t=290"
3236
description: |-
33-
朱明 20年项目中,通过微信语音控制网页 “方向迷宫” 小游戏的视频,将网页游戏和微信进行了跨设备的同构。
37+
ZhuMing 20年项目中,通过微信语音控制网页 “方向迷宫” 小游戏的视频,将网页游戏和微信进行了跨设备的同构。 是 MOSS 控制具身智能思路起点的示例之一.
3438
- id: "20年关于自然语言编程的视频"
3539
url: "https://www.bilibili.com/video/BV1tK4y1a75B/?share_source=copy_web&vd_source=d16eb4aa121a670f02fa576471d30a41&t=672"
3640
description: |-
37-
朱明 20年项目中,讨论到未来实现自然语言编程,对话式编程的设想。
41+
ZhuMing 20年项目中,讨论到未来实现自然语言编程,对话式编程的设想。 是 MOSS 代码驱动理念起点的示例之一.
3842

examples/miku/main.py

Lines changed: 13 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,14 @@
1212
import live2d.v3 as live2d
1313
import pygame
1414
from ghoshell_container import Container
15+
16+
current_dir = os.path.dirname(os.path.abspath(__file__))
17+
try:
18+
import miku_channels
19+
except ImportError:
20+
# 加载当前路径.
21+
sys.path.append(current_dir)
22+
1523
from miku_channels.arm import left_arm_chan, right_arm_chan
1624
from miku_channels.body import body_chan
1725
from miku_channels.elbow import left_elbow_chan, right_elbow_chan
@@ -21,40 +29,18 @@
2129
from miku_channels.head import head_chan
2230
from miku_channels.leg import left_leg_chan, right_leg_chan
2331
from miku_channels.necktie import necktie_chan
32+
from miku_provider import init_live2d, init_pygame
2433
from ghoshell_moss.core.shell import new_shell
2534
from ghoshell_moss_contrib.example_ws import workspace_container, get_example_speech
2635
import pathlib
2736

28-
# 加载当前路径.
29-
current_dir = os.path.dirname(os.path.abspath(__file__))
30-
sys.path.append(current_dir)
31-
3237
# 全局状态
33-
model: live2d.LAppModel | None = None
3438
WIDTH = 600
3539
HEIGHT = 800
3640

41+
model: live2d.LAppModel | None = None
3742

3843
# 初始化Pygame和Live2D
39-
def init_pygame():
40-
pygame.init()
41-
display = (WIDTH, HEIGHT)
42-
screen = pygame.display.set_mode(display, pygame.DOUBLEBUF | pygame.OPENGL)
43-
pygame.display.set_caption("Digital Human Demo with PyChannel")
44-
return screen, display
45-
46-
47-
# 初始化Live2D模型
48-
def init_live2d(model_path: str, container: Container):
49-
global model
50-
live2d.init()
51-
live2d.glInit()
52-
model = live2d.LAppModel()
53-
model.LoadModelJson(model_path)
54-
model.Resize(WIDTH, HEIGHT)
55-
# model.SetAutoBlinkEnable(False)
56-
# model.SetAutoBreathEnable(True)
57-
container.bind(live2d.LAppModel, model)
5844

5945

6046
async def speak(duration: float = 5.0, speed: float = 1.0, max_open: float = 0.9, min_open: float = 0.0):
@@ -160,9 +146,10 @@ async def speaking():
160146

161147
async def run_agent_and_render(container: Container, speech: Speech | None = None):
162148
# 初始化 Pygame 和 Live2D
149+
global model
163150
screen, display = init_pygame()
164151
model_path = join(dirname(__file__), "model/miku.model3.json")
165-
init_live2d(model_path, container)
152+
model = init_live2d(model_path, container)
166153

167154
# 保持窗口打开,直到用户关闭
168155
running = True
@@ -215,7 +202,7 @@ async def run_agent_and_render(container: Container, speech: Speech | None = Non
215202
def main():
216203
# 运行异步主函数
217204
with workspace_container(WORKSPACE_DIR) as container:
218-
speech = get_example_speech(container)
205+
speech = get_example_speech(container, default_speaker='saturn_zh_female_keainvsheng_tob')
219206
asyncio.run(run_agent_and_render(container, speech))
220207

221208

examples/miku/miku_provider.py

Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
import asyncio
2+
import os
3+
import sys
4+
from os.path import dirname, join
5+
6+
import live2d.v3 as live2d
7+
import pygame
8+
from ghoshell_container import Container, get_container
9+
10+
try:
11+
import miku_channels
12+
except ImportError:
13+
current_dir = os.path.dirname(os.path.abspath(__file__))
14+
sys.path.append(current_dir)
15+
16+
from miku_channels.arm import left_arm_chan, right_arm_chan
17+
from miku_channels.body import body_chan
18+
from miku_channels.elbow import left_elbow_chan, right_elbow_chan
19+
from miku_channels.expression import expression_chan
20+
from miku_channels.eye import eye_chan
21+
from miku_channels.eyebrow import eyebrow_left_chan, eyebrow_right_chan
22+
from miku_channels.head import head_chan
23+
from miku_channels.leg import left_leg_chan, right_leg_chan
24+
from miku_channels.necktie import necktie_chan
25+
from ghoshell_moss.transports.zmq_channel import ZMQChannelProvider
26+
from ghoshell_moss import Channel
27+
28+
# 全局状态
29+
model: live2d.LAppModel | None = None
30+
WIDTH = 600
31+
HEIGHT = 800
32+
33+
34+
# 初始化Pygame和Live2D
35+
def init_pygame():
36+
pygame.init()
37+
display = (WIDTH, HEIGHT)
38+
screen = pygame.display.set_mode(display, pygame.DOUBLEBUF | pygame.OPENGL)
39+
pygame.display.set_caption("Digital Human Demo with PyChannel")
40+
return screen, display
41+
42+
43+
# 初始化Live2D模型
44+
def init_live2d(model_path: str, con: Container | None = None) -> live2d.LAppModel:
45+
global model
46+
live2d.init()
47+
live2d.glInit()
48+
model = live2d.LAppModel()
49+
model.LoadModelJson(model_path)
50+
model.Resize(WIDTH, HEIGHT)
51+
# model.SetAutoBlinkEnable(False)
52+
# model.SetAutoBreathEnable(True)
53+
con = con or get_container()
54+
con.bind(live2d.LAppModel, model)
55+
return model
56+
57+
58+
def miku_body() -> Channel:
59+
head_chan.import_channels(
60+
expression_chan,
61+
# mouth_chan, 不把嘴巴给大模型调用.
62+
eye_chan,
63+
eyebrow_left_chan,
64+
eyebrow_right_chan,
65+
)
66+
body_chan.import_channels(
67+
head_chan,
68+
left_arm_chan,
69+
right_arm_chan,
70+
left_elbow_chan,
71+
right_elbow_chan,
72+
necktie_chan,
73+
left_leg_chan,
74+
right_leg_chan,
75+
)
76+
return body_chan
77+
78+
79+
async def run_game_with_zmq_provider(address: str = "tcp://localhost:5555", con: Container | None = None):
80+
# 初始化 Pygame 和 Live2D
81+
screen, display = init_pygame()
82+
model_path = join(dirname(__file__), "model/miku.model3.json")
83+
init_live2d(model_path, con=con)
84+
85+
# 保持窗口打开,直到用户关闭
86+
running = True
87+
clock = pygame.time.Clock()
88+
font = pygame.font.SysFont(None, 24)
89+
90+
# 创建一个任务来运行 agent
91+
provider = ZMQChannelProvider(
92+
address=address,
93+
container=con,
94+
)
95+
_miku = miku_body()
96+
task = asyncio.create_task(provider.arun(_miku))
97+
98+
try:
99+
while running:
100+
# 处理pygame事件
101+
for event in pygame.event.get():
102+
if event.type == pygame.QUIT:
103+
running = False
104+
105+
# 更新和绘制模型
106+
model.Update()
107+
live2d.clearBuffer(255, 255, 255, 150.0)
108+
model.Draw()
109+
110+
# 显示完成信息
111+
info_text = font.render("演示完成,按关闭按钮退出", True, (255, 255, 255))
112+
screen.blit(info_text, (10, 10))
113+
114+
pygame.display.flip()
115+
clock.tick(60)
116+
117+
# 让出控制权给其他协程,确保agent也能运行
118+
await asyncio.sleep(0.01)
119+
except KeyboardInterrupt:
120+
pass
121+
finally:
122+
# 关闭 provider.
123+
try:
124+
provider.close()
125+
await task
126+
except asyncio.CancelledError:
127+
pass
128+
# 清理资源
129+
live2d.dispose()
130+
pygame.quit()
131+
132+
133+
async def run_provider(address: str = "tcp://localhost:5555"):
134+
_body_chan = miku_body()
135+
provider = ZMQChannelProvider(
136+
address=address,
137+
container=get_container(),
138+
)
139+
140+
try:
141+
await provider.arun(_body_chan)
142+
except KeyboardInterrupt:
143+
pass

examples/moss/README.md

Lines changed: 0 additions & 4 deletions
This file was deleted.

examples/moss/__init__.py

Whitespace-only changes.

0 commit comments

Comments
 (0)