Skip to content

Commit

Permalink
Dev broadcast agent (modelscope#33)
Browse files Browse the repository at this point in the history
  • Loading branch information
qbc2016 authored Oct 29, 2024
1 parent 0bb6ce3 commit 9cb6402
Show file tree
Hide file tree
Showing 13 changed files with 700 additions and 20 deletions.
471 changes: 471 additions & 0 deletions gallery/undercover.json

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<div>
<div class="title-box" data-class="BroadcastAgent">
<div class="title-box-left-items">
<svg class="title-box-svg" viewBox="0 0 1024 1024"
xmlns="http://www.w3.org/2000/svg">
<path d="M21.344 448h85.344v234.656H21.344V448zM554.656 192h64V106.656h-213.344V192h64v42.656h-320V896h725.344V234.656h-320V192z m234.688 128v490.656H234.688V320h554.656zM917.344 448h85.344v234.656h-85.344V448z"></path>
<path d="M341.344 512H448v106.656h-106.656V512zM576 512h106.656v106.656H576V512z"></path>
</svg>
<span>BroadcastAgent</span>
</div>
<button class="button copy-button"
i18n="agent-broadcast-Copy">Copy</button>
<span class="toggle-arrow">&#x25B2;</span></div>
<div class="box">
<div class="readme">
<span i18n="agent-broadcast-readme">
An agent that only broadcasts its content
</span>
<div>Node ID: <span class="node-id">ID_PLACEHOLDER</span></div>
</div>

<label i18n="agent-broadcast-labelName">Name</label>
<input type="text" df-args-name placeholder="Assistant"
i18n="agent-broadcast-labelName-Assistant"
data-required="true">
<br>

<label i18n="agent-broadcast-content">content</label>
<textarea type="text" df-args-content class="text-input"
data-required="true"></textarea>
</div>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<div>
<div class="title-box" data-class="node-DialogAgent">
<div class="title-box-left-items">
<svg class="title-box-svg" viewBox="0 0 1024 1024"
xmlns="http://www.w3.org/2000/svg">
<path d="M21.344 448h85.344v234.656H21.344V448zM554.656 192h64V106.656h-213.344V192h64v42.656h-320V896h725.344V234.656h-320V192z m234.688 128v490.656H234.688V320h554.656zM917.344 448h85.344v234.656h-85.344V448z"></path>
<path d="M341.344 512H448v106.656h-106.656V512zM576 512h106.656v106.656H576V512z"></path>
</svg>
<span>NAME_PLACEHOLDER</span>
</div>
<span class="toggle-arrow">&#x25B2;</span></div>
<div class="box">
<div class="readme">
README_PLACEHOLDER
<div>Copy from Node ID:
<span class="node-id">ID_PLACEHOLDER</span></div>
</div>
</div>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
<span class="toggle-arrow">&#x25B2;</span>
</div>
<div class="box">
<div class="readme" i18n="tool-image-composition-readme">Image composition Configurations</div>
<div class="readme" i18n="tool-image-composition-readme">Composite images into one image</div>
<br>
<label i18n="tool-image-composition-Titles"> Titles </label>
<textarea type="text" df-args-titles placeholder="['Title 1', 'Title 2', ... ]"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
<span class="toggle-arrow">&#x25B2;</span>
</div>
<div class="box">
<div class="readme" i18n="tool-image-motion-readme">Image Motion Configurations</div>
<div class="readme" i18n="tool-image-motion-readme">Convert an image to an mp4 or a gif by shifting the perspective</div>
<br>

<label i18n="tool-image-motion-outputPath"> Output path </label>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
<span class="toggle-arrow">&#x25B2;</span>
</div>
<div class="box">
<div class="readme" i18n="tool-post-readme">Post Configurations</div>
<div class="readme" i18n="tool-post-readme">Post a request and return the response</div>
<br>
<label> url </label>
<input type="text" df-args-url placeholder=""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
<span class="toggle-arrow">&#x25B2;</span>
</div>
<div class="box">
<div class="readme" i18n="tool-video-composition-readme">Video composition Configurations</div>
<div class="readme" i18n="tool-video-composition-readme">Composite videos into one video</div>
<br>

<label i18n="tool-video-composition-outputPath"> Output path </label>
Expand Down
13 changes: 9 additions & 4 deletions src/agentscope/studio/static/i18n/i18n_en.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,11 @@
"workstation-menu-btn-run": "Run the workflow",
"workstation-menu-btn-save": "Save workflow",
"workstation-menu-btn-workflow": "Load workflow",
"agent-broadcast-Copy": "Copy",
"agent-broadcast-readme": "An agent that only broadcasts its content",
"agent-broadcast-labelName": "Name",
"agent-broadcast-labelName-Assistant": "Assistant",
"agent-broadcast-content": "content",
"agent-dialogagent-Copy": "Copy",
"agent-dialogagent-readme": "An dialog agent that can interact with users or other agents.",
"agent-dialogagent-labelName": "Name",
Expand Down Expand Up @@ -193,23 +198,23 @@
"service-text-to-image-modelName": "Model Name",
"service-text-to-image-numberofImages": "Number of Images",
"service-text-to-image-size": "size",
"tool-image-composition-readme": "Image composition Configurations",
"tool-image-composition-readme": "Composite images into one image",
"tool-image-composition-Titles": "Titles",
"tool-image-composition-Outputpath": "Output path",
"tool-image-composition-row": "Row",
"tool-image-composition-Column": "Column",
"tool-image-composition-Spacing": "Spacing",
"tool-image-composition-titleHeight": "Title height",
"tool-image-composition-fontName": "Font name",
"tool-image-motion-readme": "Image Motion Configurations",
"tool-image-motion-readme": "Convert an image to an mp4 or a gif by shifting the perspective",
"tool-image-motion-outputPath": "Output path",
"tool-image-motion-outputFormat": "Output Format",
"tool-image-motion-labelDuration": "Duration",
"tool-image-motion-labelMotiondirection": "Motion direction",
"tool-post-readme": "Post Configurations",
"tool-post-readme": "Post a request and return the response",
"tool-post-label-outputPath": "Output path",
"tool-post-label-outputtype": "Output type",
"tool-video-composition-readme": "Video composition Configurations",
"tool-video-composition-readme": "Composite videos into one video",
"tool-video-composition-outputPath": "Output path",
"tool-video-composition-targetVideoWidth": "Target Video Width",
"tool-video-composition-targetVideoHeight": "Target Video Height",
Expand Down
13 changes: 9 additions & 4 deletions src/agentscope/studio/static/i18n/i18n_zh.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,11 @@
"workstation-menu-btn-run": "运行工作流",
"workstation-menu-btn-save": "保存工作流",
"workstation-menu-btn-workflow": "加载工作流",
"agent-broadcast-Copy": "复制",
"agent-broadcast-readme": "只会广播其内容框中文本的智能体",
"agent-broadcast-labelName": "名称",
"agent-broadcast-labelName-Assistant": "助理",
"agent-broadcast-content": "内容",
"agent-dialogagent-Copy": "复制",
"agent-dialogagent-readme": "可与用户或其他智能体互动的对话智能体。",
"agent-dialogagent-labelName": "名称",
Expand Down Expand Up @@ -193,23 +198,23 @@
"service-text-to-image-numberofImages": "图片数量",
"service-text-to-image-size": "图片尺寸",
"service-text-to-image-readme": "将文本转图像服务集成到 ReActAgent 中以增强智能体功能",
"tool-image-composition-readme": "图像合成配置",
"tool-image-composition-readme": "将多张图片合成一张",
"tool-image-composition-Titles": "标题",
"tool-image-composition-Outputpath": "输出路径",
"tool-image-composition-row": "",
"tool-image-composition-Column": "",
"tool-image-composition-Spacing": "间距",
"tool-image-composition-titleHeight": "标题高度",
"tool-image-composition-fontName": "字体名称",
"tool-image-motion-readme": "图像运动配置",
"tool-image-motion-readme": "通过视角移动将图片转化为mp4或者gif格式",
"tool-image-motion-outputPath": "输出路径",
"tool-image-motion-outputFormat": "输出格式",
"tool-image-motion-labelDuration": "持续时间",
"tool-image-motion-labelMotiondirection": "运动方向",
"tool-post-readme": "Post 配置",
"tool-post-readme": "提交Post请求并返回结果",
"tool-post-label-outputPath": "输出路径",
"tool-post-label-outputtype": "输出类型",
"tool-video-composition-readme": "视频合成配置",
"tool-video-composition-readme": "将多个视频合成一个",
"tool-video-composition-outputPath": "输出路径",
"tool-video-composition-targetVideoWidth": "目标视频宽度",
"tool-video-composition-targetVideoHeight": "目标视频高度",
Expand Down
66 changes: 58 additions & 8 deletions src/agentscope/studio/static/js/workstation.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ const nameToHtmlFile = {
"TextToImageAgent": "agent-texttoimageagent.html",
"DictDialogAgent": "agent-dictdialogagent.html",
"ReActAgent": "agent-reactagent.html",
"BroadcastAgent": "agent-broadcastagent.html",
"Placeholder": "pipeline-placeholder.html",
"MsgHub": "pipeline-msghub.html",
"SequentialPipeline": "pipeline-sequentialpipeline.html",
Expand All @@ -44,6 +45,7 @@ const nameToHtmlFile = {
// 'IF/ELSE': 'tool-if-else.html',
"ImageMotion": "tool-image-motion.html",
"VideoComposition": "tool-video-composition.html",
"CopyNode": "agent-copyagent.html"
};

const ModelNames48k = [
Expand Down Expand Up @@ -611,6 +613,7 @@ async function addNodeToDrawFlow(name, pos_x, pos_y) {
}, htmlSourceCode);
break;


// Workflow-Agent
case "DialogAgent":
const DialogAgentID = editor.addNode("DialogAgent", 1, 1,
Expand Down Expand Up @@ -693,6 +696,34 @@ async function addNodeToDrawFlow(name, pos_x, pos_y) {
}
break;

case "BroadcastAgent":
const BroadcastAgentID = editor.addNode("BroadcastAgent", 1, 1,
pos_x,
pos_y,
"BroadcastAgent", {
"args": {
"name": "",
"content": ""
}
}, htmlSourceCode);
var nodeElement = document.querySelector(`#node-${BroadcastAgentID} .node-id`);
if (nodeElement) {
nodeElement.textContent = BroadcastAgentID;
}
break;

case "CopyNode":
const CopyNodeID = editor.addNode("CopyNode", 1, 1,
pos_x,
pos_y,
"CopyNode", {
}, htmlSourceCode);
var nodeElement = document.querySelector(`#node-${CopyNodeID} .node-id`);
if (nodeElement) {
nodeElement.textContent = nodeElement;
}
break;

// Workflow-Pipeline
case "Placeholder":
editor.addNode("Placeholder", 1, 1,
Expand Down Expand Up @@ -947,7 +978,6 @@ function initializeMonacoEditor(nodeId) {
parentNode.addEventListener("DOMNodeRemoved", function () {
resizeObserver.disconnect();
});

}, function (error) {
console.error("Error encountered while loading monaco editor: ", error);
});
Expand Down Expand Up @@ -2349,20 +2379,40 @@ async function fetchHtmlSourceCodeByName(name) {

async function addHtmlAndReplacePlaceHolderBeforeImport(data) {
const idPlaceholderRegex = /ID_PLACEHOLDER/g;
const namePlaceholderRegex = /NAME_PLACEHOLDER/g;
const readmePlaceholderRegex = /README_PLACEHOLDER/g;

const classToReadmeDescription = {
"node-DialogAgent": "A dialog agent that can interact with users or other agents",
"node-UserAgent": "A proxy agent for user",
"node-TextToImageAgent": "Agent for text to image generation",
"node-DictDialogAgent": "Agent that generates response in a dict format",
"node-ReActAgent": "Agent for ReAct (reasoning and acting) with tools",
"node-BroadcastAgent": "A broadcast agent that only broadcasts the messages it receives"
};

for (const nodeId of Object.keys(data.drawflow.Home.data)) {
const node = data.drawflow.Home.data[nodeId];

if (!node.html) {
if (node.name === "readme") {
// Remove the node if its name is "readme"
delete data.drawflow.Home.data[nodeId];
continue; // Skip to the next iteration
continue;
}
console.log(node.name);
const sourceCode = await fetchHtmlSourceCodeByName(node.name);

// Add new html attribute to the node
console.log(sourceCode);
node.html = sourceCode.replace(idPlaceholderRegex, nodeId);
node.html = await fetchHtmlSourceCodeByName(node.name);

if (node.name === "CopyNode") {
node.html = node.html.replace(idPlaceholderRegex, node.data.elements[0]);
node.html = node.html.replace(namePlaceholderRegex, node.class.split("-").slice(-1)[0]);

const readmeDescription = classToReadmeDescription[node.class];
if (readmeDescription) {
node.html = node.html.replace(readmePlaceholderRegex, readmeDescription);
}
} else {
node.html = node.html.replace(idPlaceholderRegex, nodeId);
}
}
}
}
Expand Down
5 changes: 5 additions & 0 deletions src/agentscope/studio/templates/workstation.html
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,11 @@
draggable="true" ondragstart="drag(event)">
ReActAgent
</li>
<li class="workstation-sidebar-dragitem unselectable-text"
data-node="BroadcastAgent"
draggable="true" ondragstart="drag(event)">
BroadcastAgent
</li>
</ul>
</li>
<li>
Expand Down
66 changes: 66 additions & 0 deletions src/agentscope/studio/tools/broadcast_agent.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# -*- coding: utf-8 -*-
"""A dummy agent."""
from typing import Optional, Union, Sequence

from agentscope.agents import AgentBase
from agentscope.message import Msg


class BroadcastAgent(AgentBase):
"""A dummy agent used to only speak what he gets."""

def __init__(
self,
name: str,
content: str,
sys_prompt: str = None,
model_config_name: str = None,
use_memory: bool = False,
memory_config: Optional[dict] = None,
) -> None:
"""Initialize the dummy agent.
Arguments:
name (`str`):
The name of the agent.
sys_prompt (`Optional[str]`):
The system prompt of the agent, which can be passed by args
or hard-coded in the agent.
model_config_name (`str`):
The name of the model config, which is used to load model from
configuration.
use_memory (`bool`, defaults to `True`):
Whether the agent has memory.
memory_config (`Optional[dict]`):
The config of memory.
"""
super().__init__(
name=name,
sys_prompt=sys_prompt,
model_config_name=model_config_name,
use_memory=use_memory,
memory_config=memory_config,
)
self.content = content

def reply(self, x: Optional[Union[Msg, Sequence[Msg]]] = None) -> Msg:
"""Reply function of the agent. Processes the input data,
generates a prompt using the current dialogue memory and system
prompt, and invokes the language model to produce a response. The
response is then formatted and added to the dialogue memory.
Args:
x (`Optional[Union[Msg, Sequence[Msg]]]`, defaults to `None`):
The input message(s) to the agent, which also can be omitted if
the agent doesn't need any input.
Returns:
`Msg`: The output message generated by the agent.
"""

# Print/speak the message in this agent's voice
# Support both streaming and non-streaming responses by "or"
x = Msg(name=self.name, content=self.content, role="assistant")
self.speak(x)

return x
Loading

0 comments on commit 9cb6402

Please sign in to comment.