Зафиксирована рабочая версия TEN-Agent для HuggingFace Space
Browse filesThis view is limited to 50 files because it contains too many changes.
See raw diff
- .devcontainer/devcontainer.json +28 -0
- .dockerignore +2 -0
- .gitattributes +5 -0
- .github/ISSUE_TEMPLATE/bug_report.yml +67 -0
- .github/ISSUE_TEMPLATE/feature_request.yml +39 -0
- .github/workflows/build-docker.yaml +87 -0
- .github/workflows/ci.yaml +45 -0
- .pylintrc +652 -0
- .vscode/launch.json +47 -0
- .vscode/settings.json +13 -0
- .vscode/tasks.json +22 -0
- Dockerfile +8 -11
- LICENSE +201 -0
- Taskfile.yml +120 -0
- agents/.clang-format +8 -0
- agents/.gitignore +43 -0
- agents/bin/start +12 -0
- agents/examples/default/manifest.json +152 -0
- agents/examples/default/property.json +1331 -0
- agents/examples/demo/manifest.json +97 -0
- agents/examples/demo/property.json +2322 -0
- agents/examples/experimental/manifest.json +122 -0
- agents/examples/experimental/property.json +862 -0
- agents/go.mod +7 -0
- agents/go.sum +0 -0
- agents/main.go +71 -0
- agents/scripts/.gitignore +4 -0
- agents/scripts/BUILD.gn +18 -0
- agents/scripts/dot.py +117 -0
- agents/scripts/install_deps_and_build.sh +145 -0
- agents/scripts/package.sh +68 -0
- agents/scripts/pylint.sh +4 -0
- agents/session_control.conf +2 -0
- agents/ten_packages/bak/litellm_python/__init__.py +6 -0
- agents/ten_packages/bak/litellm_python/extension.py +1 -0
- agents/ten_packages/bak/litellm_python/litellm.py +79 -0
- agents/ten_packages/bak/litellm_python/litellm_addon.py +23 -0
- agents/ten_packages/bak/litellm_python/litellm_extension.py +229 -0
- agents/ten_packages/bak/litellm_python/log.py +12 -0
- agents/ten_packages/bak/litellm_python/manifest.json +82 -0
- agents/ten_packages/bak/litellm_python/requirements.txt +1 -0
- agents/ten_packages/bak/litellm_python/utils.py +19 -0
- agents/ten_packages/extension/agora_rtm_wrapper/extension.go +180 -0
- agents/ten_packages/extension/agora_rtm_wrapper/go.mod +7 -0
- agents/ten_packages/extension/agora_rtm_wrapper/manifest.json +32 -0
- agents/ten_packages/extension/agora_rtm_wrapper/property.json +1 -0
- agents/ten_packages/extension/aliyun_analyticdb_vector_storage/__init__.py +1 -0
- agents/ten_packages/extension/aliyun_analyticdb_vector_storage/client.py +95 -0
- agents/ten_packages/extension/aliyun_analyticdb_vector_storage/manifest.json +121 -0
- agents/ten_packages/extension/aliyun_analyticdb_vector_storage/model.py +546 -0
.devcontainer/devcontainer.json
ADDED
@@ -0,0 +1,28 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
// For format details, see https://aka.ms/devcontainer.json. For config options, see the
|
2 |
+
// README at: https://github.com/devcontainers/templates/tree/main/src/docker-existing-dockerfile
|
3 |
+
{
|
4 |
+
"name": "ten_agent_dev",
|
5 |
+
"image": "ghcr.io/ten-framework/ten_agent_build:0.4.17",
|
6 |
+
"customizations": {
|
7 |
+
"vscode": {
|
8 |
+
"extensions": [
|
9 |
+
"golang.go",
|
10 |
+
"ms-vscode.cpptools"
|
11 |
+
]
|
12 |
+
}
|
13 |
+
},
|
14 |
+
"workspaceMount": "source=${localWorkspaceFolder},target=/app,type=bind",
|
15 |
+
"workspaceFolder": "/app",
|
16 |
+
// Use 'forwardPorts' to make a list of ports inside the container available locally.
|
17 |
+
"forwardPorts": [
|
18 |
+
3000,
|
19 |
+
8080,
|
20 |
+
49483
|
21 |
+
],
|
22 |
+
// Features to add to the dev container. More info: https://containers.dev/features.
|
23 |
+
"features": {
|
24 |
+
"ghcr.io/devcontainers/features/git:1": {},
|
25 |
+
"ghcr.io/devcontainers/features/python:1": {},
|
26 |
+
"ghcr.io/devcontainers/features/node:1": {}
|
27 |
+
}
|
28 |
+
}
|
.dockerignore
ADDED
@@ -0,0 +1,2 @@
|
|
|
|
|
|
|
1 |
+
.git
|
2 |
+
playground/
|
.gitattributes
ADDED
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Shell scripts use LF as line separator, even checked out to Windows(NTFS) file-system
|
2 |
+
*.sh text eol=lf
|
3 |
+
agents/bin/* text eol=lf
|
4 |
+
agents/scripts/* text eol=lf
|
5 |
+
*.lockb filter=lfs diff=lfs merge=lfs -text
|
.github/ISSUE_TEMPLATE/bug_report.yml
ADDED
@@ -0,0 +1,67 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
name: Bug Report
|
2 |
+
description: Report a bug or issue with the project
|
3 |
+
title: "[BUG] "
|
4 |
+
labels: [bug]
|
5 |
+
body:
|
6 |
+
- type: markdown
|
7 |
+
attributes:
|
8 |
+
value: |
|
9 |
+
Thanks for taking the time to report a bug! Please fill in the following details.
|
10 |
+
|
11 |
+
- type: textarea
|
12 |
+
id: description
|
13 |
+
attributes:
|
14 |
+
label: Description
|
15 |
+
description: A clear and detailed description of the bug.
|
16 |
+
placeholder: "Enter a clear and concise description of what the bug is."
|
17 |
+
validations:
|
18 |
+
required: true
|
19 |
+
|
20 |
+
- type: input
|
21 |
+
id: environment
|
22 |
+
attributes:
|
23 |
+
label: Environment
|
24 |
+
description: The environment where this bug occurred (e.g., operating system, CPU arch, etc.).
|
25 |
+
placeholder: "Enter details about the environment."
|
26 |
+
validations:
|
27 |
+
required: true
|
28 |
+
|
29 |
+
- type: textarea
|
30 |
+
id: steps
|
31 |
+
attributes:
|
32 |
+
label: Steps to reproduce
|
33 |
+
description: What are the steps to reproduce this issue?
|
34 |
+
placeholder: |
|
35 |
+
1. ...
|
36 |
+
validations:
|
37 |
+
required: true
|
38 |
+
|
39 |
+
- type: textarea
|
40 |
+
id: expected
|
41 |
+
attributes:
|
42 |
+
label: Expected behavior
|
43 |
+
description: What should have happened instead?
|
44 |
+
placeholder: "Describe what you expected to happen."
|
45 |
+
validations:
|
46 |
+
required: true
|
47 |
+
|
48 |
+
- type: dropdown
|
49 |
+
id: severity
|
50 |
+
attributes:
|
51 |
+
label: Severity
|
52 |
+
description: How severe is the bug?
|
53 |
+
options:
|
54 |
+
- Critical
|
55 |
+
- Major
|
56 |
+
- Minor
|
57 |
+
validations:
|
58 |
+
required: true
|
59 |
+
|
60 |
+
- type: textarea
|
61 |
+
id: additional_info
|
62 |
+
attributes:
|
63 |
+
label: Additional Information
|
64 |
+
description: Any other context or screenshots related to the bug.
|
65 |
+
placeholder: "Enter additional context or information."
|
66 |
+
validations:
|
67 |
+
required: false
|
.github/ISSUE_TEMPLATE/feature_request.yml
ADDED
@@ -0,0 +1,39 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
name: Feature Request
|
2 |
+
description: Request a feature
|
3 |
+
title: "[FEATURE] "
|
4 |
+
labels: [feature]
|
5 |
+
body:
|
6 |
+
- type: markdown
|
7 |
+
attributes:
|
8 |
+
value: |
|
9 |
+
Thanks for taking the time to request a feature! Please fill in the following details.
|
10 |
+
|
11 |
+
- type: textarea
|
12 |
+
id: description
|
13 |
+
attributes:
|
14 |
+
label: Description
|
15 |
+
description: A clear and detailed description of the feature request.
|
16 |
+
placeholder: "Enter a clear and concise description of what the feature request is."
|
17 |
+
validations:
|
18 |
+
required: true
|
19 |
+
|
20 |
+
- type: dropdown
|
21 |
+
id: severity
|
22 |
+
attributes:
|
23 |
+
label: Severity
|
24 |
+
description: How severe is the bug?
|
25 |
+
options:
|
26 |
+
- Critical
|
27 |
+
- Major
|
28 |
+
- Minor
|
29 |
+
validations:
|
30 |
+
required: true
|
31 |
+
|
32 |
+
- type: textarea
|
33 |
+
id: additional_info
|
34 |
+
attributes:
|
35 |
+
label: Additional Information
|
36 |
+
description: Any other context or screenshots related to the bug.
|
37 |
+
placeholder: "Enter additional context or information."
|
38 |
+
validations:
|
39 |
+
required: false
|
.github/workflows/build-docker.yaml
ADDED
@@ -0,0 +1,87 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
name: Build Docker
|
2 |
+
|
3 |
+
on:
|
4 |
+
push:
|
5 |
+
branches: [ "**" ]
|
6 |
+
tags: [ "**" ]
|
7 |
+
paths-ignore:
|
8 |
+
- ".devcontainer/**"
|
9 |
+
- ".github/**"
|
10 |
+
- "!.github/workflows/build-docker.yaml"
|
11 |
+
- ".vscode/**"
|
12 |
+
- "docs/**"
|
13 |
+
- "**.md"
|
14 |
+
pull_request:
|
15 |
+
branches: [ "main" ]
|
16 |
+
paths-ignore:
|
17 |
+
- ".devcontainer/**"
|
18 |
+
- ".github/**"
|
19 |
+
- "!.github/workflows/build-docker.yaml"
|
20 |
+
- ".vscode/**"
|
21 |
+
- "docs/**"
|
22 |
+
- "**.md"
|
23 |
+
workflow_dispatch:
|
24 |
+
|
25 |
+
env:
|
26 |
+
SERVER_IMAGE_NAME: ten_agent_server
|
27 |
+
PLAYGROUND_IMAGE_NAME: ten_agent_playground
|
28 |
+
NON_EDIT_PLAYGROUND_IMAGE_NAME: ten_agent_non_edit_playground
|
29 |
+
DEMO_IMAGE_NAME: ten_agent_demo
|
30 |
+
|
31 |
+
jobs:
|
32 |
+
build:
|
33 |
+
runs-on: ubuntu-latest
|
34 |
+
steps:
|
35 |
+
- name: Checkout
|
36 |
+
uses: actions/checkout@v4
|
37 |
+
with:
|
38 |
+
fetch-tags: true
|
39 |
+
fetch-depth: "0"
|
40 |
+
- id: pre-step
|
41 |
+
shell: bash
|
42 |
+
run: echo "image-tag=$(git describe --tags --always)" >> $GITHUB_OUTPUT
|
43 |
+
- name: Build & Publish Docker Image for Agents Server
|
44 |
+
uses: elgohr/Publish-Docker-Github-Action@v5
|
45 |
+
with:
|
46 |
+
name: ${{ github.repository_owner }}/${{ env.SERVER_IMAGE_NAME }}
|
47 |
+
username: ${{ github.actor }}
|
48 |
+
password: ${{ secrets.GITHUB_TOKEN }}
|
49 |
+
registry: ghcr.io
|
50 |
+
tags: "${{ github.ref == 'refs/heads/main' && 'latest,' || '' }}${{ steps.pre-step.outputs.image-tag }}"
|
51 |
+
no_push: ${{ github.event_name == 'pull_request' }}
|
52 |
+
- name: Build & Publish Docker Image for Playground
|
53 |
+
uses: elgohr/Publish-Docker-Github-Action@v5
|
54 |
+
env:
|
55 |
+
EDIT_GRAPH_MODE: true
|
56 |
+
with:
|
57 |
+
name: ${{ github.repository_owner }}/${{ env.PLAYGROUND_IMAGE_NAME }}
|
58 |
+
username: ${{ github.actor }}
|
59 |
+
password: ${{ secrets.GITHUB_TOKEN }}
|
60 |
+
registry: ghcr.io
|
61 |
+
workdir: playground
|
62 |
+
tags: "${{ github.ref == 'refs/heads/main' && 'latest,' || '' }}${{ steps.pre-step.outputs.image-tag }}"
|
63 |
+
no_push: ${{ github.event_name == 'pull_request' }}
|
64 |
+
buildargs: EDIT_GRAPH_MODE
|
65 |
+
- name: Build & Publish Docker Image for Non-Editable Playground
|
66 |
+
uses: elgohr/Publish-Docker-Github-Action@v5
|
67 |
+
env:
|
68 |
+
EDIT_GRAPH_MODE: false
|
69 |
+
with:
|
70 |
+
name: ${{ github.repository_owner }}/${{ env.NON_EDIT_PLAYGROUND_IMAGE_NAME }}
|
71 |
+
username: ${{ github.actor }}
|
72 |
+
password: ${{ secrets.GITHUB_TOKEN }}
|
73 |
+
registry: ghcr.io
|
74 |
+
workdir: playground
|
75 |
+
tags: "${{ github.ref == 'refs/heads/main' && 'latest,' || '' }}${{ steps.pre-step.outputs.image-tag }}"
|
76 |
+
no_push: ${{ github.event_name == 'pull_request' }}
|
77 |
+
buildargs: EDIT_GRAPH_MODE
|
78 |
+
- name: Build & Publish Docker Image for demo
|
79 |
+
uses: elgohr/Publish-Docker-Github-Action@v5
|
80 |
+
with:
|
81 |
+
name: ${{ github.repository_owner }}/${{ env.DEMO_IMAGE_NAME }}
|
82 |
+
username: ${{ github.actor }}
|
83 |
+
password: ${{ secrets.GITHUB_TOKEN }}
|
84 |
+
registry: ghcr.io
|
85 |
+
workdir: demo
|
86 |
+
tags: "${{ github.ref == 'refs/heads/main' && 'latest,' || '' }}${{ steps.pre-step.outputs.image-tag }}"
|
87 |
+
no_push: ${{ github.event_name == 'pull_request' }}
|
.github/workflows/ci.yaml
ADDED
@@ -0,0 +1,45 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
name: CI
|
2 |
+
|
3 |
+
on:
|
4 |
+
pull_request:
|
5 |
+
branches: [ "main" ]
|
6 |
+
paths-ignore:
|
7 |
+
- ".devcontainer/**"
|
8 |
+
- ".github/**"
|
9 |
+
- "!.github/workflows/ci.yaml"
|
10 |
+
- ".vscode/**"
|
11 |
+
- "docs/**"
|
12 |
+
- "esp32-client/**"
|
13 |
+
- "**.md"
|
14 |
+
- "Dockerfile"
|
15 |
+
- "docker-compose.yml"
|
16 |
+
- "demo/**"
|
17 |
+
- "playground/**"
|
18 |
+
workflow_dispatch:
|
19 |
+
|
20 |
+
jobs:
|
21 |
+
ci:
|
22 |
+
runs-on: ubuntu-latest
|
23 |
+
container:
|
24 |
+
image: ghcr.io/ten-framework/ten_agent_build:0.4.17
|
25 |
+
strategy:
|
26 |
+
matrix:
|
27 |
+
agent: [agents/examples/default, agents/examples/demo, agents/examples/experimental]
|
28 |
+
steps:
|
29 |
+
- uses: actions/checkout@v4
|
30 |
+
with:
|
31 |
+
fetch-depth: "0"
|
32 |
+
submodules: "true"
|
33 |
+
|
34 |
+
- name: Use agent
|
35 |
+
run: |
|
36 |
+
git config --global --add safe.directory $(pwd)
|
37 |
+
task use AGENT=${{ matrix.agent }}
|
38 |
+
|
39 |
+
- name: Run tests
|
40 |
+
run: |
|
41 |
+
task test -- -s -v
|
42 |
+
|
43 |
+
# - name: Run lint
|
44 |
+
# run: |
|
45 |
+
# task lint
|
.pylintrc
ADDED
@@ -0,0 +1,652 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
[MAIN]
|
2 |
+
|
3 |
+
# Analyse import fallback blocks. This can be used to support both Python 2 and
|
4 |
+
# 3 compatible code, which means that the block might have code that exists
|
5 |
+
# only in one or another interpreter, leading to false positives when analysed.
|
6 |
+
analyse-fallback-blocks=no
|
7 |
+
|
8 |
+
# Clear in-memory caches upon conclusion of linting. Useful if running pylint
|
9 |
+
# in a server-like mode.
|
10 |
+
clear-cache-post-run=no
|
11 |
+
|
12 |
+
# Load and enable all available extensions. Use --list-extensions to see a list
|
13 |
+
# all available extensions.
|
14 |
+
#enable-all-extensions=
|
15 |
+
|
16 |
+
# In error mode, messages with a category besides ERROR or FATAL are
|
17 |
+
# suppressed, and no reports are done by default. Error mode is compatible with
|
18 |
+
# disabling specific errors.
|
19 |
+
#errors-only=
|
20 |
+
|
21 |
+
# Always return a 0 (non-error) status code, even if lint errors are found.
|
22 |
+
# This is primarily useful in continuous integration scripts.
|
23 |
+
#exit-zero=
|
24 |
+
|
25 |
+
# A comma-separated list of package or module names from where C extensions may
|
26 |
+
# be loaded. Extensions are loading into the active Python interpreter and may
|
27 |
+
# run arbitrary code.
|
28 |
+
extension-pkg-allow-list=
|
29 |
+
|
30 |
+
# A comma-separated list of package or module names from where C extensions may
|
31 |
+
# be loaded. Extensions are loading into the active Python interpreter and may
|
32 |
+
# run arbitrary code. (This is an alternative name to extension-pkg-allow-list
|
33 |
+
# for backward compatibility.)
|
34 |
+
extension-pkg-whitelist=
|
35 |
+
|
36 |
+
# Return non-zero exit code if any of these messages/categories are detected,
|
37 |
+
# even if score is above --fail-under value. Syntax same as enable. Messages
|
38 |
+
# specified are enabled, while categories only check already-enabled messages.
|
39 |
+
fail-on=
|
40 |
+
|
41 |
+
# Specify a score threshold under which the program will exit with error.
|
42 |
+
fail-under=10
|
43 |
+
|
44 |
+
# Interpret the stdin as a python script, whose filename needs to be passed as
|
45 |
+
# the module_or_package argument.
|
46 |
+
#from-stdin=
|
47 |
+
|
48 |
+
# Files or directories to be skipped. They should be base names, not paths.
|
49 |
+
ignore=CVS,examples,tests,out
|
50 |
+
|
51 |
+
# Add files or directories matching the regular expressions patterns to the
|
52 |
+
# ignore-list. The regex matches against paths and can be in Posix or Windows
|
53 |
+
# format. Because '\\' represents the directory delimiter on Windows systems,
|
54 |
+
# it can't be used as an escape character.
|
55 |
+
ignore-paths=
|
56 |
+
|
57 |
+
# Files or directories matching the regular expression patterns are skipped.
|
58 |
+
# The regex matches against base names, not paths. The default value ignores
|
59 |
+
# Emacs file locks
|
60 |
+
ignore-patterns=
|
61 |
+
|
62 |
+
# List of module names for which member attributes should not be checked and
|
63 |
+
# will not be imported (useful for modules/projects where namespaces are
|
64 |
+
# manipulated during runtime and thus existing member attributes cannot be
|
65 |
+
# deduced by static analysis). It supports qualified module names, as well as
|
66 |
+
# Unix pattern matching.
|
67 |
+
ignored-modules=
|
68 |
+
|
69 |
+
# Python code to execute, usually for sys.path manipulation such as
|
70 |
+
# pygtk.require().
|
71 |
+
#init-hook=
|
72 |
+
|
73 |
+
# Use multiple processes to speed up Pylint. Specifying 0 will auto-detect the
|
74 |
+
# number of processors available to use, and will cap the count on Windows to
|
75 |
+
# avoid hangs.
|
76 |
+
jobs=1
|
77 |
+
|
78 |
+
# Control the amount of potential inferred values when inferring a single
|
79 |
+
# object. This can help the performance when dealing with large functions or
|
80 |
+
# complex, nested conditions.
|
81 |
+
limit-inference-results=100
|
82 |
+
|
83 |
+
# List of plugins (as comma separated values of python module names) to load,
|
84 |
+
# usually to register additional checkers.
|
85 |
+
load-plugins=
|
86 |
+
|
87 |
+
# Pickle collected data for later comparisons.
|
88 |
+
persistent=yes
|
89 |
+
|
90 |
+
# Resolve imports to .pyi stubs if available. May reduce no-member messages and
|
91 |
+
# increase not-an-iterable messages.
|
92 |
+
prefer-stubs=no
|
93 |
+
|
94 |
+
# Minimum Python version to use for version dependent checks. Will default to
|
95 |
+
# the version used to run pylint.
|
96 |
+
py-version=3.10
|
97 |
+
|
98 |
+
# Discover python modules and packages in the file system subtree.
|
99 |
+
recursive=no
|
100 |
+
|
101 |
+
# Add paths to the list of the source roots. Supports globbing patterns. The
|
102 |
+
# source root is an absolute path or a path relative to the current working
|
103 |
+
# directory used to determine a package namespace for modules located under the
|
104 |
+
# source root.
|
105 |
+
source-roots=
|
106 |
+
|
107 |
+
# When enabled, pylint would attempt to guess common misconfiguration and emit
|
108 |
+
# user-friendly hints instead of false-positive error messages.
|
109 |
+
suggestion-mode=yes
|
110 |
+
|
111 |
+
# Allow loading of arbitrary C extensions. Extensions are imported into the
|
112 |
+
# active Python interpreter and may run arbitrary code.
|
113 |
+
unsafe-load-any-extension=no
|
114 |
+
|
115 |
+
# In verbose mode, extra non-checker-related info will be displayed.
|
116 |
+
#verbose=
|
117 |
+
|
118 |
+
|
119 |
+
[BASIC]
|
120 |
+
|
121 |
+
# Naming style matching correct argument names.
|
122 |
+
argument-naming-style=snake_case
|
123 |
+
|
124 |
+
# Regular expression matching correct argument names. Overrides argument-
|
125 |
+
# naming-style. If left empty, argument names will be checked with the set
|
126 |
+
# naming style.
|
127 |
+
#argument-rgx=
|
128 |
+
|
129 |
+
# Naming style matching correct attribute names.
|
130 |
+
attr-naming-style=snake_case
|
131 |
+
|
132 |
+
# Regular expression matching correct attribute names. Overrides attr-naming-
|
133 |
+
# style. If left empty, attribute names will be checked with the set naming
|
134 |
+
# style.
|
135 |
+
#attr-rgx=
|
136 |
+
|
137 |
+
# Bad variable names which should always be refused, separated by a comma.
|
138 |
+
bad-names=foo,
|
139 |
+
bar,
|
140 |
+
baz,
|
141 |
+
toto,
|
142 |
+
tutu,
|
143 |
+
tata
|
144 |
+
|
145 |
+
# Bad variable names regexes, separated by a comma. If names match any regex,
|
146 |
+
# they will always be refused
|
147 |
+
bad-names-rgxs=
|
148 |
+
|
149 |
+
# Naming style matching correct class attribute names.
|
150 |
+
class-attribute-naming-style=any
|
151 |
+
|
152 |
+
# Regular expression matching correct class attribute names. Overrides class-
|
153 |
+
# attribute-naming-style. If left empty, class attribute names will be checked
|
154 |
+
# with the set naming style.
|
155 |
+
#class-attribute-rgx=
|
156 |
+
|
157 |
+
# Naming style matching correct class constant names.
|
158 |
+
class-const-naming-style=UPPER_CASE
|
159 |
+
|
160 |
+
# Regular expression matching correct class constant names. Overrides class-
|
161 |
+
# const-naming-style. If left empty, class constant names will be checked with
|
162 |
+
# the set naming style.
|
163 |
+
#class-const-rgx=
|
164 |
+
|
165 |
+
# Naming style matching correct class names.
|
166 |
+
class-naming-style=PascalCase
|
167 |
+
|
168 |
+
# Regular expression matching correct class names. Overrides class-naming-
|
169 |
+
# style. If left empty, class names will be checked with the set naming style.
|
170 |
+
#class-rgx=
|
171 |
+
|
172 |
+
# Naming style matching correct constant names.
|
173 |
+
const-naming-style=UPPER_CASE
|
174 |
+
|
175 |
+
# Regular expression matching correct constant names. Overrides const-naming-
|
176 |
+
# style. If left empty, constant names will be checked with the set naming
|
177 |
+
# style.
|
178 |
+
#const-rgx=
|
179 |
+
|
180 |
+
# Minimum line length for functions/classes that require docstrings, shorter
|
181 |
+
# ones are exempt.
|
182 |
+
docstring-min-length=-1
|
183 |
+
|
184 |
+
# Naming style matching correct function names.
|
185 |
+
function-naming-style=snake_case
|
186 |
+
|
187 |
+
# Regular expression matching correct function names. Overrides function-
|
188 |
+
# naming-style. If left empty, function names will be checked with the set
|
189 |
+
# naming style.
|
190 |
+
#function-rgx=
|
191 |
+
|
192 |
+
# Good variable names which should always be accepted, separated by a comma.
|
193 |
+
good-names=i,
|
194 |
+
j,
|
195 |
+
k,
|
196 |
+
ex,
|
197 |
+
Run,
|
198 |
+
_
|
199 |
+
|
200 |
+
# Good variable names regexes, separated by a comma. If names match any regex,
|
201 |
+
# they will always be accepted
|
202 |
+
good-names-rgxs=
|
203 |
+
|
204 |
+
# Include a hint for the correct naming format with invalid-name.
|
205 |
+
include-naming-hint=no
|
206 |
+
|
207 |
+
# Naming style matching correct inline iteration names.
|
208 |
+
inlinevar-naming-style=any
|
209 |
+
|
210 |
+
# Regular expression matching correct inline iteration names. Overrides
|
211 |
+
# inlinevar-naming-style. If left empty, inline iteration names will be checked
|
212 |
+
# with the set naming style.
|
213 |
+
#inlinevar-rgx=
|
214 |
+
|
215 |
+
# Naming style matching correct method names.
|
216 |
+
method-naming-style=snake_case
|
217 |
+
|
218 |
+
# Regular expression matching correct method names. Overrides method-naming-
|
219 |
+
# style. If left empty, method names will be checked with the set naming style.
|
220 |
+
#method-rgx=
|
221 |
+
|
222 |
+
# Naming style matching correct module names.
|
223 |
+
module-naming-style=snake_case
|
224 |
+
|
225 |
+
# Regular expression matching correct module names. Overrides module-naming-
|
226 |
+
# style. If left empty, module names will be checked with the set naming style.
|
227 |
+
#module-rgx=
|
228 |
+
|
229 |
+
# Colon-delimited sets of names that determine each other's naming style when
|
230 |
+
# the name regexes allow several styles.
|
231 |
+
name-group=
|
232 |
+
|
233 |
+
# Regular expression which should only match function or class names that do
|
234 |
+
# not require a docstring.
|
235 |
+
no-docstring-rgx=^_
|
236 |
+
|
237 |
+
# List of decorators that produce properties, such as abc.abstractproperty. Add
|
238 |
+
# to this list to register other decorators that produce valid properties.
|
239 |
+
# These decorators are taken in consideration only for invalid-name.
|
240 |
+
property-classes=abc.abstractproperty
|
241 |
+
|
242 |
+
# Regular expression matching correct type alias names. If left empty, type
|
243 |
+
# alias names will be checked with the set naming style.
|
244 |
+
#typealias-rgx=
|
245 |
+
|
246 |
+
# Regular expression matching correct type variable names. If left empty, type
|
247 |
+
# variable names will be checked with the set naming style.
|
248 |
+
#typevar-rgx=
|
249 |
+
|
250 |
+
# Naming style matching correct variable names.
|
251 |
+
variable-naming-style=snake_case
|
252 |
+
|
253 |
+
# Regular expression matching correct variable names. Overrides variable-
|
254 |
+
# naming-style. If left empty, variable names will be checked with the set
|
255 |
+
# naming style.
|
256 |
+
#variable-rgx=
|
257 |
+
|
258 |
+
|
259 |
+
[CLASSES]
|
260 |
+
|
261 |
+
# Warn about protected attribute access inside special methods
|
262 |
+
check-protected-access-in-special-methods=no
|
263 |
+
|
264 |
+
# List of method names used to declare (i.e. assign) instance attributes.
|
265 |
+
defining-attr-methods=__init__,
|
266 |
+
__new__,
|
267 |
+
setUp,
|
268 |
+
asyncSetUp,
|
269 |
+
__post_init__
|
270 |
+
|
271 |
+
# List of member names, which should be excluded from the protected access
|
272 |
+
# warning.
|
273 |
+
exclude-protected=_asdict,_fields,_replace,_source,_make,os._exit
|
274 |
+
|
275 |
+
# List of valid names for the first argument in a class method.
|
276 |
+
valid-classmethod-first-arg=cls
|
277 |
+
|
278 |
+
# List of valid names for the first argument in a metaclass class method.
|
279 |
+
valid-metaclass-classmethod-first-arg=mcs
|
280 |
+
|
281 |
+
|
282 |
+
[DESIGN]
|
283 |
+
|
284 |
+
# List of regular expressions of class ancestor names to ignore when counting
|
285 |
+
# public methods (see R0903)
|
286 |
+
exclude-too-few-public-methods=
|
287 |
+
|
288 |
+
# List of qualified class names to ignore when counting class parents (see
|
289 |
+
# R0901)
|
290 |
+
ignored-parents=
|
291 |
+
|
292 |
+
# Maximum number of arguments for function / method.
|
293 |
+
max-args=5
|
294 |
+
|
295 |
+
# Maximum number of attributes for a class (see R0902).
|
296 |
+
max-attributes=7
|
297 |
+
|
298 |
+
# Maximum number of boolean expressions in an if statement (see R0916).
|
299 |
+
max-bool-expr=5
|
300 |
+
|
301 |
+
# Maximum number of branch for function / method body.
|
302 |
+
max-branches=12
|
303 |
+
|
304 |
+
# Maximum number of locals for function / method body.
|
305 |
+
max-locals=15
|
306 |
+
|
307 |
+
# Maximum number of parents for a class (see R0901).
|
308 |
+
max-parents=7
|
309 |
+
|
310 |
+
# Maximum number of positional arguments for function / method.
|
311 |
+
#max-positional-arguments=5
|
312 |
+
|
313 |
+
# Maximum number of public methods for a class (see R0904).
|
314 |
+
max-public-methods=20
|
315 |
+
|
316 |
+
# Maximum number of return / yield for function / method body.
|
317 |
+
max-returns=6
|
318 |
+
|
319 |
+
# Maximum number of statements in function / method body.
|
320 |
+
max-statements=50
|
321 |
+
|
322 |
+
# Minimum number of public methods for a class (see R0903).
|
323 |
+
min-public-methods=2
|
324 |
+
|
325 |
+
|
326 |
+
[EXCEPTIONS]
|
327 |
+
|
328 |
+
# Exceptions that will emit a warning when caught.
|
329 |
+
overgeneral-exceptions=builtins.BaseException,builtins.Exception
|
330 |
+
|
331 |
+
|
332 |
+
[FORMAT]
|
333 |
+
|
334 |
+
# Expected format of line ending, e.g. empty (any line ending), LF or CRLF.
|
335 |
+
expected-line-ending-format=
|
336 |
+
|
337 |
+
# Regexp for a line that is allowed to be longer than the limit.
|
338 |
+
ignore-long-lines=^\s*(# )?<?https?://\S+>?$
|
339 |
+
|
340 |
+
# Number of spaces of indent required inside a hanging or continued line.
|
341 |
+
indent-after-paren=4
|
342 |
+
|
343 |
+
# String used as indentation unit. This is usually " " (4 spaces) or "\t" (1
|
344 |
+
# tab).
|
345 |
+
indent-string=' '
|
346 |
+
|
347 |
+
# Maximum number of characters on a single line.
|
348 |
+
max-line-length=100
|
349 |
+
|
350 |
+
# Maximum number of lines in a module.
|
351 |
+
max-module-lines=1000
|
352 |
+
|
353 |
+
# Allow the body of a class to be on the same line as the declaration if body
|
354 |
+
# contains single statement.
|
355 |
+
single-line-class-stmt=no
|
356 |
+
|
357 |
+
# Allow the body of an if to be on the same line as the test if there is no
|
358 |
+
# else.
|
359 |
+
single-line-if-stmt=no
|
360 |
+
|
361 |
+
|
362 |
+
[IMPORTS]
|
363 |
+
|
364 |
+
# List of modules that can be imported at any level, not just the top level
|
365 |
+
# one.
|
366 |
+
allow-any-import-level=
|
367 |
+
|
368 |
+
# Allow explicit reexports by alias from a package __init__.
|
369 |
+
allow-reexport-from-package=no
|
370 |
+
|
371 |
+
# Allow wildcard imports from modules that define __all__.
|
372 |
+
allow-wildcard-with-all=no
|
373 |
+
|
374 |
+
# Deprecated modules which should not be used, separated by a comma.
|
375 |
+
deprecated-modules=
|
376 |
+
|
377 |
+
# Output a graph (.gv or any supported image format) of external dependencies
|
378 |
+
# to the given file (report RP0402 must not be disabled).
|
379 |
+
ext-import-graph=
|
380 |
+
|
381 |
+
# Output a graph (.gv or any supported image format) of all (i.e. internal and
|
382 |
+
# external) dependencies to the given file (report RP0402 must not be
|
383 |
+
# disabled).
|
384 |
+
import-graph=
|
385 |
+
|
386 |
+
# Output a graph (.gv or any supported image format) of internal dependencies
|
387 |
+
# to the given file (report RP0402 must not be disabled).
|
388 |
+
int-import-graph=
|
389 |
+
|
390 |
+
# Force import order to recognize a module as part of the standard
|
391 |
+
# compatibility libraries.
|
392 |
+
known-standard-library=
|
393 |
+
|
394 |
+
# Force import order to recognize a module as part of a third party library.
|
395 |
+
known-third-party=enchant
|
396 |
+
|
397 |
+
# Couples of modules and preferred modules, separated by a comma.
|
398 |
+
preferred-modules=
|
399 |
+
|
400 |
+
|
401 |
+
[LOGGING]
|
402 |
+
|
403 |
+
# The type of string formatting that logging methods do. `old` means using %
|
404 |
+
# formatting, `new` is for `{}` formatting.
|
405 |
+
logging-format-style=old
|
406 |
+
|
407 |
+
# Logging modules to check that the string format arguments are in logging
|
408 |
+
# function parameter format.
|
409 |
+
logging-modules=logging
|
410 |
+
|
411 |
+
|
412 |
+
[MESSAGES CONTROL]
|
413 |
+
|
414 |
+
# Only show warnings with the listed confidence levels. Leave empty to show
|
415 |
+
# all. Valid levels: HIGH, CONTROL_FLOW, INFERENCE, INFERENCE_FAILURE,
|
416 |
+
# UNDEFINED.
|
417 |
+
confidence=HIGH,
|
418 |
+
CONTROL_FLOW,
|
419 |
+
INFERENCE,
|
420 |
+
INFERENCE_FAILURE,
|
421 |
+
UNDEFINED
|
422 |
+
|
423 |
+
# Disable the message, report, category or checker with the given id(s). You
|
424 |
+
# can either give multiple identifiers separated by comma (,) or put this
|
425 |
+
# option multiple times (only on the command line, not in the configuration
|
426 |
+
# file where it should appear only once). You can also use "--disable=all" to
|
427 |
+
# disable everything first and then re-enable specific checks. For example, if
|
428 |
+
# you want to run only the similarities checker, you can use "--disable=all
|
429 |
+
# --enable=similarities". If you want to run only the classes checker, but have
|
430 |
+
# no Warning level messages displayed, use "--disable=all --enable=classes
|
431 |
+
# --disable=W".
|
432 |
+
disable=raw-checker-failed,
|
433 |
+
bad-inline-option,
|
434 |
+
locally-disabled,
|
435 |
+
file-ignored,
|
436 |
+
suppressed-message,
|
437 |
+
useless-suppression,
|
438 |
+
deprecated-pragma,
|
439 |
+
use-symbolic-message-instead,
|
440 |
+
use-implicit-booleaness-not-comparison-to-string,
|
441 |
+
use-implicit-booleaness-not-comparison-to-zero,
|
442 |
+
broad-exception-caught,
|
443 |
+
logging-fstring-interpolation,
|
444 |
+
arguments-renamed,
|
445 |
+
I,C,R,
|
446 |
+
fixme,
|
447 |
+
|
448 |
+
# Enable the message, report, category or checker with the given id(s). You can
|
449 |
+
# either give multiple identifier separated by comma (,) or put this option
|
450 |
+
# multiple time (only on the command line, not in the configuration file where
|
451 |
+
# it should appear only once). See also the "--disable" option for examples.
|
452 |
+
enable=
|
453 |
+
|
454 |
+
|
455 |
+
[METHOD_ARGS]
|
456 |
+
|
457 |
+
# List of qualified names (i.e., library.method) which require a timeout
|
458 |
+
# parameter e.g. 'requests.api.get,requests.api.post'
|
459 |
+
timeout-methods=requests.api.delete,requests.api.get,requests.api.head,requests.api.options,requests.api.patch,requests.api.post,requests.api.put,requests.api.request
|
460 |
+
|
461 |
+
|
462 |
+
[MISCELLANEOUS]
|
463 |
+
|
464 |
+
# List of note tags to take in consideration, separated by a comma.
|
465 |
+
notes=FIXME,
|
466 |
+
XXX,
|
467 |
+
TODO
|
468 |
+
|
469 |
+
# Regular expression of note tags to take in consideration.
|
470 |
+
notes-rgx=
|
471 |
+
|
472 |
+
|
473 |
+
[REFACTORING]
|
474 |
+
|
475 |
+
# Maximum number of nested blocks for function / method body
|
476 |
+
max-nested-blocks=5
|
477 |
+
|
478 |
+
# Complete name of functions that never returns. When checking for
|
479 |
+
# inconsistent-return-statements if a never returning function is called then
|
480 |
+
# it will be considered as an explicit return statement and no message will be
|
481 |
+
# printed.
|
482 |
+
never-returning-functions=sys.exit,argparse.parse_error
|
483 |
+
|
484 |
+
# Let 'consider-using-join' be raised when the separator to join on would be
|
485 |
+
# non-empty (resulting in expected fixes of the type: ``"- " + " -
|
486 |
+
# ".join(items)``)
|
487 |
+
suggest-join-with-non-empty-separator=yes
|
488 |
+
|
489 |
+
|
490 |
+
[REPORTS]
|
491 |
+
|
492 |
+
# Python expression which should return a score less than or equal to 10. You
|
493 |
+
# have access to the variables 'fatal', 'error', 'warning', 'refactor',
|
494 |
+
# 'convention', and 'info' which contain the number of messages in each
|
495 |
+
# category, as well as 'statement' which is the total number of statements
|
496 |
+
# analyzed. This score is used by the global evaluation report (RP0004).
|
497 |
+
evaluation=max(0, 0 if fatal else 10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10))
|
498 |
+
|
499 |
+
# Template used to display messages. This is a python new-style format string
|
500 |
+
# used to format the message information. See doc for all details.
|
501 |
+
msg-template=
|
502 |
+
|
503 |
+
# Set the output format. Available formats are: text, parseable, colorized,
|
504 |
+
# json2 (improved json format), json (old json format) and msvs (visual
|
505 |
+
# studio). You can also give a reporter class, e.g.
|
506 |
+
# mypackage.mymodule.MyReporterClass.
|
507 |
+
#output-format=
|
508 |
+
|
509 |
+
# Tells whether to display a full report or only the messages.
|
510 |
+
reports=no
|
511 |
+
|
512 |
+
# Activate the evaluation score.
|
513 |
+
score=yes
|
514 |
+
|
515 |
+
|
516 |
+
[SIMILARITIES]
|
517 |
+
|
518 |
+
# Comments are removed from the similarity computation
|
519 |
+
ignore-comments=yes
|
520 |
+
|
521 |
+
# Docstrings are removed from the similarity computation
|
522 |
+
ignore-docstrings=yes
|
523 |
+
|
524 |
+
# Imports are removed from the similarity computation
|
525 |
+
ignore-imports=yes
|
526 |
+
|
527 |
+
# Signatures are removed from the similarity computation
|
528 |
+
ignore-signatures=yes
|
529 |
+
|
530 |
+
# Minimum lines number of a similarity.
|
531 |
+
min-similarity-lines=4
|
532 |
+
|
533 |
+
|
534 |
+
[SPELLING]
|
535 |
+
|
536 |
+
# Limits count of emitted suggestions for spelling mistakes.
|
537 |
+
max-spelling-suggestions=4
|
538 |
+
|
539 |
+
# Spelling dictionary name. No available dictionaries : You need to install
|
540 |
+
# both the python package and the system dependency for enchant to work.
|
541 |
+
spelling-dict=
|
542 |
+
|
543 |
+
# List of comma separated words that should be considered directives if they
|
544 |
+
# appear at the beginning of a comment and should not be checked.
|
545 |
+
spelling-ignore-comment-directives=fmt: on,fmt: off,noqa:,noqa,nosec,isort:skip,mypy:
|
546 |
+
|
547 |
+
# List of comma separated words that should not be checked.
|
548 |
+
spelling-ignore-words=
|
549 |
+
|
550 |
+
# A path to a file that contains the private dictionary; one word per line.
|
551 |
+
spelling-private-dict-file=
|
552 |
+
|
553 |
+
# Tells whether to store unknown words to the private dictionary (see the
|
554 |
+
# --spelling-private-dict-file option) instead of raising a message.
|
555 |
+
spelling-store-unknown-words=no
|
556 |
+
|
557 |
+
|
558 |
+
[STRING]
|
559 |
+
|
560 |
+
# This flag controls whether inconsistent-quotes generates a warning when the
|
561 |
+
# character used as a quote delimiter is used inconsistently within a module.
|
562 |
+
check-quote-consistency=no
|
563 |
+
|
564 |
+
# This flag controls whether the implicit-str-concat should generate a warning
|
565 |
+
# on implicit string concatenation in sequences defined over several lines.
|
566 |
+
check-str-concat-over-line-jumps=no
|
567 |
+
|
568 |
+
|
569 |
+
[TYPECHECK]
|
570 |
+
|
571 |
+
# List of decorators that produce context managers, such as
|
572 |
+
# contextlib.contextmanager. Add to this list to register other decorators that
|
573 |
+
# produce valid context managers.
|
574 |
+
contextmanager-decorators=contextlib.contextmanager
|
575 |
+
|
576 |
+
# List of members which are set dynamically and missed by pylint inference
|
577 |
+
# system, and so shouldn't trigger E1101 when accessed. Python regular
|
578 |
+
# expressions are accepted.
|
579 |
+
generated-members=firebase_admin.firestore.*,firestore.*
|
580 |
+
|
581 |
+
# Tells whether to warn about missing members when the owner of the attribute
|
582 |
+
# is inferred to be None.
|
583 |
+
ignore-none=yes
|
584 |
+
|
585 |
+
# This flag controls whether pylint should warn about no-member and similar
|
586 |
+
# checks whenever an opaque object is returned when inferring. The inference
|
587 |
+
# can return multiple potential results while evaluating a Python object, but
|
588 |
+
# some branches might not be evaluated, which results in partial inference. In
|
589 |
+
# that case, it might be useful to still emit no-member and other checks for
|
590 |
+
# the rest of the inferred objects.
|
591 |
+
ignore-on-opaque-inference=yes
|
592 |
+
|
593 |
+
# List of symbolic message names to ignore for Mixin members.
|
594 |
+
ignored-checks-for-mixins=no-member,
|
595 |
+
not-async-context-manager,
|
596 |
+
not-context-manager,
|
597 |
+
attribute-defined-outside-init
|
598 |
+
|
599 |
+
# List of class names for which member attributes should not be checked (useful
|
600 |
+
# for classes with dynamically set attributes). This supports the use of
|
601 |
+
# qualified names.
|
602 |
+
ignored-classes=optparse.Values,thread._local,_thread._local,argparse.Namespace
|
603 |
+
|
604 |
+
# Show a hint with possible names when a member name was not found. The aspect
|
605 |
+
# of finding the hint is based on edit distance.
|
606 |
+
missing-member-hint=yes
|
607 |
+
|
608 |
+
# The minimum edit distance a name should have in order to be considered a
|
609 |
+
# similar match for a missing member name.
|
610 |
+
missing-member-hint-distance=1
|
611 |
+
|
612 |
+
# The total number of similar names that should be taken in consideration when
|
613 |
+
# showing a hint for a missing member.
|
614 |
+
missing-member-max-choices=1
|
615 |
+
|
616 |
+
# Regex pattern to define which classes are considered mixins.
|
617 |
+
mixin-class-rgx=.*[Mm]ixin
|
618 |
+
|
619 |
+
# List of decorators that change the signature of a decorated function.
|
620 |
+
signature-mutators=
|
621 |
+
|
622 |
+
|
623 |
+
[VARIABLES]
|
624 |
+
|
625 |
+
# List of additional names supposed to be defined in builtins. Remember that
|
626 |
+
# you should avoid defining new builtins when possible.
|
627 |
+
additional-builtins=
|
628 |
+
|
629 |
+
# Tells whether unused global variables should be treated as a violation.
|
630 |
+
allow-global-unused-variables=yes
|
631 |
+
|
632 |
+
# List of names allowed to shadow builtins
|
633 |
+
allowed-redefined-builtins=
|
634 |
+
|
635 |
+
# List of strings which can identify a callback function by name. A callback
|
636 |
+
# name must start or end with one of those strings.
|
637 |
+
callbacks=cb_,
|
638 |
+
_cb
|
639 |
+
|
640 |
+
# A regular expression matching the name of dummy variables (i.e. expected to
|
641 |
+
# not be used).
|
642 |
+
dummy-variables-rgx=_+$|(_[a-zA-Z0-9_]*[a-zA-Z0-9]+?$)|dummy|^ignored_|^unused_
|
643 |
+
|
644 |
+
# Argument names that match this expression will be ignored.
|
645 |
+
ignored-argument-names=_.*|^ignored_|^unused_
|
646 |
+
|
647 |
+
# Tells whether we should check for unused import in __init__ files.
|
648 |
+
init-import=no
|
649 |
+
|
650 |
+
# List of qualified module names which can have objects that can redefine
|
651 |
+
# builtins.
|
652 |
+
redefining-builtins-modules=six.moves,past.builtins,future.builtins,builtins,io
|
.vscode/launch.json
ADDED
@@ -0,0 +1,47 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
// Use IntelliSense to learn about possible attributes.
|
3 |
+
// Hover to view descriptions of existing attributes.
|
4 |
+
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
5 |
+
"version": "0.2.0",
|
6 |
+
"configurations": [
|
7 |
+
{
|
8 |
+
"name": "debug go",
|
9 |
+
"type": "go",
|
10 |
+
"request": "launch",
|
11 |
+
"mode": "exec",
|
12 |
+
"cwd": "${workspaceFolder}",
|
13 |
+
"program": "${workspaceFolder}/agents/bin/worker",
|
14 |
+
"env": {
|
15 |
+
"LD_LIBRARY_PATH": "${workspaceFolder}/agents/ten_packages/system/ten_runtime_go/lib:${workspaceFolder}/agents/ten_packages/system/agora_rtc_sdk/lib:${workspaceFolder}/agents/ten_packages/system/azure_speech_sdk/lib",
|
16 |
+
"TEN_APP_BASE_DIR": "${workspaceFolder}/agents"
|
17 |
+
}
|
18 |
+
},
|
19 |
+
{
|
20 |
+
"name": "debug python",
|
21 |
+
"type": "debugpy",
|
22 |
+
"request": "attach",
|
23 |
+
"connect": {
|
24 |
+
"host": "localhost",
|
25 |
+
"port": 5678
|
26 |
+
},
|
27 |
+
"preLaunchTask": "start app"
|
28 |
+
},
|
29 |
+
{
|
30 |
+
"name": "debug cpp",
|
31 |
+
"type": "cppdbg",
|
32 |
+
"request": "launch",
|
33 |
+
"program": "${workspaceFolder}/agents/bin/worker",
|
34 |
+
"cwd": "${workspaceFolder}",
|
35 |
+
"environment": [
|
36 |
+
{
|
37 |
+
"name": "LD_LIBRARY_PATH",
|
38 |
+
"value": "${workspaceFolder}/agents/ten_packages/system/agora_rtc_sdk/lib:${workspaceFolder}/agents/ten_packages/system/azure_speech_sdk/lib"
|
39 |
+
},
|
40 |
+
{
|
41 |
+
"name": "CGO_LDFLAGS",
|
42 |
+
"value": "-L${workspaceFolder}/agents/ten_packages/system/ten_runtime_go/lib -lten_runtime_go -Wl,-rpath,@loader_path/lib -Wl,-rpath,@loader_path/../lib"
|
43 |
+
}
|
44 |
+
]
|
45 |
+
}
|
46 |
+
]
|
47 |
+
}
|
.vscode/settings.json
ADDED
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"C_Cpp.intelliSenseEngine": "disabled",
|
3 |
+
"editor.formatOnSave": true,
|
4 |
+
"editor.defaultFormatter": null,
|
5 |
+
"[python]": {
|
6 |
+
"editor.defaultFormatter": "ms-python.black-formatter"
|
7 |
+
},
|
8 |
+
"git.ignoreLimitWarning": true,
|
9 |
+
"pylint.ignorePatterns": [
|
10 |
+
"*/ten_runtime_python/**/*",
|
11 |
+
"/usr/lib/**/*"
|
12 |
+
],
|
13 |
+
}
|
.vscode/tasks.json
ADDED
@@ -0,0 +1,22 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"version": "2.0.0",
|
3 |
+
"tasks": [
|
4 |
+
{
|
5 |
+
"type": "shell",
|
6 |
+
"label": "build",
|
7 |
+
"command": "make build",
|
8 |
+
"args": [],
|
9 |
+
"group": {
|
10 |
+
"kind": "build",
|
11 |
+
"isDefault": true
|
12 |
+
}
|
13 |
+
},
|
14 |
+
{
|
15 |
+
"label": "start app",
|
16 |
+
"type": "shell",
|
17 |
+
"command": "export TEN_ENABLE_PYTHON_DEBUG=true; export TEN_PYTHON_DEBUG_PORT=5678; ./agents/bin/start",
|
18 |
+
"group": "none",
|
19 |
+
"isBackground": true
|
20 |
+
},
|
21 |
+
]
|
22 |
+
}
|
Dockerfile
CHANGED
@@ -22,25 +22,22 @@ RUN apt-get clean && apt-get update && apt-get install -y --no-install-recommend
|
|
22 |
ca-certificates \
|
23 |
&& apt-get clean && rm -rf /var/lib/apt/lists/* && rm -rf /tmp/*
|
24 |
|
25 |
-
#
|
26 |
-
RUN useradd -m -s /bin/bash tenuser
|
27 |
-
|
28 |
-
# Установка Go 1.21 с правильными правами доступа
|
29 |
RUN wget https://golang.org/dl/go1.21.0.linux-amd64.tar.gz && \
|
30 |
tar -C /usr/local -xzf go1.21.0.linux-amd64.tar.gz && \
|
31 |
-
rm go1.21.0.linux-amd64.tar.gz
|
32 |
-
mkdir -p /home/tenuser/go && \
|
33 |
-
chown -R tenuser:tenuser /home/tenuser/go
|
34 |
-
|
35 |
ENV PATH=$PATH:/usr/local/go/bin
|
36 |
-
ENV GOPATH=/
|
37 |
ENV PATH=$PATH:$GOPATH/bin
|
38 |
|
39 |
-
# Установка Node.js 20.x и pnpm для Playground
|
40 |
RUN curl -fsSL https://deb.nodesource.com/setup_20.x | bash - && \
|
41 |
apt-get install -y nodejs && \
|
42 |
npm install -g pnpm
|
43 |
|
|
|
|
|
|
|
44 |
WORKDIR /app
|
45 |
|
46 |
# Клонирование репозитория TEN Agent (основная ветка)
|
@@ -73,7 +70,7 @@ RUN cd /app/server && \
|
|
73 |
|
74 |
# Сборка Playground UI с правами пользователя
|
75 |
WORKDIR /app/playground
|
76 |
-
ENV PNPM_HOME="/
|
77 |
ENV PATH="$PNPM_HOME:$PATH"
|
78 |
RUN pnpm install --no-frozen-lockfile && \
|
79 |
NEXT_PUBLIC_EDIT_GRAPH_MODE=false pnpm build
|
|
|
22 |
ca-certificates \
|
23 |
&& apt-get clean && rm -rf /var/lib/apt/lists/* && rm -rf /tmp/*
|
24 |
|
25 |
+
# Установка Go 1.21
|
|
|
|
|
|
|
26 |
RUN wget https://golang.org/dl/go1.21.0.linux-amd64.tar.gz && \
|
27 |
tar -C /usr/local -xzf go1.21.0.linux-amd64.tar.gz && \
|
28 |
+
rm go1.21.0.linux-amd64.tar.gz
|
|
|
|
|
|
|
29 |
ENV PATH=$PATH:/usr/local/go/bin
|
30 |
+
ENV GOPATH=/go
|
31 |
ENV PATH=$PATH:$GOPATH/bin
|
32 |
|
33 |
+
# Установка Node.js 20.x (вместо 18.x) и pnpm для Playground
|
34 |
RUN curl -fsSL https://deb.nodesource.com/setup_20.x | bash - && \
|
35 |
apt-get install -y nodejs && \
|
36 |
npm install -g pnpm
|
37 |
|
38 |
+
# Создаем пользователя для запуска приложения с правильными правами
|
39 |
+
RUN useradd -m -s /bin/bash tenuser
|
40 |
+
|
41 |
WORKDIR /app
|
42 |
|
43 |
# Клонирование репозитория TEN Agent (основная ветка)
|
|
|
70 |
|
71 |
# Сборка Playground UI с правами пользователя
|
72 |
WORKDIR /app/playground
|
73 |
+
ENV PNPM_HOME="/app/.pnpm-store"
|
74 |
ENV PATH="$PNPM_HOME:$PATH"
|
75 |
RUN pnpm install --no-frozen-lockfile && \
|
76 |
NEXT_PUBLIC_EDIT_GRAPH_MODE=false pnpm build
|
LICENSE
ADDED
@@ -0,0 +1,201 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
Apache License
|
2 |
+
Version 2.0, January 2004
|
3 |
+
http://www.apache.org/licenses/
|
4 |
+
|
5 |
+
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
6 |
+
|
7 |
+
1. Definitions.
|
8 |
+
|
9 |
+
"License" shall mean the terms and conditions for use, reproduction,
|
10 |
+
and distribution as defined by Sections 1 through 9 of this document.
|
11 |
+
|
12 |
+
"Licensor" shall mean the copyright owner or entity authorized by
|
13 |
+
the copyright owner that is granting the License.
|
14 |
+
|
15 |
+
"Legal Entity" shall mean the union of the acting entity and all
|
16 |
+
other entities that control, are controlled by, or are under common
|
17 |
+
control with that entity. For the purposes of this definition,
|
18 |
+
"control" means (i) the power, direct or indirect, to cause the
|
19 |
+
direction or management of such entity, whether by contract or
|
20 |
+
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
21 |
+
outstanding shares, or (iii) beneficial ownership of such entity.
|
22 |
+
|
23 |
+
"You" (or "Your") shall mean an individual or Legal Entity
|
24 |
+
exercising permissions granted by this License.
|
25 |
+
|
26 |
+
"Source" form shall mean the preferred form for making modifications,
|
27 |
+
including but not limited to software source code, documentation
|
28 |
+
source, and configuration files.
|
29 |
+
|
30 |
+
"Object" form shall mean any form resulting from mechanical
|
31 |
+
transformation or translation of a Source form, including but
|
32 |
+
not limited to compiled object code, generated documentation,
|
33 |
+
and conversions to other media types.
|
34 |
+
|
35 |
+
"Work" shall mean the work of authorship, whether in Source or
|
36 |
+
Object form, made available under the License, as indicated by a
|
37 |
+
copyright notice that is included in or attached to the work
|
38 |
+
(an example is provided in the Appendix below).
|
39 |
+
|
40 |
+
"Derivative Works" shall mean any work, whether in Source or Object
|
41 |
+
form, that is based on (or derived from) the Work and for which the
|
42 |
+
editorial revisions, annotations, elaborations, or other modifications
|
43 |
+
represent, as a whole, an original work of authorship. For the purposes
|
44 |
+
of this License, Derivative Works shall not include works that remain
|
45 |
+
separable from, or merely link (or bind by name) to the interfaces of,
|
46 |
+
the Work and Derivative Works thereof.
|
47 |
+
|
48 |
+
"Contribution" shall mean any work of authorship, including
|
49 |
+
the original version of the Work and any modifications or additions
|
50 |
+
to that Work or Derivative Works thereof, that is intentionally
|
51 |
+
submitted to Licensor for inclusion in the Work by the copyright owner
|
52 |
+
or by an individual or Legal Entity authorized to submit on behalf of
|
53 |
+
the copyright owner. For the purposes of this definition, "submitted"
|
54 |
+
means any form of electronic, verbal, or written communication sent
|
55 |
+
to the Licensor or its representatives, including but not limited to
|
56 |
+
communication on electronic mailing lists, source code control systems,
|
57 |
+
and issue tracking systems that are managed by, or on behalf of, the
|
58 |
+
Licensor for the purpose of discussing and improving the Work, but
|
59 |
+
excluding communication that is conspicuously marked or otherwise
|
60 |
+
designated in writing by the copyright owner as "Not a Contribution."
|
61 |
+
|
62 |
+
"Contributor" shall mean Licensor and any individual or Legal Entity
|
63 |
+
on behalf of whom a Contribution has been received by Licensor and
|
64 |
+
subsequently incorporated within the Work.
|
65 |
+
|
66 |
+
2. Grant of Copyright License. Subject to the terms and conditions of
|
67 |
+
this License, each Contributor hereby grants to You a perpetual,
|
68 |
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
69 |
+
copyright license to reproduce, prepare Derivative Works of,
|
70 |
+
publicly display, publicly perform, sublicense, and distribute the
|
71 |
+
Work and such Derivative Works in Source or Object form.
|
72 |
+
|
73 |
+
3. Grant of Patent License. Subject to the terms and conditions of
|
74 |
+
this License, each Contributor hereby grants to You a perpetual,
|
75 |
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
76 |
+
(except as stated in this section) patent license to make, have made,
|
77 |
+
use, offer to sell, sell, import, and otherwise transfer the Work,
|
78 |
+
where such license applies only to those patent claims licensable
|
79 |
+
by such Contributor that are necessarily infringed by their
|
80 |
+
Contribution(s) alone or by combination of their Contribution(s)
|
81 |
+
with the Work to which such Contribution(s) was submitted. If You
|
82 |
+
institute patent litigation against any entity (including a
|
83 |
+
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
84 |
+
or a Contribution incorporated within the Work constitutes direct
|
85 |
+
or contributory patent infringement, then any patent licenses
|
86 |
+
granted to You under this License for that Work shall terminate
|
87 |
+
as of the date such litigation is filed.
|
88 |
+
|
89 |
+
4. Redistribution. You may reproduce and distribute copies of the
|
90 |
+
Work or Derivative Works thereof in any medium, with or without
|
91 |
+
modifications, and in Source or Object form, provided that You
|
92 |
+
meet the following conditions:
|
93 |
+
|
94 |
+
(a) You must give any other recipients of the Work or
|
95 |
+
Derivative Works a copy of this License; and
|
96 |
+
|
97 |
+
(b) You must cause any modified files to carry prominent notices
|
98 |
+
stating that You changed the files; and
|
99 |
+
|
100 |
+
(c) You must retain, in the Source form of any Derivative Works
|
101 |
+
that You distribute, all copyright, patent, trademark, and
|
102 |
+
attribution notices from the Source form of the Work,
|
103 |
+
excluding those notices that do not pertain to any part of
|
104 |
+
the Derivative Works; and
|
105 |
+
|
106 |
+
(d) If the Work includes a "NOTICE" text file as part of its
|
107 |
+
distribution, then any Derivative Works that You distribute must
|
108 |
+
include a readable copy of the attribution notices contained
|
109 |
+
within such NOTICE file, excluding those notices that do not
|
110 |
+
pertain to any part of the Derivative Works, in at least one
|
111 |
+
of the following places: within a NOTICE text file distributed
|
112 |
+
as part of the Derivative Works; within the Source form or
|
113 |
+
documentation, if provided along with the Derivative Works; or,
|
114 |
+
within a display generated by the Derivative Works, if and
|
115 |
+
wherever such third-party notices normally appear. The contents
|
116 |
+
of the NOTICE file are for informational purposes only and
|
117 |
+
do not modify the License. You may add Your own attribution
|
118 |
+
notices within Derivative Works that You distribute, alongside
|
119 |
+
or as an addendum to the NOTICE text from the Work, provided
|
120 |
+
that such additional attribution notices cannot be construed
|
121 |
+
as modifying the License.
|
122 |
+
|
123 |
+
You may add Your own copyright statement to Your modifications and
|
124 |
+
may provide additional or different license terms and conditions
|
125 |
+
for use, reproduction, or distribution of Your modifications, or
|
126 |
+
for any such Derivative Works as a whole, provided Your use,
|
127 |
+
reproduction, and distribution of the Work otherwise complies with
|
128 |
+
the conditions stated in this License.
|
129 |
+
|
130 |
+
5. Submission of Contributions. Unless You explicitly state otherwise,
|
131 |
+
any Contribution intentionally submitted for inclusion in the Work
|
132 |
+
by You to the Licensor shall be under the terms and conditions of
|
133 |
+
this License, without any additional terms or conditions.
|
134 |
+
Notwithstanding the above, nothing herein shall supersede or modify
|
135 |
+
the terms of any separate license agreement you may have executed
|
136 |
+
with Licensor regarding such Contributions.
|
137 |
+
|
138 |
+
6. Trademarks. This License does not grant permission to use the trade
|
139 |
+
names, trademarks, service marks, or product names of the Licensor,
|
140 |
+
except as required for reasonable and customary use in describing the
|
141 |
+
origin of the Work and reproducing the content of the NOTICE file.
|
142 |
+
|
143 |
+
7. Disclaimer of Warranty. Unless required by applicable law or
|
144 |
+
agreed to in writing, Licensor provides the Work (and each
|
145 |
+
Contributor provides its Contributions) on an "AS IS" BASIS,
|
146 |
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
147 |
+
implied, including, without limitation, any warranties or conditions
|
148 |
+
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
149 |
+
PARTICULAR PURPOSE. You are solely responsible for determining the
|
150 |
+
appropriateness of using or redistributing the Work and assume any
|
151 |
+
risks associated with Your exercise of permissions under this License.
|
152 |
+
|
153 |
+
8. Limitation of Liability. In no event and under no legal theory,
|
154 |
+
whether in tort (including negligence), contract, or otherwise,
|
155 |
+
unless required by applicable law (such as deliberate and grossly
|
156 |
+
negligent acts) or agreed to in writing, shall any Contributor be
|
157 |
+
liable to You for damages, including any direct, indirect, special,
|
158 |
+
incidental, or consequential damages of any character arising as a
|
159 |
+
result of this License or out of the use or inability to use the
|
160 |
+
Work (including but not limited to damages for loss of goodwill,
|
161 |
+
work stoppage, computer failure or malfunction, or any and all
|
162 |
+
other commercial damages or losses), even if such Contributor
|
163 |
+
has been advised of the possibility of such damages.
|
164 |
+
|
165 |
+
9. Accepting Warranty or Additional Liability. While redistributing
|
166 |
+
the Work or Derivative Works thereof, You may choose to offer,
|
167 |
+
and charge a fee for, acceptance of support, warranty, indemnity,
|
168 |
+
or other liability obligations and/or rights consistent with this
|
169 |
+
License. However, in accepting such obligations, You may act only
|
170 |
+
on Your own behalf and on Your sole responsibility, not on behalf
|
171 |
+
of any other Contributor, and only if You agree to indemnify,
|
172 |
+
defend, and hold each Contributor harmless for any liability
|
173 |
+
incurred by, or claims asserted against, such Contributor by reason
|
174 |
+
of your accepting any such warranty or additional liability.
|
175 |
+
|
176 |
+
END OF TERMS AND CONDITIONS
|
177 |
+
|
178 |
+
APPENDIX: How to apply the Apache License to your work.
|
179 |
+
|
180 |
+
To apply the Apache License to your work, attach the following
|
181 |
+
boilerplate notice, with the fields enclosed by brackets "[]"
|
182 |
+
replaced with your own identifying information. (Don't include
|
183 |
+
the brackets!) The text should be enclosed in the appropriate
|
184 |
+
comment syntax for the file format. We also recommend that a
|
185 |
+
file or class name and description of purpose be included on the
|
186 |
+
same "printed page" as the copyright notice for easier
|
187 |
+
identification within third-party archives.
|
188 |
+
|
189 |
+
Copyright [yyyy] [name of copyright owner]
|
190 |
+
|
191 |
+
Licensed under the Apache License, Version 2.0 (the "License");
|
192 |
+
you may not use this file except in compliance with the License.
|
193 |
+
You may obtain a copy of the License at
|
194 |
+
|
195 |
+
http://www.apache.org/licenses/LICENSE-2.0
|
196 |
+
|
197 |
+
Unless required by applicable law or agreed to in writing, software
|
198 |
+
distributed under the License is distributed on an "AS IS" BASIS,
|
199 |
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
200 |
+
See the License for the specific language governing permissions and
|
201 |
+
limitations under the License.
|
Taskfile.yml
ADDED
@@ -0,0 +1,120 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
version: '3'
|
2 |
+
|
3 |
+
tasks:
|
4 |
+
clean:
|
5 |
+
desc: clean up
|
6 |
+
cmds:
|
7 |
+
- task: clean-agents
|
8 |
+
- task: clean-server
|
9 |
+
|
10 |
+
lint:
|
11 |
+
desc: lint-agent
|
12 |
+
env:
|
13 |
+
PYTHONPATH: "./agents/ten_packages/system/ten_runtime_python/lib:./agents/ten_packages/system/ten_runtime_python/interface:./agents/ten_packages/system/ten_ai_base/interface"
|
14 |
+
cmds:
|
15 |
+
- ./agents/scripts/pylint.sh
|
16 |
+
|
17 |
+
install-tools:
|
18 |
+
desc: install tools
|
19 |
+
cmds:
|
20 |
+
- pip install pylint
|
21 |
+
|
22 |
+
build:
|
23 |
+
desc: build
|
24 |
+
cmds:
|
25 |
+
- task: build-agent
|
26 |
+
- task: build-server
|
27 |
+
|
28 |
+
use:
|
29 |
+
desc: use agent, default 'agents/examples/default'
|
30 |
+
vars:
|
31 |
+
AGENT: '{{.AGENT| default "agents/examples/default"}}'
|
32 |
+
cmds:
|
33 |
+
- ln -sf {{.USER_WORKING_DIR}}/{{.AGENT}}/manifest.json ./agents/
|
34 |
+
- ln -sf {{.USER_WORKING_DIR}}/{{.AGENT}}/property.json ./agents/
|
35 |
+
- task: build
|
36 |
+
|
37 |
+
run-server:
|
38 |
+
desc: run backend http server
|
39 |
+
cmds:
|
40 |
+
- source .env && /app/server/bin/api
|
41 |
+
|
42 |
+
run-gd-server:
|
43 |
+
desc: run tman dev http server for graph designer
|
44 |
+
dir: ./agents
|
45 |
+
cmds:
|
46 |
+
- tman designer
|
47 |
+
|
48 |
+
run:
|
49 |
+
desc: run servers
|
50 |
+
deps:
|
51 |
+
- task: run-server
|
52 |
+
- task: run-gd-server
|
53 |
+
|
54 |
+
build-agent:
|
55 |
+
desc: build agent
|
56 |
+
dir: ./agents
|
57 |
+
internal: true
|
58 |
+
cmds:
|
59 |
+
- ./scripts/install_deps_and_build.sh linux x64 && mv bin/main bin/worker
|
60 |
+
|
61 |
+
build-server:
|
62 |
+
desc: build server
|
63 |
+
dir: ./server
|
64 |
+
cmds:
|
65 |
+
- go mod tidy && go mod download && go build -o bin/api main.go
|
66 |
+
|
67 |
+
clean-agents:
|
68 |
+
desc: clean up agents
|
69 |
+
dir: ./agents
|
70 |
+
internal: true
|
71 |
+
cmds:
|
72 |
+
- rm -rf manifest.json property.json manifest-lock.json bin/main bin/worker out .release ten_packages/system ten_packages/system/agora_rtc_sdk ten_packages/system/azure_speech_sdk ten_packages/system/nlohmann_json ten_packages/extension/agora_rtc ten_packages/extension/agora_rtm ten_packages/extension/agora_sess_ctrl ten_packages/extension/azure_tts ten_packages/addon_loader
|
73 |
+
- find . -type d -name .pytest_cache -exec rm -rf {} \; || true
|
74 |
+
- find . -type d -name __pycache__ -exec rm -rf {} \; || true
|
75 |
+
- find . -type d -name .ten -exec rm -rf {} \; || true
|
76 |
+
- find . -name .coverage -exec rm -f {} \; || true
|
77 |
+
|
78 |
+
clean-server:
|
79 |
+
desc: clean up server
|
80 |
+
dir: ./server
|
81 |
+
internal: true
|
82 |
+
cmds:
|
83 |
+
- rm -rf bin
|
84 |
+
|
85 |
+
test:
|
86 |
+
desc: run tests
|
87 |
+
cmds:
|
88 |
+
- task: test-agent-extensions
|
89 |
+
- task: test-server
|
90 |
+
|
91 |
+
test-server:
|
92 |
+
desc: test server
|
93 |
+
dir: ./server
|
94 |
+
internal: true
|
95 |
+
cmds:
|
96 |
+
- go test -v ./...
|
97 |
+
|
98 |
+
test-agent-extensions:
|
99 |
+
desc: run standalone testing of extensions
|
100 |
+
internal: true
|
101 |
+
env:
|
102 |
+
PYTHONPATH: "{{.USER_WORKING_DIR}}:{{.USER_WORKING_DIR}}/agents/ten_packages/system/ten_runtime_python/lib:{{.USER_WORKING_DIR}}/agents/ten_packages/system/ten_runtime_python/interface:{{.USER_WORKING_DIR}}/agents/ten_packages/system/ten_ai_base/interface"
|
103 |
+
vars:
|
104 |
+
EXTENSIONS:
|
105 |
+
sh: 'find agents/ten_packages/extension -type d -exec test -d "{}/tests" \; -print'
|
106 |
+
cmds:
|
107 |
+
- for: { var: EXTENSIONS }
|
108 |
+
task: test-extension
|
109 |
+
vars:
|
110 |
+
EXTENSION: '{{ .ITEM }}'
|
111 |
+
|
112 |
+
test-extension:
|
113 |
+
desc: run standalone testing of one single extension
|
114 |
+
vars:
|
115 |
+
EXTENSION: '{{.EXTENSION| default "agents/ten_packages/extension/elevenlabs_tts_python"}}'
|
116 |
+
env:
|
117 |
+
PYTHONPATH: "{{.USER_WORKING_DIR}}:{{.USER_WORKING_DIR}}/agents/ten_packages/system/ten_runtime_python/lib:{{.USER_WORKING_DIR}}/agents/ten_packages/system/ten_runtime_python/interface:{{.USER_WORKING_DIR}}/agents/ten_packages/system/ten_ai_base/interface"
|
118 |
+
dotenv: ['.env']
|
119 |
+
cmds:
|
120 |
+
- cd {{.EXTENSION}} && tman -y install --standalone && ./tests/bin/start {{ .CLI_ARGS }}
|
agents/.clang-format
ADDED
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
BasedOnStyle: Google
|
2 |
+
SeparateDefinitionBlocks: Always
|
3 |
+
ColumnLimit: 120
|
4 |
+
BinPackArguments: false
|
5 |
+
BinPackParameters: false
|
6 |
+
AlignAfterOpenBracket: Align
|
7 |
+
AllowAllArgumentsOnNextLine: false
|
8 |
+
AllowAllParametersOfDeclarationOnNextLine: false
|
agents/.gitignore
ADDED
@@ -0,0 +1,43 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
*.log
|
2 |
+
ten_packages/extension_group/
|
3 |
+
ten_packages/extension/agora_rtc
|
4 |
+
ten_packages/extension/azure_tts
|
5 |
+
ten_packages/extension/agora_sess_ctrl
|
6 |
+
ten_packages/extension/agora_rtm
|
7 |
+
ten_packages/extension/http_server_python
|
8 |
+
ten_packages/system/agora_rtc_sdk
|
9 |
+
ten_packages/system/azure_speech_sdk
|
10 |
+
ten_packages/system/nlohmann_json
|
11 |
+
ten_packages/system/ten_runtime*
|
12 |
+
ten_packages/system
|
13 |
+
ten_packages/addon_loader
|
14 |
+
.ten
|
15 |
+
agoradns.dat
|
16 |
+
agorareport.dat
|
17 |
+
agorartmreport.dat
|
18 |
+
agora_cache.db
|
19 |
+
bin/man
|
20 |
+
bin/worker
|
21 |
+
/BUILD.gn
|
22 |
+
.cache/
|
23 |
+
/compile_commands.json
|
24 |
+
core
|
25 |
+
crash_context_v1
|
26 |
+
.deps/
|
27 |
+
.DS_Store
|
28 |
+
/.gn
|
29 |
+
/.gnfiles
|
30 |
+
include/
|
31 |
+
interface/
|
32 |
+
lib/
|
33 |
+
/out/
|
34 |
+
*.pcm
|
35 |
+
.release
|
36 |
+
session_control.conf.agora
|
37 |
+
xdump_config
|
38 |
+
.vscode
|
39 |
+
*.pyc
|
40 |
+
*.pyc.*
|
41 |
+
/manifest.json
|
42 |
+
/manifest-lock.json
|
43 |
+
/property.json
|
agents/bin/start
ADDED
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#!/bin/bash
|
2 |
+
|
3 |
+
set -e
|
4 |
+
|
5 |
+
cd "$(dirname "${BASH_SOURCE[0]}")/.."
|
6 |
+
|
7 |
+
#export TEN_ENABLE_PYTHON_DEBUG=true
|
8 |
+
#export TEN_PYTHON_DEBUG_PORT=5678
|
9 |
+
export PYTHONPATH=$(pwd)/ten_packages/system/ten_ai_base/interface:$PYTHONPATH
|
10 |
+
export LD_LIBRARY_PATH=$(pwd)/ten_packages/system/agora_rtc_sdk/lib:$(pwd)/ten_packages/extension/agora_rtm/lib:$(pwd)/ten_packages/system/azure_speech_sdk/lib
|
11 |
+
|
12 |
+
exec bin/worker "$@"
|
agents/examples/default/manifest.json
ADDED
@@ -0,0 +1,152 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"type": "app",
|
3 |
+
"name": "agent_demo",
|
4 |
+
"version": "0.8.0",
|
5 |
+
"dependencies": [
|
6 |
+
{
|
7 |
+
"type": "system",
|
8 |
+
"name": "ten_runtime_go",
|
9 |
+
"version": "0.8"
|
10 |
+
},
|
11 |
+
{
|
12 |
+
"type": "extension",
|
13 |
+
"name": "agora_rtc",
|
14 |
+
"version": "=0.12.0"
|
15 |
+
},
|
16 |
+
{
|
17 |
+
"type": "extension",
|
18 |
+
"name": "agora_sess_ctrl",
|
19 |
+
"version": "=0.4.4"
|
20 |
+
},
|
21 |
+
{
|
22 |
+
"type": "system",
|
23 |
+
"name": "azure_speech_sdk",
|
24 |
+
"version": "1.38.0"
|
25 |
+
},
|
26 |
+
{
|
27 |
+
"type": "system",
|
28 |
+
"name": "ten_ai_base",
|
29 |
+
"version": "0.4.1"
|
30 |
+
},
|
31 |
+
{
|
32 |
+
"type": "extension",
|
33 |
+
"name": "azure_tts",
|
34 |
+
"version": "=0.8.1"
|
35 |
+
},
|
36 |
+
{
|
37 |
+
"type": "extension",
|
38 |
+
"name": "openai_v2v_python",
|
39 |
+
"version": "=0.1.0"
|
40 |
+
},
|
41 |
+
{
|
42 |
+
"type": "extension",
|
43 |
+
"name": "message_collector",
|
44 |
+
"version": "=0.1.0"
|
45 |
+
},
|
46 |
+
{
|
47 |
+
"type": "extension",
|
48 |
+
"name": "bingsearch_tool_python",
|
49 |
+
"version": "=0.1.0"
|
50 |
+
},
|
51 |
+
{
|
52 |
+
"type": "extension",
|
53 |
+
"name": "openai_chatgpt_python",
|
54 |
+
"version": "=0.1.0"
|
55 |
+
},
|
56 |
+
{
|
57 |
+
"type": "extension",
|
58 |
+
"name": "fish_audio_tts",
|
59 |
+
"version": "=0.1.0"
|
60 |
+
},
|
61 |
+
{
|
62 |
+
"type": "extension",
|
63 |
+
"name": "interrupt_detector_python",
|
64 |
+
"version": "=0.1.0"
|
65 |
+
},
|
66 |
+
{
|
67 |
+
"type": "extension",
|
68 |
+
"name": "weatherapi_tool_python",
|
69 |
+
"version": "=0.1.0"
|
70 |
+
},
|
71 |
+
{
|
72 |
+
"type": "extension",
|
73 |
+
"name": "deepgram_asr_python",
|
74 |
+
"version": "=0.1.0"
|
75 |
+
},
|
76 |
+
{
|
77 |
+
"type": "extension",
|
78 |
+
"name": "vision_tool_python",
|
79 |
+
"version": "=0.1.0"
|
80 |
+
},
|
81 |
+
{
|
82 |
+
"type": "extension",
|
83 |
+
"name": "vision_analyze_tool_python",
|
84 |
+
"version": "=0.1.0"
|
85 |
+
},
|
86 |
+
{
|
87 |
+
"type": "extension",
|
88 |
+
"name": "transcribe_asr_python",
|
89 |
+
"version": "=0.1.0"
|
90 |
+
},
|
91 |
+
{
|
92 |
+
"type": "extension",
|
93 |
+
"name": "gemini_llm_python",
|
94 |
+
"version": "=0.1.0"
|
95 |
+
},
|
96 |
+
{
|
97 |
+
"type": "extension",
|
98 |
+
"name": "bedrock_llm_python",
|
99 |
+
"version": "=0.1.0"
|
100 |
+
},
|
101 |
+
{
|
102 |
+
"type": "extension",
|
103 |
+
"name": "polly_tts",
|
104 |
+
"version": "=0.1.0"
|
105 |
+
},
|
106 |
+
{
|
107 |
+
"type": "extension",
|
108 |
+
"name": "minimax_tts_python",
|
109 |
+
"version": "=0.1.0"
|
110 |
+
},
|
111 |
+
{
|
112 |
+
"type": "extension",
|
113 |
+
"name": "minimax_v2v_python",
|
114 |
+
"version": "=0.1.0"
|
115 |
+
},
|
116 |
+
{
|
117 |
+
"type": "extension",
|
118 |
+
"name": "cosy_tts_python",
|
119 |
+
"version": "=0.1.0"
|
120 |
+
},
|
121 |
+
{
|
122 |
+
"type": "extension",
|
123 |
+
"name": "elevenlabs_tts_python",
|
124 |
+
"version": "=0.1.0"
|
125 |
+
},
|
126 |
+
{
|
127 |
+
"type": "extension",
|
128 |
+
"name": "dify_python",
|
129 |
+
"version": "=0.1.0"
|
130 |
+
},
|
131 |
+
{
|
132 |
+
"type": "extension",
|
133 |
+
"name": "gemini_v2v_python",
|
134 |
+
"version": "=0.1.0"
|
135 |
+
},
|
136 |
+
{
|
137 |
+
"type": "extension",
|
138 |
+
"name": "coze_python_async",
|
139 |
+
"version": "=0.1.0"
|
140 |
+
},
|
141 |
+
{
|
142 |
+
"type": "extension",
|
143 |
+
"name": "openai_image_generate_tool",
|
144 |
+
"version": "=0.1.0"
|
145 |
+
},
|
146 |
+
{
|
147 |
+
"type": "extension",
|
148 |
+
"name": "computer_tool_python",
|
149 |
+
"version": "=0.1.0"
|
150 |
+
}
|
151 |
+
]
|
152 |
+
}
|
agents/examples/default/property.json
ADDED
@@ -0,0 +1,1331 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"_ten": {
|
3 |
+
"predefined_graphs": [
|
4 |
+
{
|
5 |
+
"name": "voice_assistant",
|
6 |
+
"auto_start": true,
|
7 |
+
"nodes": [
|
8 |
+
{
|
9 |
+
"type": "extension",
|
10 |
+
"name": "agora_rtc",
|
11 |
+
"addon": "agora_rtc",
|
12 |
+
"extension_group": "default",
|
13 |
+
"property": {
|
14 |
+
"app_id": "${env:AGORA_APP_ID}",
|
15 |
+
"token": "<agora_token>",
|
16 |
+
"channel": "ten_agent_test",
|
17 |
+
"stream_id": 1234,
|
18 |
+
"remote_stream_id": "123",
|
19 |
+
"subscribe_audio": true,
|
20 |
+
"publish_audio": true,
|
21 |
+
"publish_data": true,
|
22 |
+
"enable_agora_asr": false,
|
23 |
+
"agora_asr_vendor_name": "microsoft",
|
24 |
+
"agora_asr_language": "ru-RU",
|
25 |
+
"agora_asr_vendor_key": "${env:AZURE_STT_KEY|}",
|
26 |
+
"agora_asr_vendor_region": "${env:AZURE_STT_REGION|}",
|
27 |
+
"agora_asr_session_control_file_path": "session_control.conf"
|
28 |
+
}
|
29 |
+
},
|
30 |
+
{
|
31 |
+
"type": "extension",
|
32 |
+
"name": "stt",
|
33 |
+
"addon": "deepgram_asr_python",
|
34 |
+
"extension_group": "stt",
|
35 |
+
"property": {
|
36 |
+
"api_key": "${env:DEEPGRAM_API_KEY}",
|
37 |
+
"language": "ru-RU",
|
38 |
+
"model": "nova-2",
|
39 |
+
"sample_rate": 16000
|
40 |
+
}
|
41 |
+
},
|
42 |
+
{
|
43 |
+
"type": "extension",
|
44 |
+
"name": "llm",
|
45 |
+
"addon": "openai_chatgpt_python",
|
46 |
+
"extension_group": "chatgpt",
|
47 |
+
"property": {
|
48 |
+
"api_key": "${env:OPENAI_API_KEY}",
|
49 |
+
"base_url": "https://nitrox-fastflowwrapper.hf.space/v1",
|
50 |
+
"frequency_penalty": 0.9,
|
51 |
+
"greeting": "Я подключилась, о чем сегодня?",
|
52 |
+
"max_memory_length": 150,
|
53 |
+
"max_tokens": 512,
|
54 |
+
"model": "${env:OPENAI_MODEL}",
|
55 |
+
"prompt": "Your role is Friend. You provide emotional support, actively listen and reflect on the user's feelings, validate their emotions, and ask open-ended questions to deepen the conversation in a safe and non-judgmental space. Engage informally and share personal experiences while respecting boundaries and encouraging the user. Maintain clarity and conciseness by replying in no more than five sentences per answer using friendly English language. Your responses must always include answers to the user's inquiries while offering insights, comfort, and encouragement without using any special symbols. Your language is Russian.",
|
56 |
+
"proxy_url": "${env:OPENAI_PROXY_URL}"
|
57 |
+
}
|
58 |
+
},
|
59 |
+
{
|
60 |
+
"type": "extension",
|
61 |
+
"name": "tts",
|
62 |
+
"addon": "fish_audio_tts",
|
63 |
+
"extension_group": "tts",
|
64 |
+
"property": {
|
65 |
+
"api_key": "${env:FISH_AUDIO_TTS_KEY}",
|
66 |
+
"base_url": "https://api.fish.audio",
|
67 |
+
"model_id": "d61694f4ee5042aba2ffe11a9635d97e",
|
68 |
+
"optimize_streaming_latency": true,
|
69 |
+
"request_timeout_seconds": 30
|
70 |
+
}
|
71 |
+
},
|
72 |
+
{
|
73 |
+
"type": "extension",
|
74 |
+
"name": "interrupt_detector",
|
75 |
+
"addon": "interrupt_detector_python",
|
76 |
+
"extension_group": "default",
|
77 |
+
"property": {}
|
78 |
+
},
|
79 |
+
{
|
80 |
+
"type": "extension",
|
81 |
+
"name": "message_collector",
|
82 |
+
"addon": "message_collector",
|
83 |
+
"extension_group": "transcriber",
|
84 |
+
"property": {}
|
85 |
+
}
|
86 |
+
],
|
87 |
+
"connections": [
|
88 |
+
{
|
89 |
+
"extension": "agora_rtc",
|
90 |
+
"cmd": [
|
91 |
+
{
|
92 |
+
"name": "on_user_joined",
|
93 |
+
"dest": [
|
94 |
+
{
|
95 |
+
"extension": "llm"
|
96 |
+
}
|
97 |
+
]
|
98 |
+
},
|
99 |
+
{
|
100 |
+
"name": "on_user_left",
|
101 |
+
"dest": [
|
102 |
+
{
|
103 |
+
"extension": "llm"
|
104 |
+
}
|
105 |
+
]
|
106 |
+
},
|
107 |
+
{
|
108 |
+
"name": "on_connection_failure",
|
109 |
+
"dest": [
|
110 |
+
{
|
111 |
+
"extension": "llm"
|
112 |
+
}
|
113 |
+
]
|
114 |
+
}
|
115 |
+
],
|
116 |
+
"audio_frame": [
|
117 |
+
{
|
118 |
+
"name": "pcm_frame",
|
119 |
+
"dest": [
|
120 |
+
{
|
121 |
+
"extension": "stt"
|
122 |
+
}
|
123 |
+
]
|
124 |
+
}
|
125 |
+
]
|
126 |
+
},
|
127 |
+
{
|
128 |
+
"extension": "stt",
|
129 |
+
"data": [
|
130 |
+
{
|
131 |
+
"name": "text_data",
|
132 |
+
"dest": [
|
133 |
+
{
|
134 |
+
"extension": "interrupt_detector"
|
135 |
+
},
|
136 |
+
{
|
137 |
+
"extension": "message_collector"
|
138 |
+
}
|
139 |
+
]
|
140 |
+
}
|
141 |
+
]
|
142 |
+
},
|
143 |
+
{
|
144 |
+
"extension": "llm",
|
145 |
+
"cmd": [
|
146 |
+
{
|
147 |
+
"name": "flush",
|
148 |
+
"dest": [
|
149 |
+
{
|
150 |
+
"extension": "tts"
|
151 |
+
}
|
152 |
+
]
|
153 |
+
}
|
154 |
+
],
|
155 |
+
"data": [
|
156 |
+
{
|
157 |
+
"name": "text_data",
|
158 |
+
"dest": [
|
159 |
+
{
|
160 |
+
"extension": "tts"
|
161 |
+
},
|
162 |
+
{
|
163 |
+
"extension": "message_collector"
|
164 |
+
}
|
165 |
+
]
|
166 |
+
},
|
167 |
+
{
|
168 |
+
"name": "content_data",
|
169 |
+
"dest": [
|
170 |
+
{
|
171 |
+
"extension": "message_collector"
|
172 |
+
}
|
173 |
+
]
|
174 |
+
}
|
175 |
+
]
|
176 |
+
},
|
177 |
+
{
|
178 |
+
"extension": "message_collector",
|
179 |
+
"data": [
|
180 |
+
{
|
181 |
+
"name": "data",
|
182 |
+
"dest": [
|
183 |
+
{
|
184 |
+
"extension": "agora_rtc"
|
185 |
+
}
|
186 |
+
]
|
187 |
+
}
|
188 |
+
]
|
189 |
+
},
|
190 |
+
{
|
191 |
+
"extension": "tts",
|
192 |
+
"cmd": [
|
193 |
+
{
|
194 |
+
"name": "flush",
|
195 |
+
"dest": [
|
196 |
+
{
|
197 |
+
"extension": "agora_rtc"
|
198 |
+
}
|
199 |
+
]
|
200 |
+
}
|
201 |
+
],
|
202 |
+
"audio_frame": [
|
203 |
+
{
|
204 |
+
"name": "pcm_frame",
|
205 |
+
"dest": [
|
206 |
+
{
|
207 |
+
"extension": "agora_rtc"
|
208 |
+
}
|
209 |
+
]
|
210 |
+
}
|
211 |
+
]
|
212 |
+
},
|
213 |
+
{
|
214 |
+
"extension": "interrupt_detector",
|
215 |
+
"cmd": [
|
216 |
+
{
|
217 |
+
"name": "flush",
|
218 |
+
"dest": [
|
219 |
+
{
|
220 |
+
"extension": "llm"
|
221 |
+
}
|
222 |
+
]
|
223 |
+
}
|
224 |
+
],
|
225 |
+
"data": [
|
226 |
+
{
|
227 |
+
"name": "text_data",
|
228 |
+
"dest": [
|
229 |
+
{
|
230 |
+
"extension": "llm"
|
231 |
+
}
|
232 |
+
]
|
233 |
+
}
|
234 |
+
]
|
235 |
+
}
|
236 |
+
]
|
237 |
+
},
|
238 |
+
{
|
239 |
+
"name": "voice_assistant_integrated_stt",
|
240 |
+
"auto_start": true,
|
241 |
+
"nodes": [
|
242 |
+
{
|
243 |
+
"type": "extension",
|
244 |
+
"name": "agora_rtc",
|
245 |
+
"addon": "agora_rtc",
|
246 |
+
"extension_group": "default",
|
247 |
+
"property": {
|
248 |
+
"app_id": "${env:AGORA_APP_ID}",
|
249 |
+
"token": "<agora_token>",
|
250 |
+
"channel": "ten_agent_test",
|
251 |
+
"stream_id": 1234,
|
252 |
+
"remote_stream_id": 123,
|
253 |
+
"subscribe_audio": true,
|
254 |
+
"publish_audio": true,
|
255 |
+
"publish_data": true,
|
256 |
+
"enable_agora_asr": true,
|
257 |
+
"agora_asr_vendor_name": "microsoft",
|
258 |
+
"agora_asr_language": "en-US",
|
259 |
+
"agora_asr_vendor_key": "${env:AZURE_STT_KEY|}",
|
260 |
+
"agora_asr_vendor_region": "${env:AZURE_STT_REGION|}",
|
261 |
+
"agora_asr_session_control_file_path": "session_control.conf"
|
262 |
+
}
|
263 |
+
},
|
264 |
+
{
|
265 |
+
"type": "extension",
|
266 |
+
"name": "llm",
|
267 |
+
"addon": "openai_chatgpt_python",
|
268 |
+
"extension_group": "chatgpt",
|
269 |
+
"property": {
|
270 |
+
"api_key": "${env:OPENAI_API_KEY}",
|
271 |
+
"base_url": "",
|
272 |
+
"frequency_penalty": 0.9,
|
273 |
+
"greeting": "TEN Agent connected. How can I help you today?",
|
274 |
+
"max_memory_length": 10,
|
275 |
+
"max_tokens": 512,
|
276 |
+
"model": "${env:OPENAI_MODEL}",
|
277 |
+
"prompt": "",
|
278 |
+
"proxy_url": "${env:OPENAI_PROXY_URL}"
|
279 |
+
}
|
280 |
+
},
|
281 |
+
{
|
282 |
+
"type": "extension",
|
283 |
+
"name": "tts",
|
284 |
+
"addon": "fish_audio_tts",
|
285 |
+
"extension_group": "tts",
|
286 |
+
"property": {
|
287 |
+
"api_key": "${env:FISH_AUDIO_TTS_KEY}",
|
288 |
+
"model_id": "d8639b5cc95548f5afbcfe22d3ba5ce5",
|
289 |
+
"optimize_streaming_latency": true,
|
290 |
+
"request_timeout_seconds": 30,
|
291 |
+
"base_url": "https://api.fish.audio"
|
292 |
+
}
|
293 |
+
},
|
294 |
+
{
|
295 |
+
"type": "extension",
|
296 |
+
"name": "interrupt_detector",
|
297 |
+
"addon": "interrupt_detector_python",
|
298 |
+
"extension_group": "default",
|
299 |
+
"property": {}
|
300 |
+
},
|
301 |
+
{
|
302 |
+
"type": "extension",
|
303 |
+
"name": "message_collector",
|
304 |
+
"addon": "message_collector",
|
305 |
+
"extension_group": "transcriber",
|
306 |
+
"property": {}
|
307 |
+
},
|
308 |
+
{
|
309 |
+
"type": "extension",
|
310 |
+
"name": "weatherapi_tool_python",
|
311 |
+
"addon": "weatherapi_tool_python",
|
312 |
+
"extension_group": "default",
|
313 |
+
"property": {
|
314 |
+
"api_key": "${env:WEATHERAPI_API_KEY|}"
|
315 |
+
}
|
316 |
+
}
|
317 |
+
],
|
318 |
+
"connections": [
|
319 |
+
{
|
320 |
+
"extension": "agora_rtc",
|
321 |
+
"cmd": [
|
322 |
+
{
|
323 |
+
"name": "on_user_joined",
|
324 |
+
"dest": [
|
325 |
+
{
|
326 |
+
"extension": "llm"
|
327 |
+
}
|
328 |
+
]
|
329 |
+
},
|
330 |
+
{
|
331 |
+
"name": "on_user_left",
|
332 |
+
"dest": [
|
333 |
+
{
|
334 |
+
"extension": "llm"
|
335 |
+
}
|
336 |
+
]
|
337 |
+
},
|
338 |
+
{
|
339 |
+
"name": "on_connection_failure",
|
340 |
+
"dest": [
|
341 |
+
{
|
342 |
+
"extension": "llm"
|
343 |
+
}
|
344 |
+
]
|
345 |
+
}
|
346 |
+
],
|
347 |
+
"data": [
|
348 |
+
{
|
349 |
+
"name": "text_data",
|
350 |
+
"dest": [
|
351 |
+
{
|
352 |
+
"extension": "interrupt_detector"
|
353 |
+
},
|
354 |
+
{
|
355 |
+
"extension": "message_collector"
|
356 |
+
}
|
357 |
+
]
|
358 |
+
}
|
359 |
+
]
|
360 |
+
},
|
361 |
+
{
|
362 |
+
"extension": "llm",
|
363 |
+
"cmd": [
|
364 |
+
{
|
365 |
+
"name": "flush",
|
366 |
+
"dest": [
|
367 |
+
{
|
368 |
+
"extension": "tts"
|
369 |
+
}
|
370 |
+
]
|
371 |
+
},
|
372 |
+
{
|
373 |
+
"name": "tool_call",
|
374 |
+
"dest": [
|
375 |
+
{
|
376 |
+
"extension": "weatherapi_tool_python"
|
377 |
+
}
|
378 |
+
]
|
379 |
+
}
|
380 |
+
],
|
381 |
+
"data": [
|
382 |
+
{
|
383 |
+
"name": "text_data",
|
384 |
+
"dest": [
|
385 |
+
{
|
386 |
+
"extension": "tts"
|
387 |
+
},
|
388 |
+
{
|
389 |
+
"extension": "message_collector"
|
390 |
+
}
|
391 |
+
]
|
392 |
+
},
|
393 |
+
{
|
394 |
+
"name": "content_data",
|
395 |
+
"dest": [
|
396 |
+
{
|
397 |
+
"extension": "message_collector"
|
398 |
+
}
|
399 |
+
]
|
400 |
+
}
|
401 |
+
]
|
402 |
+
},
|
403 |
+
{
|
404 |
+
"extension": "message_collector",
|
405 |
+
"data": [
|
406 |
+
{
|
407 |
+
"name": "data",
|
408 |
+
"dest": [
|
409 |
+
{
|
410 |
+
"extension": "agora_rtc"
|
411 |
+
}
|
412 |
+
]
|
413 |
+
}
|
414 |
+
]
|
415 |
+
},
|
416 |
+
{
|
417 |
+
"extension": "tts",
|
418 |
+
"cmd": [
|
419 |
+
{
|
420 |
+
"name": "flush",
|
421 |
+
"dest": [
|
422 |
+
{
|
423 |
+
"extension": "agora_rtc"
|
424 |
+
}
|
425 |
+
]
|
426 |
+
}
|
427 |
+
],
|
428 |
+
"audio_frame": [
|
429 |
+
{
|
430 |
+
"name": "pcm_frame",
|
431 |
+
"dest": [
|
432 |
+
{
|
433 |
+
"extension": "agora_rtc"
|
434 |
+
}
|
435 |
+
]
|
436 |
+
}
|
437 |
+
]
|
438 |
+
},
|
439 |
+
{
|
440 |
+
"extension": "interrupt_detector",
|
441 |
+
"cmd": [
|
442 |
+
{
|
443 |
+
"name": "flush",
|
444 |
+
"dest": [
|
445 |
+
{
|
446 |
+
"extension": "llm"
|
447 |
+
}
|
448 |
+
]
|
449 |
+
}
|
450 |
+
],
|
451 |
+
"data": [
|
452 |
+
{
|
453 |
+
"name": "text_data",
|
454 |
+
"dest": [
|
455 |
+
{
|
456 |
+
"extension": "llm"
|
457 |
+
}
|
458 |
+
]
|
459 |
+
}
|
460 |
+
]
|
461 |
+
},
|
462 |
+
{
|
463 |
+
"extension": "weatherapi_tool_python",
|
464 |
+
"cmd": [
|
465 |
+
{
|
466 |
+
"name": "tool_register",
|
467 |
+
"dest": [
|
468 |
+
{
|
469 |
+
"extension": "llm"
|
470 |
+
}
|
471 |
+
]
|
472 |
+
}
|
473 |
+
]
|
474 |
+
}
|
475 |
+
]
|
476 |
+
},
|
477 |
+
{
|
478 |
+
"name": "voice_assistant_realtime",
|
479 |
+
"auto_start": true,
|
480 |
+
"nodes": [
|
481 |
+
{
|
482 |
+
"type": "extension",
|
483 |
+
"name": "agora_rtc",
|
484 |
+
"addon": "agora_rtc",
|
485 |
+
"extension_group": "rtc",
|
486 |
+
"property": {
|
487 |
+
"app_id": "${env:AGORA_APP_ID}",
|
488 |
+
"token": "",
|
489 |
+
"channel": "ten_agent_test",
|
490 |
+
"stream_id": 1234,
|
491 |
+
"remote_stream_id": 123,
|
492 |
+
"subscribe_audio": true,
|
493 |
+
"publish_audio": true,
|
494 |
+
"publish_data": true,
|
495 |
+
"subscribe_audio_sample_rate": 24000
|
496 |
+
}
|
497 |
+
},
|
498 |
+
{
|
499 |
+
"type": "extension",
|
500 |
+
"name": "v2v",
|
501 |
+
"addon": "openai_v2v_python",
|
502 |
+
"extension_group": "llm",
|
503 |
+
"property": {
|
504 |
+
"api_key": "${env:OPENAI_REALTIME_API_KEY}",
|
505 |
+
"enable_storage": false,
|
506 |
+
"history": 10,
|
507 |
+
"language": "en-US",
|
508 |
+
"max_tokens": 2048,
|
509 |
+
"model": "gpt-4o-realtime-preview",
|
510 |
+
"server_vad": true,
|
511 |
+
"temperature": 0.9,
|
512 |
+
"voice": "alloy"
|
513 |
+
}
|
514 |
+
},
|
515 |
+
{
|
516 |
+
"type": "extension",
|
517 |
+
"name": "message_collector",
|
518 |
+
"addon": "message_collector",
|
519 |
+
"extension_group": "transcriber",
|
520 |
+
"property": {}
|
521 |
+
},
|
522 |
+
{
|
523 |
+
"type": "extension",
|
524 |
+
"name": "weatherapi_tool_python",
|
525 |
+
"addon": "weatherapi_tool_python",
|
526 |
+
"extension_group": "default",
|
527 |
+
"property": {
|
528 |
+
"api_key": "${env:WEATHERAPI_API_KEY|}"
|
529 |
+
}
|
530 |
+
}
|
531 |
+
],
|
532 |
+
"connections": [
|
533 |
+
{
|
534 |
+
"extension": "agora_rtc",
|
535 |
+
"cmd": [
|
536 |
+
{
|
537 |
+
"name": "on_user_joined",
|
538 |
+
"dest": [
|
539 |
+
{
|
540 |
+
"extension": "v2v"
|
541 |
+
}
|
542 |
+
]
|
543 |
+
},
|
544 |
+
{
|
545 |
+
"name": "on_user_left",
|
546 |
+
"dest": [
|
547 |
+
{
|
548 |
+
"extension": "v2v"
|
549 |
+
}
|
550 |
+
]
|
551 |
+
},
|
552 |
+
{
|
553 |
+
"name": "on_connection_failure",
|
554 |
+
"dest": [
|
555 |
+
{
|
556 |
+
"extension": "v2v"
|
557 |
+
}
|
558 |
+
]
|
559 |
+
}
|
560 |
+
],
|
561 |
+
"audio_frame": [
|
562 |
+
{
|
563 |
+
"name": "pcm_frame",
|
564 |
+
"dest": [
|
565 |
+
{
|
566 |
+
"extension": "v2v"
|
567 |
+
}
|
568 |
+
]
|
569 |
+
}
|
570 |
+
],
|
571 |
+
"video_frame": [
|
572 |
+
{
|
573 |
+
"name": "video_frame",
|
574 |
+
"dest": [
|
575 |
+
{
|
576 |
+
"extension": "v2v"
|
577 |
+
}
|
578 |
+
]
|
579 |
+
}
|
580 |
+
]
|
581 |
+
},
|
582 |
+
{
|
583 |
+
"extension": "v2v",
|
584 |
+
"cmd": [
|
585 |
+
{
|
586 |
+
"name": "flush",
|
587 |
+
"dest": [
|
588 |
+
{
|
589 |
+
"extension": "agora_rtc"
|
590 |
+
}
|
591 |
+
]
|
592 |
+
},
|
593 |
+
{
|
594 |
+
"name": "tool_call",
|
595 |
+
"dest": [
|
596 |
+
{
|
597 |
+
"extension": "weatherapi_tool_python"
|
598 |
+
}
|
599 |
+
]
|
600 |
+
}
|
601 |
+
],
|
602 |
+
"data": [
|
603 |
+
{
|
604 |
+
"name": "text_data",
|
605 |
+
"dest": [
|
606 |
+
{
|
607 |
+
"extension": "message_collector"
|
608 |
+
}
|
609 |
+
]
|
610 |
+
}
|
611 |
+
],
|
612 |
+
"audio_frame": [
|
613 |
+
{
|
614 |
+
"name": "pcm_frame",
|
615 |
+
"dest": [
|
616 |
+
{
|
617 |
+
"extension": "agora_rtc"
|
618 |
+
}
|
619 |
+
]
|
620 |
+
}
|
621 |
+
]
|
622 |
+
},
|
623 |
+
{
|
624 |
+
"extension": "message_collector",
|
625 |
+
"data": [
|
626 |
+
{
|
627 |
+
"name": "data",
|
628 |
+
"dest": [
|
629 |
+
{
|
630 |
+
"extension": "agora_rtc"
|
631 |
+
}
|
632 |
+
]
|
633 |
+
}
|
634 |
+
]
|
635 |
+
},
|
636 |
+
{
|
637 |
+
"extension": "weatherapi_tool_python",
|
638 |
+
"cmd": [
|
639 |
+
{
|
640 |
+
"name": "tool_register",
|
641 |
+
"dest": [
|
642 |
+
{
|
643 |
+
"extension": "v2v"
|
644 |
+
}
|
645 |
+
]
|
646 |
+
}
|
647 |
+
]
|
648 |
+
}
|
649 |
+
]
|
650 |
+
},
|
651 |
+
{
|
652 |
+
"name": "story_teller",
|
653 |
+
"auto_start": true,
|
654 |
+
"nodes": [
|
655 |
+
{
|
656 |
+
"type": "extension",
|
657 |
+
"name": "agora_rtc",
|
658 |
+
"addon": "agora_rtc",
|
659 |
+
"extension_group": "default",
|
660 |
+
"property": {
|
661 |
+
"app_id": "${env:AGORA_APP_ID}",
|
662 |
+
"token": "<agora_token>",
|
663 |
+
"channel": "ten_agent_test",
|
664 |
+
"stream_id": 1234,
|
665 |
+
"remote_stream_id": 123,
|
666 |
+
"subscribe_audio": true,
|
667 |
+
"publish_audio": true,
|
668 |
+
"publish_data": true,
|
669 |
+
"enable_agora_asr": false
|
670 |
+
}
|
671 |
+
},
|
672 |
+
{
|
673 |
+
"type": "extension",
|
674 |
+
"name": "stt",
|
675 |
+
"addon": "deepgram_asr_python",
|
676 |
+
"extension_group": "stt",
|
677 |
+
"property": {
|
678 |
+
"api_key": "${env:DEEPGRAM_API_KEY}",
|
679 |
+
"language": "en-US",
|
680 |
+
"model": "nova-2",
|
681 |
+
"sample_rate": 16000
|
682 |
+
}
|
683 |
+
},
|
684 |
+
{
|
685 |
+
"type": "extension",
|
686 |
+
"name": "llm",
|
687 |
+
"addon": "openai_chatgpt_python",
|
688 |
+
"extension_group": "chatgpt",
|
689 |
+
"property": {
|
690 |
+
"api_key": "${env:OPENAI_API_KEY}",
|
691 |
+
"base_url": "",
|
692 |
+
"frequency_penalty": 0.9,
|
693 |
+
"greeting": "TEN Agent connected. How can I help you today?",
|
694 |
+
"max_memory_length": 10,
|
695 |
+
"max_tokens": 512,
|
696 |
+
"model": "${env:OPENAI_MODEL}",
|
697 |
+
"prompt": "You are an ai agent bot producing child picture books. Each response should be short and no more than 50 words as it's for child. \nFor every response relevant to the story-telling, you will use the 'image_generate' tool to create an image based on the description or key moment in that part of the story. \n The story should be set in a fantasy world. Try asking questions relevant to the story to decide how the story should proceed. Every response should include rich, vivid descriptions that will guide the 'image_generate' tool to produce an image that aligns with the scene or mood.\n Whether it’s the setting, a character’s expression, or a dramatic moment, the paragraph should give enough detail for a meaningful visual representation.",
|
698 |
+
"proxy_url": "${env:OPENAI_PROXY_URL}"
|
699 |
+
}
|
700 |
+
},
|
701 |
+
{
|
702 |
+
"type": "extension",
|
703 |
+
"name": "tts",
|
704 |
+
"addon": "fish_audio_tts",
|
705 |
+
"extension_group": "tts",
|
706 |
+
"property": {
|
707 |
+
"api_key": "${env:FISH_AUDIO_TTS_KEY}",
|
708 |
+
"model_id": "d8639b5cc95548f5afbcfe22d3ba5ce5",
|
709 |
+
"optimize_streaming_latency": true,
|
710 |
+
"request_timeout_seconds": 30,
|
711 |
+
"base_url": "https://api.fish.audio"
|
712 |
+
}
|
713 |
+
},
|
714 |
+
{
|
715 |
+
"type": "extension",
|
716 |
+
"name": "interrupt_detector",
|
717 |
+
"addon": "interrupt_detector_python",
|
718 |
+
"extension_group": "default",
|
719 |
+
"property": {}
|
720 |
+
},
|
721 |
+
{
|
722 |
+
"type": "extension",
|
723 |
+
"name": "message_collector",
|
724 |
+
"addon": "message_collector",
|
725 |
+
"extension_group": "transcriber",
|
726 |
+
"property": {}
|
727 |
+
},
|
728 |
+
{
|
729 |
+
"type": "extension",
|
730 |
+
"name": "openai_image_generate_tool",
|
731 |
+
"addon": "openai_image_generate_tool",
|
732 |
+
"extension_group": "default",
|
733 |
+
"property": {
|
734 |
+
"api_key": "${env:OPENAI_API_KEY}"
|
735 |
+
}
|
736 |
+
}
|
737 |
+
],
|
738 |
+
"connections": [
|
739 |
+
{
|
740 |
+
"extension": "agora_rtc",
|
741 |
+
"cmd": [
|
742 |
+
{
|
743 |
+
"name": "on_user_joined",
|
744 |
+
"dest": [
|
745 |
+
{
|
746 |
+
"extension": "llm"
|
747 |
+
}
|
748 |
+
]
|
749 |
+
},
|
750 |
+
{
|
751 |
+
"name": "on_user_left",
|
752 |
+
"dest": [
|
753 |
+
{
|
754 |
+
"extension": "llm"
|
755 |
+
}
|
756 |
+
]
|
757 |
+
},
|
758 |
+
{
|
759 |
+
"name": "on_connection_failure",
|
760 |
+
"dest": [
|
761 |
+
{
|
762 |
+
"extension": "llm"
|
763 |
+
}
|
764 |
+
]
|
765 |
+
}
|
766 |
+
],
|
767 |
+
"audio_frame": [
|
768 |
+
{
|
769 |
+
"name": "pcm_frame",
|
770 |
+
"dest": [
|
771 |
+
{
|
772 |
+
"extension": "stt"
|
773 |
+
}
|
774 |
+
]
|
775 |
+
}
|
776 |
+
]
|
777 |
+
},
|
778 |
+
{
|
779 |
+
"extension": "stt",
|
780 |
+
"data": [
|
781 |
+
{
|
782 |
+
"name": "text_data",
|
783 |
+
"dest": [
|
784 |
+
{
|
785 |
+
"extension": "interrupt_detector"
|
786 |
+
},
|
787 |
+
{
|
788 |
+
"extension": "message_collector"
|
789 |
+
}
|
790 |
+
]
|
791 |
+
}
|
792 |
+
]
|
793 |
+
},
|
794 |
+
{
|
795 |
+
"extension": "llm",
|
796 |
+
"cmd": [
|
797 |
+
{
|
798 |
+
"name": "flush",
|
799 |
+
"dest": [
|
800 |
+
{
|
801 |
+
"extension": "tts"
|
802 |
+
}
|
803 |
+
]
|
804 |
+
},
|
805 |
+
{
|
806 |
+
"name": "tool_call",
|
807 |
+
"dest": [
|
808 |
+
{
|
809 |
+
"extension": "openai_image_generate_tool"
|
810 |
+
}
|
811 |
+
]
|
812 |
+
}
|
813 |
+
],
|
814 |
+
"data": [
|
815 |
+
{
|
816 |
+
"name": "text_data",
|
817 |
+
"dest": [
|
818 |
+
{
|
819 |
+
"extension": "tts"
|
820 |
+
},
|
821 |
+
{
|
822 |
+
"extension": "message_collector"
|
823 |
+
}
|
824 |
+
]
|
825 |
+
}
|
826 |
+
]
|
827 |
+
},
|
828 |
+
{
|
829 |
+
"extension": "message_collector",
|
830 |
+
"data": [
|
831 |
+
{
|
832 |
+
"name": "data",
|
833 |
+
"dest": [
|
834 |
+
{
|
835 |
+
"extension": "agora_rtc"
|
836 |
+
}
|
837 |
+
]
|
838 |
+
}
|
839 |
+
]
|
840 |
+
},
|
841 |
+
{
|
842 |
+
"extension": "tts",
|
843 |
+
"cmd": [
|
844 |
+
{
|
845 |
+
"name": "flush",
|
846 |
+
"dest": [
|
847 |
+
{
|
848 |
+
"extension": "agora_rtc"
|
849 |
+
}
|
850 |
+
]
|
851 |
+
}
|
852 |
+
],
|
853 |
+
"audio_frame": [
|
854 |
+
{
|
855 |
+
"name": "pcm_frame",
|
856 |
+
"dest": [
|
857 |
+
{
|
858 |
+
"extension": "agora_rtc"
|
859 |
+
}
|
860 |
+
]
|
861 |
+
}
|
862 |
+
]
|
863 |
+
},
|
864 |
+
{
|
865 |
+
"extension": "interrupt_detector",
|
866 |
+
"cmd": [
|
867 |
+
{
|
868 |
+
"name": "flush",
|
869 |
+
"dest": [
|
870 |
+
{
|
871 |
+
"extension": "llm"
|
872 |
+
}
|
873 |
+
]
|
874 |
+
}
|
875 |
+
],
|
876 |
+
"data": [
|
877 |
+
{
|
878 |
+
"name": "text_data",
|
879 |
+
"dest": [
|
880 |
+
{
|
881 |
+
"extension": "llm"
|
882 |
+
}
|
883 |
+
]
|
884 |
+
}
|
885 |
+
]
|
886 |
+
},
|
887 |
+
{
|
888 |
+
"extension": "openai_image_generate_tool",
|
889 |
+
"cmd": [
|
890 |
+
{
|
891 |
+
"name": "tool_register",
|
892 |
+
"dest": [
|
893 |
+
{
|
894 |
+
"extension": "llm"
|
895 |
+
}
|
896 |
+
]
|
897 |
+
}
|
898 |
+
],
|
899 |
+
"data": [
|
900 |
+
{
|
901 |
+
"name": "content_data",
|
902 |
+
"dest": [
|
903 |
+
{
|
904 |
+
"extension": "message_collector"
|
905 |
+
}
|
906 |
+
]
|
907 |
+
}
|
908 |
+
]
|
909 |
+
}
|
910 |
+
]
|
911 |
+
},
|
912 |
+
{
|
913 |
+
"name": "story_teller_stt_integrated",
|
914 |
+
"auto_start": true,
|
915 |
+
"nodes": [
|
916 |
+
{
|
917 |
+
"type": "extension",
|
918 |
+
"name": "agora_rtc",
|
919 |
+
"addon": "agora_rtc",
|
920 |
+
"extension_group": "default",
|
921 |
+
"property": {
|
922 |
+
"app_id": "${env:AGORA_APP_ID}",
|
923 |
+
"token": "<agora_token>",
|
924 |
+
"channel": "ten_agent_test",
|
925 |
+
"stream_id": 1234,
|
926 |
+
"remote_stream_id": 123,
|
927 |
+
"subscribe_audio": true,
|
928 |
+
"publish_audio": true,
|
929 |
+
"publish_data": true,
|
930 |
+
"enable_agora_asr": true,
|
931 |
+
"agora_asr_vendor_name": "microsoft",
|
932 |
+
"agora_asr_language": "en-US",
|
933 |
+
"agora_asr_vendor_key": "${env:AZURE_STT_KEY|}",
|
934 |
+
"agora_asr_vendor_region": "${env:AZURE_STT_REGION|}",
|
935 |
+
"agora_asr_session_control_file_path": "session_control.conf"
|
936 |
+
}
|
937 |
+
},
|
938 |
+
{
|
939 |
+
"type": "extension",
|
940 |
+
"name": "llm",
|
941 |
+
"addon": "openai_chatgpt_python",
|
942 |
+
"extension_group": "chatgpt",
|
943 |
+
"property": {
|
944 |
+
"api_key": "${env:OPENAI_API_KEY}",
|
945 |
+
"base_url": "",
|
946 |
+
"frequency_penalty": 0.9,
|
947 |
+
"greeting": "TEN Agent connected. How can I help you today?",
|
948 |
+
"max_memory_length": 10,
|
949 |
+
"max_tokens": 512,
|
950 |
+
"model": "${env:OPENAI_MODEL}",
|
951 |
+
"prompt": "You are an ai agent bot producing child picture books. Each response should be short and no more than 50 words as it's for child. \nFor every response relevant to the story-telling, you will use the 'image_generate' tool to create an image based on the description or key moment in that part of the story. \n The story should be set in a fantasy world. Try asking questions relevant to the story to decide how the story should proceed. Every response should include rich, vivid descriptions that will guide the 'image_generate' tool to produce an image that aligns with the scene or mood.\n Whether it’s the setting, a character’s expression, or a dramatic moment, the paragraph should give enough detail for a meaningful visual representation.",
|
952 |
+
"proxy_url": "${env:OPENAI_PROXY_URL}"
|
953 |
+
}
|
954 |
+
},
|
955 |
+
{
|
956 |
+
"type": "extension",
|
957 |
+
"name": "tts",
|
958 |
+
"addon": "fish_audio_tts",
|
959 |
+
"extension_group": "tts",
|
960 |
+
"property": {
|
961 |
+
"api_key": "${env:FISH_AUDIO_TTS_KEY}",
|
962 |
+
"model_id": "d8639b5cc95548f5afbcfe22d3ba5ce5",
|
963 |
+
"optimize_streaming_latency": true,
|
964 |
+
"request_timeout_seconds": 30,
|
965 |
+
"base_url": "https://api.fish.audio"
|
966 |
+
}
|
967 |
+
},
|
968 |
+
{
|
969 |
+
"type": "extension",
|
970 |
+
"name": "interrupt_detector",
|
971 |
+
"addon": "interrupt_detector_python",
|
972 |
+
"extension_group": "default",
|
973 |
+
"property": {}
|
974 |
+
},
|
975 |
+
{
|
976 |
+
"type": "extension",
|
977 |
+
"name": "message_collector",
|
978 |
+
"addon": "message_collector",
|
979 |
+
"extension_group": "transcriber",
|
980 |
+
"property": {}
|
981 |
+
},
|
982 |
+
{
|
983 |
+
"type": "extension",
|
984 |
+
"name": "openai_image_generate_tool",
|
985 |
+
"addon": "openai_image_generate_tool",
|
986 |
+
"extension_group": "default",
|
987 |
+
"property": {
|
988 |
+
"api_key": "${env:OPENAI_API_KEY}"
|
989 |
+
}
|
990 |
+
}
|
991 |
+
],
|
992 |
+
"connections": [
|
993 |
+
{
|
994 |
+
"extension": "agora_rtc",
|
995 |
+
"cmd": [
|
996 |
+
{
|
997 |
+
"name": "on_user_joined",
|
998 |
+
"dest": [
|
999 |
+
{
|
1000 |
+
"extension": "llm"
|
1001 |
+
}
|
1002 |
+
]
|
1003 |
+
},
|
1004 |
+
{
|
1005 |
+
"name": "on_user_left",
|
1006 |
+
"dest": [
|
1007 |
+
{
|
1008 |
+
"extension": "llm"
|
1009 |
+
}
|
1010 |
+
]
|
1011 |
+
},
|
1012 |
+
{
|
1013 |
+
"name": "on_connection_failure",
|
1014 |
+
"dest": [
|
1015 |
+
{
|
1016 |
+
"extension": "llm"
|
1017 |
+
}
|
1018 |
+
]
|
1019 |
+
}
|
1020 |
+
],
|
1021 |
+
"data": [
|
1022 |
+
{
|
1023 |
+
"name": "text_data",
|
1024 |
+
"dest": [
|
1025 |
+
{
|
1026 |
+
"extension": "interrupt_detector"
|
1027 |
+
},
|
1028 |
+
{
|
1029 |
+
"extension": "message_collector"
|
1030 |
+
}
|
1031 |
+
]
|
1032 |
+
}
|
1033 |
+
]
|
1034 |
+
},
|
1035 |
+
{
|
1036 |
+
"extension": "llm",
|
1037 |
+
"cmd": [
|
1038 |
+
{
|
1039 |
+
"name": "flush",
|
1040 |
+
"dest": [
|
1041 |
+
{
|
1042 |
+
"extension": "tts"
|
1043 |
+
}
|
1044 |
+
]
|
1045 |
+
},
|
1046 |
+
{
|
1047 |
+
"name": "tool_call",
|
1048 |
+
"dest": [
|
1049 |
+
{
|
1050 |
+
"extension": "openai_image_generate_tool"
|
1051 |
+
}
|
1052 |
+
]
|
1053 |
+
}
|
1054 |
+
],
|
1055 |
+
"data": [
|
1056 |
+
{
|
1057 |
+
"name": "text_data",
|
1058 |
+
"dest": [
|
1059 |
+
{
|
1060 |
+
"extension": "tts"
|
1061 |
+
},
|
1062 |
+
{
|
1063 |
+
"extension": "message_collector"
|
1064 |
+
}
|
1065 |
+
]
|
1066 |
+
}
|
1067 |
+
]
|
1068 |
+
},
|
1069 |
+
{
|
1070 |
+
"extension": "message_collector",
|
1071 |
+
"data": [
|
1072 |
+
{
|
1073 |
+
"name": "data",
|
1074 |
+
"dest": [
|
1075 |
+
{
|
1076 |
+
"extension": "agora_rtc"
|
1077 |
+
}
|
1078 |
+
]
|
1079 |
+
}
|
1080 |
+
]
|
1081 |
+
},
|
1082 |
+
{
|
1083 |
+
"extension": "tts",
|
1084 |
+
"cmd": [
|
1085 |
+
{
|
1086 |
+
"name": "flush",
|
1087 |
+
"dest": [
|
1088 |
+
{
|
1089 |
+
"extension": "agora_rtc"
|
1090 |
+
}
|
1091 |
+
]
|
1092 |
+
}
|
1093 |
+
],
|
1094 |
+
"audio_frame": [
|
1095 |
+
{
|
1096 |
+
"name": "pcm_frame",
|
1097 |
+
"dest": [
|
1098 |
+
{
|
1099 |
+
"extension": "agora_rtc"
|
1100 |
+
}
|
1101 |
+
]
|
1102 |
+
}
|
1103 |
+
]
|
1104 |
+
},
|
1105 |
+
{
|
1106 |
+
"extension": "interrupt_detector",
|
1107 |
+
"cmd": [
|
1108 |
+
{
|
1109 |
+
"name": "flush",
|
1110 |
+
"dest": [
|
1111 |
+
{
|
1112 |
+
"extension": "llm"
|
1113 |
+
}
|
1114 |
+
]
|
1115 |
+
}
|
1116 |
+
],
|
1117 |
+
"data": [
|
1118 |
+
{
|
1119 |
+
"name": "text_data",
|
1120 |
+
"dest": [
|
1121 |
+
{
|
1122 |
+
"extension": "llm"
|
1123 |
+
}
|
1124 |
+
]
|
1125 |
+
}
|
1126 |
+
]
|
1127 |
+
},
|
1128 |
+
{
|
1129 |
+
"extension": "openai_image_generate_tool",
|
1130 |
+
"cmd": [
|
1131 |
+
{
|
1132 |
+
"name": "tool_register",
|
1133 |
+
"dest": [
|
1134 |
+
{
|
1135 |
+
"extension": "llm"
|
1136 |
+
}
|
1137 |
+
]
|
1138 |
+
}
|
1139 |
+
],
|
1140 |
+
"data": [
|
1141 |
+
{
|
1142 |
+
"name": "content_data",
|
1143 |
+
"dest": [
|
1144 |
+
{
|
1145 |
+
"extension": "message_collector"
|
1146 |
+
}
|
1147 |
+
]
|
1148 |
+
}
|
1149 |
+
]
|
1150 |
+
}
|
1151 |
+
]
|
1152 |
+
},
|
1153 |
+
{
|
1154 |
+
"name": "story_teller_realtime",
|
1155 |
+
"auto_start": true,
|
1156 |
+
"nodes": [
|
1157 |
+
{
|
1158 |
+
"type": "extension",
|
1159 |
+
"name": "agora_rtc",
|
1160 |
+
"addon": "agora_rtc",
|
1161 |
+
"extension_group": "rtc",
|
1162 |
+
"property": {
|
1163 |
+
"app_id": "${env:AGORA_APP_ID}",
|
1164 |
+
"token": "",
|
1165 |
+
"channel": "ten_agent_test",
|
1166 |
+
"stream_id": 1234,
|
1167 |
+
"remote_stream_id": 123,
|
1168 |
+
"subscribe_audio": true,
|
1169 |
+
"publish_audio": true,
|
1170 |
+
"publish_data": true,
|
1171 |
+
"subscribe_audio_sample_rate": 24000
|
1172 |
+
}
|
1173 |
+
},
|
1174 |
+
{
|
1175 |
+
"type": "extension",
|
1176 |
+
"name": "v2v",
|
1177 |
+
"addon": "openai_v2v_python",
|
1178 |
+
"extension_group": "llm",
|
1179 |
+
"property": {
|
1180 |
+
"api_key": "${env:OPENAI_REALTIME_API_KEY}",
|
1181 |
+
"temperature": 0.9,
|
1182 |
+
"model": "gpt-4o-realtime-preview-2024-12-17",
|
1183 |
+
"max_tokens": 2048,
|
1184 |
+
"voice": "alloy",
|
1185 |
+
"language": "en-US",
|
1186 |
+
"server_vad": true,
|
1187 |
+
"prompt": "You are an ai agent bot producing child picture books. Each response should be short and no more than 50 words as it's for child. \nFor every response relevant to the story-telling, you will use the 'image_generate' tool to create an image based on the description or key moment in that part of the story. \n The story should be set in a fantasy world. Try asking questions relevant to the story to decide how the story should proceed. Every response should include rich, vivid descriptions that will guide the 'image_generate' tool to produce an image that aligns with the scene or mood.\n Whether it’s the setting, a character’s expression, or a dramatic moment, the paragraph should give enough detail for a meaningful visual representation.",
|
1188 |
+
"dump": false,
|
1189 |
+
"max_history": 10
|
1190 |
+
}
|
1191 |
+
},
|
1192 |
+
{
|
1193 |
+
"type": "extension",
|
1194 |
+
"name": "message_collector",
|
1195 |
+
"addon": "message_collector",
|
1196 |
+
"extension_group": "transcriber",
|
1197 |
+
"property": {}
|
1198 |
+
},
|
1199 |
+
{
|
1200 |
+
"type": "extension",
|
1201 |
+
"name": "openai_image_generate_tool",
|
1202 |
+
"addon": "openai_image_generate_tool",
|
1203 |
+
"extension_group": "default",
|
1204 |
+
"property": {
|
1205 |
+
"api_key": "${env:OPENAI_API_KEY}"
|
1206 |
+
}
|
1207 |
+
}
|
1208 |
+
],
|
1209 |
+
"connections": [
|
1210 |
+
{
|
1211 |
+
"extension": "agora_rtc",
|
1212 |
+
"cmd": [
|
1213 |
+
{
|
1214 |
+
"name": "on_user_joined",
|
1215 |
+
"dest": [
|
1216 |
+
{
|
1217 |
+
"extension": "v2v"
|
1218 |
+
}
|
1219 |
+
]
|
1220 |
+
},
|
1221 |
+
{
|
1222 |
+
"name": "on_user_left",
|
1223 |
+
"dest": [
|
1224 |
+
{
|
1225 |
+
"extension": "v2v"
|
1226 |
+
}
|
1227 |
+
]
|
1228 |
+
},
|
1229 |
+
{
|
1230 |
+
"name": "on_connection_failure",
|
1231 |
+
"dest": [
|
1232 |
+
{
|
1233 |
+
"extension": "v2v"
|
1234 |
+
}
|
1235 |
+
]
|
1236 |
+
}
|
1237 |
+
],
|
1238 |
+
"audio_frame": [
|
1239 |
+
{
|
1240 |
+
"name": "pcm_frame",
|
1241 |
+
"dest": [
|
1242 |
+
{
|
1243 |
+
"extension": "v2v"
|
1244 |
+
}
|
1245 |
+
]
|
1246 |
+
}
|
1247 |
+
]
|
1248 |
+
},
|
1249 |
+
{
|
1250 |
+
"extension": "v2v",
|
1251 |
+
"cmd": [
|
1252 |
+
{
|
1253 |
+
"name": "flush",
|
1254 |
+
"dest": [
|
1255 |
+
{
|
1256 |
+
"extension": "agora_rtc"
|
1257 |
+
}
|
1258 |
+
]
|
1259 |
+
},
|
1260 |
+
{
|
1261 |
+
"name": "tool_call",
|
1262 |
+
"dest": [
|
1263 |
+
{
|
1264 |
+
"extension": "openai_image_generate_tool"
|
1265 |
+
}
|
1266 |
+
]
|
1267 |
+
}
|
1268 |
+
],
|
1269 |
+
"data": [
|
1270 |
+
{
|
1271 |
+
"name": "text_data",
|
1272 |
+
"dest": [
|
1273 |
+
{
|
1274 |
+
"extension": "message_collector"
|
1275 |
+
}
|
1276 |
+
]
|
1277 |
+
}
|
1278 |
+
],
|
1279 |
+
"audio_frame": [
|
1280 |
+
{
|
1281 |
+
"name": "pcm_frame",
|
1282 |
+
"dest": [
|
1283 |
+
{
|
1284 |
+
"extension": "agora_rtc"
|
1285 |
+
}
|
1286 |
+
]
|
1287 |
+
}
|
1288 |
+
]
|
1289 |
+
},
|
1290 |
+
{
|
1291 |
+
"extension": "message_collector",
|
1292 |
+
"data": [
|
1293 |
+
{
|
1294 |
+
"name": "data",
|
1295 |
+
"dest": [
|
1296 |
+
{
|
1297 |
+
"extension": "agora_rtc"
|
1298 |
+
}
|
1299 |
+
]
|
1300 |
+
}
|
1301 |
+
]
|
1302 |
+
},
|
1303 |
+
{
|
1304 |
+
"extension": "openai_image_generate_tool",
|
1305 |
+
"cmd": [
|
1306 |
+
{
|
1307 |
+
"name": "tool_register",
|
1308 |
+
"dest": [
|
1309 |
+
{
|
1310 |
+
"extension": "v2v"
|
1311 |
+
}
|
1312 |
+
]
|
1313 |
+
}
|
1314 |
+
],
|
1315 |
+
"data": [
|
1316 |
+
{
|
1317 |
+
"name": "content_data",
|
1318 |
+
"dest": [
|
1319 |
+
{
|
1320 |
+
"extension": "message_collector"
|
1321 |
+
}
|
1322 |
+
]
|
1323 |
+
}
|
1324 |
+
]
|
1325 |
+
}
|
1326 |
+
]
|
1327 |
+
}
|
1328 |
+
],
|
1329 |
+
"log_level": 3
|
1330 |
+
}
|
1331 |
+
}
|
agents/examples/demo/manifest.json
ADDED
@@ -0,0 +1,97 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"type": "app",
|
3 |
+
"name": "agent_demo",
|
4 |
+
"version": "0.8.0",
|
5 |
+
"dependencies": [
|
6 |
+
{
|
7 |
+
"type": "system",
|
8 |
+
"name": "ten_runtime_go",
|
9 |
+
"version": "0.8"
|
10 |
+
},
|
11 |
+
{
|
12 |
+
"type": "extension",
|
13 |
+
"name": "agora_rtc",
|
14 |
+
"version": "=0.12.0"
|
15 |
+
},
|
16 |
+
{
|
17 |
+
"type": "extension",
|
18 |
+
"name": "agora_sess_ctrl",
|
19 |
+
"version": "=0.4.4"
|
20 |
+
},
|
21 |
+
{
|
22 |
+
"type": "system",
|
23 |
+
"name": "azure_speech_sdk",
|
24 |
+
"version": "1.38.0"
|
25 |
+
},
|
26 |
+
{
|
27 |
+
"type": "system",
|
28 |
+
"name": "ten_ai_base",
|
29 |
+
"version": "0.4.1"
|
30 |
+
},
|
31 |
+
{
|
32 |
+
"type": "extension",
|
33 |
+
"name": "azure_tts",
|
34 |
+
"version": "=0.8.1"
|
35 |
+
},
|
36 |
+
{
|
37 |
+
"type": "extension",
|
38 |
+
"name": "dify_python",
|
39 |
+
"version": "=0.1.0"
|
40 |
+
},
|
41 |
+
{
|
42 |
+
"type": "extension",
|
43 |
+
"name": "gemini_v2v_python",
|
44 |
+
"version": "=0.1.0"
|
45 |
+
},
|
46 |
+
{
|
47 |
+
"type": "extension",
|
48 |
+
"name": "openai_chatgpt_python",
|
49 |
+
"version": "=0.1.0"
|
50 |
+
},
|
51 |
+
{
|
52 |
+
"type": "extension",
|
53 |
+
"name": "bingsearch_tool_python",
|
54 |
+
"version": "=0.1.0"
|
55 |
+
},
|
56 |
+
{
|
57 |
+
"type": "extension",
|
58 |
+
"name": "vision_tool_python",
|
59 |
+
"version": "=0.1.0"
|
60 |
+
},
|
61 |
+
{
|
62 |
+
"type": "extension",
|
63 |
+
"name": "weatherapi_tool_python",
|
64 |
+
"version": "=0.1.0"
|
65 |
+
},
|
66 |
+
{
|
67 |
+
"type": "extension",
|
68 |
+
"name": "interrupt_detector_python",
|
69 |
+
"version": "=0.1.0"
|
70 |
+
},
|
71 |
+
{
|
72 |
+
"type": "extension",
|
73 |
+
"name": "openai_v2v_python",
|
74 |
+
"version": "=0.1.0"
|
75 |
+
},
|
76 |
+
{
|
77 |
+
"type": "extension",
|
78 |
+
"name": "message_collector",
|
79 |
+
"version": "=0.1.0"
|
80 |
+
},
|
81 |
+
{
|
82 |
+
"type": "extension",
|
83 |
+
"name": "coze_python_async",
|
84 |
+
"version": "=0.1.0"
|
85 |
+
},
|
86 |
+
{
|
87 |
+
"type": "extension",
|
88 |
+
"name": "fish_audio_tts",
|
89 |
+
"version": "=0.1.0"
|
90 |
+
},
|
91 |
+
{
|
92 |
+
"type": "extension",
|
93 |
+
"name": "openai_image_generate_tool",
|
94 |
+
"version": "=0.1.0"
|
95 |
+
}
|
96 |
+
]
|
97 |
+
}
|
agents/examples/demo/property.json
ADDED
@@ -0,0 +1,2322 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"_ten": {
|
3 |
+
"predefined_graphs": [
|
4 |
+
{
|
5 |
+
"name": "qwq_32b",
|
6 |
+
"auto_start": true,
|
7 |
+
"nodes": [
|
8 |
+
{
|
9 |
+
"type": "extension",
|
10 |
+
"name": "agora_rtc",
|
11 |
+
"addon": "agora_rtc",
|
12 |
+
"extension_group": "default",
|
13 |
+
"property": {
|
14 |
+
"app_id": "${env:AGORA_APP_ID}",
|
15 |
+
"token": "<agora_token>",
|
16 |
+
"channel": "ten_agent_test",
|
17 |
+
"stream_id": 1234,
|
18 |
+
"remote_stream_id": 123,
|
19 |
+
"subscribe_audio": true,
|
20 |
+
"publish_audio": true,
|
21 |
+
"publish_data": true,
|
22 |
+
"enable_agora_asr": true,
|
23 |
+
"agora_asr_vendor_name": "microsoft",
|
24 |
+
"agora_asr_language": "en-US",
|
25 |
+
"agora_asr_vendor_key": "${env:AZURE_STT_KEY|}",
|
26 |
+
"agora_asr_vendor_region": "${env:AZURE_STT_REGION|}",
|
27 |
+
"agora_asr_session_control_file_path": "session_control.conf"
|
28 |
+
}
|
29 |
+
},
|
30 |
+
{
|
31 |
+
"type": "extension",
|
32 |
+
"name": "llm",
|
33 |
+
"addon": "openai_chatgpt_python",
|
34 |
+
"extension_group": "chatgpt",
|
35 |
+
"property": {
|
36 |
+
"api_key": "${env:QWEN_API_KEY}",
|
37 |
+
"base_url": "https://dashscope.aliyuncs.com/compatible-mode/v1",
|
38 |
+
"frequency_penalty": 0.9,
|
39 |
+
"greeting": "TEN Agent connected. How can I help you today?",
|
40 |
+
"max_memory_length": 10,
|
41 |
+
"max_tokens": 512,
|
42 |
+
"model": "qwq-plus",
|
43 |
+
"prompt": "",
|
44 |
+
"proxy_url": "${env:OPENAI_PROXY_URL}"
|
45 |
+
}
|
46 |
+
},
|
47 |
+
{
|
48 |
+
"type": "extension",
|
49 |
+
"name": "tts",
|
50 |
+
"addon": "azure_tts",
|
51 |
+
"extension_group": "tts",
|
52 |
+
"property": {
|
53 |
+
"azure_subscription_key": "${env:AZURE_TTS_KEY}",
|
54 |
+
"azure_subscription_region": "${env:AZURE_TTS_REGION}",
|
55 |
+
"azure_synthesis_voice_name": "en-US-AndrewMultilingualNeural"
|
56 |
+
}
|
57 |
+
},
|
58 |
+
{
|
59 |
+
"type": "extension",
|
60 |
+
"name": "interrupt_detector",
|
61 |
+
"addon": "interrupt_detector_python",
|
62 |
+
"extension_group": "default",
|
63 |
+
"property": {}
|
64 |
+
},
|
65 |
+
{
|
66 |
+
"type": "extension",
|
67 |
+
"name": "message_collector",
|
68 |
+
"addon": "message_collector",
|
69 |
+
"extension_group": "transcriber",
|
70 |
+
"property": {}
|
71 |
+
}
|
72 |
+
],
|
73 |
+
"connections": [
|
74 |
+
{
|
75 |
+
"extension": "agora_rtc",
|
76 |
+
"cmd": [
|
77 |
+
{
|
78 |
+
"name": "on_user_joined",
|
79 |
+
"dest": [
|
80 |
+
{
|
81 |
+
"extension": "llm"
|
82 |
+
}
|
83 |
+
]
|
84 |
+
},
|
85 |
+
{
|
86 |
+
"name": "on_user_left",
|
87 |
+
"dest": [
|
88 |
+
{
|
89 |
+
"extension": "llm"
|
90 |
+
}
|
91 |
+
]
|
92 |
+
},
|
93 |
+
{
|
94 |
+
"name": "on_connection_failure",
|
95 |
+
"dest": [
|
96 |
+
{
|
97 |
+
"extension": "llm"
|
98 |
+
}
|
99 |
+
]
|
100 |
+
}
|
101 |
+
],
|
102 |
+
"data": [
|
103 |
+
{
|
104 |
+
"name": "text_data",
|
105 |
+
"dest": [
|
106 |
+
{
|
107 |
+
"extension": "interrupt_detector"
|
108 |
+
},
|
109 |
+
{
|
110 |
+
"extension": "message_collector"
|
111 |
+
}
|
112 |
+
]
|
113 |
+
}
|
114 |
+
]
|
115 |
+
},
|
116 |
+
{
|
117 |
+
"extension": "llm",
|
118 |
+
"cmd": [
|
119 |
+
{
|
120 |
+
"name": "flush",
|
121 |
+
"dest": [
|
122 |
+
{
|
123 |
+
"extension": "tts"
|
124 |
+
}
|
125 |
+
]
|
126 |
+
}
|
127 |
+
],
|
128 |
+
"data": [
|
129 |
+
{
|
130 |
+
"name": "text_data",
|
131 |
+
"dest": [
|
132 |
+
{
|
133 |
+
"extension": "tts"
|
134 |
+
},
|
135 |
+
{
|
136 |
+
"extension": "message_collector"
|
137 |
+
}
|
138 |
+
]
|
139 |
+
},
|
140 |
+
{
|
141 |
+
"name": "content_data",
|
142 |
+
"dest": [
|
143 |
+
{
|
144 |
+
"extension": "message_collector"
|
145 |
+
}
|
146 |
+
]
|
147 |
+
}
|
148 |
+
]
|
149 |
+
},
|
150 |
+
{
|
151 |
+
"extension": "message_collector",
|
152 |
+
"data": [
|
153 |
+
{
|
154 |
+
"name": "data",
|
155 |
+
"dest": [
|
156 |
+
{
|
157 |
+
"extension": "agora_rtc"
|
158 |
+
}
|
159 |
+
]
|
160 |
+
}
|
161 |
+
]
|
162 |
+
},
|
163 |
+
{
|
164 |
+
"extension": "tts",
|
165 |
+
"cmd": [
|
166 |
+
{
|
167 |
+
"name": "flush",
|
168 |
+
"dest": [
|
169 |
+
{
|
170 |
+
"extension": "agora_rtc"
|
171 |
+
}
|
172 |
+
]
|
173 |
+
}
|
174 |
+
],
|
175 |
+
"audio_frame": [
|
176 |
+
{
|
177 |
+
"name": "pcm_frame",
|
178 |
+
"dest": [
|
179 |
+
{
|
180 |
+
"extension": "agora_rtc"
|
181 |
+
}
|
182 |
+
]
|
183 |
+
}
|
184 |
+
]
|
185 |
+
},
|
186 |
+
{
|
187 |
+
"extension": "interrupt_detector",
|
188 |
+
"cmd": [
|
189 |
+
{
|
190 |
+
"name": "flush",
|
191 |
+
"dest": [
|
192 |
+
{
|
193 |
+
"extension": "llm"
|
194 |
+
}
|
195 |
+
]
|
196 |
+
}
|
197 |
+
],
|
198 |
+
"data": [
|
199 |
+
{
|
200 |
+
"name": "text_data",
|
201 |
+
"dest": [
|
202 |
+
{
|
203 |
+
"extension": "llm"
|
204 |
+
}
|
205 |
+
]
|
206 |
+
}
|
207 |
+
]
|
208 |
+
}
|
209 |
+
]
|
210 |
+
},
|
211 |
+
{
|
212 |
+
"name": "deepseek_r1",
|
213 |
+
"auto_start": true,
|
214 |
+
"nodes": [
|
215 |
+
{
|
216 |
+
"type": "extension",
|
217 |
+
"name": "agora_rtc",
|
218 |
+
"addon": "agora_rtc",
|
219 |
+
"extension_group": "default",
|
220 |
+
"property": {
|
221 |
+
"app_id": "${env:AGORA_APP_ID}",
|
222 |
+
"token": "<agora_token>",
|
223 |
+
"channel": "ten_agent_test",
|
224 |
+
"stream_id": 1234,
|
225 |
+
"remote_stream_id": 123,
|
226 |
+
"subscribe_audio": true,
|
227 |
+
"publish_audio": true,
|
228 |
+
"publish_data": true,
|
229 |
+
"enable_agora_asr": true,
|
230 |
+
"agora_asr_vendor_name": "microsoft",
|
231 |
+
"agora_asr_language": "en-US",
|
232 |
+
"agora_asr_vendor_key": "${env:AZURE_STT_KEY|}",
|
233 |
+
"agora_asr_vendor_region": "${env:AZURE_STT_REGION|}",
|
234 |
+
"agora_asr_session_control_file_path": "session_control.conf"
|
235 |
+
}
|
236 |
+
},
|
237 |
+
{
|
238 |
+
"type": "extension",
|
239 |
+
"name": "llm",
|
240 |
+
"addon": "openai_chatgpt_python",
|
241 |
+
"extension_group": "chatgpt",
|
242 |
+
"property": {
|
243 |
+
"api_key": "${env:DEEPSEEK_API_KEY}",
|
244 |
+
"base_url": "https://tenagentopenai.services.ai.azure.com/models",
|
245 |
+
"frequency_penalty": 0.9,
|
246 |
+
"greeting": "TEN Agent connected. How can I help you today?",
|
247 |
+
"max_memory_length": 10,
|
248 |
+
"max_tokens": 512,
|
249 |
+
"model": "DeepSeek-R1",
|
250 |
+
"prompt": "",
|
251 |
+
"proxy_url": "${env:OPENAI_PROXY_URL}"
|
252 |
+
}
|
253 |
+
},
|
254 |
+
{
|
255 |
+
"type": "extension",
|
256 |
+
"name": "tts",
|
257 |
+
"addon": "azure_tts",
|
258 |
+
"extension_group": "tts",
|
259 |
+
"property": {
|
260 |
+
"azure_subscription_key": "${env:AZURE_TTS_KEY}",
|
261 |
+
"azure_subscription_region": "${env:AZURE_TTS_REGION}",
|
262 |
+
"azure_synthesis_voice_name": "en-US-AndrewMultilingualNeural"
|
263 |
+
}
|
264 |
+
},
|
265 |
+
{
|
266 |
+
"type": "extension",
|
267 |
+
"name": "interrupt_detector",
|
268 |
+
"addon": "interrupt_detector_python",
|
269 |
+
"extension_group": "default",
|
270 |
+
"property": {}
|
271 |
+
},
|
272 |
+
{
|
273 |
+
"type": "extension",
|
274 |
+
"name": "message_collector",
|
275 |
+
"addon": "message_collector",
|
276 |
+
"extension_group": "transcriber",
|
277 |
+
"property": {}
|
278 |
+
}
|
279 |
+
],
|
280 |
+
"connections": [
|
281 |
+
{
|
282 |
+
"extension": "agora_rtc",
|
283 |
+
"cmd": [
|
284 |
+
{
|
285 |
+
"name": "on_user_joined",
|
286 |
+
"dest": [
|
287 |
+
{
|
288 |
+
"extension": "llm"
|
289 |
+
}
|
290 |
+
]
|
291 |
+
},
|
292 |
+
{
|
293 |
+
"name": "on_user_left",
|
294 |
+
"dest": [
|
295 |
+
{
|
296 |
+
"extension": "llm"
|
297 |
+
}
|
298 |
+
]
|
299 |
+
},
|
300 |
+
{
|
301 |
+
"name": "on_connection_failure",
|
302 |
+
"dest": [
|
303 |
+
{
|
304 |
+
"extension": "llm"
|
305 |
+
}
|
306 |
+
]
|
307 |
+
}
|
308 |
+
],
|
309 |
+
"data": [
|
310 |
+
{
|
311 |
+
"name": "text_data",
|
312 |
+
"dest": [
|
313 |
+
{
|
314 |
+
"extension": "interrupt_detector"
|
315 |
+
},
|
316 |
+
{
|
317 |
+
"extension": "message_collector"
|
318 |
+
}
|
319 |
+
]
|
320 |
+
}
|
321 |
+
]
|
322 |
+
},
|
323 |
+
{
|
324 |
+
"extension": "llm",
|
325 |
+
"cmd": [
|
326 |
+
{
|
327 |
+
"name": "flush",
|
328 |
+
"dest": [
|
329 |
+
{
|
330 |
+
"extension": "tts"
|
331 |
+
}
|
332 |
+
]
|
333 |
+
}
|
334 |
+
],
|
335 |
+
"data": [
|
336 |
+
{
|
337 |
+
"name": "text_data",
|
338 |
+
"dest": [
|
339 |
+
{
|
340 |
+
"extension": "tts"
|
341 |
+
},
|
342 |
+
{
|
343 |
+
"extension": "message_collector"
|
344 |
+
}
|
345 |
+
]
|
346 |
+
},
|
347 |
+
{
|
348 |
+
"name": "content_data",
|
349 |
+
"dest": [
|
350 |
+
{
|
351 |
+
"extension": "message_collector"
|
352 |
+
}
|
353 |
+
]
|
354 |
+
}
|
355 |
+
]
|
356 |
+
},
|
357 |
+
{
|
358 |
+
"extension": "message_collector",
|
359 |
+
"data": [
|
360 |
+
{
|
361 |
+
"name": "data",
|
362 |
+
"dest": [
|
363 |
+
{
|
364 |
+
"extension": "agora_rtc"
|
365 |
+
}
|
366 |
+
]
|
367 |
+
}
|
368 |
+
]
|
369 |
+
},
|
370 |
+
{
|
371 |
+
"extension": "tts",
|
372 |
+
"cmd": [
|
373 |
+
{
|
374 |
+
"name": "flush",
|
375 |
+
"dest": [
|
376 |
+
{
|
377 |
+
"extension": "agora_rtc"
|
378 |
+
}
|
379 |
+
]
|
380 |
+
}
|
381 |
+
],
|
382 |
+
"audio_frame": [
|
383 |
+
{
|
384 |
+
"name": "pcm_frame",
|
385 |
+
"dest": [
|
386 |
+
{
|
387 |
+
"extension": "agora_rtc"
|
388 |
+
}
|
389 |
+
]
|
390 |
+
}
|
391 |
+
]
|
392 |
+
},
|
393 |
+
{
|
394 |
+
"extension": "interrupt_detector",
|
395 |
+
"cmd": [
|
396 |
+
{
|
397 |
+
"name": "flush",
|
398 |
+
"dest": [
|
399 |
+
{
|
400 |
+
"extension": "llm"
|
401 |
+
}
|
402 |
+
]
|
403 |
+
}
|
404 |
+
],
|
405 |
+
"data": [
|
406 |
+
{
|
407 |
+
"name": "text_data",
|
408 |
+
"dest": [
|
409 |
+
{
|
410 |
+
"extension": "llm"
|
411 |
+
}
|
412 |
+
]
|
413 |
+
}
|
414 |
+
]
|
415 |
+
}
|
416 |
+
]
|
417 |
+
},
|
418 |
+
{
|
419 |
+
"name": "voice_assistant_realtime",
|
420 |
+
"auto_start": true,
|
421 |
+
"nodes": [
|
422 |
+
{
|
423 |
+
"type": "extension",
|
424 |
+
"name": "agora_rtc",
|
425 |
+
"addon": "agora_rtc",
|
426 |
+
"extension_group": "rtc",
|
427 |
+
"property": {
|
428 |
+
"app_id": "${env:AGORA_APP_ID}",
|
429 |
+
"token": "",
|
430 |
+
"channel": "ten_agent_test",
|
431 |
+
"stream_id": 1234,
|
432 |
+
"remote_stream_id": 123,
|
433 |
+
"subscribe_audio": true,
|
434 |
+
"publish_audio": true,
|
435 |
+
"publish_data": true,
|
436 |
+
"subscribe_audio_sample_rate": 24000
|
437 |
+
}
|
438 |
+
},
|
439 |
+
{
|
440 |
+
"type": "extension",
|
441 |
+
"name": "v2v",
|
442 |
+
"addon": "openai_v2v_python",
|
443 |
+
"extension_group": "llm",
|
444 |
+
"property": {
|
445 |
+
"api_key": "${env:OPENAI_REALTIME_API_KEY}",
|
446 |
+
"temperature": 0.9,
|
447 |
+
"model": "gpt-4o-realtime-preview-2024-12-17",
|
448 |
+
"max_tokens": 2048,
|
449 |
+
"voice": "alloy",
|
450 |
+
"language": "en-US",
|
451 |
+
"server_vad": true,
|
452 |
+
"dump": true,
|
453 |
+
"max_history": 10
|
454 |
+
}
|
455 |
+
},
|
456 |
+
{
|
457 |
+
"type": "extension",
|
458 |
+
"name": "message_collector",
|
459 |
+
"addon": "message_collector",
|
460 |
+
"extension_group": "transcriber",
|
461 |
+
"property": {}
|
462 |
+
},
|
463 |
+
{
|
464 |
+
"type": "extension",
|
465 |
+
"name": "weatherapi_tool_python",
|
466 |
+
"addon": "weatherapi_tool_python",
|
467 |
+
"extension_group": "default",
|
468 |
+
"property": {
|
469 |
+
"api_key": "${env:WEATHERAPI_API_KEY|}"
|
470 |
+
}
|
471 |
+
}
|
472 |
+
],
|
473 |
+
"connections": [
|
474 |
+
{
|
475 |
+
"extension": "agora_rtc",
|
476 |
+
"cmd": [
|
477 |
+
{
|
478 |
+
"name": "on_user_joined",
|
479 |
+
"dest": [
|
480 |
+
{
|
481 |
+
"extension": "v2v"
|
482 |
+
}
|
483 |
+
]
|
484 |
+
},
|
485 |
+
{
|
486 |
+
"name": "on_user_left",
|
487 |
+
"dest": [
|
488 |
+
{
|
489 |
+
"extension": "v2v"
|
490 |
+
}
|
491 |
+
]
|
492 |
+
},
|
493 |
+
{
|
494 |
+
"name": "on_connection_failure",
|
495 |
+
"dest": [
|
496 |
+
{
|
497 |
+
"extension": "v2v"
|
498 |
+
}
|
499 |
+
]
|
500 |
+
}
|
501 |
+
],
|
502 |
+
"audio_frame": [
|
503 |
+
{
|
504 |
+
"name": "pcm_frame",
|
505 |
+
"dest": [
|
506 |
+
{
|
507 |
+
"extension": "v2v"
|
508 |
+
}
|
509 |
+
]
|
510 |
+
}
|
511 |
+
]
|
512 |
+
},
|
513 |
+
{
|
514 |
+
"extension": "v2v",
|
515 |
+
"cmd": [
|
516 |
+
{
|
517 |
+
"name": "flush",
|
518 |
+
"dest": [
|
519 |
+
{
|
520 |
+
"extension": "agora_rtc"
|
521 |
+
}
|
522 |
+
]
|
523 |
+
},
|
524 |
+
{
|
525 |
+
"name": "tool_call",
|
526 |
+
"dest": [
|
527 |
+
{
|
528 |
+
"extension": "weatherapi_tool_python"
|
529 |
+
}
|
530 |
+
]
|
531 |
+
}
|
532 |
+
],
|
533 |
+
"data": [
|
534 |
+
{
|
535 |
+
"name": "text_data",
|
536 |
+
"dest": [
|
537 |
+
{
|
538 |
+
"extension": "message_collector"
|
539 |
+
}
|
540 |
+
]
|
541 |
+
}
|
542 |
+
],
|
543 |
+
"audio_frame": [
|
544 |
+
{
|
545 |
+
"name": "pcm_frame",
|
546 |
+
"dest": [
|
547 |
+
{
|
548 |
+
"extension": "agora_rtc"
|
549 |
+
}
|
550 |
+
]
|
551 |
+
}
|
552 |
+
]
|
553 |
+
},
|
554 |
+
{
|
555 |
+
"extension": "message_collector",
|
556 |
+
"data": [
|
557 |
+
{
|
558 |
+
"name": "data",
|
559 |
+
"dest": [
|
560 |
+
{
|
561 |
+
"extension": "agora_rtc"
|
562 |
+
}
|
563 |
+
]
|
564 |
+
}
|
565 |
+
]
|
566 |
+
},
|
567 |
+
{
|
568 |
+
"extension": "weatherapi_tool_python",
|
569 |
+
"cmd": [
|
570 |
+
{
|
571 |
+
"name": "tool_register",
|
572 |
+
"dest": [
|
573 |
+
{
|
574 |
+
"extension": "v2v"
|
575 |
+
}
|
576 |
+
]
|
577 |
+
}
|
578 |
+
]
|
579 |
+
}
|
580 |
+
]
|
581 |
+
},
|
582 |
+
{
|
583 |
+
"name": "va_openai_azure",
|
584 |
+
"auto_start": true,
|
585 |
+
"nodes": [
|
586 |
+
{
|
587 |
+
"type": "extension",
|
588 |
+
"name": "agora_rtc",
|
589 |
+
"addon": "agora_rtc",
|
590 |
+
"extension_group": "default",
|
591 |
+
"property": {
|
592 |
+
"app_id": "${env:AGORA_APP_ID}",
|
593 |
+
"token": "<agora_token>",
|
594 |
+
"channel": "ten_agent_test",
|
595 |
+
"stream_id": 1234,
|
596 |
+
"remote_stream_id": 123,
|
597 |
+
"subscribe_audio": true,
|
598 |
+
"publish_audio": true,
|
599 |
+
"publish_data": true,
|
600 |
+
"enable_agora_asr": true,
|
601 |
+
"agora_asr_vendor_name": "microsoft",
|
602 |
+
"agora_asr_language": "en-US",
|
603 |
+
"agora_asr_vendor_key": "${env:AZURE_STT_KEY|}",
|
604 |
+
"agora_asr_vendor_region": "${env:AZURE_STT_REGION|}",
|
605 |
+
"agora_asr_session_control_file_path": "session_control.conf",
|
606 |
+
"subscribe_video_pix_fmt": 4,
|
607 |
+
"subscribe_video": true
|
608 |
+
}
|
609 |
+
},
|
610 |
+
{
|
611 |
+
"type": "extension",
|
612 |
+
"name": "llm",
|
613 |
+
"addon": "openai_chatgpt_python",
|
614 |
+
"extension_group": "chatgpt",
|
615 |
+
"property": {
|
616 |
+
"api_key": "${env:OPENAI_API_KEY}",
|
617 |
+
"base_url": "",
|
618 |
+
"frequency_penalty": 0.9,
|
619 |
+
"greeting": "TEN Agent connected. How can I help you today?",
|
620 |
+
"max_memory_length": 10,
|
621 |
+
"max_tokens": 512,
|
622 |
+
"model": "${env:OPENAI_MODEL}",
|
623 |
+
"prompt": "",
|
624 |
+
"proxy_url": "${env:OPENAI_PROXY_URL}"
|
625 |
+
}
|
626 |
+
},
|
627 |
+
{
|
628 |
+
"type": "extension",
|
629 |
+
"name": "tts",
|
630 |
+
"addon": "azure_tts",
|
631 |
+
"extension_group": "tts",
|
632 |
+
"property": {
|
633 |
+
"azure_subscription_key": "${env:AZURE_TTS_KEY}",
|
634 |
+
"azure_subscription_region": "${env:AZURE_TTS_REGION}",
|
635 |
+
"azure_synthesis_voice_name": "en-US-AndrewMultilingualNeural"
|
636 |
+
}
|
637 |
+
},
|
638 |
+
{
|
639 |
+
"type": "extension",
|
640 |
+
"name": "interrupt_detector",
|
641 |
+
"addon": "interrupt_detector_python",
|
642 |
+
"extension_group": "default",
|
643 |
+
"property": {}
|
644 |
+
},
|
645 |
+
{
|
646 |
+
"type": "extension",
|
647 |
+
"name": "message_collector",
|
648 |
+
"addon": "message_collector",
|
649 |
+
"extension_group": "transcriber",
|
650 |
+
"property": {}
|
651 |
+
},
|
652 |
+
{
|
653 |
+
"type": "extension",
|
654 |
+
"name": "weatherapi_tool_python",
|
655 |
+
"addon": "weatherapi_tool_python",
|
656 |
+
"extension_group": "default",
|
657 |
+
"property": {
|
658 |
+
"api_key": "${env:WEATHERAPI_API_KEY|}"
|
659 |
+
}
|
660 |
+
},
|
661 |
+
{
|
662 |
+
"type": "extension",
|
663 |
+
"name": "vision_tool_python",
|
664 |
+
"addon": "vision_tool_python",
|
665 |
+
"extension_group": "default",
|
666 |
+
"property": {}
|
667 |
+
},
|
668 |
+
{
|
669 |
+
"type": "extension",
|
670 |
+
"name": "bingsearch_tool_python",
|
671 |
+
"addon": "bingsearch_tool_python",
|
672 |
+
"extension_group": "default",
|
673 |
+
"property": {
|
674 |
+
"api_key": "${env:BING_API_KEY|}"
|
675 |
+
}
|
676 |
+
}
|
677 |
+
],
|
678 |
+
"connections": [
|
679 |
+
{
|
680 |
+
"extension": "agora_rtc",
|
681 |
+
"cmd": [
|
682 |
+
{
|
683 |
+
"name": "on_user_joined",
|
684 |
+
"dest": [
|
685 |
+
{
|
686 |
+
"extension": "llm"
|
687 |
+
}
|
688 |
+
]
|
689 |
+
},
|
690 |
+
{
|
691 |
+
"name": "on_user_left",
|
692 |
+
"dest": [
|
693 |
+
{
|
694 |
+
"extension": "llm"
|
695 |
+
}
|
696 |
+
]
|
697 |
+
},
|
698 |
+
{
|
699 |
+
"name": "on_connection_failure",
|
700 |
+
"dest": [
|
701 |
+
{
|
702 |
+
"extension": "llm"
|
703 |
+
}
|
704 |
+
]
|
705 |
+
}
|
706 |
+
],
|
707 |
+
"data": [
|
708 |
+
{
|
709 |
+
"name": "text_data",
|
710 |
+
"dest": [
|
711 |
+
{
|
712 |
+
"extension": "interrupt_detector"
|
713 |
+
},
|
714 |
+
{
|
715 |
+
"extension": "message_collector"
|
716 |
+
}
|
717 |
+
]
|
718 |
+
}
|
719 |
+
],
|
720 |
+
"video_frame": [
|
721 |
+
{
|
722 |
+
"name": "video_frame",
|
723 |
+
"dest": [
|
724 |
+
{
|
725 |
+
"extension": "vision_tool_python"
|
726 |
+
}
|
727 |
+
]
|
728 |
+
}
|
729 |
+
]
|
730 |
+
},
|
731 |
+
{
|
732 |
+
"extension": "llm",
|
733 |
+
"cmd": [
|
734 |
+
{
|
735 |
+
"name": "flush",
|
736 |
+
"dest": [
|
737 |
+
{
|
738 |
+
"extension": "tts"
|
739 |
+
}
|
740 |
+
]
|
741 |
+
},
|
742 |
+
{
|
743 |
+
"name": "tool_call",
|
744 |
+
"dest": [
|
745 |
+
{
|
746 |
+
"extension": "weatherapi_tool_python"
|
747 |
+
},
|
748 |
+
{
|
749 |
+
"extension": "vision_tool_python"
|
750 |
+
},
|
751 |
+
{
|
752 |
+
"extension": "bingsearch_tool_python"
|
753 |
+
}
|
754 |
+
]
|
755 |
+
}
|
756 |
+
],
|
757 |
+
"data": [
|
758 |
+
{
|
759 |
+
"name": "text_data",
|
760 |
+
"dest": [
|
761 |
+
{
|
762 |
+
"extension": "tts"
|
763 |
+
},
|
764 |
+
{
|
765 |
+
"extension": "message_collector"
|
766 |
+
}
|
767 |
+
]
|
768 |
+
}
|
769 |
+
]
|
770 |
+
},
|
771 |
+
{
|
772 |
+
"extension": "message_collector",
|
773 |
+
"data": [
|
774 |
+
{
|
775 |
+
"name": "data",
|
776 |
+
"dest": [
|
777 |
+
{
|
778 |
+
"extension": "agora_rtc"
|
779 |
+
}
|
780 |
+
]
|
781 |
+
}
|
782 |
+
]
|
783 |
+
},
|
784 |
+
{
|
785 |
+
"extension": "tts",
|
786 |
+
"cmd": [
|
787 |
+
{
|
788 |
+
"name": "flush",
|
789 |
+
"dest": [
|
790 |
+
{
|
791 |
+
"extension": "agora_rtc"
|
792 |
+
}
|
793 |
+
]
|
794 |
+
}
|
795 |
+
],
|
796 |
+
"audio_frame": [
|
797 |
+
{
|
798 |
+
"name": "pcm_frame",
|
799 |
+
"dest": [
|
800 |
+
{
|
801 |
+
"extension": "agora_rtc"
|
802 |
+
}
|
803 |
+
]
|
804 |
+
}
|
805 |
+
]
|
806 |
+
},
|
807 |
+
{
|
808 |
+
"extension": "interrupt_detector",
|
809 |
+
"cmd": [
|
810 |
+
{
|
811 |
+
"name": "flush",
|
812 |
+
"dest": [
|
813 |
+
{
|
814 |
+
"extension": "llm"
|
815 |
+
}
|
816 |
+
]
|
817 |
+
}
|
818 |
+
],
|
819 |
+
"data": [
|
820 |
+
{
|
821 |
+
"name": "text_data",
|
822 |
+
"dest": [
|
823 |
+
{
|
824 |
+
"extension": "llm"
|
825 |
+
}
|
826 |
+
]
|
827 |
+
}
|
828 |
+
]
|
829 |
+
},
|
830 |
+
{
|
831 |
+
"extension": "weatherapi_tool_python",
|
832 |
+
"cmd": [
|
833 |
+
{
|
834 |
+
"name": "tool_register",
|
835 |
+
"dest": [
|
836 |
+
{
|
837 |
+
"extension": "llm"
|
838 |
+
}
|
839 |
+
]
|
840 |
+
}
|
841 |
+
]
|
842 |
+
},
|
843 |
+
{
|
844 |
+
"extension": "vision_tool_python",
|
845 |
+
"cmd": [
|
846 |
+
{
|
847 |
+
"name": "tool_register",
|
848 |
+
"dest": [
|
849 |
+
{
|
850 |
+
"extension": "llm"
|
851 |
+
}
|
852 |
+
]
|
853 |
+
}
|
854 |
+
]
|
855 |
+
},
|
856 |
+
{
|
857 |
+
"extension": "bingsearch_tool_python",
|
858 |
+
"cmd": [
|
859 |
+
{
|
860 |
+
"name": "tool_register",
|
861 |
+
"dest": [
|
862 |
+
{
|
863 |
+
"extension": "llm"
|
864 |
+
}
|
865 |
+
]
|
866 |
+
}
|
867 |
+
]
|
868 |
+
}
|
869 |
+
]
|
870 |
+
},
|
871 |
+
{
|
872 |
+
"name": "va_openai_v2v",
|
873 |
+
"auto_start": true,
|
874 |
+
"nodes": [
|
875 |
+
{
|
876 |
+
"type": "extension",
|
877 |
+
"name": "agora_rtc",
|
878 |
+
"addon": "agora_rtc",
|
879 |
+
"extension_group": "rtc",
|
880 |
+
"property": {
|
881 |
+
"app_id": "${env:AGORA_APP_ID}",
|
882 |
+
"token": "",
|
883 |
+
"channel": "ten_agent_test",
|
884 |
+
"stream_id": 1234,
|
885 |
+
"remote_stream_id": 123,
|
886 |
+
"subscribe_audio": true,
|
887 |
+
"publish_audio": true,
|
888 |
+
"publish_data": true,
|
889 |
+
"subscribe_audio_sample_rate": 24000
|
890 |
+
}
|
891 |
+
},
|
892 |
+
{
|
893 |
+
"type": "extension",
|
894 |
+
"name": "v2v",
|
895 |
+
"addon": "openai_v2v_python",
|
896 |
+
"extension_group": "llm",
|
897 |
+
"property": {
|
898 |
+
"api_key": "${env:OPENAI_REALTIME_API_KEY}",
|
899 |
+
"temperature": 0.9,
|
900 |
+
"model": "gpt-4o-realtime-preview-2024-12-17",
|
901 |
+
"max_tokens": 2048,
|
902 |
+
"voice": "alloy",
|
903 |
+
"language": "en-US",
|
904 |
+
"server_vad": true,
|
905 |
+
"dump": true,
|
906 |
+
"max_history": 10
|
907 |
+
}
|
908 |
+
},
|
909 |
+
{
|
910 |
+
"type": "extension",
|
911 |
+
"name": "message_collector",
|
912 |
+
"addon": "message_collector",
|
913 |
+
"extension_group": "transcriber",
|
914 |
+
"property": {}
|
915 |
+
},
|
916 |
+
{
|
917 |
+
"type": "extension",
|
918 |
+
"name": "bingsearch_tool_python",
|
919 |
+
"addon": "bingsearch_tool_python",
|
920 |
+
"extension_group": "default",
|
921 |
+
"property": {
|
922 |
+
"api_key": "${env:BING_API_KEY|}"
|
923 |
+
}
|
924 |
+
},
|
925 |
+
{
|
926 |
+
"type": "extension",
|
927 |
+
"name": "weatherapi_tool_python",
|
928 |
+
"addon": "weatherapi_tool_python",
|
929 |
+
"extension_group": "default",
|
930 |
+
"property": {
|
931 |
+
"api_key": "${env:WEATHERAPI_API_KEY|}"
|
932 |
+
}
|
933 |
+
}
|
934 |
+
],
|
935 |
+
"connections": [
|
936 |
+
{
|
937 |
+
"extension": "agora_rtc",
|
938 |
+
"cmd": [
|
939 |
+
{
|
940 |
+
"name": "on_user_joined",
|
941 |
+
"dest": [
|
942 |
+
{
|
943 |
+
"extension": "v2v"
|
944 |
+
}
|
945 |
+
]
|
946 |
+
},
|
947 |
+
{
|
948 |
+
"name": "on_user_left",
|
949 |
+
"dest": [
|
950 |
+
{
|
951 |
+
"extension": "v2v"
|
952 |
+
}
|
953 |
+
]
|
954 |
+
},
|
955 |
+
{
|
956 |
+
"name": "on_connection_failure",
|
957 |
+
"dest": [
|
958 |
+
{
|
959 |
+
"extension": "v2v"
|
960 |
+
}
|
961 |
+
]
|
962 |
+
}
|
963 |
+
],
|
964 |
+
"audio_frame": [
|
965 |
+
{
|
966 |
+
"name": "pcm_frame",
|
967 |
+
"dest": [
|
968 |
+
{
|
969 |
+
"extension": "v2v"
|
970 |
+
}
|
971 |
+
]
|
972 |
+
}
|
973 |
+
]
|
974 |
+
},
|
975 |
+
{
|
976 |
+
"extension": "v2v",
|
977 |
+
"cmd": [
|
978 |
+
{
|
979 |
+
"name": "flush",
|
980 |
+
"dest": [
|
981 |
+
{
|
982 |
+
"extension": "agora_rtc"
|
983 |
+
}
|
984 |
+
]
|
985 |
+
},
|
986 |
+
{
|
987 |
+
"name": "tool_call",
|
988 |
+
"dest": [
|
989 |
+
{
|
990 |
+
"extension": "bingsearch_tool_python"
|
991 |
+
},
|
992 |
+
{
|
993 |
+
"extension": "weatherapi_tool_python"
|
994 |
+
}
|
995 |
+
]
|
996 |
+
}
|
997 |
+
],
|
998 |
+
"data": [
|
999 |
+
{
|
1000 |
+
"name": "text_data",
|
1001 |
+
"dest": [
|
1002 |
+
{
|
1003 |
+
"extension": "message_collector"
|
1004 |
+
}
|
1005 |
+
]
|
1006 |
+
}
|
1007 |
+
],
|
1008 |
+
"audio_frame": [
|
1009 |
+
{
|
1010 |
+
"name": "pcm_frame",
|
1011 |
+
"dest": [
|
1012 |
+
{
|
1013 |
+
"extension": "agora_rtc"
|
1014 |
+
}
|
1015 |
+
]
|
1016 |
+
}
|
1017 |
+
]
|
1018 |
+
},
|
1019 |
+
{
|
1020 |
+
"extension": "message_collector",
|
1021 |
+
"data": [
|
1022 |
+
{
|
1023 |
+
"name": "data",
|
1024 |
+
"dest": [
|
1025 |
+
{
|
1026 |
+
"extension": "agora_rtc"
|
1027 |
+
}
|
1028 |
+
]
|
1029 |
+
}
|
1030 |
+
]
|
1031 |
+
},
|
1032 |
+
{
|
1033 |
+
"extension": "bingsearch_tool_python",
|
1034 |
+
"cmd": [
|
1035 |
+
{
|
1036 |
+
"name": "tool_register",
|
1037 |
+
"dest": [
|
1038 |
+
{
|
1039 |
+
"extension": "v2v"
|
1040 |
+
}
|
1041 |
+
]
|
1042 |
+
}
|
1043 |
+
]
|
1044 |
+
},
|
1045 |
+
{
|
1046 |
+
"extension": "weatherapi_tool_python",
|
1047 |
+
"cmd": [
|
1048 |
+
{
|
1049 |
+
"name": "tool_register",
|
1050 |
+
"dest": [
|
1051 |
+
{
|
1052 |
+
"extension": "v2v"
|
1053 |
+
}
|
1054 |
+
]
|
1055 |
+
}
|
1056 |
+
]
|
1057 |
+
}
|
1058 |
+
]
|
1059 |
+
},
|
1060 |
+
{
|
1061 |
+
"name": "va_openai_v2v_fish",
|
1062 |
+
"auto_start": true,
|
1063 |
+
"nodes": [
|
1064 |
+
{
|
1065 |
+
"type": "extension",
|
1066 |
+
"name": "agora_rtc",
|
1067 |
+
"addon": "agora_rtc",
|
1068 |
+
"extension_group": "rtc",
|
1069 |
+
"property": {
|
1070 |
+
"app_id": "${env:AGORA_APP_ID}",
|
1071 |
+
"token": "",
|
1072 |
+
"channel": "ten_agent_test",
|
1073 |
+
"stream_id": 1234,
|
1074 |
+
"remote_stream_id": 123,
|
1075 |
+
"subscribe_audio": true,
|
1076 |
+
"publish_audio": true,
|
1077 |
+
"publish_data": true,
|
1078 |
+
"subscribe_audio_sample_rate": 24000,
|
1079 |
+
"enable_agora_asr": false,
|
1080 |
+
"agora_asr_vendor_name": "microsoft",
|
1081 |
+
"agora_asr_language": "en-US",
|
1082 |
+
"agora_asr_vendor_key": "${env:AZURE_STT_KEY}",
|
1083 |
+
"agora_asr_vendor_region": "${env:AZURE_STT_REGION}",
|
1084 |
+
"agora_asr_session_control_file_path": "session_control.conf"
|
1085 |
+
}
|
1086 |
+
},
|
1087 |
+
{
|
1088 |
+
"type": "extension",
|
1089 |
+
"name": "v2v",
|
1090 |
+
"addon": "openai_v2v_python",
|
1091 |
+
"extension_group": "llm",
|
1092 |
+
"property": {
|
1093 |
+
"api_key": "${env:OPENAI_REALTIME_API_KEY}",
|
1094 |
+
"temperature": 0.9,
|
1095 |
+
"model": "gpt-4o-realtime-preview-2024-12-17",
|
1096 |
+
"max_tokens": 2048,
|
1097 |
+
"audio_out": false,
|
1098 |
+
"input_transcript": false,
|
1099 |
+
"language": "en-US",
|
1100 |
+
"server_vad": true,
|
1101 |
+
"dump": true,
|
1102 |
+
"max_history": 10
|
1103 |
+
}
|
1104 |
+
},
|
1105 |
+
{
|
1106 |
+
"type": "extension",
|
1107 |
+
"name": "tts",
|
1108 |
+
"addon": "fish_audio_tts",
|
1109 |
+
"extension_group": "tts",
|
1110 |
+
"property": {
|
1111 |
+
"api_key": "${env:FISH_AUDIO_TTS_KEY}",
|
1112 |
+
"base_url": "https://api.fish.audio",
|
1113 |
+
"model_id": "d8639b5cc95548f5afbcfe22d3ba5ce5",
|
1114 |
+
"optimize_streaming_latency": true,
|
1115 |
+
"request_timeout_seconds": 30
|
1116 |
+
}
|
1117 |
+
},
|
1118 |
+
{
|
1119 |
+
"type": "extension",
|
1120 |
+
"name": "message_collector",
|
1121 |
+
"addon": "message_collector",
|
1122 |
+
"extension_group": "transcriber",
|
1123 |
+
"property": {}
|
1124 |
+
},
|
1125 |
+
{
|
1126 |
+
"type": "extension",
|
1127 |
+
"name": "weatherapi_tool_python",
|
1128 |
+
"addon": "weatherapi_tool_python",
|
1129 |
+
"extension_group": "tools",
|
1130 |
+
"property": {
|
1131 |
+
"api_key": "${env:WEATHERAPI_API_KEY}"
|
1132 |
+
}
|
1133 |
+
},
|
1134 |
+
{
|
1135 |
+
"type": "extension",
|
1136 |
+
"name": "bingsearch_tool_python",
|
1137 |
+
"addon": "bingsearch_tool_python",
|
1138 |
+
"extension_group": "tools",
|
1139 |
+
"property": {
|
1140 |
+
"api_key": "${env:BING_API_KEY}"
|
1141 |
+
}
|
1142 |
+
}
|
1143 |
+
],
|
1144 |
+
"connections": [
|
1145 |
+
{
|
1146 |
+
"extension": "agora_rtc",
|
1147 |
+
"data": [
|
1148 |
+
{
|
1149 |
+
"name": "text_data",
|
1150 |
+
"dest": [
|
1151 |
+
{
|
1152 |
+
"extension": "message_collector"
|
1153 |
+
}
|
1154 |
+
]
|
1155 |
+
}
|
1156 |
+
],
|
1157 |
+
"audio_frame": [
|
1158 |
+
{
|
1159 |
+
"name": "pcm_frame",
|
1160 |
+
"dest": [
|
1161 |
+
{
|
1162 |
+
"extension": "v2v"
|
1163 |
+
}
|
1164 |
+
]
|
1165 |
+
}
|
1166 |
+
]
|
1167 |
+
},
|
1168 |
+
{
|
1169 |
+
"extension": "weatherapi_tool_python",
|
1170 |
+
"cmd": [
|
1171 |
+
{
|
1172 |
+
"name": "tool_register",
|
1173 |
+
"dest": [
|
1174 |
+
{
|
1175 |
+
"extension": "v2v"
|
1176 |
+
}
|
1177 |
+
]
|
1178 |
+
}
|
1179 |
+
]
|
1180 |
+
},
|
1181 |
+
{
|
1182 |
+
"extension": "bingsearch_tool_python",
|
1183 |
+
"cmd": [
|
1184 |
+
{
|
1185 |
+
"name": "tool_register",
|
1186 |
+
"dest": [
|
1187 |
+
{
|
1188 |
+
"extension": "v2v"
|
1189 |
+
}
|
1190 |
+
]
|
1191 |
+
}
|
1192 |
+
]
|
1193 |
+
},
|
1194 |
+
{
|
1195 |
+
"extension": "v2v",
|
1196 |
+
"cmd": [
|
1197 |
+
{
|
1198 |
+
"name": "flush",
|
1199 |
+
"dest": [
|
1200 |
+
{
|
1201 |
+
"extension": "tts"
|
1202 |
+
}
|
1203 |
+
]
|
1204 |
+
},
|
1205 |
+
{
|
1206 |
+
"name": "tool_call",
|
1207 |
+
"dest": [
|
1208 |
+
{
|
1209 |
+
"extension": "weatherapi_tool_python"
|
1210 |
+
},
|
1211 |
+
{
|
1212 |
+
"extension": "bingsearch_tool_python"
|
1213 |
+
}
|
1214 |
+
]
|
1215 |
+
},
|
1216 |
+
{
|
1217 |
+
"name": "on_user_joined",
|
1218 |
+
"dest": [
|
1219 |
+
{
|
1220 |
+
"extension": "v2v"
|
1221 |
+
}
|
1222 |
+
]
|
1223 |
+
},
|
1224 |
+
{
|
1225 |
+
"name": "on_user_left",
|
1226 |
+
"dest": [
|
1227 |
+
{
|
1228 |
+
"extension": "v2v"
|
1229 |
+
}
|
1230 |
+
]
|
1231 |
+
}
|
1232 |
+
],
|
1233 |
+
"data": [
|
1234 |
+
{
|
1235 |
+
"name": "text_data",
|
1236 |
+
"dest": [
|
1237 |
+
{
|
1238 |
+
"extension": "message_collector"
|
1239 |
+
},
|
1240 |
+
{
|
1241 |
+
"extension": "tts"
|
1242 |
+
}
|
1243 |
+
]
|
1244 |
+
}
|
1245 |
+
]
|
1246 |
+
},
|
1247 |
+
{
|
1248 |
+
"extension": "tts",
|
1249 |
+
"cmd": [
|
1250 |
+
{
|
1251 |
+
"name": "flush",
|
1252 |
+
"dest": [
|
1253 |
+
{
|
1254 |
+
"extension": "agora_rtc"
|
1255 |
+
}
|
1256 |
+
]
|
1257 |
+
}
|
1258 |
+
],
|
1259 |
+
"audio_frame": [
|
1260 |
+
{
|
1261 |
+
"name": "pcm_frame",
|
1262 |
+
"dest": [
|
1263 |
+
{
|
1264 |
+
"extension": "agora_rtc"
|
1265 |
+
}
|
1266 |
+
]
|
1267 |
+
}
|
1268 |
+
]
|
1269 |
+
},
|
1270 |
+
{
|
1271 |
+
"extension": "message_collector",
|
1272 |
+
"data": [
|
1273 |
+
{
|
1274 |
+
"name": "data",
|
1275 |
+
"dest": [
|
1276 |
+
{
|
1277 |
+
"extension": "agora_rtc"
|
1278 |
+
}
|
1279 |
+
]
|
1280 |
+
}
|
1281 |
+
]
|
1282 |
+
}
|
1283 |
+
]
|
1284 |
+
},
|
1285 |
+
{
|
1286 |
+
"name": "va_coze_azure",
|
1287 |
+
"auto_start": false,
|
1288 |
+
"nodes": [
|
1289 |
+
{
|
1290 |
+
"type": "extension",
|
1291 |
+
"name": "agora_rtc",
|
1292 |
+
"addon": "agora_rtc",
|
1293 |
+
"extension_group": "default",
|
1294 |
+
"property": {
|
1295 |
+
"app_id": "${env:AGORA_APP_ID}",
|
1296 |
+
"token": "<agora_token>",
|
1297 |
+
"channel": "ten_agent_test",
|
1298 |
+
"stream_id": 1234,
|
1299 |
+
"remote_stream_id": 123,
|
1300 |
+
"subscribe_audio": true,
|
1301 |
+
"publish_audio": true,
|
1302 |
+
"publish_data": true,
|
1303 |
+
"enable_agora_asr": true,
|
1304 |
+
"agora_asr_vendor_name": "microsoft",
|
1305 |
+
"agora_asr_language": "en-US",
|
1306 |
+
"agora_asr_vendor_key": "${env:AZURE_STT_KEY}",
|
1307 |
+
"agora_asr_vendor_region": "${env:AZURE_STT_REGION}",
|
1308 |
+
"agora_asr_session_control_file_path": "session_control.conf"
|
1309 |
+
}
|
1310 |
+
},
|
1311 |
+
{
|
1312 |
+
"type": "extension",
|
1313 |
+
"name": "interrupt_detector",
|
1314 |
+
"addon": "interrupt_detector_python",
|
1315 |
+
"extension_group": "default"
|
1316 |
+
},
|
1317 |
+
{
|
1318 |
+
"type": "extension",
|
1319 |
+
"name": "coze_python_async",
|
1320 |
+
"addon": "coze_python_async",
|
1321 |
+
"extension_group": "glue",
|
1322 |
+
"property": {
|
1323 |
+
"token": "<coze_token>",
|
1324 |
+
"bot_id": "<coze_bot_id>",
|
1325 |
+
"base_url": "https://api.coze.cn",
|
1326 |
+
"prompt": "",
|
1327 |
+
"greeting": "TEN Agent connected. How can I help you today?"
|
1328 |
+
}
|
1329 |
+
},
|
1330 |
+
{
|
1331 |
+
"type": "extension",
|
1332 |
+
"name": "tts",
|
1333 |
+
"addon": "azure_tts",
|
1334 |
+
"extension_group": "tts",
|
1335 |
+
"property": {
|
1336 |
+
"azure_subscription_key": "${env:AZURE_TTS_KEY}",
|
1337 |
+
"azure_subscription_region": "${env:AZURE_TTS_REGION}",
|
1338 |
+
"azure_synthesis_voice_name": "en-US-AndrewMultilingualNeural"
|
1339 |
+
}
|
1340 |
+
},
|
1341 |
+
{
|
1342 |
+
"type": "extension",
|
1343 |
+
"name": "message_collector",
|
1344 |
+
"addon": "message_collector",
|
1345 |
+
"extension_group": "transcriber"
|
1346 |
+
}
|
1347 |
+
],
|
1348 |
+
"connections": [
|
1349 |
+
{
|
1350 |
+
"extension": "agora_rtc",
|
1351 |
+
"cmd": [
|
1352 |
+
{
|
1353 |
+
"name": "on_user_joined",
|
1354 |
+
"dest": [
|
1355 |
+
{
|
1356 |
+
"extension": "coze_python_async"
|
1357 |
+
}
|
1358 |
+
]
|
1359 |
+
},
|
1360 |
+
{
|
1361 |
+
"name": "on_user_left",
|
1362 |
+
"dest": [
|
1363 |
+
{
|
1364 |
+
"extension": "coze_python_async"
|
1365 |
+
}
|
1366 |
+
]
|
1367 |
+
}
|
1368 |
+
],
|
1369 |
+
"data": [
|
1370 |
+
{
|
1371 |
+
"name": "text_data",
|
1372 |
+
"dest": [
|
1373 |
+
{
|
1374 |
+
"extension": "interrupt_detector"
|
1375 |
+
},
|
1376 |
+
{
|
1377 |
+
"extension": "coze_python_async"
|
1378 |
+
},
|
1379 |
+
{
|
1380 |
+
"extension": "message_collector"
|
1381 |
+
}
|
1382 |
+
]
|
1383 |
+
}
|
1384 |
+
]
|
1385 |
+
},
|
1386 |
+
{
|
1387 |
+
"extension": "coze_python_async",
|
1388 |
+
"cmd": [
|
1389 |
+
{
|
1390 |
+
"name": "flush",
|
1391 |
+
"dest": [
|
1392 |
+
{
|
1393 |
+
"extension": "tts"
|
1394 |
+
}
|
1395 |
+
]
|
1396 |
+
}
|
1397 |
+
],
|
1398 |
+
"data": [
|
1399 |
+
{
|
1400 |
+
"name": "text_data",
|
1401 |
+
"dest": [
|
1402 |
+
{
|
1403 |
+
"extension": "tts"
|
1404 |
+
},
|
1405 |
+
{
|
1406 |
+
"extension": "message_collector"
|
1407 |
+
}
|
1408 |
+
]
|
1409 |
+
}
|
1410 |
+
]
|
1411 |
+
},
|
1412 |
+
{
|
1413 |
+
"extension": "tts",
|
1414 |
+
"cmd": [
|
1415 |
+
{
|
1416 |
+
"name": "flush",
|
1417 |
+
"dest": [
|
1418 |
+
{
|
1419 |
+
"extension": "agora_rtc"
|
1420 |
+
}
|
1421 |
+
]
|
1422 |
+
}
|
1423 |
+
],
|
1424 |
+
"audio_frame": [
|
1425 |
+
{
|
1426 |
+
"name": "pcm_frame",
|
1427 |
+
"dest": [
|
1428 |
+
{
|
1429 |
+
"extension": "agora_rtc"
|
1430 |
+
}
|
1431 |
+
]
|
1432 |
+
}
|
1433 |
+
]
|
1434 |
+
},
|
1435 |
+
{
|
1436 |
+
"extension": "message_collector",
|
1437 |
+
"data": [
|
1438 |
+
{
|
1439 |
+
"name": "data",
|
1440 |
+
"dest": [
|
1441 |
+
{
|
1442 |
+
"extension": "agora_rtc"
|
1443 |
+
}
|
1444 |
+
]
|
1445 |
+
}
|
1446 |
+
]
|
1447 |
+
},
|
1448 |
+
{
|
1449 |
+
"extension": "interrupt_detector",
|
1450 |
+
"cmd": [
|
1451 |
+
{
|
1452 |
+
"name": "flush",
|
1453 |
+
"dest": [
|
1454 |
+
{
|
1455 |
+
"extension": "coze_python_async"
|
1456 |
+
}
|
1457 |
+
]
|
1458 |
+
}
|
1459 |
+
]
|
1460 |
+
}
|
1461 |
+
]
|
1462 |
+
},
|
1463 |
+
{
|
1464 |
+
"name": "va_gemini_v2v",
|
1465 |
+
"auto_start": true,
|
1466 |
+
"nodes": [
|
1467 |
+
{
|
1468 |
+
"type": "extension",
|
1469 |
+
"name": "agora_rtc",
|
1470 |
+
"addon": "agora_rtc",
|
1471 |
+
"extension_group": "rtc",
|
1472 |
+
"property": {
|
1473 |
+
"app_id": "${env:AGORA_APP_ID}",
|
1474 |
+
"token": "",
|
1475 |
+
"channel": "ten_agent_test",
|
1476 |
+
"stream_id": 1234,
|
1477 |
+
"remote_stream_id": 123,
|
1478 |
+
"subscribe_audio": true,
|
1479 |
+
"publish_audio": true,
|
1480 |
+
"publish_data": true,
|
1481 |
+
"subscribe_audio_sample_rate": 24000,
|
1482 |
+
"subscribe_video_pix_fmt": 4,
|
1483 |
+
"subscribe_video": true
|
1484 |
+
}
|
1485 |
+
},
|
1486 |
+
{
|
1487 |
+
"type": "extension",
|
1488 |
+
"name": "v2v",
|
1489 |
+
"addon": "gemini_v2v_python",
|
1490 |
+
"extension_group": "llm",
|
1491 |
+
"property": {
|
1492 |
+
"api_key": "${env:GEMINI_API_KEY}",
|
1493 |
+
"api_version": "v1alpha",
|
1494 |
+
"base_uri": "generativelanguage.googleapis.com",
|
1495 |
+
"dump": true,
|
1496 |
+
"language": "en-US",
|
1497 |
+
"max_tokens": 2048,
|
1498 |
+
"model": "gemini-2.0-flash-exp",
|
1499 |
+
"server_vad": true,
|
1500 |
+
"temperature": 0.9,
|
1501 |
+
"voice": "Puck"
|
1502 |
+
}
|
1503 |
+
},
|
1504 |
+
{
|
1505 |
+
"type": "extension",
|
1506 |
+
"name": "message_collector",
|
1507 |
+
"addon": "message_collector",
|
1508 |
+
"extension_group": "transcriber",
|
1509 |
+
"property": {}
|
1510 |
+
},
|
1511 |
+
{
|
1512 |
+
"type": "extension",
|
1513 |
+
"name": "weatherapi_tool_python",
|
1514 |
+
"addon": "weatherapi_tool_python",
|
1515 |
+
"extension_group": "default",
|
1516 |
+
"property": {
|
1517 |
+
"api_key": "${env:WEATHERAPI_API_KEY|}"
|
1518 |
+
}
|
1519 |
+
}
|
1520 |
+
],
|
1521 |
+
"connections": [
|
1522 |
+
{
|
1523 |
+
"extension": "agora_rtc",
|
1524 |
+
"cmd": [
|
1525 |
+
{
|
1526 |
+
"name": "on_user_joined",
|
1527 |
+
"dest": [
|
1528 |
+
{
|
1529 |
+
"extension": "v2v"
|
1530 |
+
}
|
1531 |
+
]
|
1532 |
+
},
|
1533 |
+
{
|
1534 |
+
"name": "on_user_left",
|
1535 |
+
"dest": [
|
1536 |
+
{
|
1537 |
+
"extension": "v2v"
|
1538 |
+
}
|
1539 |
+
]
|
1540 |
+
},
|
1541 |
+
{
|
1542 |
+
"name": "on_connection_failure",
|
1543 |
+
"dest": [
|
1544 |
+
{
|
1545 |
+
"extension": "v2v"
|
1546 |
+
}
|
1547 |
+
]
|
1548 |
+
}
|
1549 |
+
],
|
1550 |
+
"audio_frame": [
|
1551 |
+
{
|
1552 |
+
"name": "pcm_frame",
|
1553 |
+
"dest": [
|
1554 |
+
{
|
1555 |
+
"extension": "v2v"
|
1556 |
+
}
|
1557 |
+
]
|
1558 |
+
}
|
1559 |
+
],
|
1560 |
+
"video_frame": [
|
1561 |
+
{
|
1562 |
+
"name": "video_frame",
|
1563 |
+
"dest": [
|
1564 |
+
{
|
1565 |
+
"extension": "v2v"
|
1566 |
+
}
|
1567 |
+
]
|
1568 |
+
}
|
1569 |
+
]
|
1570 |
+
},
|
1571 |
+
{
|
1572 |
+
"extension": "v2v",
|
1573 |
+
"cmd": [
|
1574 |
+
{
|
1575 |
+
"name": "flush",
|
1576 |
+
"dest": [
|
1577 |
+
{
|
1578 |
+
"extension": "agora_rtc"
|
1579 |
+
}
|
1580 |
+
]
|
1581 |
+
},
|
1582 |
+
{
|
1583 |
+
"name": "tool_call",
|
1584 |
+
"dest": [
|
1585 |
+
{
|
1586 |
+
"extension": "weatherapi_tool_python"
|
1587 |
+
}
|
1588 |
+
]
|
1589 |
+
}
|
1590 |
+
],
|
1591 |
+
"data": [
|
1592 |
+
{
|
1593 |
+
"name": "text_data",
|
1594 |
+
"dest": [
|
1595 |
+
{
|
1596 |
+
"extension": "message_collector"
|
1597 |
+
}
|
1598 |
+
]
|
1599 |
+
}
|
1600 |
+
],
|
1601 |
+
"audio_frame": [
|
1602 |
+
{
|
1603 |
+
"name": "pcm_frame",
|
1604 |
+
"dest": [
|
1605 |
+
{
|
1606 |
+
"extension": "agora_rtc"
|
1607 |
+
}
|
1608 |
+
]
|
1609 |
+
}
|
1610 |
+
]
|
1611 |
+
},
|
1612 |
+
{
|
1613 |
+
"extension": "message_collector",
|
1614 |
+
"data": [
|
1615 |
+
{
|
1616 |
+
"name": "data",
|
1617 |
+
"dest": [
|
1618 |
+
{
|
1619 |
+
"extension": "agora_rtc"
|
1620 |
+
}
|
1621 |
+
]
|
1622 |
+
}
|
1623 |
+
]
|
1624 |
+
},
|
1625 |
+
{
|
1626 |
+
"extension": "weatherapi_tool_python",
|
1627 |
+
"cmd": [
|
1628 |
+
{
|
1629 |
+
"name": "tool_register",
|
1630 |
+
"dest": [
|
1631 |
+
{
|
1632 |
+
"extension": "v2v"
|
1633 |
+
}
|
1634 |
+
]
|
1635 |
+
}
|
1636 |
+
]
|
1637 |
+
}
|
1638 |
+
]
|
1639 |
+
},
|
1640 |
+
{
|
1641 |
+
"name": "va_dify_azure",
|
1642 |
+
"auto_start": true,
|
1643 |
+
"nodes": [
|
1644 |
+
{
|
1645 |
+
"type": "extension",
|
1646 |
+
"name": "agora_rtc",
|
1647 |
+
"addon": "agora_rtc",
|
1648 |
+
"extension_group": "default",
|
1649 |
+
"property": {
|
1650 |
+
"app_id": "${env:AGORA_APP_ID}",
|
1651 |
+
"token": "<agora_token>",
|
1652 |
+
"channel": "ten_agent_test",
|
1653 |
+
"stream_id": 1234,
|
1654 |
+
"remote_stream_id": 123,
|
1655 |
+
"subscribe_audio": true,
|
1656 |
+
"publish_audio": true,
|
1657 |
+
"publish_data": true,
|
1658 |
+
"enable_agora_asr": true,
|
1659 |
+
"agora_asr_vendor_name": "microsoft",
|
1660 |
+
"agora_asr_language": "en-US",
|
1661 |
+
"agora_asr_vendor_key": "${env:AZURE_STT_KEY|}",
|
1662 |
+
"agora_asr_vendor_region": "${env:AZURE_STT_REGION|}",
|
1663 |
+
"agora_asr_session_control_file_path": "session_control.conf"
|
1664 |
+
}
|
1665 |
+
},
|
1666 |
+
{
|
1667 |
+
"type": "extension",
|
1668 |
+
"name": "llm",
|
1669 |
+
"addon": "dify_python",
|
1670 |
+
"extension_group": "chatgpt",
|
1671 |
+
"property": {
|
1672 |
+
"api_key": "${env:DIFY_API_KEY}",
|
1673 |
+
"base_url": "https://api.dify.ai/v1",
|
1674 |
+
"greeting": "TEN Agent connected with Dify. How can I help you today?",
|
1675 |
+
"user_id": "User"
|
1676 |
+
}
|
1677 |
+
},
|
1678 |
+
{
|
1679 |
+
"type": "extension",
|
1680 |
+
"name": "tts",
|
1681 |
+
"addon": "azure_tts",
|
1682 |
+
"extension_group": "tts",
|
1683 |
+
"property": {
|
1684 |
+
"azure_subscription_key": "${env:AZURE_TTS_KEY}",
|
1685 |
+
"azure_subscription_region": "${env:AZURE_TTS_REGION}",
|
1686 |
+
"azure_synthesis_voice_name": "en-US-AndrewMultilingualNeural"
|
1687 |
+
}
|
1688 |
+
},
|
1689 |
+
{
|
1690 |
+
"type": "extension",
|
1691 |
+
"name": "interrupt_detector",
|
1692 |
+
"addon": "interrupt_detector_python",
|
1693 |
+
"extension_group": "default",
|
1694 |
+
"property": {}
|
1695 |
+
},
|
1696 |
+
{
|
1697 |
+
"type": "extension",
|
1698 |
+
"name": "message_collector",
|
1699 |
+
"addon": "message_collector",
|
1700 |
+
"extension_group": "transcriber",
|
1701 |
+
"property": {}
|
1702 |
+
}
|
1703 |
+
],
|
1704 |
+
"connections": [
|
1705 |
+
{
|
1706 |
+
"extension": "agora_rtc",
|
1707 |
+
"cmd": [
|
1708 |
+
{
|
1709 |
+
"name": "on_user_joined",
|
1710 |
+
"dest": [
|
1711 |
+
{
|
1712 |
+
"extension": "llm"
|
1713 |
+
}
|
1714 |
+
]
|
1715 |
+
},
|
1716 |
+
{
|
1717 |
+
"name": "on_user_left",
|
1718 |
+
"dest": [
|
1719 |
+
{
|
1720 |
+
"extension": "llm"
|
1721 |
+
}
|
1722 |
+
]
|
1723 |
+
},
|
1724 |
+
{
|
1725 |
+
"name": "on_connection_failure",
|
1726 |
+
"dest": [
|
1727 |
+
{
|
1728 |
+
"extension": "llm"
|
1729 |
+
}
|
1730 |
+
]
|
1731 |
+
}
|
1732 |
+
],
|
1733 |
+
"data": [
|
1734 |
+
{
|
1735 |
+
"name": "text_data",
|
1736 |
+
"dest": [
|
1737 |
+
{
|
1738 |
+
"extension": "interrupt_detector"
|
1739 |
+
},
|
1740 |
+
{
|
1741 |
+
"extension": "message_collector"
|
1742 |
+
}
|
1743 |
+
]
|
1744 |
+
}
|
1745 |
+
]
|
1746 |
+
},
|
1747 |
+
{
|
1748 |
+
"extension": "llm",
|
1749 |
+
"cmd": [
|
1750 |
+
{
|
1751 |
+
"name": "flush",
|
1752 |
+
"dest": [
|
1753 |
+
{
|
1754 |
+
"extension": "tts"
|
1755 |
+
}
|
1756 |
+
]
|
1757 |
+
}
|
1758 |
+
],
|
1759 |
+
"data": [
|
1760 |
+
{
|
1761 |
+
"name": "text_data",
|
1762 |
+
"dest": [
|
1763 |
+
{
|
1764 |
+
"extension": "tts"
|
1765 |
+
},
|
1766 |
+
{
|
1767 |
+
"extension": "message_collector"
|
1768 |
+
}
|
1769 |
+
]
|
1770 |
+
}
|
1771 |
+
]
|
1772 |
+
},
|
1773 |
+
{
|
1774 |
+
"extension": "message_collector",
|
1775 |
+
"data": [
|
1776 |
+
{
|
1777 |
+
"name": "data",
|
1778 |
+
"dest": [
|
1779 |
+
{
|
1780 |
+
"extension": "agora_rtc"
|
1781 |
+
}
|
1782 |
+
]
|
1783 |
+
}
|
1784 |
+
]
|
1785 |
+
},
|
1786 |
+
{
|
1787 |
+
"extension": "tts",
|
1788 |
+
"cmd": [
|
1789 |
+
{
|
1790 |
+
"name": "flush",
|
1791 |
+
"dest": [
|
1792 |
+
{
|
1793 |
+
"extension": "agora_rtc"
|
1794 |
+
}
|
1795 |
+
]
|
1796 |
+
}
|
1797 |
+
],
|
1798 |
+
"audio_frame": [
|
1799 |
+
{
|
1800 |
+
"name": "pcm_frame",
|
1801 |
+
"dest": [
|
1802 |
+
{
|
1803 |
+
"extension": "agora_rtc"
|
1804 |
+
}
|
1805 |
+
]
|
1806 |
+
}
|
1807 |
+
]
|
1808 |
+
},
|
1809 |
+
{
|
1810 |
+
"extension": "interrupt_detector",
|
1811 |
+
"cmd": [
|
1812 |
+
{
|
1813 |
+
"name": "flush",
|
1814 |
+
"dest": [
|
1815 |
+
{
|
1816 |
+
"extension": "llm"
|
1817 |
+
}
|
1818 |
+
]
|
1819 |
+
}
|
1820 |
+
],
|
1821 |
+
"data": [
|
1822 |
+
{
|
1823 |
+
"name": "text_data",
|
1824 |
+
"dest": [
|
1825 |
+
{
|
1826 |
+
"extension": "llm"
|
1827 |
+
}
|
1828 |
+
]
|
1829 |
+
}
|
1830 |
+
]
|
1831 |
+
}
|
1832 |
+
]
|
1833 |
+
},
|
1834 |
+
{
|
1835 |
+
"name": "story_teller_stt_integrated",
|
1836 |
+
"auto_start": true,
|
1837 |
+
"nodes": [
|
1838 |
+
{
|
1839 |
+
"type": "extension",
|
1840 |
+
"name": "agora_rtc",
|
1841 |
+
"addon": "agora_rtc",
|
1842 |
+
"extension_group": "default",
|
1843 |
+
"property": {
|
1844 |
+
"app_id": "${env:AGORA_APP_ID}",
|
1845 |
+
"token": "<agora_token>",
|
1846 |
+
"channel": "ten_agent_test",
|
1847 |
+
"stream_id": 1234,
|
1848 |
+
"remote_stream_id": 123,
|
1849 |
+
"subscribe_audio": true,
|
1850 |
+
"publish_audio": true,
|
1851 |
+
"publish_data": true,
|
1852 |
+
"enable_agora_asr": true,
|
1853 |
+
"agora_asr_vendor_name": "microsoft",
|
1854 |
+
"agora_asr_language": "en-US",
|
1855 |
+
"agora_asr_vendor_key": "${env:AZURE_STT_KEY|}",
|
1856 |
+
"agora_asr_vendor_region": "${env:AZURE_STT_REGION|}",
|
1857 |
+
"agora_asr_session_control_file_path": "session_control.conf"
|
1858 |
+
}
|
1859 |
+
},
|
1860 |
+
{
|
1861 |
+
"type": "extension",
|
1862 |
+
"name": "llm",
|
1863 |
+
"addon": "openai_chatgpt_python",
|
1864 |
+
"extension_group": "chatgpt",
|
1865 |
+
"property": {
|
1866 |
+
"api_key": "${env:OPENAI_API_KEY}",
|
1867 |
+
"base_url": "",
|
1868 |
+
"frequency_penalty": 0.9,
|
1869 |
+
"greeting": "TEN Agent connected. How can I help you today?",
|
1870 |
+
"max_memory_length": 10,
|
1871 |
+
"max_tokens": 512,
|
1872 |
+
"model": "${env:OPENAI_MODEL}",
|
1873 |
+
"prompt": "You are an ai agent bot producing child picture books. Each response should be short and no more than 50 words as it's for child. \nFor every response relevant to the story-telling, you will use the 'image_generate' tool to create an image based on the description or key moment in that part of the story. \n The story should be set in a fantasy world. Try asking questions relevant to the story to decide how the story should proceed. Every response should include rich, vivid descriptions that will guide the 'image_generate' tool to produce an image that aligns with the scene or mood.\n Whether it’s the setting, a character’s expression, or a dramatic moment, the paragraph should give enough detail for a meaningful visual representation.",
|
1874 |
+
"proxy_url": "${env:OPENAI_PROXY_URL}"
|
1875 |
+
}
|
1876 |
+
},
|
1877 |
+
{
|
1878 |
+
"type": "extension",
|
1879 |
+
"name": "tts",
|
1880 |
+
"addon": "azure_tts",
|
1881 |
+
"extension_group": "tts",
|
1882 |
+
"property": {
|
1883 |
+
"azure_subscription_key": "${env:AZURE_TTS_KEY}",
|
1884 |
+
"azure_subscription_region": "${env:AZURE_TTS_REGION}",
|
1885 |
+
"azure_synthesis_voice_name": "en-US-AndrewMultilingualNeural"
|
1886 |
+
}
|
1887 |
+
},
|
1888 |
+
{
|
1889 |
+
"type": "extension",
|
1890 |
+
"name": "interrupt_detector",
|
1891 |
+
"addon": "interrupt_detector_python",
|
1892 |
+
"extension_group": "default",
|
1893 |
+
"property": {}
|
1894 |
+
},
|
1895 |
+
{
|
1896 |
+
"type": "extension",
|
1897 |
+
"name": "message_collector",
|
1898 |
+
"addon": "message_collector",
|
1899 |
+
"extension_group": "transcriber",
|
1900 |
+
"property": {}
|
1901 |
+
},
|
1902 |
+
{
|
1903 |
+
"type": "extension",
|
1904 |
+
"name": "openai_image_generate_tool",
|
1905 |
+
"addon": "openai_image_generate_tool",
|
1906 |
+
"extension_group": "default",
|
1907 |
+
"property": {
|
1908 |
+
"api_key": "${env:OPENAI_API_KEY}"
|
1909 |
+
}
|
1910 |
+
}
|
1911 |
+
],
|
1912 |
+
"connections": [
|
1913 |
+
{
|
1914 |
+
"extension": "agora_rtc",
|
1915 |
+
"cmd": [
|
1916 |
+
{
|
1917 |
+
"name": "on_user_joined",
|
1918 |
+
"dest": [
|
1919 |
+
{
|
1920 |
+
"extension": "llm"
|
1921 |
+
}
|
1922 |
+
]
|
1923 |
+
},
|
1924 |
+
{
|
1925 |
+
"name": "on_user_left",
|
1926 |
+
"dest": [
|
1927 |
+
{
|
1928 |
+
"extension": "llm"
|
1929 |
+
}
|
1930 |
+
]
|
1931 |
+
},
|
1932 |
+
{
|
1933 |
+
"name": "on_connection_failure",
|
1934 |
+
"dest": [
|
1935 |
+
{
|
1936 |
+
"extension": "llm"
|
1937 |
+
}
|
1938 |
+
]
|
1939 |
+
}
|
1940 |
+
],
|
1941 |
+
"data": [
|
1942 |
+
{
|
1943 |
+
"name": "text_data",
|
1944 |
+
"dest": [
|
1945 |
+
{
|
1946 |
+
"extension": "interrupt_detector"
|
1947 |
+
},
|
1948 |
+
{
|
1949 |
+
"extension": "message_collector"
|
1950 |
+
}
|
1951 |
+
]
|
1952 |
+
}
|
1953 |
+
]
|
1954 |
+
},
|
1955 |
+
{
|
1956 |
+
"extension": "llm",
|
1957 |
+
"cmd": [
|
1958 |
+
{
|
1959 |
+
"name": "flush",
|
1960 |
+
"dest": [
|
1961 |
+
{
|
1962 |
+
"extension": "tts"
|
1963 |
+
}
|
1964 |
+
]
|
1965 |
+
},
|
1966 |
+
{
|
1967 |
+
"name": "tool_call",
|
1968 |
+
"dest": [
|
1969 |
+
{
|
1970 |
+
"extension": "openai_image_generate_tool"
|
1971 |
+
}
|
1972 |
+
]
|
1973 |
+
}
|
1974 |
+
],
|
1975 |
+
"data": [
|
1976 |
+
{
|
1977 |
+
"name": "text_data",
|
1978 |
+
"dest": [
|
1979 |
+
{
|
1980 |
+
"extension": "tts"
|
1981 |
+
},
|
1982 |
+
{
|
1983 |
+
"extension": "message_collector"
|
1984 |
+
}
|
1985 |
+
]
|
1986 |
+
}
|
1987 |
+
]
|
1988 |
+
},
|
1989 |
+
{
|
1990 |
+
"extension": "message_collector",
|
1991 |
+
"data": [
|
1992 |
+
{
|
1993 |
+
"name": "data",
|
1994 |
+
"dest": [
|
1995 |
+
{
|
1996 |
+
"extension": "agora_rtc"
|
1997 |
+
}
|
1998 |
+
]
|
1999 |
+
}
|
2000 |
+
]
|
2001 |
+
},
|
2002 |
+
{
|
2003 |
+
"extension": "tts",
|
2004 |
+
"cmd": [
|
2005 |
+
{
|
2006 |
+
"name": "flush",
|
2007 |
+
"dest": [
|
2008 |
+
{
|
2009 |
+
"extension": "agora_rtc"
|
2010 |
+
}
|
2011 |
+
]
|
2012 |
+
}
|
2013 |
+
],
|
2014 |
+
"audio_frame": [
|
2015 |
+
{
|
2016 |
+
"name": "pcm_frame",
|
2017 |
+
"dest": [
|
2018 |
+
{
|
2019 |
+
"extension": "agora_rtc"
|
2020 |
+
}
|
2021 |
+
]
|
2022 |
+
}
|
2023 |
+
]
|
2024 |
+
},
|
2025 |
+
{
|
2026 |
+
"extension": "interrupt_detector",
|
2027 |
+
"cmd": [
|
2028 |
+
{
|
2029 |
+
"name": "flush",
|
2030 |
+
"dest": [
|
2031 |
+
{
|
2032 |
+
"extension": "llm"
|
2033 |
+
}
|
2034 |
+
]
|
2035 |
+
}
|
2036 |
+
],
|
2037 |
+
"data": [
|
2038 |
+
{
|
2039 |
+
"name": "text_data",
|
2040 |
+
"dest": [
|
2041 |
+
{
|
2042 |
+
"extension": "llm"
|
2043 |
+
}
|
2044 |
+
]
|
2045 |
+
}
|
2046 |
+
]
|
2047 |
+
},
|
2048 |
+
{
|
2049 |
+
"extension": "openai_image_generate_tool",
|
2050 |
+
"cmd": [
|
2051 |
+
{
|
2052 |
+
"name": "tool_register",
|
2053 |
+
"dest": [
|
2054 |
+
{
|
2055 |
+
"extension": "llm"
|
2056 |
+
}
|
2057 |
+
]
|
2058 |
+
}
|
2059 |
+
],
|
2060 |
+
"data": [
|
2061 |
+
{
|
2062 |
+
"name": "content_data",
|
2063 |
+
"dest": [
|
2064 |
+
{
|
2065 |
+
"extension": "message_collector"
|
2066 |
+
}
|
2067 |
+
]
|
2068 |
+
}
|
2069 |
+
]
|
2070 |
+
}
|
2071 |
+
]
|
2072 |
+
},
|
2073 |
+
{
|
2074 |
+
"name": "va_nova_multimodal_aws",
|
2075 |
+
"auto_start": true,
|
2076 |
+
"nodes": [
|
2077 |
+
{
|
2078 |
+
"type": "extension",
|
2079 |
+
"name": "agora_rtc",
|
2080 |
+
"addon": "agora_rtc",
|
2081 |
+
"extension_group": "default",
|
2082 |
+
"property": {
|
2083 |
+
"app_id": "${env:AGORA_APP_ID}",
|
2084 |
+
"token": "<agora_token>",
|
2085 |
+
"channel": "ten_agent_test",
|
2086 |
+
"stream_id": 1234,
|
2087 |
+
"remote_stream_id": 123,
|
2088 |
+
"subscribe_audio": true,
|
2089 |
+
"publish_audio": true,
|
2090 |
+
"publish_data": true,
|
2091 |
+
"enable_agora_asr": false,
|
2092 |
+
"agora_asr_vendor_name": "microsoft",
|
2093 |
+
"agora_asr_language": "en-US",
|
2094 |
+
"agora_asr_vendor_key": "${env:AZURE_STT_KEY|}",
|
2095 |
+
"agora_asr_vendor_region": "${env:AZURE_STT_REGION|}",
|
2096 |
+
"agora_asr_session_control_file_path": "session_control.conf",
|
2097 |
+
"subscribe_video_pix_fmt": 4,
|
2098 |
+
"subscribe_video": true,
|
2099 |
+
"max_memory_length": 10
|
2100 |
+
}
|
2101 |
+
},
|
2102 |
+
{
|
2103 |
+
"type": "extension",
|
2104 |
+
"name": "stt",
|
2105 |
+
"addon": "transcribe_asr_python",
|
2106 |
+
"extension_group": "stt",
|
2107 |
+
"property": {
|
2108 |
+
"access_key": "${env:AWS_ACCESS_KEY_ID}",
|
2109 |
+
"lang_code": "en-US",
|
2110 |
+
"region": "us-east-1",
|
2111 |
+
"sample_rate": "16000",
|
2112 |
+
"secret_key": "${env:AWS_SECRET_ACCESS_KEY}"
|
2113 |
+
}
|
2114 |
+
},
|
2115 |
+
{
|
2116 |
+
"type": "extension",
|
2117 |
+
"name": "llm",
|
2118 |
+
"addon": "bedrock_llm_python",
|
2119 |
+
"extension_group": "chatgpt",
|
2120 |
+
"property": {
|
2121 |
+
"access_key_id": "${env:AWS_ACCESS_KEY_ID}",
|
2122 |
+
"greeting": "TEN Agent connected. I am nova, How can I help you today?",
|
2123 |
+
"max_memory_length": 10,
|
2124 |
+
"max_tokens": 256,
|
2125 |
+
"model": "us.amazon.nova-lite-v1:0",
|
2126 |
+
"prompt": "Now you are an intelligent assistant with real-time interaction capabilities. I will provide you with a series of real-time video image information. Please understand these images as video frames. Based on the images and the user's input, engage in a conversation with the user, remembering the dialogue content in a concise and clear manner.",
|
2127 |
+
"region": "us-east-1",
|
2128 |
+
"secret_access_key": "${env:AWS_SECRET_ACCESS_KEY}",
|
2129 |
+
"temperature": 0.7,
|
2130 |
+
"topK": 10,
|
2131 |
+
"topP": 0.5,
|
2132 |
+
"is_memory_enabled": false,
|
2133 |
+
"is_enable_video": true
|
2134 |
+
}
|
2135 |
+
},
|
2136 |
+
{
|
2137 |
+
"type": "extension",
|
2138 |
+
"name": "tts",
|
2139 |
+
"addon": "polly_tts",
|
2140 |
+
"extension_group": "tts",
|
2141 |
+
"property": {
|
2142 |
+
"region": "us-east-1",
|
2143 |
+
"access_key": "${env:AWS_ACCESS_KEY_ID}",
|
2144 |
+
"secret_key": "${env:AWS_SECRET_ACCESS_KEY}",
|
2145 |
+
"engine": "generative",
|
2146 |
+
"voice": "Ruth",
|
2147 |
+
"sample_rate": 16000,
|
2148 |
+
"lang_code": "en-US"
|
2149 |
+
}
|
2150 |
+
},
|
2151 |
+
{
|
2152 |
+
"type": "extension",
|
2153 |
+
"name": "interrupt_detector",
|
2154 |
+
"addon": "interrupt_detector_python",
|
2155 |
+
"extension_group": "default",
|
2156 |
+
"property": {}
|
2157 |
+
},
|
2158 |
+
{
|
2159 |
+
"type": "extension",
|
2160 |
+
"name": "message_collector",
|
2161 |
+
"addon": "message_collector",
|
2162 |
+
"extension_group": "transcriber",
|
2163 |
+
"property": {}
|
2164 |
+
}
|
2165 |
+
],
|
2166 |
+
"connections": [
|
2167 |
+
{
|
2168 |
+
"extension": "agora_rtc",
|
2169 |
+
"cmd": [
|
2170 |
+
{
|
2171 |
+
"name": "on_user_joined",
|
2172 |
+
"dest": [
|
2173 |
+
{
|
2174 |
+
"extension": "llm"
|
2175 |
+
}
|
2176 |
+
]
|
2177 |
+
},
|
2178 |
+
{
|
2179 |
+
"name": "on_user_left",
|
2180 |
+
"dest": [
|
2181 |
+
{
|
2182 |
+
"extension": "llm"
|
2183 |
+
}
|
2184 |
+
]
|
2185 |
+
},
|
2186 |
+
{
|
2187 |
+
"name": "on_connection_failure",
|
2188 |
+
"dest": [
|
2189 |
+
{
|
2190 |
+
"extension": "llm"
|
2191 |
+
}
|
2192 |
+
]
|
2193 |
+
}
|
2194 |
+
],
|
2195 |
+
"audio_frame": [
|
2196 |
+
{
|
2197 |
+
"name": "pcm_frame",
|
2198 |
+
"dest": [
|
2199 |
+
{
|
2200 |
+
"extension": "stt"
|
2201 |
+
}
|
2202 |
+
]
|
2203 |
+
}
|
2204 |
+
],
|
2205 |
+
"video_frame": [
|
2206 |
+
{
|
2207 |
+
"name": "video_frame",
|
2208 |
+
"dest": [
|
2209 |
+
{
|
2210 |
+
"extension": "llm"
|
2211 |
+
}
|
2212 |
+
]
|
2213 |
+
}
|
2214 |
+
]
|
2215 |
+
},
|
2216 |
+
{
|
2217 |
+
"extension": "stt",
|
2218 |
+
"data": [
|
2219 |
+
{
|
2220 |
+
"name": "text_data",
|
2221 |
+
"dest": [
|
2222 |
+
{
|
2223 |
+
"extension": "interrupt_detector"
|
2224 |
+
},
|
2225 |
+
{
|
2226 |
+
"extension": "message_collector"
|
2227 |
+
}
|
2228 |
+
]
|
2229 |
+
}
|
2230 |
+
]
|
2231 |
+
},
|
2232 |
+
{
|
2233 |
+
"extension": "llm",
|
2234 |
+
"cmd": [
|
2235 |
+
{
|
2236 |
+
"name": "flush",
|
2237 |
+
"dest": [
|
2238 |
+
{
|
2239 |
+
"extension": "tts"
|
2240 |
+
}
|
2241 |
+
]
|
2242 |
+
}
|
2243 |
+
],
|
2244 |
+
"data": [
|
2245 |
+
{
|
2246 |
+
"name": "text_data",
|
2247 |
+
"dest": [
|
2248 |
+
{
|
2249 |
+
"extension": "tts"
|
2250 |
+
},
|
2251 |
+
{
|
2252 |
+
"extension": "message_collector"
|
2253 |
+
}
|
2254 |
+
]
|
2255 |
+
}
|
2256 |
+
]
|
2257 |
+
},
|
2258 |
+
{
|
2259 |
+
"extension": "message_collector",
|
2260 |
+
"data": [
|
2261 |
+
{
|
2262 |
+
"name": "data",
|
2263 |
+
"dest": [
|
2264 |
+
{
|
2265 |
+
"extension": "agora_rtc"
|
2266 |
+
}
|
2267 |
+
]
|
2268 |
+
}
|
2269 |
+
]
|
2270 |
+
},
|
2271 |
+
{
|
2272 |
+
"extension": "tts",
|
2273 |
+
"cmd": [
|
2274 |
+
{
|
2275 |
+
"name": "flush",
|
2276 |
+
"dest": [
|
2277 |
+
{
|
2278 |
+
"extension": "agora_rtc"
|
2279 |
+
}
|
2280 |
+
]
|
2281 |
+
}
|
2282 |
+
],
|
2283 |
+
"audio_frame": [
|
2284 |
+
{
|
2285 |
+
"name": "pcm_frame",
|
2286 |
+
"dest": [
|
2287 |
+
{
|
2288 |
+
"extension": "agora_rtc"
|
2289 |
+
}
|
2290 |
+
]
|
2291 |
+
}
|
2292 |
+
]
|
2293 |
+
},
|
2294 |
+
{
|
2295 |
+
"extension": "interrupt_detector",
|
2296 |
+
"cmd": [
|
2297 |
+
{
|
2298 |
+
"name": "flush",
|
2299 |
+
"dest": [
|
2300 |
+
{
|
2301 |
+
"extension": "llm"
|
2302 |
+
}
|
2303 |
+
]
|
2304 |
+
}
|
2305 |
+
],
|
2306 |
+
"data": [
|
2307 |
+
{
|
2308 |
+
"name": "text_data",
|
2309 |
+
"dest": [
|
2310 |
+
{
|
2311 |
+
"extension": "llm"
|
2312 |
+
}
|
2313 |
+
]
|
2314 |
+
}
|
2315 |
+
]
|
2316 |
+
}
|
2317 |
+
]
|
2318 |
+
}
|
2319 |
+
],
|
2320 |
+
"log_level": 3
|
2321 |
+
}
|
2322 |
+
}
|
agents/examples/experimental/manifest.json
ADDED
@@ -0,0 +1,122 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"type": "app",
|
3 |
+
"name": "agent_experimental",
|
4 |
+
"version": "0.8.0",
|
5 |
+
"dependencies": [
|
6 |
+
{
|
7 |
+
"type": "system",
|
8 |
+
"name": "ten_runtime_go",
|
9 |
+
"version": "0.8"
|
10 |
+
},
|
11 |
+
{
|
12 |
+
"type": "extension",
|
13 |
+
"name": "agora_rtc",
|
14 |
+
"version": "=0.12.0"
|
15 |
+
},
|
16 |
+
{
|
17 |
+
"type": "extension",
|
18 |
+
"name": "agora_sess_ctrl",
|
19 |
+
"version": "=0.4.4"
|
20 |
+
},
|
21 |
+
{
|
22 |
+
"type": "system",
|
23 |
+
"name": "azure_speech_sdk",
|
24 |
+
"version": "1.38.0"
|
25 |
+
},
|
26 |
+
{
|
27 |
+
"type": "system",
|
28 |
+
"name": "ten_ai_base",
|
29 |
+
"version": "0.4.1"
|
30 |
+
},
|
31 |
+
{
|
32 |
+
"type": "extension",
|
33 |
+
"name": "azure_tts",
|
34 |
+
"version": "=0.8.1"
|
35 |
+
},
|
36 |
+
{
|
37 |
+
"type": "extension",
|
38 |
+
"name": "agora_rtm",
|
39 |
+
"version": "=0.8.1"
|
40 |
+
},
|
41 |
+
{
|
42 |
+
"type": "extension",
|
43 |
+
"name": "interrupt_detector_python",
|
44 |
+
"version": "=0.1.0"
|
45 |
+
},
|
46 |
+
{
|
47 |
+
"type": "extension",
|
48 |
+
"name": "openai_chatgpt_python",
|
49 |
+
"version": "=0.1.0"
|
50 |
+
},
|
51 |
+
{
|
52 |
+
"type": "extension",
|
53 |
+
"name": "message_collector",
|
54 |
+
"version": "=0.1.0"
|
55 |
+
},
|
56 |
+
{
|
57 |
+
"type": "extension",
|
58 |
+
"name": "fashionai",
|
59 |
+
"version": "=0.1.0"
|
60 |
+
},
|
61 |
+
{
|
62 |
+
"type": "extension",
|
63 |
+
"name": "qwen_llm_python",
|
64 |
+
"version": "=0.1.0"
|
65 |
+
},
|
66 |
+
{
|
67 |
+
"type": "extension",
|
68 |
+
"name": "cosy_tts_python",
|
69 |
+
"version": "=0.1.0"
|
70 |
+
},
|
71 |
+
{
|
72 |
+
"type": "extension",
|
73 |
+
"name": "http_server_python",
|
74 |
+
"version": "=0.10.1"
|
75 |
+
},
|
76 |
+
{
|
77 |
+
"type": "extension",
|
78 |
+
"name": "aliyun_text_embedding",
|
79 |
+
"version": "=0.1.0"
|
80 |
+
},
|
81 |
+
{
|
82 |
+
"type": "extension",
|
83 |
+
"name": "aliyun_analyticdb_vector_storage",
|
84 |
+
"version": "=0.1.0"
|
85 |
+
},
|
86 |
+
{
|
87 |
+
"type": "extension",
|
88 |
+
"name": "file_chunker",
|
89 |
+
"version": "=0.1.0"
|
90 |
+
},
|
91 |
+
{
|
92 |
+
"type": "extension",
|
93 |
+
"name": "llama_index_chat_engine",
|
94 |
+
"version": "=0.1.0"
|
95 |
+
},
|
96 |
+
{
|
97 |
+
"type": "extension",
|
98 |
+
"name": "openai_v2v_python",
|
99 |
+
"version": "=0.1.0"
|
100 |
+
},
|
101 |
+
{
|
102 |
+
"type": "extension",
|
103 |
+
"name": "weatherapi_tool_python",
|
104 |
+
"version": "=0.1.0"
|
105 |
+
},
|
106 |
+
{
|
107 |
+
"type": "extension",
|
108 |
+
"name": "bingsearch_tool_python",
|
109 |
+
"version": "=0.1.0"
|
110 |
+
},
|
111 |
+
{
|
112 |
+
"type": "extension",
|
113 |
+
"name": "tsdb_firestore",
|
114 |
+
"version": "=0.1.0"
|
115 |
+
},
|
116 |
+
{
|
117 |
+
"type": "extension",
|
118 |
+
"name": "minimax_v2v_python",
|
119 |
+
"version": "=0.1.0"
|
120 |
+
}
|
121 |
+
]
|
122 |
+
}
|
agents/examples/experimental/property.json
ADDED
@@ -0,0 +1,862 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"_ten": {
|
3 |
+
"log_level": 3,
|
4 |
+
"predefined_graphs": [
|
5 |
+
{
|
6 |
+
"name": "va_openai_azure_fashionai",
|
7 |
+
"auto_start": false,
|
8 |
+
"connections": [
|
9 |
+
{
|
10 |
+
"data": [
|
11 |
+
{
|
12 |
+
"dest": [
|
13 |
+
{
|
14 |
+
"extension": "interrupt_detector"
|
15 |
+
},
|
16 |
+
{
|
17 |
+
"extension": "openai_chatgpt"
|
18 |
+
},
|
19 |
+
{
|
20 |
+
"extension": "message_collector"
|
21 |
+
}
|
22 |
+
],
|
23 |
+
"name": "text_data"
|
24 |
+
}
|
25 |
+
],
|
26 |
+
"cmd": [
|
27 |
+
{
|
28 |
+
"name": "on_user_joined",
|
29 |
+
"dest": [
|
30 |
+
{
|
31 |
+
"extension": "openai_chatgpt"
|
32 |
+
}
|
33 |
+
]
|
34 |
+
},
|
35 |
+
{
|
36 |
+
"name": "on_user_left",
|
37 |
+
"dest": [
|
38 |
+
{
|
39 |
+
"extension": "openai_chatgpt"
|
40 |
+
}
|
41 |
+
]
|
42 |
+
}
|
43 |
+
],
|
44 |
+
"extension": "agora_rtc"
|
45 |
+
},
|
46 |
+
{
|
47 |
+
"cmd": [
|
48 |
+
{
|
49 |
+
"dest": [
|
50 |
+
{
|
51 |
+
"extension": "fashionai"
|
52 |
+
}
|
53 |
+
],
|
54 |
+
"name": "flush"
|
55 |
+
}
|
56 |
+
],
|
57 |
+
"data": [
|
58 |
+
{
|
59 |
+
"dest": [
|
60 |
+
{
|
61 |
+
"extension": "message_collector"
|
62 |
+
},
|
63 |
+
{
|
64 |
+
"extension": "fashionai"
|
65 |
+
}
|
66 |
+
],
|
67 |
+
"name": "text_data"
|
68 |
+
}
|
69 |
+
],
|
70 |
+
"extension": "openai_chatgpt"
|
71 |
+
},
|
72 |
+
{
|
73 |
+
"data": [
|
74 |
+
{
|
75 |
+
"dest": [
|
76 |
+
{
|
77 |
+
"extension": "agora_rtc"
|
78 |
+
}
|
79 |
+
],
|
80 |
+
"name": "data"
|
81 |
+
}
|
82 |
+
],
|
83 |
+
"extension": "message_collector"
|
84 |
+
},
|
85 |
+
{
|
86 |
+
"cmd": [
|
87 |
+
{
|
88 |
+
"dest": [
|
89 |
+
{
|
90 |
+
"extension": "openai_chatgpt"
|
91 |
+
}
|
92 |
+
],
|
93 |
+
"name": "flush"
|
94 |
+
}
|
95 |
+
],
|
96 |
+
"extension": "interrupt_detector"
|
97 |
+
}
|
98 |
+
],
|
99 |
+
"nodes": [
|
100 |
+
{
|
101 |
+
"addon": "agora_rtc",
|
102 |
+
"extension_group": "default",
|
103 |
+
"name": "agora_rtc",
|
104 |
+
"property": {
|
105 |
+
"agora_asr_language": "en-US",
|
106 |
+
"agora_asr_session_control_file_path": "session_control.conf",
|
107 |
+
"agora_asr_vendor_key": "${env:AZURE_STT_KEY}",
|
108 |
+
"agora_asr_vendor_name": "microsoft",
|
109 |
+
"agora_asr_vendor_region": "${env:AZURE_STT_REGION}",
|
110 |
+
"app_id": "${env:AGORA_APP_ID}",
|
111 |
+
"channel": "ten_agent_test",
|
112 |
+
"enable_agora_asr": true,
|
113 |
+
"publish_audio": true,
|
114 |
+
"publish_data": true,
|
115 |
+
"remote_stream_id": 123,
|
116 |
+
"stream_id": 1234,
|
117 |
+
"subscribe_audio": true,
|
118 |
+
"token": "<agora_token>"
|
119 |
+
},
|
120 |
+
"type": "extension"
|
121 |
+
},
|
122 |
+
{
|
123 |
+
"addon": "interrupt_detector",
|
124 |
+
"extension_group": "default",
|
125 |
+
"name": "interrupt_detector",
|
126 |
+
"type": "extension"
|
127 |
+
},
|
128 |
+
{
|
129 |
+
"addon": "openai_chatgpt_python",
|
130 |
+
"extension_group": "chatgpt",
|
131 |
+
"name": "openai_chatgpt",
|
132 |
+
"property": {
|
133 |
+
"api_key": "${env:OPENAI_API_KEY}",
|
134 |
+
"base_url": "${env:OPENAI_API_BASE}",
|
135 |
+
"frequency_penalty": 0.9,
|
136 |
+
"greeting": "TEN Agent connected. How can I help you today?",
|
137 |
+
"max_memory_length": 10,
|
138 |
+
"max_tokens": 512,
|
139 |
+
"model": "${env:OPENAI_MODEL}",
|
140 |
+
"prompt": "",
|
141 |
+
"proxy_url": "${env:OPENAI_PROXY_URL}"
|
142 |
+
},
|
143 |
+
"type": "extension"
|
144 |
+
},
|
145 |
+
{
|
146 |
+
"addon": "message_collector",
|
147 |
+
"extension_group": "transcriber",
|
148 |
+
"name": "message_collector",
|
149 |
+
"type": "extension"
|
150 |
+
},
|
151 |
+
{
|
152 |
+
"addon": "fashionai",
|
153 |
+
"extension_group": "default",
|
154 |
+
"name": "fashionai",
|
155 |
+
"property": {
|
156 |
+
"app_id": "${env:AGORA_APP_ID}",
|
157 |
+
"channel": "ten_agent_test",
|
158 |
+
"stream_id": 12345,
|
159 |
+
"token": "<agora_token>",
|
160 |
+
"service_id": "agoramultimodel"
|
161 |
+
},
|
162 |
+
"type": "extension"
|
163 |
+
}
|
164 |
+
]
|
165 |
+
},
|
166 |
+
{
|
167 |
+
"name": "va_qwen_rag",
|
168 |
+
"auto_start": false,
|
169 |
+
"nodes": [
|
170 |
+
{
|
171 |
+
"type": "extension",
|
172 |
+
"extension_group": "rtc",
|
173 |
+
"addon": "agora_rtc",
|
174 |
+
"name": "agora_rtc",
|
175 |
+
"property": {
|
176 |
+
"app_id": "${env:AGORA_APP_ID}",
|
177 |
+
"token": "<agora_token>",
|
178 |
+
"channel": "ten_agent_test",
|
179 |
+
"stream_id": 1234,
|
180 |
+
"remote_stream_id": 123,
|
181 |
+
"subscribe_audio": true,
|
182 |
+
"publish_audio": true,
|
183 |
+
"publish_data": true,
|
184 |
+
"enable_agora_asr": true,
|
185 |
+
"agora_asr_vendor_name": "microsoft",
|
186 |
+
"agora_asr_language": "en-US",
|
187 |
+
"agora_asr_vendor_key": "${env:AZURE_STT_KEY}",
|
188 |
+
"agora_asr_vendor_region": "${env:AZURE_STT_REGION}",
|
189 |
+
"agora_asr_session_control_file_path": "session_control.conf"
|
190 |
+
}
|
191 |
+
},
|
192 |
+
{
|
193 |
+
"type": "extension",
|
194 |
+
"extension_group": "llm",
|
195 |
+
"addon": "qwen_llm_python",
|
196 |
+
"name": "qwen_llm",
|
197 |
+
"property": {
|
198 |
+
"api_key": "${env:QWEN_API_KEY}",
|
199 |
+
"model": "qwen-max",
|
200 |
+
"max_tokens": 512,
|
201 |
+
"prompt": "",
|
202 |
+
"max_memory_length": 10,
|
203 |
+
"greeting": "TEN Agent connected. How can I help you today?"
|
204 |
+
}
|
205 |
+
},
|
206 |
+
{
|
207 |
+
"type": "extension",
|
208 |
+
"extension_group": "tts",
|
209 |
+
"addon": "cosy_tts_python",
|
210 |
+
"name": "cosy_tts",
|
211 |
+
"property": {
|
212 |
+
"api_key": "${env:QWEN_API_KEY}",
|
213 |
+
"model": "cosyvoice-v1",
|
214 |
+
"voice": "longxiaochun",
|
215 |
+
"sample_rate": 16000
|
216 |
+
}
|
217 |
+
},
|
218 |
+
{
|
219 |
+
"type": "extension",
|
220 |
+
"extension_group": "tts",
|
221 |
+
"addon": "azure_tts",
|
222 |
+
"name": "azure_tts",
|
223 |
+
"property": {
|
224 |
+
"azure_subscription_key": "${env:AZURE_TTS_KEY}",
|
225 |
+
"azure_subscription_region": "${env:AZURE_TTS_REGION}",
|
226 |
+
"azure_synthesis_voice_name": "en-US-AndrewMultilingualNeural"
|
227 |
+
}
|
228 |
+
},
|
229 |
+
{
|
230 |
+
"type": "extension",
|
231 |
+
"extension_group": "chat_transcriber",
|
232 |
+
"addon": "message_collector",
|
233 |
+
"name": "message_collector"
|
234 |
+
},
|
235 |
+
{
|
236 |
+
"type": "extension",
|
237 |
+
"extension_group": "interrupt_detector",
|
238 |
+
"addon": "interrupt_detector_python",
|
239 |
+
"name": "interrupt_detector"
|
240 |
+
},
|
241 |
+
{
|
242 |
+
"type": "extension",
|
243 |
+
"extension_group": "http_server",
|
244 |
+
"addon": "http_server_python",
|
245 |
+
"name": "http_server",
|
246 |
+
"property": {
|
247 |
+
"listen_addr": "127.0.0.1",
|
248 |
+
"listen_port": 8080
|
249 |
+
}
|
250 |
+
},
|
251 |
+
{
|
252 |
+
"type": "extension",
|
253 |
+
"extension_group": "embedding",
|
254 |
+
"addon": "aliyun_text_embedding",
|
255 |
+
"name": "aliyun_text_embedding",
|
256 |
+
"property": {
|
257 |
+
"api_key": "${env:ALIYUN_TEXT_EMBEDDING_API_KEY}",
|
258 |
+
"model": "text-embedding-v3"
|
259 |
+
}
|
260 |
+
},
|
261 |
+
{
|
262 |
+
"type": "extension",
|
263 |
+
"extension_group": "vector_storage",
|
264 |
+
"addon": "aliyun_analyticdb_vector_storage",
|
265 |
+
"name": "aliyun_analyticdb_vector_storage",
|
266 |
+
"property": {
|
267 |
+
"alibaba_cloud_access_key_id": "${env:ALIBABA_CLOUD_ACCESS_KEY_ID}",
|
268 |
+
"alibaba_cloud_access_key_secret": "${env:ALIBABA_CLOUD_ACCESS_KEY_SECRET}",
|
269 |
+
"adbpg_instance_id": "${env:ALIYUN_ANALYTICDB_INSTANCE_ID}",
|
270 |
+
"adbpg_instance_region": "${env:ALIYUN_ANALYTICDB_INSTANCE_REGION}",
|
271 |
+
"adbpg_account": "${env:ALIYUN_ANALYTICDB_ACCOUNT}",
|
272 |
+
"adbpg_account_password": "${env:ALIYUN_ANALYTICDB_ACCOUNT_PASSWORD}",
|
273 |
+
"adbpg_namespace": "${env:ALIYUN_ANALYTICDB_NAMESPACE}",
|
274 |
+
"adbpg_namespace_password": "${env:ALIYUN_ANALYTICDB_NAMESPACE_PASSWORD}"
|
275 |
+
}
|
276 |
+
},
|
277 |
+
{
|
278 |
+
"type": "extension",
|
279 |
+
"extension_group": "file_chunker",
|
280 |
+
"addon": "file_chunker",
|
281 |
+
"name": "file_chunker",
|
282 |
+
"property": {}
|
283 |
+
},
|
284 |
+
{
|
285 |
+
"type": "extension",
|
286 |
+
"extension_group": "llama_index",
|
287 |
+
"addon": "llama_index_chat_engine",
|
288 |
+
"name": "llama_index",
|
289 |
+
"property": {
|
290 |
+
"greeting": "TEN Agent connected. How can I help you today?",
|
291 |
+
"chat_memory_token_limit": 3000
|
292 |
+
}
|
293 |
+
}
|
294 |
+
],
|
295 |
+
"connections": [
|
296 |
+
{
|
297 |
+
"extension": "agora_rtc",
|
298 |
+
"data": [
|
299 |
+
{
|
300 |
+
"name": "text_data",
|
301 |
+
"dest": [
|
302 |
+
{
|
303 |
+
"extension": "interrupt_detector"
|
304 |
+
},
|
305 |
+
{
|
306 |
+
"extension": "message_collector"
|
307 |
+
}
|
308 |
+
]
|
309 |
+
}
|
310 |
+
]
|
311 |
+
},
|
312 |
+
{
|
313 |
+
"extension": "interrupt_detector",
|
314 |
+
"cmd": [
|
315 |
+
{
|
316 |
+
"name": "flush",
|
317 |
+
"dest": [
|
318 |
+
{
|
319 |
+
"extension": "llama_index"
|
320 |
+
}
|
321 |
+
]
|
322 |
+
},
|
323 |
+
{
|
324 |
+
"name": "file_chunk",
|
325 |
+
"dest": [
|
326 |
+
{
|
327 |
+
"extension": "file_chunker"
|
328 |
+
},
|
329 |
+
{
|
330 |
+
"extension": "llama_index"
|
331 |
+
}
|
332 |
+
]
|
333 |
+
},
|
334 |
+
{
|
335 |
+
"name": "file_chunked",
|
336 |
+
"dest": [
|
337 |
+
{
|
338 |
+
"extension": "llama_index"
|
339 |
+
}
|
340 |
+
]
|
341 |
+
},
|
342 |
+
{
|
343 |
+
"name": "update_querying_collection",
|
344 |
+
"dest": [
|
345 |
+
{
|
346 |
+
"extension": "llama_index"
|
347 |
+
}
|
348 |
+
]
|
349 |
+
}
|
350 |
+
],
|
351 |
+
"data": [
|
352 |
+
{
|
353 |
+
"name": "text_data",
|
354 |
+
"dest": [
|
355 |
+
{
|
356 |
+
"extension": "llama_index"
|
357 |
+
}
|
358 |
+
]
|
359 |
+
}
|
360 |
+
]
|
361 |
+
},
|
362 |
+
{
|
363 |
+
"extension": "llama_index",
|
364 |
+
"data": [
|
365 |
+
{
|
366 |
+
"name": "text_data",
|
367 |
+
"dest": [
|
368 |
+
{
|
369 |
+
"extension": "azure_tts"
|
370 |
+
},
|
371 |
+
{
|
372 |
+
"extension": "message_collector"
|
373 |
+
}
|
374 |
+
]
|
375 |
+
}
|
376 |
+
],
|
377 |
+
"cmd": [
|
378 |
+
{
|
379 |
+
"name": "flush",
|
380 |
+
"dest": [
|
381 |
+
{
|
382 |
+
"extension": "qwen_llm"
|
383 |
+
},
|
384 |
+
{
|
385 |
+
"extension": "azure_tts"
|
386 |
+
}
|
387 |
+
]
|
388 |
+
},
|
389 |
+
{
|
390 |
+
"name": "call_chat",
|
391 |
+
"dest": [
|
392 |
+
{
|
393 |
+
"extension": "qwen_llm"
|
394 |
+
}
|
395 |
+
]
|
396 |
+
},
|
397 |
+
{
|
398 |
+
"name": "embed",
|
399 |
+
"dest": [
|
400 |
+
{
|
401 |
+
"extension": "aliyun_text_embedding"
|
402 |
+
}
|
403 |
+
]
|
404 |
+
},
|
405 |
+
{
|
406 |
+
"name": "query_vector",
|
407 |
+
"dest": [
|
408 |
+
{
|
409 |
+
"extension": "aliyun_analyticdb_vector_storage"
|
410 |
+
}
|
411 |
+
]
|
412 |
+
}
|
413 |
+
]
|
414 |
+
},
|
415 |
+
{
|
416 |
+
"extension": "azure_tts",
|
417 |
+
"audio_frame": [
|
418 |
+
{
|
419 |
+
"name": "pcm_frame",
|
420 |
+
"dest": [
|
421 |
+
{
|
422 |
+
"extension": "agora_rtc"
|
423 |
+
}
|
424 |
+
]
|
425 |
+
}
|
426 |
+
],
|
427 |
+
"cmd": [
|
428 |
+
{
|
429 |
+
"name": "flush",
|
430 |
+
"dest": [
|
431 |
+
{
|
432 |
+
"extension": "agora_rtc"
|
433 |
+
}
|
434 |
+
]
|
435 |
+
}
|
436 |
+
]
|
437 |
+
},
|
438 |
+
{
|
439 |
+
"extension": "message_collector",
|
440 |
+
"data": [
|
441 |
+
{
|
442 |
+
"name": "data",
|
443 |
+
"dest": [
|
444 |
+
{
|
445 |
+
"extension": "agora_rtc"
|
446 |
+
}
|
447 |
+
]
|
448 |
+
}
|
449 |
+
]
|
450 |
+
},
|
451 |
+
{
|
452 |
+
"extension": "http_server",
|
453 |
+
"cmd": [
|
454 |
+
{
|
455 |
+
"name": "file_chunk",
|
456 |
+
"dest": [
|
457 |
+
{
|
458 |
+
"extension": "interrupt_detector"
|
459 |
+
}
|
460 |
+
]
|
461 |
+
},
|
462 |
+
{
|
463 |
+
"name": "update_querying_collection",
|
464 |
+
"dest": [
|
465 |
+
{
|
466 |
+
"extension": "interrupt_detector"
|
467 |
+
}
|
468 |
+
]
|
469 |
+
}
|
470 |
+
]
|
471 |
+
},
|
472 |
+
{
|
473 |
+
"extension": "file_chunker",
|
474 |
+
"cmd": [
|
475 |
+
{
|
476 |
+
"name": "embed_batch",
|
477 |
+
"dest": [
|
478 |
+
{
|
479 |
+
"extension": "aliyun_text_embedding"
|
480 |
+
}
|
481 |
+
]
|
482 |
+
},
|
483 |
+
{
|
484 |
+
"name": "create_collection",
|
485 |
+
"dest": [
|
486 |
+
{
|
487 |
+
"extension": "aliyun_analyticdb_vector_storage"
|
488 |
+
}
|
489 |
+
]
|
490 |
+
},
|
491 |
+
{
|
492 |
+
"name": "upsert_vector",
|
493 |
+
"dest": [
|
494 |
+
{
|
495 |
+
"extension": "aliyun_analyticdb_vector_storage"
|
496 |
+
}
|
497 |
+
]
|
498 |
+
},
|
499 |
+
{
|
500 |
+
"name": "file_chunked",
|
501 |
+
"dest": [
|
502 |
+
{
|
503 |
+
"extension": "llama_index"
|
504 |
+
}
|
505 |
+
]
|
506 |
+
}
|
507 |
+
]
|
508 |
+
}
|
509 |
+
]
|
510 |
+
},
|
511 |
+
{
|
512 |
+
"name": "va_openai_v2v_storage",
|
513 |
+
"auto_start": false,
|
514 |
+
"nodes": [
|
515 |
+
{
|
516 |
+
"type": "extension",
|
517 |
+
"extension_group": "rtc",
|
518 |
+
"addon": "agora_rtc",
|
519 |
+
"name": "agora_rtc",
|
520 |
+
"property": {
|
521 |
+
"app_id": "${env:AGORA_APP_ID}",
|
522 |
+
"token": "",
|
523 |
+
"channel": "ten_agent_test",
|
524 |
+
"stream_id": 1234,
|
525 |
+
"remote_stream_id": 123,
|
526 |
+
"subscribe_audio": true,
|
527 |
+
"publish_audio": true,
|
528 |
+
"publish_data": true,
|
529 |
+
"subscribe_audio_sample_rate": 24000
|
530 |
+
}
|
531 |
+
},
|
532 |
+
{
|
533 |
+
"type": "extension",
|
534 |
+
"extension_group": "llm",
|
535 |
+
"addon": "openai_v2v_python",
|
536 |
+
"name": "openai_v2v_python",
|
537 |
+
"property": {
|
538 |
+
"api_key": "${env:OPENAI_REALTIME_API_KEY}",
|
539 |
+
"temperature": 0.9,
|
540 |
+
"model": "gpt-4o-realtime-preview-2024-12-17",
|
541 |
+
"max_tokens": 2048,
|
542 |
+
"voice": "alloy",
|
543 |
+
"language": "en-US",
|
544 |
+
"server_vad": true,
|
545 |
+
"dump": true,
|
546 |
+
"max_history": 10,
|
547 |
+
"enable_storage": true
|
548 |
+
}
|
549 |
+
},
|
550 |
+
{
|
551 |
+
"type": "extension",
|
552 |
+
"extension_group": "transcriber",
|
553 |
+
"addon": "message_collector",
|
554 |
+
"name": "message_collector"
|
555 |
+
},
|
556 |
+
{
|
557 |
+
"type": "extension",
|
558 |
+
"extension_group": "tools",
|
559 |
+
"addon": "weatherapi_tool_python",
|
560 |
+
"name": "weatherapi_tool_python",
|
561 |
+
"property": {
|
562 |
+
"api_key": "${env:WEATHERAPI_API_KEY}"
|
563 |
+
}
|
564 |
+
},
|
565 |
+
{
|
566 |
+
"type": "extension",
|
567 |
+
"extension_group": "tools",
|
568 |
+
"addon": "bingsearch_tool_python",
|
569 |
+
"name": "bingsearch_tool_python",
|
570 |
+
"property": {
|
571 |
+
"api_key": "${env:BING_API_KEY}"
|
572 |
+
}
|
573 |
+
},
|
574 |
+
{
|
575 |
+
"type": "extension",
|
576 |
+
"extension_group": "context",
|
577 |
+
"addon": "tsdb_firestore",
|
578 |
+
"name": "tsdb_firestore",
|
579 |
+
"property": {
|
580 |
+
"credentials": {
|
581 |
+
"type": "service_account",
|
582 |
+
"project_id": "${env:FIRESTORE_PROJECT_ID}",
|
583 |
+
"private_key_id": "${env:FIRESTORE_PRIVATE_KEY_ID}",
|
584 |
+
"private_key": "${env:FIRESTORE_PRIVATE_KEY}",
|
585 |
+
"client_email": "${env:FIRESTORE_CLIENT_EMAIL}",
|
586 |
+
"client_id": "${env:FIRESTORE_CLIENT_ID}",
|
587 |
+
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
|
588 |
+
"token_uri": "https://oauth2.googleapis.com/token",
|
589 |
+
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
|
590 |
+
"client_x509_cert_url": "${env:FIRESTORE_CERT_URL}",
|
591 |
+
"universe_domain": "googleapis.com"
|
592 |
+
},
|
593 |
+
"channel_name": "ten_agent_test",
|
594 |
+
"collection_name": "llm_context"
|
595 |
+
}
|
596 |
+
}
|
597 |
+
],
|
598 |
+
"connections": [
|
599 |
+
{
|
600 |
+
"extension": "agora_rtc",
|
601 |
+
"audio_frame": [
|
602 |
+
{
|
603 |
+
"name": "pcm_frame",
|
604 |
+
"dest": [
|
605 |
+
{
|
606 |
+
"extension": "openai_v2v_python"
|
607 |
+
}
|
608 |
+
]
|
609 |
+
}
|
610 |
+
]
|
611 |
+
},
|
612 |
+
{
|
613 |
+
"extension": "weatherapi_tool_python",
|
614 |
+
"cmd": [
|
615 |
+
{
|
616 |
+
"name": "tool_register",
|
617 |
+
"dest": [
|
618 |
+
{
|
619 |
+
"extension": "openai_v2v_python"
|
620 |
+
}
|
621 |
+
]
|
622 |
+
}
|
623 |
+
]
|
624 |
+
},
|
625 |
+
{
|
626 |
+
"extension": "bingsearch_tool_python",
|
627 |
+
"cmd": [
|
628 |
+
{
|
629 |
+
"name": "tool_register",
|
630 |
+
"dest": [
|
631 |
+
{
|
632 |
+
"extension": "openai_v2v_python"
|
633 |
+
}
|
634 |
+
]
|
635 |
+
}
|
636 |
+
]
|
637 |
+
},
|
638 |
+
{
|
639 |
+
"extension": "openai_v2v_python",
|
640 |
+
"audio_frame": [
|
641 |
+
{
|
642 |
+
"name": "pcm_frame",
|
643 |
+
"dest": [
|
644 |
+
{
|
645 |
+
"extension": "agora_rtc"
|
646 |
+
}
|
647 |
+
]
|
648 |
+
}
|
649 |
+
],
|
650 |
+
"data": [
|
651 |
+
{
|
652 |
+
"name": "append",
|
653 |
+
"dest": [
|
654 |
+
{
|
655 |
+
"extension": "tsdb_firestore"
|
656 |
+
}
|
657 |
+
]
|
658 |
+
},
|
659 |
+
{
|
660 |
+
"name": "text_data",
|
661 |
+
"dest": [
|
662 |
+
{
|
663 |
+
"extension": "message_collector"
|
664 |
+
}
|
665 |
+
]
|
666 |
+
}
|
667 |
+
],
|
668 |
+
"cmd": [
|
669 |
+
{
|
670 |
+
"name": "flush",
|
671 |
+
"dest": [
|
672 |
+
{
|
673 |
+
"extension": "agora_rtc"
|
674 |
+
}
|
675 |
+
]
|
676 |
+
},
|
677 |
+
{
|
678 |
+
"name": "retrieve",
|
679 |
+
"dest": [
|
680 |
+
{
|
681 |
+
"extension": "tsdb_firestore"
|
682 |
+
}
|
683 |
+
]
|
684 |
+
},
|
685 |
+
{
|
686 |
+
"name": "tool_call",
|
687 |
+
"dest": [
|
688 |
+
{
|
689 |
+
"extension": "weatherapi_tool_python"
|
690 |
+
}
|
691 |
+
]
|
692 |
+
},
|
693 |
+
{
|
694 |
+
"name": "tool_call",
|
695 |
+
"dest": [
|
696 |
+
{
|
697 |
+
"extension": "weatherapi_tool_python"
|
698 |
+
}
|
699 |
+
]
|
700 |
+
}
|
701 |
+
]
|
702 |
+
},
|
703 |
+
{
|
704 |
+
"extension": "message_collector",
|
705 |
+
"data": [
|
706 |
+
{
|
707 |
+
"name": "data",
|
708 |
+
"dest": [
|
709 |
+
{
|
710 |
+
"extension": "agora_rtc"
|
711 |
+
}
|
712 |
+
]
|
713 |
+
}
|
714 |
+
]
|
715 |
+
}
|
716 |
+
]
|
717 |
+
},
|
718 |
+
{
|
719 |
+
"name": "va_minimax_v2v",
|
720 |
+
"auto_start": false,
|
721 |
+
"nodes": [
|
722 |
+
{
|
723 |
+
"type": "extension",
|
724 |
+
"extension_group": "rtc",
|
725 |
+
"addon": "agora_rtc",
|
726 |
+
"name": "agora_rtc",
|
727 |
+
"property": {
|
728 |
+
"app_id": "${env:AGORA_APP_ID}",
|
729 |
+
"token": "",
|
730 |
+
"channel": "ten_agent_test",
|
731 |
+
"stream_id": 1234,
|
732 |
+
"remote_stream_id": 123,
|
733 |
+
"subscribe_audio": true,
|
734 |
+
"publish_audio": true,
|
735 |
+
"publish_data": true
|
736 |
+
}
|
737 |
+
},
|
738 |
+
{
|
739 |
+
"type": "extension",
|
740 |
+
"extension_group": "agora_sess_ctrl",
|
741 |
+
"addon": "agora_sess_ctrl",
|
742 |
+
"name": "agora_sess_ctrl",
|
743 |
+
"property": {
|
744 |
+
"wait_for_eos": true
|
745 |
+
}
|
746 |
+
},
|
747 |
+
{
|
748 |
+
"type": "extension",
|
749 |
+
"extension_group": "llm",
|
750 |
+
"addon": "minimax_v2v_python",
|
751 |
+
"name": "minimax_v2v_python",
|
752 |
+
"property": {
|
753 |
+
"in_sample_rate": 16000,
|
754 |
+
"token": "${env:MINIMAX_TOKEN}"
|
755 |
+
}
|
756 |
+
},
|
757 |
+
{
|
758 |
+
"type": "extension",
|
759 |
+
"extension_group": "message_collector",
|
760 |
+
"addon": "message_collector",
|
761 |
+
"name": "message_collector"
|
762 |
+
}
|
763 |
+
],
|
764 |
+
"connections": [
|
765 |
+
{
|
766 |
+
"extension": "agora_rtc",
|
767 |
+
"audio_frame": [
|
768 |
+
{
|
769 |
+
"name": "pcm_frame",
|
770 |
+
"dest": [
|
771 |
+
{
|
772 |
+
"extension": "agora_sess_ctrl"
|
773 |
+
}
|
774 |
+
]
|
775 |
+
}
|
776 |
+
]
|
777 |
+
},
|
778 |
+
{
|
779 |
+
"extension": "agora_sess_ctrl",
|
780 |
+
"audio_frame": [
|
781 |
+
{
|
782 |
+
"name": "pcm_frame",
|
783 |
+
"dest": [
|
784 |
+
{
|
785 |
+
"extension": "minimax_v2v_python"
|
786 |
+
}
|
787 |
+
]
|
788 |
+
}
|
789 |
+
],
|
790 |
+
"cmd": [
|
791 |
+
{
|
792 |
+
"name": "start_of_sentence",
|
793 |
+
"dest": [
|
794 |
+
{
|
795 |
+
"extension": "minimax_v2v_python",
|
796 |
+
"msg_conversion": {
|
797 |
+
"type": "per_property",
|
798 |
+
"keep_original": true,
|
799 |
+
"rules": [
|
800 |
+
{
|
801 |
+
"path": "_ten.name",
|
802 |
+
"conversion_mode": "fixed_value",
|
803 |
+
"value": "flush"
|
804 |
+
}
|
805 |
+
]
|
806 |
+
}
|
807 |
+
}
|
808 |
+
]
|
809 |
+
}
|
810 |
+
]
|
811 |
+
},
|
812 |
+
{
|
813 |
+
"extension": "minimax_v2v_python",
|
814 |
+
"data": [
|
815 |
+
{
|
816 |
+
"name": "text_data",
|
817 |
+
"dest": [
|
818 |
+
{
|
819 |
+
"extension": "message_collector"
|
820 |
+
}
|
821 |
+
]
|
822 |
+
}
|
823 |
+
],
|
824 |
+
"audio_frame": [
|
825 |
+
{
|
826 |
+
"name": "pcm_frame",
|
827 |
+
"dest": [
|
828 |
+
{
|
829 |
+
"extension": "agora_rtc"
|
830 |
+
}
|
831 |
+
]
|
832 |
+
}
|
833 |
+
],
|
834 |
+
"cmd": [
|
835 |
+
{
|
836 |
+
"name": "flush",
|
837 |
+
"dest": [
|
838 |
+
{
|
839 |
+
"extension": "agora_rtc"
|
840 |
+
}
|
841 |
+
]
|
842 |
+
}
|
843 |
+
]
|
844 |
+
},
|
845 |
+
{
|
846 |
+
"extension": "message_collector",
|
847 |
+
"data": [
|
848 |
+
{
|
849 |
+
"name": "data",
|
850 |
+
"dest": [
|
851 |
+
{
|
852 |
+
"extension": "agora_rtc"
|
853 |
+
}
|
854 |
+
]
|
855 |
+
}
|
856 |
+
]
|
857 |
+
}
|
858 |
+
]
|
859 |
+
}
|
860 |
+
]
|
861 |
+
}
|
862 |
+
}
|
agents/go.mod
ADDED
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
module app
|
2 |
+
|
3 |
+
go 1.20
|
4 |
+
|
5 |
+
replace ten_framework => ./ten_packages/system/ten_runtime_go/interface
|
6 |
+
|
7 |
+
require ten_framework v0.0.0-00010101000000-000000000000
|
agents/go.sum
ADDED
File without changes
|
agents/main.go
ADDED
@@ -0,0 +1,71 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/**
|
2 |
+
*
|
3 |
+
* Agora Real Time Engagement
|
4 |
+
* Created by Wei Hu in 2022-10.
|
5 |
+
* Copyright (c) 2024 Agora IO. All rights reserved.
|
6 |
+
*
|
7 |
+
*/
|
8 |
+
package main
|
9 |
+
|
10 |
+
import (
|
11 |
+
"flag"
|
12 |
+
"log"
|
13 |
+
"os"
|
14 |
+
|
15 |
+
"ten_framework/ten"
|
16 |
+
)
|
17 |
+
|
18 |
+
type appConfig struct {
|
19 |
+
PropertyFilePath string
|
20 |
+
}
|
21 |
+
|
22 |
+
type defaultApp struct {
|
23 |
+
ten.DefaultApp
|
24 |
+
|
25 |
+
cfg *appConfig
|
26 |
+
}
|
27 |
+
|
28 |
+
func (p *defaultApp) OnConfigure(
|
29 |
+
tenEnv ten.TenEnv,
|
30 |
+
) {
|
31 |
+
// Using the default property.json if not specified.
|
32 |
+
if len(p.cfg.PropertyFilePath) > 0 {
|
33 |
+
if b, err := os.ReadFile(p.cfg.PropertyFilePath); err != nil {
|
34 |
+
log.Fatalf("Failed to read property file %s, err %v\n", p.cfg.PropertyFilePath, err)
|
35 |
+
} else {
|
36 |
+
tenEnv.InitPropertyFromJSONBytes(b)
|
37 |
+
}
|
38 |
+
}
|
39 |
+
|
40 |
+
tenEnv.OnConfigureDone()
|
41 |
+
}
|
42 |
+
|
43 |
+
func startAppBlocking(cfg *appConfig) {
|
44 |
+
appInstance, err := ten.NewApp(&defaultApp{
|
45 |
+
cfg: cfg,
|
46 |
+
})
|
47 |
+
if err != nil {
|
48 |
+
log.Fatalf("Failed to create the app, %v\n", err)
|
49 |
+
}
|
50 |
+
|
51 |
+
appInstance.Run(true)
|
52 |
+
appInstance.Wait()
|
53 |
+
|
54 |
+
ten.EnsureCleanupWhenProcessExit()
|
55 |
+
}
|
56 |
+
|
57 |
+
func setDefaultLog() {
|
58 |
+
log.SetFlags(log.LstdFlags | log.Lmicroseconds)
|
59 |
+
}
|
60 |
+
|
61 |
+
func main() {
|
62 |
+
// Set the default log format globally, users can use `log.Println()` directly.
|
63 |
+
setDefaultLog()
|
64 |
+
|
65 |
+
cfg := &appConfig{}
|
66 |
+
|
67 |
+
flag.StringVar(&cfg.PropertyFilePath, "property", "", "The absolute path of property.json")
|
68 |
+
flag.Parse()
|
69 |
+
|
70 |
+
startAppBlocking(cfg)
|
71 |
+
}
|
agents/scripts/.gitignore
ADDED
@@ -0,0 +1,4 @@
|
|
|
|
|
|
|
|
|
|
|
1 |
+
graph
|
2 |
+
graph.pdf
|
3 |
+
graph.png
|
4 |
+
|
agents/scripts/BUILD.gn
ADDED
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#
|
2 |
+
#
|
3 |
+
# Agora Real Time Engagement
|
4 |
+
# Created by Wei Hu in 2022-11.
|
5 |
+
# Copyright (c) 2024 Agora IO. All rights reserved.
|
6 |
+
#
|
7 |
+
#
|
8 |
+
import("//build/feature/ten_package.gni")
|
9 |
+
|
10 |
+
ten_package("default_app_go") {
|
11 |
+
package_kind = "app"
|
12 |
+
enable_build = false
|
13 |
+
|
14 |
+
resources = [
|
15 |
+
"manifest.json",
|
16 |
+
"property.json",
|
17 |
+
]
|
18 |
+
}
|
agents/scripts/dot.py
ADDED
@@ -0,0 +1,117 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Generate a graph from a JSON file
|
2 |
+
# Currently it only generate the first graph but it's easy to make it generate all graphs
|
3 |
+
# Author: Seven Du <[email protected]>
|
4 |
+
# usage:
|
5 |
+
# pip install graphviz
|
6 |
+
# python dot.py
|
7 |
+
|
8 |
+
import json
|
9 |
+
import graphviz
|
10 |
+
|
11 |
+
COLORS = {
|
12 |
+
"flush": "#999",
|
13 |
+
"cmd": "#0f0",
|
14 |
+
"data": "#00f",
|
15 |
+
"text_data": "#f00",
|
16 |
+
"pcm_frame": "purple",
|
17 |
+
}
|
18 |
+
|
19 |
+
connection_types = ["data", "cmd", "audio_frame", "video_frame"]
|
20 |
+
|
21 |
+
|
22 |
+
def color(port):
|
23 |
+
if port in COLORS:
|
24 |
+
return COLORS[port]
|
25 |
+
return "#000"
|
26 |
+
|
27 |
+
|
28 |
+
def find_node(nodes, name):
|
29 |
+
for node in nodes:
|
30 |
+
if node["name"] == name:
|
31 |
+
return node
|
32 |
+
return None
|
33 |
+
|
34 |
+
|
35 |
+
def create_graph(json_data):
|
36 |
+
# Initialize a directed graph
|
37 |
+
graph = graphviz.Digraph("G", filename="graph.gv")
|
38 |
+
graph.graph_attr["rankdir"] = "LR"
|
39 |
+
graph.graph_attr["dpi"] = "150"
|
40 |
+
graph.graph_attr["splines"] = "true"
|
41 |
+
graph.attr("node", shape="none")
|
42 |
+
|
43 |
+
# Add nodes to the graph
|
44 |
+
nodes = json_data["_ten"]["predefined_graphs"][0]["nodes"]
|
45 |
+
connections = json_data["_ten"]["predefined_graphs"][0]["connections"]
|
46 |
+
for node in nodes:
|
47 |
+
node["i_ports"] = ["flush"]
|
48 |
+
node["o_ports"] = ["flush"]
|
49 |
+
for node in nodes:
|
50 |
+
if node["type"] != "extension":
|
51 |
+
continue
|
52 |
+
for connection in connections:
|
53 |
+
if connection["extension"] == node["name"]:
|
54 |
+
for connection_type in connection_types:
|
55 |
+
if connection_type in connection:
|
56 |
+
data = connection[connection_type]
|
57 |
+
for item in data:
|
58 |
+
node["o_ports"].append(item["name"])
|
59 |
+
for dest in item["dest"]:
|
60 |
+
dest_node = find_node(nodes, dest["extension"])
|
61 |
+
if dest_node:
|
62 |
+
dest_node["i_ports"].append(item["name"])
|
63 |
+
for node in nodes:
|
64 |
+
if node["type"] != "extension":
|
65 |
+
continue
|
66 |
+
node["i_ports"] = set(node["i_ports"])
|
67 |
+
node["o_ports"] = set(node["o_ports"])
|
68 |
+
print("====iports: ", node["name"], node["i_ports"])
|
69 |
+
print("====oports: ", node["name"], node["o_ports"])
|
70 |
+
iports = ""
|
71 |
+
for port in node["i_ports"]:
|
72 |
+
iports += f'<tr><td align="left" port="i_{port}">⊙ {port}</td></tr>'
|
73 |
+
oports = ""
|
74 |
+
for port in node["o_ports"]:
|
75 |
+
oports += f'<tr><td align="right" port="o_{port}">{port} ⊙</td></tr>'
|
76 |
+
|
77 |
+
# Use HTML-like label for nodes
|
78 |
+
label = f"""<
|
79 |
+
<table border="0" cellborder="1" cellspacing="0">
|
80 |
+
<tr><td colspan="2" bgcolor="#ddd"><b>{node["name"]}</b></td></tr>
|
81 |
+
<tr><td colspan="2">properties</td></tr>
|
82 |
+
<tr><td colspan="2">extensionGroup<br/>{node["extension_group"]}</td></tr>
|
83 |
+
<tr><td>
|
84 |
+
<table border="0" cellspacing="0">{iports}</table>
|
85 |
+
</td>
|
86 |
+
<td>
|
87 |
+
<table border="0" cellspacing="0">{oports}</table>
|
88 |
+
</td>
|
89 |
+
</tr>
|
90 |
+
</table>>"""
|
91 |
+
graph.node(node["name"], label)
|
92 |
+
|
93 |
+
# Add edges to the graph
|
94 |
+
for connection in connections:
|
95 |
+
for connection_type in connection_types:
|
96 |
+
if connection_type in connection:
|
97 |
+
for data in connection[connection_type]:
|
98 |
+
for dest in data["dest"]:
|
99 |
+
graph.edge(
|
100 |
+
f'{connection["extension"]}:o_{data["name"]}',
|
101 |
+
f'{dest["extension"]}:i_{data["name"]}',
|
102 |
+
color=color(data["name"]),
|
103 |
+
label=connection_type,
|
104 |
+
)
|
105 |
+
|
106 |
+
# Save the graph to a file
|
107 |
+
print(graph.source)
|
108 |
+
graph.render("graph", format="png")
|
109 |
+
graph.view()
|
110 |
+
|
111 |
+
|
112 |
+
# Load the JSON data
|
113 |
+
with open("../property.json") as f:
|
114 |
+
data = json.load(f)
|
115 |
+
|
116 |
+
# Create the graph
|
117 |
+
create_graph(data)
|
agents/scripts/install_deps_and_build.sh
ADDED
@@ -0,0 +1,145 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#!/usr/bin/env bash
|
2 |
+
|
3 |
+
# mac, linux
|
4 |
+
OS="linux"
|
5 |
+
|
6 |
+
# x64, arm64
|
7 |
+
CPU="x64"
|
8 |
+
|
9 |
+
# debug, release
|
10 |
+
BUILD_TYPE="release"
|
11 |
+
|
12 |
+
PIP_INSTALL_CMD=${PIP_INSTALL_CMD:-"uv pip install --system"}
|
13 |
+
|
14 |
+
build_cxx_extensions() {
|
15 |
+
local app_dir=$1
|
16 |
+
|
17 |
+
if [[ ! -f $app_dir/scripts/BUILD.gn ]]; then
|
18 |
+
echo "FATAL: the scripts/BUILD.gn is required to build cxx extensions."
|
19 |
+
exit 1
|
20 |
+
fi
|
21 |
+
|
22 |
+
cp $app_dir/scripts/BUILD.gn $app_dir
|
23 |
+
|
24 |
+
tgn gen $OS $CPU $BUILD_TYPE -- is_clang=false enable_sanitizer=false
|
25 |
+
tgn build $OS $CPU $BUILD_TYPE
|
26 |
+
|
27 |
+
local ret=$?
|
28 |
+
|
29 |
+
cd $app_dir
|
30 |
+
|
31 |
+
if [[ $ret -ne 0 ]]; then
|
32 |
+
echo "FATAL: failed to build cxx extensions, see logs for detail."
|
33 |
+
exit 1
|
34 |
+
fi
|
35 |
+
|
36 |
+
# Copy the output of ten_packages to the ten_packages/extension/xx/lib.
|
37 |
+
local out="out/$OS/$CPU"
|
38 |
+
for extension in $out/ten_packages/extension/*; do
|
39 |
+
local extension_name=$(basename $extension)
|
40 |
+
if [[ $extension_name == "*" ]]; then
|
41 |
+
echo "No cxx extension, nothing to copy."
|
42 |
+
break
|
43 |
+
fi
|
44 |
+
if [[ ! -d $extension/lib ]]; then
|
45 |
+
echo "No output for extension $extension_name."
|
46 |
+
continue
|
47 |
+
fi
|
48 |
+
|
49 |
+
mkdir -p $app_dir/ten_packages/extension/$extension_name/lib
|
50 |
+
cp -r $extension/lib/* $app_dir/ten_packages/extension/$extension_name/lib
|
51 |
+
done
|
52 |
+
}
|
53 |
+
|
54 |
+
install_python_requirements() {
|
55 |
+
local app_dir=$1
|
56 |
+
|
57 |
+
if [[ -f "requirements.txt" ]]; then
|
58 |
+
${PIP_INSTALL_CMD} install -r requirements.txt
|
59 |
+
fi
|
60 |
+
|
61 |
+
# traverse the ten_packages/extension directory to find the requirements.txt
|
62 |
+
if [[ -d "ten_packages/extension" ]]; then
|
63 |
+
for extension in ten_packages/extension/*; do
|
64 |
+
if [[ -f "$extension/requirements.txt" ]]; then
|
65 |
+
${PIP_INSTALL_CMD} -r $extension/requirements.txt
|
66 |
+
fi
|
67 |
+
done
|
68 |
+
fi
|
69 |
+
|
70 |
+
# traverse the ten_packages/system directory to find the requirements.txt
|
71 |
+
if [[ -d "ten_packages/system" ]]; then
|
72 |
+
for extension in ten_packages/system/*; do
|
73 |
+
if [[ -f "$extension/requirements.txt" ]]; then
|
74 |
+
${PIP_INSTALL_CMD} -r $extension/requirements.txt
|
75 |
+
fi
|
76 |
+
done
|
77 |
+
fi
|
78 |
+
|
79 |
+
# pre-import llama-index as it cloud download additional resources during the first import
|
80 |
+
echo "pre-import python modules..."
|
81 |
+
python3.10 -c "import llama_index.core;"
|
82 |
+
}
|
83 |
+
|
84 |
+
build_go_app() {
|
85 |
+
local app_dir=$1
|
86 |
+
cd $app_dir
|
87 |
+
|
88 |
+
go run ten_packages/system/ten_runtime_go/tools/build/main.go --verbose
|
89 |
+
if [[ $? -ne 0 ]]; then
|
90 |
+
echo "FATAL: failed to build go app, see logs for detail."
|
91 |
+
exit 1
|
92 |
+
fi
|
93 |
+
}
|
94 |
+
|
95 |
+
clean() {
|
96 |
+
local app_dir=$1
|
97 |
+
rm -rf BUILD.gn out
|
98 |
+
}
|
99 |
+
|
100 |
+
main() {
|
101 |
+
APP_HOME=$(
|
102 |
+
cd $(dirname $0)/..
|
103 |
+
pwd
|
104 |
+
)
|
105 |
+
|
106 |
+
if [[ $1 == "-clean" ]]; then
|
107 |
+
clean $APP_HOME
|
108 |
+
exit 0
|
109 |
+
fi
|
110 |
+
|
111 |
+
if [[ $# -ne 2 ]]; then
|
112 |
+
echo "Usage: $0 <os> <cpu>"
|
113 |
+
exit 1
|
114 |
+
fi
|
115 |
+
|
116 |
+
OS=$1
|
117 |
+
CPU=$2
|
118 |
+
|
119 |
+
echo -e "#include <stdio.h>\n#include <immintrin.h>\nint main() { __m256 a = _mm256_setzero_ps(); return 0; }" > /tmp/test.c
|
120 |
+
if gcc -mavx2 /tmp/test.c -o /tmp/test && ! /tmp/test; then
|
121 |
+
echo "FATAL: unsupported platform."
|
122 |
+
echo " Please UNCHECK the 'Use Rosetta for x86_64/amd64 emulation on Apple Silicon' Docker Desktop setting if you're running on mac."
|
123 |
+
|
124 |
+
exit 1
|
125 |
+
fi
|
126 |
+
|
127 |
+
if [[ ! -f $APP_HOME/manifest.json ]]; then
|
128 |
+
echo "FATAL: manifest.json is required."
|
129 |
+
exit 1
|
130 |
+
fi
|
131 |
+
|
132 |
+
# Install all dependencies specified in manifest.json.
|
133 |
+
echo "install dependencies..."
|
134 |
+
tman install
|
135 |
+
|
136 |
+
# build extensions and app
|
137 |
+
echo "build_cxx_extensions..."
|
138 |
+
build_cxx_extensions $APP_HOME
|
139 |
+
echo "build_go_app..."
|
140 |
+
build_go_app $APP_HOME
|
141 |
+
echo "install_python_requirements..."
|
142 |
+
install_python_requirements $APP_HOME
|
143 |
+
}
|
144 |
+
|
145 |
+
main "$@"
|
agents/scripts/package.sh
ADDED
@@ -0,0 +1,68 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#!/usr/bin/env bash
|
2 |
+
|
3 |
+
APP_HOME=$(
|
4 |
+
cd $(dirname $0)/..
|
5 |
+
pwd
|
6 |
+
)
|
7 |
+
|
8 |
+
cd $APP_HOME
|
9 |
+
|
10 |
+
rm -rf .release
|
11 |
+
mkdir .release
|
12 |
+
|
13 |
+
copy_package() {
|
14 |
+
local package_type=$1
|
15 |
+
local package_name=$2
|
16 |
+
mkdir -p .release/ten_packages/${package_type}/${package_name}
|
17 |
+
|
18 |
+
if [[ -d ten_packages/${package_type}/${package_name}/lib ]]; then
|
19 |
+
cp -r ten_packages/${package_type}/${package_name}/lib .release/ten_packages/${package_type}/${package_name}/
|
20 |
+
fi
|
21 |
+
|
22 |
+
if [[ -d ten_packages/${package_type}/${package_name}/interface ]]; then
|
23 |
+
cp -r ten_packages/${package_type}/${package_name}/interface .release/ten_packages/${package_type}/${package_name}/
|
24 |
+
fi
|
25 |
+
|
26 |
+
if [[ -f ten_packages/${package_type}/${package_name}/manifest.json ]]; then
|
27 |
+
cp ten_packages/${package_type}/${package_name}/manifest.json .release/ten_packages/${package_type}/${package_name}/
|
28 |
+
fi
|
29 |
+
|
30 |
+
if [[ -f ten_packages/${package_type}/${package_name}/property.json ]]; then
|
31 |
+
cp ten_packages/${package_type}/${package_name}/property.json .release/ten_packages/${package_type}/${package_name}/
|
32 |
+
fi
|
33 |
+
|
34 |
+
# package .py for python extensions
|
35 |
+
# TODO: package 'publish' contents only
|
36 |
+
cp ten_packages/${package_type}/${package_name}/*.py .release/ten_packages/${package_type}/${package_name}/ | true
|
37 |
+
if [[ -f ten_packages/${package_type}/${package_name}/requirements.txt ]]; then
|
38 |
+
cp ten_packages/${package_type}/${package_name}/requirements.txt .release/ten_packages/${package_type}/${package_name}/
|
39 |
+
fi
|
40 |
+
|
41 |
+
# TODO: copy specific contents
|
42 |
+
if [[ -d ten_packages/${package_type}/${package_name}/pb ]]; then
|
43 |
+
cp -r ten_packages/${package_type}/${package_name}/pb .release/ten_packages/${package_type}/${package_name}/
|
44 |
+
fi
|
45 |
+
if [[ -d ten_packages/${package_type}/${package_name}/src ]]; then
|
46 |
+
cp -r ten_packages/${package_type}/${package_name}/src .release/ten_packages/${package_type}/${package_name}/
|
47 |
+
fi
|
48 |
+
if [[ -d ten_packages/${package_type}/${package_name}/realtime ]]; then
|
49 |
+
cp -r ten_packages/${package_type}/${package_name}/realtime .release/ten_packages/${package_type}/${package_name}/
|
50 |
+
fi
|
51 |
+
}
|
52 |
+
|
53 |
+
cp -r bin .release
|
54 |
+
cp manifest.json .release
|
55 |
+
cp property.json .release
|
56 |
+
|
57 |
+
# copy packages
|
58 |
+
mkdir -p .release/ten_packages
|
59 |
+
for package_type in system extension_group extension addon_loader; do
|
60 |
+
for package_path in ten_packages/${package_type}/*; do
|
61 |
+
package_name=$(basename ${package_path})
|
62 |
+
copy_package ${package_type} ${package_name}
|
63 |
+
done
|
64 |
+
done
|
65 |
+
|
66 |
+
if [[ -f session_control.conf ]]; then
|
67 |
+
cp -r session_control.conf .release/
|
68 |
+
fi
|
agents/scripts/pylint.sh
ADDED
@@ -0,0 +1,4 @@
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#!/bin/bash
|
2 |
+
|
3 |
+
|
4 |
+
pylint ./agents/ten_packages/extension/. || pylint-exit --warn-fail --error-fail $?
|
agents/session_control.conf
ADDED
@@ -0,0 +1,2 @@
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
}
|
agents/ten_packages/bak/litellm_python/__init__.py
ADDED
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from . import litellm_addon
|
2 |
+
from .extension import EXTENSION_NAME
|
3 |
+
from .log import logger
|
4 |
+
|
5 |
+
|
6 |
+
logger.info(f"{EXTENSION_NAME} extension loaded")
|
agents/ten_packages/bak/litellm_python/extension.py
ADDED
@@ -0,0 +1 @@
|
|
|
|
|
1 |
+
EXTENSION_NAME = "litellm_python"
|
agents/ten_packages/bak/litellm_python/litellm.py
ADDED
@@ -0,0 +1,79 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import litellm
|
2 |
+
import random
|
3 |
+
from typing import Dict, List, Optional
|
4 |
+
|
5 |
+
|
6 |
+
class LiteLLMConfig:
|
7 |
+
def __init__(self,
|
8 |
+
api_key: str,
|
9 |
+
base_url: str,
|
10 |
+
frequency_penalty: float,
|
11 |
+
max_tokens: int,
|
12 |
+
model: str,
|
13 |
+
presence_penalty: float,
|
14 |
+
prompt: str,
|
15 |
+
provider: str,
|
16 |
+
temperature: float,
|
17 |
+
top_p: float,
|
18 |
+
seed: Optional[int] = None,):
|
19 |
+
self.api_key = api_key
|
20 |
+
self.base_url = base_url
|
21 |
+
self.frequency_penalty = frequency_penalty
|
22 |
+
self.max_tokens = max_tokens
|
23 |
+
self.model = model
|
24 |
+
self.presence_penalty = presence_penalty
|
25 |
+
self.prompt = prompt
|
26 |
+
self.provider = provider
|
27 |
+
self.seed = seed if seed is not None else random.randint(0, 10000)
|
28 |
+
self.temperature = temperature
|
29 |
+
self.top_p = top_p
|
30 |
+
|
31 |
+
@classmethod
|
32 |
+
def default_config(cls):
|
33 |
+
return cls(
|
34 |
+
api_key="",
|
35 |
+
base_url="",
|
36 |
+
max_tokens=512,
|
37 |
+
model="gpt-4o-mini",
|
38 |
+
frequency_penalty=0.9,
|
39 |
+
presence_penalty=0.9,
|
40 |
+
prompt="You are a voice assistant who talks in a conversational way and can chat with me like my friends. I will speak to you in English or Chinese, and you will answer in the corrected and improved version of my text with the language I use. Don’t talk like a robot, instead I would like you to talk like a real human with emotions. I will use your answer for text-to-speech, so don’t return me any meaningless characters. I want you to be helpful, when I’m asking you for advice, give me precise, practical and useful advice instead of being vague. When giving me a list of options, express the options in a narrative way instead of bullet points.",
|
41 |
+
provider="",
|
42 |
+
seed=random.randint(0, 10000),
|
43 |
+
temperature=0.1,
|
44 |
+
top_p=1.0
|
45 |
+
)
|
46 |
+
|
47 |
+
|
48 |
+
class LiteLLM:
|
49 |
+
def __init__(self, config: LiteLLMConfig):
|
50 |
+
self.config = config
|
51 |
+
|
52 |
+
def get_chat_completions_stream(self, messages: List[Dict[str, str]]):
|
53 |
+
kwargs = {
|
54 |
+
"api_key": self.config.api_key,
|
55 |
+
"base_url": self.config.base_url,
|
56 |
+
"custom_llm_provider": self.config.provider,
|
57 |
+
"frequency_penalty": self.config.frequency_penalty,
|
58 |
+
"max_tokens": self.config.max_tokens,
|
59 |
+
"messages": [
|
60 |
+
{
|
61 |
+
"role": "system",
|
62 |
+
"content": self.config.prompt,
|
63 |
+
},
|
64 |
+
*messages,
|
65 |
+
],
|
66 |
+
"model": self.config.model,
|
67 |
+
"presence_penalty": self.config.presence_penalty,
|
68 |
+
"seed": self.config.seed,
|
69 |
+
"stream": True,
|
70 |
+
"temperature": self.config.temperature,
|
71 |
+
"top_p": self.config.top_p,
|
72 |
+
}
|
73 |
+
|
74 |
+
try:
|
75 |
+
response = litellm.completion(**kwargs)
|
76 |
+
|
77 |
+
return response
|
78 |
+
except Exception as e:
|
79 |
+
raise Exception(f"get_chat_completions_stream failed, err: {e}")
|
agents/ten_packages/bak/litellm_python/litellm_addon.py
ADDED
@@ -0,0 +1,23 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#
|
2 |
+
#
|
3 |
+
# Agora Real Time Engagement
|
4 |
+
# Created by XinHui Li in 2024.
|
5 |
+
# Copyright (c) 2024 Agora IO. All rights reserved.
|
6 |
+
#
|
7 |
+
#
|
8 |
+
from ten import (
|
9 |
+
Addon,
|
10 |
+
register_addon_as_extension,
|
11 |
+
TenEnv,
|
12 |
+
)
|
13 |
+
from .extension import EXTENSION_NAME
|
14 |
+
from .log import logger
|
15 |
+
from .litellm_extension import LiteLLMExtension
|
16 |
+
|
17 |
+
|
18 |
+
@register_addon_as_extension(EXTENSION_NAME)
|
19 |
+
class LiteLLMExtensionAddon(Addon):
|
20 |
+
def on_create_instance(self, ten: TenEnv, addon_name: str, context) -> None:
|
21 |
+
logger.info("on_create_instance")
|
22 |
+
|
23 |
+
ten.on_create_instance_done(LiteLLMExtension(addon_name), context)
|
agents/ten_packages/bak/litellm_python/litellm_extension.py
ADDED
@@ -0,0 +1,229 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#
|
2 |
+
#
|
3 |
+
# Agora Real Time Engagement
|
4 |
+
# Created by XinHui Li in 2024.
|
5 |
+
# Copyright (c) 2024 Agora IO. All rights reserved.
|
6 |
+
#
|
7 |
+
#
|
8 |
+
from threading import Thread
|
9 |
+
from ten import (
|
10 |
+
Extension,
|
11 |
+
TenEnv,
|
12 |
+
Cmd,
|
13 |
+
Data,
|
14 |
+
StatusCode,
|
15 |
+
CmdResult,
|
16 |
+
)
|
17 |
+
from .litellm import LiteLLM, LiteLLMConfig
|
18 |
+
from .log import logger
|
19 |
+
from .utils import get_micro_ts, parse_sentence
|
20 |
+
|
21 |
+
|
22 |
+
CMD_IN_FLUSH = "flush"
|
23 |
+
CMD_OUT_FLUSH = "flush"
|
24 |
+
DATA_IN_TEXT_DATA_PROPERTY_TEXT = "text"
|
25 |
+
DATA_IN_TEXT_DATA_PROPERTY_IS_FINAL = "is_final"
|
26 |
+
DATA_OUT_TEXT_DATA_PROPERTY_TEXT = "text"
|
27 |
+
DATA_OUT_TEXT_DATA_PROPERTY_TEXT_END_OF_SEGMENT = "end_of_segment"
|
28 |
+
|
29 |
+
PROPERTY_API_KEY = "api_key" # Required
|
30 |
+
PROPERTY_BASE_URL = "base_url" # Optional
|
31 |
+
PROPERTY_FREQUENCY_PENALTY = "frequency_penalty" # Optional
|
32 |
+
PROPERTY_GREETING = "greeting" # Optional
|
33 |
+
PROPERTY_MAX_MEMORY_LENGTH = "max_memory_length" # Optional
|
34 |
+
PROPERTY_MAX_TOKENS = "max_tokens" # Optional
|
35 |
+
PROPERTY_MODEL = "model" # Optional
|
36 |
+
PROPERTY_PRESENCE_PENALTY = "presence_penalty" # Optional
|
37 |
+
PROPERTY_PROMPT = "prompt" # Optional
|
38 |
+
PROPERTY_PROVIDER = "provider" # Optional
|
39 |
+
PROPERTY_TEMPERATURE = "temperature" # Optional
|
40 |
+
PROPERTY_TOP_P = "top_p" # Optional
|
41 |
+
|
42 |
+
|
43 |
+
class LiteLLMExtension(Extension):
|
44 |
+
memory = []
|
45 |
+
max_memory_length = 10
|
46 |
+
outdate_ts = 0
|
47 |
+
litellm = None
|
48 |
+
|
49 |
+
def on_start(self, ten: TenEnv) -> None:
|
50 |
+
logger.info("LiteLLMExtension on_start")
|
51 |
+
# Prepare configuration
|
52 |
+
litellm_config = LiteLLMConfig.default_config()
|
53 |
+
|
54 |
+
for key in [PROPERTY_API_KEY, PROPERTY_GREETING, PROPERTY_MODEL, PROPERTY_PROMPT]:
|
55 |
+
try:
|
56 |
+
val = ten.get_property_string(key)
|
57 |
+
if val:
|
58 |
+
litellm_config.key = val
|
59 |
+
except Exception as e:
|
60 |
+
logger.warning(f"get_property_string optional {key} failed, err: {e}")
|
61 |
+
|
62 |
+
for key in [PROPERTY_FREQUENCY_PENALTY, PROPERTY_PRESENCE_PENALTY, PROPERTY_TEMPERATURE, PROPERTY_TOP_P]:
|
63 |
+
try:
|
64 |
+
litellm_config.key = float(ten.get_property_float(key))
|
65 |
+
except Exception as e:
|
66 |
+
logger.warning(f"get_property_float optional {key} failed, err: {e}")
|
67 |
+
|
68 |
+
for key in [PROPERTY_MAX_MEMORY_LENGTH, PROPERTY_MAX_TOKENS]:
|
69 |
+
try:
|
70 |
+
litellm_config.key = int(ten.get_property_int(key))
|
71 |
+
except Exception as e:
|
72 |
+
logger.warning(f"get_property_int optional {key} failed, err: {e}")
|
73 |
+
|
74 |
+
# Create LiteLLM instance
|
75 |
+
self.litellm = LiteLLM(litellm_config)
|
76 |
+
logger.info(f"newLiteLLM succeed with max_tokens: {litellm_config.max_tokens}, model: {litellm_config.model}")
|
77 |
+
|
78 |
+
# Send greeting if available
|
79 |
+
greeting = ten.get_property_string(PROPERTY_GREETING)
|
80 |
+
if greeting:
|
81 |
+
try:
|
82 |
+
output_data = Data.create("text_data")
|
83 |
+
output_data.set_property_string(DATA_OUT_TEXT_DATA_PROPERTY_TEXT, greeting)
|
84 |
+
output_data.set_property_bool(DATA_OUT_TEXT_DATA_PROPERTY_TEXT_END_OF_SEGMENT, True)
|
85 |
+
ten.send_data(output_data)
|
86 |
+
logger.info(f"greeting [{greeting}] sent")
|
87 |
+
except Exception as e:
|
88 |
+
logger.error(f"greeting [{greeting}] send failed, err: {e}")
|
89 |
+
|
90 |
+
ten.on_start_done()
|
91 |
+
|
92 |
+
def on_stop(self, ten: TenEnv) -> None:
|
93 |
+
logger.info("LiteLLMExtension on_stop")
|
94 |
+
ten.on_stop_done()
|
95 |
+
|
96 |
+
def on_cmd(self, ten: TenEnv, cmd: Cmd) -> None:
|
97 |
+
logger.info("LiteLLMExtension on_cmd")
|
98 |
+
cmd_json = cmd.to_json()
|
99 |
+
logger.info(f"LiteLLMExtension on_cmd json: {cmd_json}")
|
100 |
+
|
101 |
+
cmd_name = cmd.get_name()
|
102 |
+
|
103 |
+
if cmd_name == CMD_IN_FLUSH:
|
104 |
+
self.outdate_ts = get_micro_ts()
|
105 |
+
cmd_out = Cmd.create(CMD_OUT_FLUSH)
|
106 |
+
ten.send_cmd(cmd_out, None)
|
107 |
+
logger.info(f"LiteLLMExtension on_cmd sent flush")
|
108 |
+
else:
|
109 |
+
logger.info(f"LiteLLMExtension on_cmd unknown cmd: {cmd_name}")
|
110 |
+
cmd_result = CmdResult.create(StatusCode.ERROR)
|
111 |
+
cmd_result.set_property_string("detail", "unknown cmd")
|
112 |
+
ten.return_result(cmd_result, cmd)
|
113 |
+
return
|
114 |
+
|
115 |
+
cmd_result = CmdResult.create(StatusCode.OK)
|
116 |
+
cmd_result.set_property_string("detail", "success")
|
117 |
+
ten.return_result(cmd_result, cmd)
|
118 |
+
|
119 |
+
def on_data(self, ten: TenEnv, data: Data) -> None:
|
120 |
+
"""
|
121 |
+
on_data receives data from ten graph.
|
122 |
+
current suppotend data:
|
123 |
+
- name: text_data
|
124 |
+
example:
|
125 |
+
{name: text_data, properties: {text: "hello"}
|
126 |
+
"""
|
127 |
+
logger.info(f"LiteLLMExtension on_data")
|
128 |
+
|
129 |
+
# Assume 'data' is an object from which we can get properties
|
130 |
+
try:
|
131 |
+
is_final = data.get_property_bool(DATA_IN_TEXT_DATA_PROPERTY_IS_FINAL)
|
132 |
+
if not is_final:
|
133 |
+
logger.info("ignore non-final input")
|
134 |
+
return
|
135 |
+
except Exception as e:
|
136 |
+
logger.error(f"on_data get_property_bool {DATA_IN_TEXT_DATA_PROPERTY_IS_FINAL} failed, err: {e}")
|
137 |
+
return
|
138 |
+
|
139 |
+
# Get input text
|
140 |
+
try:
|
141 |
+
input_text = data.get_property_string(DATA_IN_TEXT_DATA_PROPERTY_TEXT)
|
142 |
+
if not input_text:
|
143 |
+
logger.info("ignore empty text")
|
144 |
+
return
|
145 |
+
logger.info(f"on_data input text: [{input_text}]")
|
146 |
+
except Exception as e:
|
147 |
+
logger.error(f"on_data get_property_string {DATA_IN_TEXT_DATA_PROPERTY_TEXT} failed, err: {e}")
|
148 |
+
return
|
149 |
+
|
150 |
+
# Prepare memory
|
151 |
+
if len(self.memory) > self.max_memory_length:
|
152 |
+
self.memory.pop(0)
|
153 |
+
self.memory.append({"role": "user", "content": input_text})
|
154 |
+
|
155 |
+
def chat_completions_stream_worker(start_time, input_text, memory):
|
156 |
+
try:
|
157 |
+
logger.info(f"chat_completions_stream_worker for input text: [{input_text}] memory: {memory}")
|
158 |
+
|
159 |
+
# Get result from AI
|
160 |
+
resp = self.litellm.get_chat_completions_stream(memory)
|
161 |
+
if resp is None:
|
162 |
+
logger.info(f"chat_completions_stream_worker for input text: [{input_text}] failed")
|
163 |
+
return
|
164 |
+
|
165 |
+
sentence = ""
|
166 |
+
full_content = ""
|
167 |
+
first_sentence_sent = False
|
168 |
+
|
169 |
+
for chat_completions in resp:
|
170 |
+
if start_time < self.outdate_ts:
|
171 |
+
logger.info(f"chat_completions_stream_worker recv interrupt and flushing for input text: [{input_text}], startTs: {start_time}, outdateTs: {self.outdate_ts}")
|
172 |
+
break
|
173 |
+
|
174 |
+
if (len(chat_completions.choices) > 0 and chat_completions.choices[0].delta.content is not None):
|
175 |
+
content = chat_completions.choices[0].delta.content
|
176 |
+
else:
|
177 |
+
content = ""
|
178 |
+
|
179 |
+
full_content += content
|
180 |
+
|
181 |
+
while True:
|
182 |
+
sentence, content, sentence_is_final = parse_sentence(sentence, content)
|
183 |
+
|
184 |
+
if len(sentence) == 0 or not sentence_is_final:
|
185 |
+
logger.info(f"sentence {sentence} is empty or not final")
|
186 |
+
break
|
187 |
+
|
188 |
+
logger.info(f"chat_completions_stream_worker recv for input text: [{input_text}] got sentence: [{sentence}]")
|
189 |
+
|
190 |
+
# send sentence
|
191 |
+
try:
|
192 |
+
output_data = Data.create("text_data")
|
193 |
+
output_data.set_property_string(DATA_OUT_TEXT_DATA_PROPERTY_TEXT, sentence)
|
194 |
+
output_data.set_property_bool(DATA_OUT_TEXT_DATA_PROPERTY_TEXT_END_OF_SEGMENT, False)
|
195 |
+
ten.send_data(output_data)
|
196 |
+
logger.info(f"chat_completions_stream_worker recv for input text: [{input_text}] sent sentence [{sentence}]")
|
197 |
+
except Exception as e:
|
198 |
+
logger.error(f"chat_completions_stream_worker recv for input text: [{input_text}] send sentence [{sentence}] failed, err: {e}")
|
199 |
+
break
|
200 |
+
|
201 |
+
sentence = ""
|
202 |
+
if not first_sentence_sent:
|
203 |
+
first_sentence_sent = True
|
204 |
+
logger.info(f"chat_completions_stream_worker recv for input text: [{input_text}] first sentence sent, first_sentence_latency {get_micro_ts() - start_time}ms")
|
205 |
+
|
206 |
+
# remember response as assistant content in memory
|
207 |
+
memory.append({"role": "assistant", "content": full_content})
|
208 |
+
|
209 |
+
# send end of segment
|
210 |
+
try:
|
211 |
+
output_data = Data.create("text_data")
|
212 |
+
output_data.set_property_string(DATA_OUT_TEXT_DATA_PROPERTY_TEXT, sentence)
|
213 |
+
output_data.set_property_bool(DATA_OUT_TEXT_DATA_PROPERTY_TEXT_END_OF_SEGMENT, True)
|
214 |
+
ten.send_data(output_data)
|
215 |
+
logger.info(f"chat_completions_stream_worker for input text: [{input_text}] end of segment with sentence [{sentence}] sent")
|
216 |
+
except Exception as e:
|
217 |
+
logger.error(f"chat_completions_stream_worker for input text: [{input_text}] end of segment with sentence [{sentence}] send failed, err: {e}")
|
218 |
+
|
219 |
+
except Exception as e:
|
220 |
+
logger.error(f"chat_completions_stream_worker for input text: [{input_text}] failed, err: {e}")
|
221 |
+
|
222 |
+
# Start thread to request and read responses from LiteLLM
|
223 |
+
start_time = get_micro_ts()
|
224 |
+
thread = Thread(
|
225 |
+
target=chat_completions_stream_worker,
|
226 |
+
args=(start_time, input_text, self.memory),
|
227 |
+
)
|
228 |
+
thread.start()
|
229 |
+
logger.info(f"LiteLLMExtension on_data end")
|
agents/ten_packages/bak/litellm_python/log.py
ADDED
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import logging
|
2 |
+
from .extension import EXTENSION_NAME
|
3 |
+
|
4 |
+
logger = logging.getLogger(EXTENSION_NAME)
|
5 |
+
logger.setLevel(logging.INFO)
|
6 |
+
|
7 |
+
formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(process)d - [%(filename)s:%(lineno)d] - %(message)s")
|
8 |
+
|
9 |
+
console_handler = logging.StreamHandler()
|
10 |
+
console_handler.setFormatter(formatter)
|
11 |
+
|
12 |
+
logger.addHandler(console_handler)
|
agents/ten_packages/bak/litellm_python/manifest.json
ADDED
@@ -0,0 +1,82 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"type": "extension",
|
3 |
+
"name": "litellm_python",
|
4 |
+
"version": "0.1.0",
|
5 |
+
"dependencies": [
|
6 |
+
{
|
7 |
+
"type": "system",
|
8 |
+
"name": "ten_runtime_python",
|
9 |
+
"version": "0.8"
|
10 |
+
}
|
11 |
+
],
|
12 |
+
"api": {
|
13 |
+
"property": {
|
14 |
+
"api_key": {
|
15 |
+
"type": "string"
|
16 |
+
},
|
17 |
+
"base_url": {
|
18 |
+
"type": "string"
|
19 |
+
},
|
20 |
+
"frequency_penalty": {
|
21 |
+
"type": "float64"
|
22 |
+
},
|
23 |
+
"greeting": {
|
24 |
+
"type": "string"
|
25 |
+
},
|
26 |
+
"max_memory_length": {
|
27 |
+
"type": "int64"
|
28 |
+
},
|
29 |
+
"max_tokens": {
|
30 |
+
"type": "int64"
|
31 |
+
},
|
32 |
+
"model": {
|
33 |
+
"type": "string"
|
34 |
+
},
|
35 |
+
"presence_penalty": {
|
36 |
+
"type": "float64"
|
37 |
+
},
|
38 |
+
"prompt": {
|
39 |
+
"type": "string"
|
40 |
+
},
|
41 |
+
"provider": {
|
42 |
+
"type": "string"
|
43 |
+
},
|
44 |
+
"temperature": {
|
45 |
+
"type": "float64"
|
46 |
+
},
|
47 |
+
"top_p": {
|
48 |
+
"type": "float64"
|
49 |
+
}
|
50 |
+
},
|
51 |
+
"data_in": [
|
52 |
+
{
|
53 |
+
"name": "text_data",
|
54 |
+
"property": {
|
55 |
+
"text": {
|
56 |
+
"type": "string"
|
57 |
+
}
|
58 |
+
}
|
59 |
+
}
|
60 |
+
],
|
61 |
+
"data_out": [
|
62 |
+
{
|
63 |
+
"name": "text_data",
|
64 |
+
"property": {
|
65 |
+
"text": {
|
66 |
+
"type": "string"
|
67 |
+
}
|
68 |
+
}
|
69 |
+
}
|
70 |
+
],
|
71 |
+
"cmd_in": [
|
72 |
+
{
|
73 |
+
"name": "flush"
|
74 |
+
}
|
75 |
+
],
|
76 |
+
"cmd_out": [
|
77 |
+
{
|
78 |
+
"name": "flush"
|
79 |
+
}
|
80 |
+
]
|
81 |
+
}
|
82 |
+
}
|
agents/ten_packages/bak/litellm_python/requirements.txt
ADDED
@@ -0,0 +1 @@
|
|
|
|
|
1 |
+
litellm==1.42.12
|
agents/ten_packages/bak/litellm_python/utils.py
ADDED
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import time
|
2 |
+
|
3 |
+
|
4 |
+
def get_micro_ts():
|
5 |
+
return int(time.time() * 1_000_000)
|
6 |
+
|
7 |
+
|
8 |
+
def is_punctuation(char: str):
|
9 |
+
return char in [",", ",", ".", "。", "?", "?", "!", "!"]
|
10 |
+
|
11 |
+
|
12 |
+
def parse_sentence(sentence: str, content: str):
|
13 |
+
for i, char in enumerate(content):
|
14 |
+
sentence += char
|
15 |
+
|
16 |
+
if is_punctuation(char):
|
17 |
+
return sentence, content[i + 1:], True
|
18 |
+
|
19 |
+
return sentence, "", False
|
agents/ten_packages/extension/agora_rtm_wrapper/extension.go
ADDED
@@ -0,0 +1,180 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/**
|
2 |
+
*
|
3 |
+
* Agora Real Time Engagement
|
4 |
+
* Created by Wei Hu in 2022-10.
|
5 |
+
* Copyright (c) 2024 Agora IO. All rights reserved.
|
6 |
+
*
|
7 |
+
*/
|
8 |
+
// Note that this is just an example extension written in the GO programming
|
9 |
+
// language, so the package name does not equal to the containing directory
|
10 |
+
// name. However, it is not common in Go.
|
11 |
+
package extension
|
12 |
+
|
13 |
+
import (
|
14 |
+
"encoding/json"
|
15 |
+
"fmt"
|
16 |
+
"strconv"
|
17 |
+
|
18 |
+
"ten_framework/ten"
|
19 |
+
)
|
20 |
+
|
21 |
+
// Message colllector represents the text output result
|
22 |
+
// @Description 输出结果
|
23 |
+
type ColllectorMessage struct {
|
24 |
+
Text string `json:"text"` // 识别出的文本
|
25 |
+
IsFinal bool `json:"is_final"` // 是否为最终结果
|
26 |
+
StreamID int32 `json:"stream_id"` // 流ID
|
27 |
+
Type string `json:"data_type"` // 数据类型
|
28 |
+
Ts uint64 `json:"text_ts"` // 时间戳
|
29 |
+
}
|
30 |
+
|
31 |
+
// Message represents the text output result
|
32 |
+
// @Description 输出结果
|
33 |
+
type Message struct {
|
34 |
+
Text string `json:"text"` // 识别出的文本
|
35 |
+
IsFinal bool `json:"is_final"` // 是否为最终结果
|
36 |
+
StreamID string `json:"stream_id"` // 流ID
|
37 |
+
Type string `json:"type"` // 数据类型
|
38 |
+
Ts uint64 `json:"ts"` // 时间戳
|
39 |
+
}
|
40 |
+
|
41 |
+
// RtcUserSate represents the rtc user state
|
42 |
+
// @Description RTC用户状态
|
43 |
+
type RtcUserSate struct {
|
44 |
+
RemoteUserID string `json:"remote_user_id"` // 远程用户ID
|
45 |
+
State string `json:"state"` // 状态
|
46 |
+
Reason string `json:"reason"` // 原因
|
47 |
+
}
|
48 |
+
|
49 |
+
type agoraRtmWrapperExtension struct {
|
50 |
+
ten.DefaultExtension
|
51 |
+
}
|
52 |
+
|
53 |
+
func newExtension(name string) ten.Extension {
|
54 |
+
return &agoraRtmWrapperExtension{}
|
55 |
+
}
|
56 |
+
|
57 |
+
// OnData receives data from ten graph.
|
58 |
+
func (p *agoraRtmWrapperExtension) OnData(
|
59 |
+
tenEnv ten.TenEnv,
|
60 |
+
data ten.Data,
|
61 |
+
) {
|
62 |
+
buf, err := data.GetPropertyBytes("data")
|
63 |
+
if err != nil {
|
64 |
+
tenEnv.LogError("OnData GetProperty data error: " + err.Error())
|
65 |
+
return
|
66 |
+
}
|
67 |
+
tenEnv.LogInfo("AGORA_RTM_WRAPPER_EXTENSION OnData: " + string(buf))
|
68 |
+
colllectorMessage := ColllectorMessage{}
|
69 |
+
err = json.Unmarshal(buf, &colllectorMessage)
|
70 |
+
if err != nil {
|
71 |
+
tenEnv.LogError("OnData Unmarshal data error: " + err.Error())
|
72 |
+
return
|
73 |
+
}
|
74 |
+
|
75 |
+
message := Message{
|
76 |
+
Text: colllectorMessage.Text,
|
77 |
+
IsFinal: colllectorMessage.IsFinal,
|
78 |
+
StreamID: strconv.Itoa(int(colllectorMessage.StreamID)),
|
79 |
+
Type: colllectorMessage.Type,
|
80 |
+
Ts: colllectorMessage.Ts,
|
81 |
+
}
|
82 |
+
jsonBytes, err := json.Marshal(message)
|
83 |
+
if err != nil {
|
84 |
+
tenEnv.LogError("failed to marshal JSON: " + err.Error())
|
85 |
+
return
|
86 |
+
}
|
87 |
+
tenEnv.LogInfo("AGORA_RTM_WRAPPER_EXTENSION OnData: " + string(jsonBytes))
|
88 |
+
|
89 |
+
cmd, _ := ten.NewCmd("publish")
|
90 |
+
|
91 |
+
err = cmd.SetPropertyBytes("message", jsonBytes)
|
92 |
+
if err != nil {
|
93 |
+
tenEnv.LogError("failed to set property message: " + err.Error())
|
94 |
+
return
|
95 |
+
}
|
96 |
+
if err := tenEnv.SendCmd(cmd, func(_ ten.TenEnv, result ten.CmdResult, _ error) {
|
97 |
+
status, err := result.GetStatusCode()
|
98 |
+
tenEnv.LogInfo(fmt.Sprintf("AGORA_RTM_WRAPPER_EXTENSION publish result %d", status))
|
99 |
+
if status != ten.StatusCodeOk || err != nil {
|
100 |
+
tenEnv.LogError("failed to subscribe")
|
101 |
+
}
|
102 |
+
}); err != nil {
|
103 |
+
tenEnv.LogError("failed to send command " + err.Error())
|
104 |
+
}
|
105 |
+
}
|
106 |
+
|
107 |
+
func (p *agoraRtmWrapperExtension) OnCmd(tenEnv ten.TenEnv, cmd ten.Cmd) {
|
108 |
+
defer func() {
|
109 |
+
if r := recover(); r != nil {
|
110 |
+
tenEnv.LogError(fmt.Sprintf("OnCmd panic: %v", r))
|
111 |
+
}
|
112 |
+
cmdResult, err := ten.NewCmdResult(ten.StatusCodeOk)
|
113 |
+
if err != nil {
|
114 |
+
tenEnv.LogError(fmt.Sprintf("failed to create cmd result: %v", err))
|
115 |
+
return
|
116 |
+
}
|
117 |
+
tenEnv.ReturnResult(cmdResult, cmd, nil)
|
118 |
+
}()
|
119 |
+
cmdName, err := cmd.GetName()
|
120 |
+
if err != nil {
|
121 |
+
tenEnv.LogError(fmt.Sprintf("failed to get cmd name: %v", err))
|
122 |
+
return
|
123 |
+
}
|
124 |
+
tenEnv.LogInfo(fmt.Sprintf("received command: %s", cmdName))
|
125 |
+
switch cmdName {
|
126 |
+
case "on_user_audio_track_state_changed":
|
127 |
+
// on_user_audio_track_state_changed
|
128 |
+
p.handleUserStateChanged(tenEnv, cmd)
|
129 |
+
default:
|
130 |
+
tenEnv.LogWarn(fmt.Sprintf("unsupported cmd: %s", cmdName))
|
131 |
+
}
|
132 |
+
}
|
133 |
+
|
134 |
+
func (p *agoraRtmWrapperExtension) handleUserStateChanged(tenEnv ten.TenEnv, cmd ten.Cmd) {
|
135 |
+
remoteUserID, err := cmd.GetPropertyString("remote_user_id")
|
136 |
+
if err != nil {
|
137 |
+
tenEnv.LogError(fmt.Sprintf("failed to get remote_user_id: %v", err))
|
138 |
+
return
|
139 |
+
}
|
140 |
+
state, err := cmd.GetPropertyInt32("state")
|
141 |
+
if err != nil {
|
142 |
+
tenEnv.LogError(fmt.Sprintf("failed to get state: %v", err))
|
143 |
+
return
|
144 |
+
}
|
145 |
+
reason, err := cmd.GetPropertyInt32("reason")
|
146 |
+
if err != nil {
|
147 |
+
tenEnv.LogError(fmt.Sprintf("failed to get reason: %v", err))
|
148 |
+
return
|
149 |
+
}
|
150 |
+
userState := RtcUserSate{
|
151 |
+
RemoteUserID: remoteUserID,
|
152 |
+
State: strconv.Itoa(int(state)),
|
153 |
+
Reason: strconv.Itoa(int(reason)),
|
154 |
+
}
|
155 |
+
jsonBytes, err := json.Marshal(userState)
|
156 |
+
if err != nil {
|
157 |
+
tenEnv.LogError("failed to marshal JSON: " + err.Error())
|
158 |
+
return
|
159 |
+
}
|
160 |
+
sendCmd, _ := ten.NewCmd("set_presence_state")
|
161 |
+
sendCmd.SetPropertyString("states", string(jsonBytes))
|
162 |
+
tenEnv.LogInfo("AGORA_RTM_WRAPPER_EXTENSION SetRtmPresenceState " + string(jsonBytes))
|
163 |
+
if err := tenEnv.SendCmd(sendCmd, func(_ ten.TenEnv, result ten.CmdResult, _ error) {
|
164 |
+
status, err := result.GetStatusCode()
|
165 |
+
tenEnv.LogInfo(fmt.Sprintf("AGORA_RTM_WRAPPER_EXTENSION SetRtmPresenceState result %d", status))
|
166 |
+
if status != ten.StatusCodeOk || err != nil {
|
167 |
+
panic("failed to SetRtmPresenceState")
|
168 |
+
}
|
169 |
+
}); err != nil {
|
170 |
+
tenEnv.LogError("failed to send command " + err.Error())
|
171 |
+
}
|
172 |
+
}
|
173 |
+
|
174 |
+
func init() {
|
175 |
+
// Register addon
|
176 |
+
ten.RegisterAddonAsExtension(
|
177 |
+
"agora_rtm_wrapper",
|
178 |
+
ten.NewDefaultExtensionAddon(newExtension),
|
179 |
+
)
|
180 |
+
}
|
agents/ten_packages/extension/agora_rtm_wrapper/go.mod
ADDED
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
module agora_rtm_wrapper
|
2 |
+
|
3 |
+
go 1.20
|
4 |
+
|
5 |
+
replace ten_framework => ../../system/ten_runtime_go/interface
|
6 |
+
|
7 |
+
require ten_framework v0.0.0-00010101000000-000000000000
|
agents/ten_packages/extension/agora_rtm_wrapper/manifest.json
ADDED
@@ -0,0 +1,32 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"type": "extension",
|
3 |
+
"name": "agora_rtm_wrapper",
|
4 |
+
"version": "0.1.4",
|
5 |
+
"dependencies": [
|
6 |
+
{
|
7 |
+
"type": "system",
|
8 |
+
"name": "ten_runtime_go",
|
9 |
+
"version": "0.8"
|
10 |
+
}
|
11 |
+
],
|
12 |
+
"api": {
|
13 |
+
"data_in": [
|
14 |
+
{
|
15 |
+
"name": "data"
|
16 |
+
}
|
17 |
+
],
|
18 |
+
"cmd_out": [
|
19 |
+
{
|
20 |
+
"name": "publish",
|
21 |
+
"property": {
|
22 |
+
"message": {
|
23 |
+
"type": "buf"
|
24 |
+
}
|
25 |
+
}
|
26 |
+
},
|
27 |
+
{
|
28 |
+
"name": "set_presence_state"
|
29 |
+
}
|
30 |
+
]
|
31 |
+
}
|
32 |
+
}
|
agents/ten_packages/extension/agora_rtm_wrapper/property.json
ADDED
@@ -0,0 +1 @@
|
|
|
|
|
1 |
+
{}
|
agents/ten_packages/extension/aliyun_analyticdb_vector_storage/__init__.py
ADDED
@@ -0,0 +1 @@
|
|
|
|
|
1 |
+
from . import vector_storage_addon
|
agents/ten_packages/extension/aliyun_analyticdb_vector_storage/client.py
ADDED
@@ -0,0 +1,95 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# -*- coding: utf-8 -*-
|
2 |
+
|
3 |
+
import asyncio
|
4 |
+
import threading
|
5 |
+
from typing import Coroutine
|
6 |
+
from concurrent.futures import Future
|
7 |
+
|
8 |
+
|
9 |
+
from alibabacloud_gpdb20160503.client import Client as gpdb20160503Client
|
10 |
+
from alibabacloud_tea_openapi import models as open_api_models
|
11 |
+
|
12 |
+
|
13 |
+
# maybe need multiple clients
|
14 |
+
class AliGPDBClient:
|
15 |
+
def __init__(self, ten_env, access_key_id, access_key_secret, endpoint):
|
16 |
+
self.stopEvent = asyncio.Event()
|
17 |
+
self.loop = None
|
18 |
+
self.tasks = asyncio.Queue()
|
19 |
+
self.access_key_id = access_key_id
|
20 |
+
self.access_key_secret = access_key_secret
|
21 |
+
self.endpoint = endpoint
|
22 |
+
self.client = self.create_client()
|
23 |
+
self.thread = threading.Thread(
|
24 |
+
target=asyncio.run, args=(self.__thread_routine(),)
|
25 |
+
)
|
26 |
+
self.thread.start()
|
27 |
+
self.ten_env = ten_env
|
28 |
+
|
29 |
+
async def stop_thread(self):
|
30 |
+
self.stopEvent.set()
|
31 |
+
|
32 |
+
def create_client(self) -> gpdb20160503Client:
|
33 |
+
config = open_api_models.Config(
|
34 |
+
access_key_id=self.access_key_id,
|
35 |
+
access_key_secret=self.access_key_secret,
|
36 |
+
endpoint=self.endpoint,
|
37 |
+
)
|
38 |
+
return gpdb20160503Client(config)
|
39 |
+
|
40 |
+
def get(self) -> gpdb20160503Client:
|
41 |
+
return self.client
|
42 |
+
|
43 |
+
def close(self):
|
44 |
+
if (self.loop is not None) and self.thread.is_alive():
|
45 |
+
self.stopEvent.set()
|
46 |
+
asyncio.run_coroutine_threadsafe(self.stop_thread(), self.loop)
|
47 |
+
self.thread.join()
|
48 |
+
|
49 |
+
async def __thread_routine(self):
|
50 |
+
self.ten_env.log_info("client __thread_routine start")
|
51 |
+
self.loop = asyncio.get_running_loop()
|
52 |
+
tasks = set()
|
53 |
+
while not self.stopEvent.is_set():
|
54 |
+
if not self.tasks.empty():
|
55 |
+
coro, future = await self.tasks.get()
|
56 |
+
try:
|
57 |
+
task = asyncio.create_task(coro)
|
58 |
+
tasks.add(task)
|
59 |
+
task.add_done_callback(lambda t: future.set_result(t.result()))
|
60 |
+
except Exception as e:
|
61 |
+
future.set_exception(e)
|
62 |
+
elif tasks:
|
63 |
+
done, tasks = await asyncio.wait(
|
64 |
+
tasks, return_when=asyncio.FIRST_COMPLETED
|
65 |
+
)
|
66 |
+
for task in done:
|
67 |
+
if task.exception():
|
68 |
+
self.ten_env.log_error(f"task exception: {task.exception()}")
|
69 |
+
future.set_exception(task.exception())
|
70 |
+
else:
|
71 |
+
await asyncio.sleep(0.1)
|
72 |
+
self.ten_env.log_info("client __thread_routine end")
|
73 |
+
|
74 |
+
async def submit_task(self, coro: Coroutine) -> Future:
|
75 |
+
future = Future()
|
76 |
+
await self.tasks.put((coro, future))
|
77 |
+
return future
|
78 |
+
|
79 |
+
def submit_task_with_new_thread(self, coro: Coroutine) -> Future:
|
80 |
+
future = Future()
|
81 |
+
|
82 |
+
def run_coro_in_new_thread():
|
83 |
+
loop = asyncio.new_event_loop()
|
84 |
+
asyncio.set_event_loop(loop)
|
85 |
+
try:
|
86 |
+
result = loop.run_until_complete(coro)
|
87 |
+
future.set_result(result)
|
88 |
+
except Exception as e:
|
89 |
+
future.set_exception(e)
|
90 |
+
finally:
|
91 |
+
loop.close()
|
92 |
+
|
93 |
+
thread = threading.Thread(target=run_coro_in_new_thread)
|
94 |
+
thread.start()
|
95 |
+
return future
|
agents/ten_packages/extension/aliyun_analyticdb_vector_storage/manifest.json
ADDED
@@ -0,0 +1,121 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"type": "extension",
|
3 |
+
"name": "aliyun_analyticdb_vector_storage",
|
4 |
+
"version": "0.1.0",
|
5 |
+
"dependencies": [
|
6 |
+
{
|
7 |
+
"type": "system",
|
8 |
+
"name": "ten_runtime_python",
|
9 |
+
"version": "0.8"
|
10 |
+
}
|
11 |
+
],
|
12 |
+
"api": {
|
13 |
+
"property": {
|
14 |
+
"alibaba_cloud_access_key_id": {
|
15 |
+
"type": "string"
|
16 |
+
},
|
17 |
+
"alibaba_cloud_access_key_secret": {
|
18 |
+
"type": "string"
|
19 |
+
},
|
20 |
+
"adbpg_instance_id": {
|
21 |
+
"type": "string"
|
22 |
+
},
|
23 |
+
"adbpg_instance_region": {
|
24 |
+
"type": "string"
|
25 |
+
},
|
26 |
+
"adbpg_account": {
|
27 |
+
"type": "string"
|
28 |
+
},
|
29 |
+
"adbpg_account_password": {
|
30 |
+
"type": "string"
|
31 |
+
},
|
32 |
+
"adbpg_namespace": {
|
33 |
+
"type": "string"
|
34 |
+
},
|
35 |
+
"adbpg_namespace_password": {
|
36 |
+
"type": "string"
|
37 |
+
}
|
38 |
+
},
|
39 |
+
"cmd_in": [
|
40 |
+
{
|
41 |
+
"name": "upsert_vector",
|
42 |
+
"property": {
|
43 |
+
"collection_name": {
|
44 |
+
"type": "string"
|
45 |
+
},
|
46 |
+
"file_name": {
|
47 |
+
"type": "string"
|
48 |
+
},
|
49 |
+
"content": {
|
50 |
+
"type": "string"
|
51 |
+
}
|
52 |
+
}
|
53 |
+
},
|
54 |
+
{
|
55 |
+
"name": "query_vector",
|
56 |
+
"property": {
|
57 |
+
"collection_name": {
|
58 |
+
"type": "string"
|
59 |
+
},
|
60 |
+
"top_k": {
|
61 |
+
"type": "int64"
|
62 |
+
},
|
63 |
+
"embedding": {
|
64 |
+
"type": "array",
|
65 |
+
"items": {
|
66 |
+
"type": "float64"
|
67 |
+
}
|
68 |
+
}
|
69 |
+
},
|
70 |
+
"required": [
|
71 |
+
"collection_name",
|
72 |
+
"top_k",
|
73 |
+
"embedding"
|
74 |
+
],
|
75 |
+
"result": {
|
76 |
+
"property": {
|
77 |
+
"response": {
|
78 |
+
"type": "array",
|
79 |
+
"items": {
|
80 |
+
"type": "object",
|
81 |
+
"properties": {
|
82 |
+
"content": {
|
83 |
+
"type": "string"
|
84 |
+
},
|
85 |
+
"score": {
|
86 |
+
"type": "float64"
|
87 |
+
}
|
88 |
+
}
|
89 |
+
}
|
90 |
+
}
|
91 |
+
}
|
92 |
+
}
|
93 |
+
},
|
94 |
+
{
|
95 |
+
"name": "create_collection",
|
96 |
+
"property": {
|
97 |
+
"collection_name": {
|
98 |
+
"type": "string"
|
99 |
+
},
|
100 |
+
"dimension": {
|
101 |
+
"type": "int32"
|
102 |
+
}
|
103 |
+
},
|
104 |
+
"required": [
|
105 |
+
"collection_name"
|
106 |
+
]
|
107 |
+
},
|
108 |
+
{
|
109 |
+
"name": "delete_collection",
|
110 |
+
"property": {
|
111 |
+
"collection_name": {
|
112 |
+
"type": "string"
|
113 |
+
}
|
114 |
+
},
|
115 |
+
"required": [
|
116 |
+
"collection_name"
|
117 |
+
]
|
118 |
+
}
|
119 |
+
]
|
120 |
+
}
|
121 |
+
}
|
agents/ten_packages/extension/aliyun_analyticdb_vector_storage/model.py
ADDED
@@ -0,0 +1,546 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# -*- coding: utf-8 -*-
|
2 |
+
|
3 |
+
from alibabacloud_gpdb20160503 import models as gpdb_20160503_models # type: ignore
|
4 |
+
import time
|
5 |
+
import json
|
6 |
+
from typing import Dict, List, Any, Tuple
|
7 |
+
from alibabacloud_tea_util import models as util_models
|
8 |
+
|
9 |
+
|
10 |
+
class Model:
|
11 |
+
def __init__(self, ten_env, region_id, dbinstance_id, client):
|
12 |
+
self.region_id = region_id
|
13 |
+
self.dbinstance_id = dbinstance_id
|
14 |
+
self.client = client
|
15 |
+
self.read_timeout = 10 * 1000
|
16 |
+
self.connect_timeout = 10 * 1000
|
17 |
+
self.ten_env = ten_env
|
18 |
+
|
19 |
+
def get_client(self):
|
20 |
+
return self.client.get()
|
21 |
+
|
22 |
+
def init_vector_database(self, account, account_password) -> None:
|
23 |
+
try:
|
24 |
+
request = gpdb_20160503_models.InitVectorDatabaseRequest(
|
25 |
+
region_id=self.region_id,
|
26 |
+
dbinstance_id=self.dbinstance_id,
|
27 |
+
manager_account=account,
|
28 |
+
manager_account_password=account_password,
|
29 |
+
)
|
30 |
+
runtime = util_models.RuntimeOptions(
|
31 |
+
read_timeout=self.read_timeout, connect_timeout=self.connect_timeout
|
32 |
+
)
|
33 |
+
response = self.get_client().init_vector_database_with_options(
|
34 |
+
request, runtime
|
35 |
+
)
|
36 |
+
self.ten_env.log_debug(
|
37 |
+
f"init_vector_database response code: {response.status_code}, body:{response.body}"
|
38 |
+
)
|
39 |
+
except Exception as e:
|
40 |
+
self.ten_env.log_error(f"Error: {e}")
|
41 |
+
return e
|
42 |
+
|
43 |
+
async def init_vector_database_async(self, account, account_password) -> None:
|
44 |
+
try:
|
45 |
+
request = gpdb_20160503_models.InitVectorDatabaseRequest(
|
46 |
+
region_id=self.region_id,
|
47 |
+
dbinstance_id=self.dbinstance_id,
|
48 |
+
manager_account=account,
|
49 |
+
manager_account_password=account_password,
|
50 |
+
)
|
51 |
+
runtime = util_models.RuntimeOptions(
|
52 |
+
read_timeout=self.read_timeout, connect_timeout=self.connect_timeout
|
53 |
+
)
|
54 |
+
response = await self.get_client().init_vector_database_with_options_async(
|
55 |
+
request, runtime
|
56 |
+
)
|
57 |
+
self.ten_env.log_debug(
|
58 |
+
f"init_vector_database response code: {response.status_code}, body:{response.body}"
|
59 |
+
)
|
60 |
+
except Exception as e:
|
61 |
+
self.ten_env.log_error(f"Error: {e}")
|
62 |
+
return e
|
63 |
+
|
64 |
+
def create_namespace(
|
65 |
+
self, account, account_password, namespace, namespace_password
|
66 |
+
) -> None:
|
67 |
+
try:
|
68 |
+
request = gpdb_20160503_models.CreateNamespaceRequest(
|
69 |
+
region_id=self.region_id,
|
70 |
+
dbinstance_id=self.dbinstance_id,
|
71 |
+
manager_account=account,
|
72 |
+
manager_account_password=account_password,
|
73 |
+
namespace=namespace,
|
74 |
+
namespace_password=namespace_password,
|
75 |
+
)
|
76 |
+
runtime = util_models.RuntimeOptions(
|
77 |
+
read_timeout=self.read_timeout, connect_timeout=self.connect_timeout
|
78 |
+
)
|
79 |
+
response = self.get_client().create_namespace_with_options(request, runtime)
|
80 |
+
self.ten_env.log_debug(
|
81 |
+
f"create_namespace response code: {response.status_code}, body:{response.body}"
|
82 |
+
)
|
83 |
+
except Exception as e:
|
84 |
+
self.ten_env.log_error(f"Error: {e}")
|
85 |
+
return e
|
86 |
+
|
87 |
+
async def create_namespace_async(
|
88 |
+
self, account, account_password, namespace, namespace_password
|
89 |
+
) -> None:
|
90 |
+
try:
|
91 |
+
request = gpdb_20160503_models.CreateNamespaceRequest(
|
92 |
+
region_id=self.region_id,
|
93 |
+
dbinstance_id=self.dbinstance_id,
|
94 |
+
manager_account=account,
|
95 |
+
manager_account_password=account_password,
|
96 |
+
namespace=namespace,
|
97 |
+
namespace_password=namespace_password,
|
98 |
+
)
|
99 |
+
runtime = util_models.RuntimeOptions(
|
100 |
+
read_timeout=self.read_timeout, connect_timeout=self.connect_timeout
|
101 |
+
)
|
102 |
+
response = await self.get_client().create_namespace_with_options_async(
|
103 |
+
request, runtime
|
104 |
+
)
|
105 |
+
self.ten_env.log_debug(
|
106 |
+
f"create_namespace response code: {response.status_code}, body:{response.body}"
|
107 |
+
)
|
108 |
+
except Exception as e:
|
109 |
+
self.ten_env.log_error(f"Error: {e}")
|
110 |
+
return e
|
111 |
+
|
112 |
+
def create_collection(
|
113 |
+
self,
|
114 |
+
account,
|
115 |
+
account_password,
|
116 |
+
namespace,
|
117 |
+
collection,
|
118 |
+
parser: str = None,
|
119 |
+
metrics: str = None,
|
120 |
+
hnsw_m: int = None,
|
121 |
+
pq_enable: int = None,
|
122 |
+
external_storage: int = None,
|
123 |
+
) -> None:
|
124 |
+
try:
|
125 |
+
metadata = '{"update_ts": "bigint", "file_name": "text", "content": "text"}'
|
126 |
+
full_text_retrieval_fields = "update_ts,file_name"
|
127 |
+
request = gpdb_20160503_models.CreateCollectionRequest(
|
128 |
+
region_id=self.region_id,
|
129 |
+
dbinstance_id=self.dbinstance_id,
|
130 |
+
manager_account=account,
|
131 |
+
manager_account_password=account_password,
|
132 |
+
namespace=namespace,
|
133 |
+
collection=collection,
|
134 |
+
metadata=metadata,
|
135 |
+
full_text_retrieval_fields=full_text_retrieval_fields,
|
136 |
+
parser=parser,
|
137 |
+
metrics=metrics,
|
138 |
+
hnsw_m=hnsw_m,
|
139 |
+
pq_enable=pq_enable,
|
140 |
+
external_storage=external_storage,
|
141 |
+
)
|
142 |
+
runtime = util_models.RuntimeOptions(
|
143 |
+
read_timeout=self.read_timeout, connect_timeout=self.connect_timeout
|
144 |
+
)
|
145 |
+
response = self.get_client().create_collection_with_options(
|
146 |
+
request, runtime
|
147 |
+
)
|
148 |
+
self.ten_env.log_debug(
|
149 |
+
f"create_document_collection response code: {response.status_code}, body:{response.body}"
|
150 |
+
)
|
151 |
+
except Exception as e:
|
152 |
+
self.ten_env.log_error(f"Error: {e}")
|
153 |
+
return e
|
154 |
+
|
155 |
+
async def create_collection_async(
|
156 |
+
self,
|
157 |
+
account,
|
158 |
+
account_password,
|
159 |
+
namespace,
|
160 |
+
collection,
|
161 |
+
parser: str = None,
|
162 |
+
metrics: str = None,
|
163 |
+
hnsw_m: int = None,
|
164 |
+
pq_enable: int = None,
|
165 |
+
external_storage: int = None,
|
166 |
+
) -> None:
|
167 |
+
try:
|
168 |
+
metadata = '{"update_ts": "bigint", "file_name": "text", "content": "text"}'
|
169 |
+
full_text_retrieval_fields = "update_ts,file_name"
|
170 |
+
request = gpdb_20160503_models.CreateCollectionRequest(
|
171 |
+
region_id=self.region_id,
|
172 |
+
dbinstance_id=self.dbinstance_id,
|
173 |
+
manager_account=account,
|
174 |
+
manager_account_password=account_password,
|
175 |
+
namespace=namespace,
|
176 |
+
collection=collection,
|
177 |
+
metadata=metadata,
|
178 |
+
full_text_retrieval_fields=full_text_retrieval_fields,
|
179 |
+
parser=parser,
|
180 |
+
metrics=metrics,
|
181 |
+
hnsw_m=hnsw_m,
|
182 |
+
pq_enable=pq_enable,
|
183 |
+
external_storage=external_storage,
|
184 |
+
)
|
185 |
+
runtime = util_models.RuntimeOptions(
|
186 |
+
read_timeout=self.read_timeout, connect_timeout=self.connect_timeout
|
187 |
+
)
|
188 |
+
response = await self.get_client().create_collection_with_options_async(
|
189 |
+
request, runtime
|
190 |
+
)
|
191 |
+
self.ten_env.log_debug(
|
192 |
+
f"create_document_collection response code: {response.status_code}, body:{response.body}"
|
193 |
+
)
|
194 |
+
except Exception as e:
|
195 |
+
self.ten_env.log_error(f"Error: {e}")
|
196 |
+
return e
|
197 |
+
|
198 |
+
def delete_collection(self, namespace, namespace_password, collection) -> None:
|
199 |
+
try:
|
200 |
+
request = gpdb_20160503_models.DeleteCollectionRequest(
|
201 |
+
region_id=self.region_id,
|
202 |
+
dbinstance_id=self.dbinstance_id,
|
203 |
+
namespace_password=namespace_password,
|
204 |
+
namespace=namespace,
|
205 |
+
collection=collection,
|
206 |
+
)
|
207 |
+
runtime = util_models.RuntimeOptions(
|
208 |
+
read_timeout=self.read_timeout, connect_timeout=self.connect_timeout
|
209 |
+
)
|
210 |
+
response = self.get_client().delete_collection_with_options(
|
211 |
+
request, runtime
|
212 |
+
)
|
213 |
+
self.ten_env.log_debug(
|
214 |
+
f"delete_collection response code: {response.status_code}, body:{response.body}"
|
215 |
+
)
|
216 |
+
except Exception as e:
|
217 |
+
self.ten_env.log_error(f"Error: {e}")
|
218 |
+
return e
|
219 |
+
|
220 |
+
async def delete_collection_async(
|
221 |
+
self, namespace, namespace_password, collection
|
222 |
+
) -> None:
|
223 |
+
try:
|
224 |
+
request = gpdb_20160503_models.DeleteCollectionRequest(
|
225 |
+
region_id=self.region_id,
|
226 |
+
dbinstance_id=self.dbinstance_id,
|
227 |
+
namespace_password=namespace_password,
|
228 |
+
namespace=namespace,
|
229 |
+
collection=collection,
|
230 |
+
)
|
231 |
+
runtime = util_models.RuntimeOptions(
|
232 |
+
read_timeout=self.read_timeout, connect_timeout=self.connect_timeout
|
233 |
+
)
|
234 |
+
response = await self.get_client().delete_collection_with_options_async(
|
235 |
+
request, runtime
|
236 |
+
)
|
237 |
+
self.ten_env.log_info(
|
238 |
+
f"delete_collection response code: {response.status_code}, body:{response.body}"
|
239 |
+
)
|
240 |
+
except Exception as e:
|
241 |
+
self.ten_env.log_error(f"Error: {e}")
|
242 |
+
return e
|
243 |
+
|
244 |
+
def upsert_collection_data(
|
245 |
+
self,
|
246 |
+
collection,
|
247 |
+
namespace,
|
248 |
+
namespace_password,
|
249 |
+
rows: List[Tuple[str, str, List[float]]] = None,
|
250 |
+
) -> None:
|
251 |
+
try:
|
252 |
+
request_rows = []
|
253 |
+
for row in rows:
|
254 |
+
file_name = row[0]
|
255 |
+
content = row[1]
|
256 |
+
vector = row[2]
|
257 |
+
metadata = {
|
258 |
+
"update_ts": int(time.time() * 1000),
|
259 |
+
"file_name": file_name,
|
260 |
+
"content": content,
|
261 |
+
}
|
262 |
+
request_row = gpdb_20160503_models.UpsertCollectionDataRequestRows(
|
263 |
+
metadata=metadata, vector=vector
|
264 |
+
)
|
265 |
+
request_rows.append(request_row)
|
266 |
+
upsert_collection_data_request = (
|
267 |
+
gpdb_20160503_models.UpsertCollectionDataRequest(
|
268 |
+
region_id=self.region_id,
|
269 |
+
dbinstance_id=self.dbinstance_id,
|
270 |
+
collection=collection,
|
271 |
+
namespace_password=namespace_password,
|
272 |
+
namespace=namespace,
|
273 |
+
rows=request_rows,
|
274 |
+
)
|
275 |
+
)
|
276 |
+
runtime = util_models.RuntimeOptions(
|
277 |
+
read_timeout=self.read_timeout, connect_timeout=self.connect_timeout
|
278 |
+
)
|
279 |
+
response = self.get_client().upsert_collection_data_with_options(
|
280 |
+
upsert_collection_data_request, runtime
|
281 |
+
)
|
282 |
+
self.ten_env.log_debug(
|
283 |
+
f"upsert_collection response code: {response.status_code}, body:{response.body}"
|
284 |
+
)
|
285 |
+
except Exception as e:
|
286 |
+
self.ten_env.log_error(f"Error: {e}")
|
287 |
+
return e
|
288 |
+
|
289 |
+
async def upsert_collection_data_async(
|
290 |
+
self,
|
291 |
+
collection,
|
292 |
+
namespace,
|
293 |
+
namespace_password,
|
294 |
+
rows: List[Tuple[str, str, List[float]]] = None,
|
295 |
+
) -> None:
|
296 |
+
try:
|
297 |
+
request_rows = []
|
298 |
+
for row in rows:
|
299 |
+
file_name = row[0]
|
300 |
+
content = row[1]
|
301 |
+
vector = row[2]
|
302 |
+
metadata = {
|
303 |
+
"update_ts": int(time.time() * 1000),
|
304 |
+
"file_name": file_name,
|
305 |
+
"content": content,
|
306 |
+
}
|
307 |
+
request_row = gpdb_20160503_models.UpsertCollectionDataRequestRows(
|
308 |
+
metadata=metadata, vector=vector
|
309 |
+
)
|
310 |
+
request_rows.append(request_row)
|
311 |
+
upsert_collection_data_request = (
|
312 |
+
gpdb_20160503_models.UpsertCollectionDataRequest(
|
313 |
+
region_id=self.region_id,
|
314 |
+
dbinstance_id=self.dbinstance_id,
|
315 |
+
collection=collection,
|
316 |
+
namespace_password=namespace_password,
|
317 |
+
namespace=namespace,
|
318 |
+
rows=request_rows,
|
319 |
+
)
|
320 |
+
)
|
321 |
+
runtime = util_models.RuntimeOptions(
|
322 |
+
read_timeout=self.read_timeout, connect_timeout=self.connect_timeout
|
323 |
+
)
|
324 |
+
response = (
|
325 |
+
await self.get_client().upsert_collection_data_with_options_async(
|
326 |
+
upsert_collection_data_request, runtime
|
327 |
+
)
|
328 |
+
)
|
329 |
+
self.ten_env.log_debug(
|
330 |
+
f"upsert_collection response code: {response.status_code}, body:{response.body}"
|
331 |
+
)
|
332 |
+
except Exception as e:
|
333 |
+
self.ten_env.log_error(f"Error: {e}")
|
334 |
+
return e
|
335 |
+
|
336 |
+
# pylint: disable=redefined-builtin
|
337 |
+
def query_collection_data(
|
338 |
+
self,
|
339 |
+
collection,
|
340 |
+
namespace,
|
341 |
+
namespace_password,
|
342 |
+
vector: List[float] = None,
|
343 |
+
top_k: int = 10,
|
344 |
+
content: str = None,
|
345 |
+
filter: str = None,
|
346 |
+
hybrid_search: str = None,
|
347 |
+
hybrid_search_args: Dict[str, dict] = None,
|
348 |
+
include_metadata_fields: str = None,
|
349 |
+
include_values: bool = None,
|
350 |
+
metrics: str = None,
|
351 |
+
) -> Tuple[Any, Any]:
|
352 |
+
try:
|
353 |
+
query_collection_data_request = (
|
354 |
+
gpdb_20160503_models.QueryCollectionDataRequest(
|
355 |
+
region_id=self.region_id,
|
356 |
+
dbinstance_id=self.dbinstance_id,
|
357 |
+
collection=collection,
|
358 |
+
namespace_password=namespace_password,
|
359 |
+
namespace=namespace,
|
360 |
+
vector=vector,
|
361 |
+
top_k=top_k,
|
362 |
+
content=content,
|
363 |
+
filter=filter,
|
364 |
+
hybrid_search=hybrid_search,
|
365 |
+
hybrid_search_args=hybrid_search_args,
|
366 |
+
include_metadata_fields=include_metadata_fields,
|
367 |
+
include_values=include_values,
|
368 |
+
metrics=metrics,
|
369 |
+
)
|
370 |
+
)
|
371 |
+
runtime = util_models.RuntimeOptions(
|
372 |
+
read_timeout=self.read_timeout, connect_timeout=self.connect_timeout
|
373 |
+
)
|
374 |
+
response = self.get_client().query_collection_data_with_options(
|
375 |
+
query_collection_data_request, runtime
|
376 |
+
)
|
377 |
+
self.ten_env.log_debug(f"query_collection response code: {response.status_code}")
|
378 |
+
return response, None
|
379 |
+
except Exception as e:
|
380 |
+
self.ten_env.log_error(f"Error: {e}")
|
381 |
+
return None, e
|
382 |
+
|
383 |
+
# pylint: disable=redefined-builtin
|
384 |
+
async def query_collection_data_async(
|
385 |
+
self,
|
386 |
+
collection,
|
387 |
+
namespace,
|
388 |
+
namespace_password,
|
389 |
+
vector: List[float] = None,
|
390 |
+
top_k: int = 10,
|
391 |
+
content: str = None,
|
392 |
+
filter: str = None,
|
393 |
+
hybrid_search: str = None,
|
394 |
+
hybrid_search_args: Dict[str, dict] = None,
|
395 |
+
include_metadata_fields: str = None,
|
396 |
+
include_values: bool = None,
|
397 |
+
metrics: str = None,
|
398 |
+
) -> Tuple[Any, Any]:
|
399 |
+
try:
|
400 |
+
query_collection_data_request = (
|
401 |
+
gpdb_20160503_models.QueryCollectionDataRequest(
|
402 |
+
region_id=self.region_id,
|
403 |
+
dbinstance_id=self.dbinstance_id,
|
404 |
+
collection=collection,
|
405 |
+
namespace_password=namespace_password,
|
406 |
+
namespace=namespace,
|
407 |
+
vector=vector,
|
408 |
+
top_k=top_k,
|
409 |
+
content=content,
|
410 |
+
filter=filter,
|
411 |
+
hybrid_search=hybrid_search,
|
412 |
+
hybrid_search_args=hybrid_search_args,
|
413 |
+
include_metadata_fields=include_metadata_fields,
|
414 |
+
include_values=include_values,
|
415 |
+
metrics=metrics,
|
416 |
+
)
|
417 |
+
)
|
418 |
+
runtime = util_models.RuntimeOptions(
|
419 |
+
read_timeout=self.read_timeout, connect_timeout=self.connect_timeout
|
420 |
+
)
|
421 |
+
response = await self.get_client().query_collection_data_with_options_async(
|
422 |
+
query_collection_data_request, runtime
|
423 |
+
)
|
424 |
+
self.ten_env.log_debug(f"query_collection response code: {response.status_code}")
|
425 |
+
return response, None
|
426 |
+
except Exception as e:
|
427 |
+
self.ten_env.log_error(f"Error: {e}")
|
428 |
+
return None, e
|
429 |
+
|
430 |
+
def parse_collection_data(
|
431 |
+
self, body: gpdb_20160503_models.QueryCollectionDataResponseBody
|
432 |
+
) -> str:
|
433 |
+
try:
|
434 |
+
matches = body.to_map()["Matches"]["match"]
|
435 |
+
results = [
|
436 |
+
{"content": match["Metadata"]["content"], "score": match["Score"]}
|
437 |
+
for match in matches
|
438 |
+
]
|
439 |
+
results.sort(key=lambda x: x["score"], reverse=True)
|
440 |
+
json_str = json.dumps(results)
|
441 |
+
return json_str
|
442 |
+
except Exception as e:
|
443 |
+
self.ten_env.log_error(
|
444 |
+
f"parse collection data failed, error: {e}, data: {body.to_map()}"
|
445 |
+
)
|
446 |
+
return "[]"
|
447 |
+
|
448 |
+
def list_collections(self, namespace, namespace_password) -> Tuple[List[str], Any]:
|
449 |
+
try:
|
450 |
+
request = gpdb_20160503_models.ListCollectionsRequest(
|
451 |
+
region_id=self.region_id,
|
452 |
+
dbinstance_id=self.dbinstance_id,
|
453 |
+
namespace=namespace,
|
454 |
+
namespace_password=namespace_password,
|
455 |
+
)
|
456 |
+
runtime = util_models.RuntimeOptions(
|
457 |
+
read_timeout=self.read_timeout, connect_timeout=self.connect_timeout
|
458 |
+
)
|
459 |
+
response = self.get_client().list_collections_with_options(request, runtime)
|
460 |
+
self.ten_env.log_debug(
|
461 |
+
f"list_collections response code: {response.status_code}, body:{response.body}"
|
462 |
+
)
|
463 |
+
collections = response.body.to_map()["Collections"]["collection"]
|
464 |
+
return collections, None
|
465 |
+
except Exception as e:
|
466 |
+
self.ten_env.log_error(f"Error: {e}")
|
467 |
+
return [], e
|
468 |
+
|
469 |
+
async def list_collections_async(
|
470 |
+
self, namespace, namespace_password
|
471 |
+
) -> Tuple[List[str], Any]:
|
472 |
+
try:
|
473 |
+
request = gpdb_20160503_models.ListCollectionsRequest(
|
474 |
+
region_id=self.region_id,
|
475 |
+
dbinstance_id=self.dbinstance_id,
|
476 |
+
namespace=namespace,
|
477 |
+
namespace_password=namespace_password,
|
478 |
+
)
|
479 |
+
runtime = util_models.RuntimeOptions(
|
480 |
+
read_timeout=self.read_timeout, connect_timeout=self.connect_timeout
|
481 |
+
)
|
482 |
+
response = await self.get_client().list_collections_with_options_async(
|
483 |
+
request, runtime
|
484 |
+
)
|
485 |
+
self.ten_env.log_debug(
|
486 |
+
f"list_collections response code: {response.status_code}, body:{response.body}"
|
487 |
+
)
|
488 |
+
collections = response.body.to_map()["Collections"]["collection"]
|
489 |
+
return collections, None
|
490 |
+
except Exception as e:
|
491 |
+
self.ten_env.log_error(f"Error: {e}")
|
492 |
+
return [], e
|
493 |
+
|
494 |
+
def create_vector_index(
|
495 |
+
self, account, account_password, namespace, collection, dimension
|
496 |
+
) -> None:
|
497 |
+
try:
|
498 |
+
request = gpdb_20160503_models.CreateVectorIndexRequest(
|
499 |
+
region_id=self.region_id,
|
500 |
+
dbinstance_id=self.dbinstance_id,
|
501 |
+
manager_account=account,
|
502 |
+
manager_account_password=account_password,
|
503 |
+
namespace=namespace,
|
504 |
+
collection=collection,
|
505 |
+
dimension=dimension,
|
506 |
+
pq_enable=0,
|
507 |
+
)
|
508 |
+
runtime = util_models.RuntimeOptions(
|
509 |
+
read_timeout=self.read_timeout, connect_timeout=self.connect_timeout
|
510 |
+
)
|
511 |
+
response = self.get_client().create_vector_index_with_options(
|
512 |
+
request, runtime
|
513 |
+
)
|
514 |
+
self.ten_env.log_debug(
|
515 |
+
f"create_vector_index response code: {response.status_code}, body:{response.body}"
|
516 |
+
)
|
517 |
+
except Exception as e:
|
518 |
+
self.ten_env.log_error(f"Error: {e}")
|
519 |
+
return e
|
520 |
+
|
521 |
+
async def create_vector_index_async(
|
522 |
+
self, account, account_password, namespace, collection, dimension
|
523 |
+
) -> None:
|
524 |
+
try:
|
525 |
+
request = gpdb_20160503_models.CreateVectorIndexRequest(
|
526 |
+
region_id=self.region_id,
|
527 |
+
dbinstance_id=self.dbinstance_id,
|
528 |
+
manager_account=account,
|
529 |
+
manager_account_password=account_password,
|
530 |
+
namespace=namespace,
|
531 |
+
collection=collection,
|
532 |
+
dimension=dimension,
|
533 |
+
pq_enable=0,
|
534 |
+
)
|
535 |
+
runtime = util_models.RuntimeOptions(
|
536 |
+
read_timeout=self.read_timeout, connect_timeout=self.connect_timeout
|
537 |
+
)
|
538 |
+
response = await self.get_client().create_vector_index_with_options_async(
|
539 |
+
request, runtime
|
540 |
+
)
|
541 |
+
self.ten_env.log_debug(
|
542 |
+
f"create_vector_index response code: {response.status_code}, body:{response.body}"
|
543 |
+
)
|
544 |
+
except Exception as e:
|
545 |
+
self.ten_env.log_error(f"Error: {e}")
|
546 |
+
return e
|