\ No newline at end of file
diff --git a/src/agentscope/studio/static/html-drag-components/agent-copyagent.html b/src/agentscope/studio/static/html-drag-components/agent-copyagent.html
new file mode 100644
index 000000000..a6868005f
--- /dev/null
+++ b/src/agentscope/studio/static/html-drag-components/agent-copyagent.html
@@ -0,0 +1,19 @@
+
+
+
+
+ NAME_PLACEHOLDER
+
+ ▲
+
+
+ README_PLACEHOLDER
+
Copy from Node ID:
+ ID_PLACEHOLDER
+
+
+
\ No newline at end of file
diff --git a/src/agentscope/studio/static/html-drag-components/tool-image-composition.html b/src/agentscope/studio/static/html-drag-components/tool-image-composition.html
index ef59afdcc..a373f9a69 100644
--- a/src/agentscope/studio/static/html-drag-components/tool-image-composition.html
+++ b/src/agentscope/studio/static/html-drag-components/tool-image-composition.html
@@ -10,7 +10,7 @@
▲
-
Image composition Configurations
+
Composite images into one image
-
Image Motion Configurations
+
Convert an image to an mp4 or a gif by shifting the perspective
diff --git a/src/agentscope/studio/static/i18n/i18n_en.json b/src/agentscope/studio/static/i18n/i18n_en.json
index 4cba00fd8..21ce31913 100644
--- a/src/agentscope/studio/static/i18n/i18n_en.json
+++ b/src/agentscope/studio/static/i18n/i18n_en.json
@@ -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",
@@ -193,7 +198,7 @@
"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",
@@ -201,15 +206,15 @@
"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",
diff --git a/src/agentscope/studio/static/i18n/i18n_zh.json b/src/agentscope/studio/static/i18n/i18n_zh.json
index 9790534fe..9fd12f0c0 100644
--- a/src/agentscope/studio/static/i18n/i18n_zh.json
+++ b/src/agentscope/studio/static/i18n/i18n_zh.json
@@ -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": "名称",
@@ -193,7 +198,7 @@
"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": "行",
@@ -201,15 +206,15 @@
"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": "目标视频高度",
diff --git a/src/agentscope/studio/static/js/workstation.js b/src/agentscope/studio/static/js/workstation.js
index 32e6381db..9ea615ffb 100644
--- a/src/agentscope/studio/static/js/workstation.js
+++ b/src/agentscope/studio/static/js/workstation.js
@@ -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",
@@ -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 = [
@@ -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,
@@ -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,
@@ -947,7 +978,6 @@ function initializeMonacoEditor(nodeId) {
parentNode.addEventListener("DOMNodeRemoved", function () {
resizeObserver.disconnect();
});
-
}, function (error) {
console.error("Error encountered while loading monaco editor: ", error);
});
@@ -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);
+ }
}
}
}
diff --git a/src/agentscope/studio/templates/workstation.html b/src/agentscope/studio/templates/workstation.html
index d97f43cad..c1ec1403d 100644
--- a/src/agentscope/studio/templates/workstation.html
+++ b/src/agentscope/studio/templates/workstation.html
@@ -238,6 +238,11 @@
draggable="true" ondragstart="drag(event)">
ReActAgent
+
+ BroadcastAgent
+
diff --git a/src/agentscope/studio/tools/broadcast_agent.py b/src/agentscope/studio/tools/broadcast_agent.py
new file mode 100644
index 000000000..61f1d51b7
--- /dev/null
+++ b/src/agentscope/studio/tools/broadcast_agent.py
@@ -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
diff --git a/src/agentscope/web/workstation/workflow_node.py b/src/agentscope/web/workstation/workflow_node.py
index dd6f37e23..af0e01a63 100644
--- a/src/agentscope/web/workstation/workflow_node.py
+++ b/src/agentscope/web/workstation/workflow_node.py
@@ -50,6 +50,7 @@
from agentscope.studio.tools.condition_operator import eval_condition_operator
from agentscope.studio.tools.web_post import web_post
+from agentscope.studio.tools.broadcast_agent import BroadcastAgent
DEFAULT_FLOW_VAR = "flow"
@@ -318,6 +319,31 @@ def compile(self) -> dict:
}
+class BroadcastAgentNode(WorkflowNode):
+ """
+ A node representing a BroadcastAgent within a workflow.
+ """
+
+ node_type = WorkflowNodeType.AGENT
+
+ def _post_init(self) -> None:
+ super()._post_init()
+ self.pipeline = BroadcastAgent(**self.opt_kwargs)
+
+ def __call__(self, x: dict = None) -> dict:
+ return self.pipeline(x)
+
+ def compile(self) -> dict:
+ return {
+ "imports": "from agentscope.studio.tools.broadcast_agent "
+ "import BroadcastAgent",
+ "inits": f"{self.var_name} = BroadcastAgent("
+ f"{kwarg_converter(self.opt_kwargs)})",
+ "execs": f"{DEFAULT_FLOW_VAR} = {self.var_name}"
+ f"([{DEFAULT_FLOW_VAR}])",
+ }
+
+
class MsgHubNode(WorkflowNode):
"""
A node that serves as a messaging hub within a workflow.
@@ -1033,6 +1059,7 @@ def compile(self) -> dict:
"TextToImageAgent": TextToImageAgentNode,
"DictDialogAgent": DictDialogAgentNode,
"ReActAgent": ReActAgentNode,
+ "BroadcastAgent": BroadcastAgentNode,
"Placeholder": PlaceHolderNode,
"MsgHub": MsgHubNode,
"SequentialPipeline": SequentialPipelineNode,