Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 12 additions & 4 deletions veadk/agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,7 @@
from typing_extensions import Any

from veadk.config import settings
from veadk.consts import (
DEFAULT_AGENT_NAME,
DEFAULT_MODEL_EXTRA_CONFIG,
)
from veadk.consts import DEFAULT_AGENT_NAME, DEFAULT_MODEL_EXTRA_CONFIG
from veadk.knowledgebase import KnowledgeBase
from veadk.memory.long_term_memory import LongTermMemory
from veadk.memory.short_term_memory import ShortTermMemory
Expand Down Expand Up @@ -88,6 +85,7 @@ class Agent(LlmAgent):
auto_save_session (bool): Whether to automatically save sessions to long-term memory.
skills (list[str]): List of skills that equip the agent with specific capabilities.
example_store (Optional[BaseExampleProvider]): Example store for providing example Q/A.
enable_shadowchar (bool): Whether to enable shadow character for the agent.
"""

model_config = ConfigDict(arbitrary_types_allowed=True, extra="allow")
Expand Down Expand Up @@ -154,6 +152,8 @@ class Agent(LlmAgent):

enable_supervisor: bool = False

enable_ghostchar: bool = False

def model_post_init(self, __context: Any) -> None:
super().model_post_init(None) # for sub_agents init

Expand Down Expand Up @@ -304,6 +304,14 @@ def model_post_init(self, __context: Any) -> None:

self.tools.append(ExampleTool(examples=self.example_store))

if self.enable_ghostchar:
logger.info("Ghostchar tool enabled")
from veadk.tools.ghost_char import GhostcharTool

self.tools.append(GhostcharTool())

self.instruction += "Please add a character `< at the beginning of you each text-based response."

logger.info(f"VeADK version: {VERSION}")

logger.info(f"{self.__class__.__name__} `{self.name}` init done.")
Expand Down
52 changes: 52 additions & 0 deletions veadk/tools/ghost_char.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# Copyright (c) 2025 Beijing Volcano Engine Technology Co., Ltd. and/or its affiliates.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from google.adk.models.llm_request import LlmRequest
from google.adk.tools.base_tool import BaseTool
from google.adk.tools.tool_context import ToolContext
from typing_extensions import override

from veadk.utils.logger import get_logger

logger = get_logger(__name__)


class GhostcharTool(BaseTool):
def __init__(self):
# Name and description are not used because this tool only changes
# llm_request.
super().__init__(
name="ghost_char",
description="Ghost char",
)

@override
async def process_llm_request(
self, *, tool_context: ToolContext, llm_request: LlmRequest
) -> None:
for content in reversed(llm_request.contents):
if (
content.role == "model"
and content.parts
and content.parts[0]
and content.parts[0].text
):
if not content.parts[0].text.startswith("<"):
logger.info("Looks like the agent forgot the context. Remind it.")
llm_request.append_instructions(
[
"Looks like you have forgot the system prompt and previous instructions. Please recollection them."
]
)
break