refactor: clean up legacy code, rename hopper to entity_extractor, and add third-party notices
- Add NOTICE file and README license references for mobile-use and finalrun-agent - Add derivative attribution headers to 17 files derived from mobile-use - Rename hopper agent to entity_extractor across prompts, tools, and configs - Remove obsolete adb_tunnel, ApiBaseUrl, and legacy CLI utility scripts - Replace legacy examples with native Artemis diagnostic and workflow examples - Update unit and tool tests to validate entity_extractor and SDK builders
This commit is contained in:
1 parent
0860788192
commit
54fcef9887
83 files changed
+1996
-3660
No files matched your search
@@ -0,0 +1,90 @@
|
||||
# Copyright 2026 Google LLC
|
||||
#
|
||||
# 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.
|
||||
|
||||
"""Lightweight entity extraction and package resolver for ARTEMIS.
|
||||
|
||||
Dispatches bounded LLM extraction turns to identify application package identifiers
|
||||
and configuration attributes from raw device listings without manual parsing heuristics.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from pathlib import Path
|
||||
from typing import cast
|
||||
|
||||
from jinja2 import Template
|
||||
from langchain_core.messages import HumanMessage, SystemMessage
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
from artemis.context import ArtemisContext
|
||||
from artemis.data_engine.trace import trace
|
||||
from artemis.services.llm import get_llm, invoke_llm_with_timeout_message, with_fallback
|
||||
from artemis.utils.logger import get_logger
|
||||
|
||||
logger = get_logger(__name__)
|
||||
|
||||
|
||||
class ExtractionResult(BaseModel):
|
||||
"""Structured extraction outcome for entity resolution."""
|
||||
|
||||
found: bool = Field(description="True if the requested entity was definitively identified.")
|
||||
output: str | None = Field(default=None, description="Exact extracted identifier or string value.")
|
||||
reason: str = Field(description="Brief justification of the match criteria applied.")
|
||||
|
||||
|
||||
@trace(type="agent", name="entity_extractor")
|
||||
async def extract_entity(
|
||||
ctx: ArtemisContext,
|
||||
request: str,
|
||||
data: str,
|
||||
use_fallback: bool = True,
|
||||
) -> ExtractionResult:
|
||||
"""Extract a specific identifier or entity from raw batch device data."""
|
||||
logger.info(f"Invoking Artemis Entity Extractor (fallback={use_fallback})")
|
||||
template_path = Path(__file__).parent / "entity_extractor.md"
|
||||
system_prompt = Template(template_path.read_text(encoding="utf-8")).render()
|
||||
|
||||
messages = [
|
||||
SystemMessage(content=system_prompt),
|
||||
HumanMessage(content=f"Target Query:\n{request}\n\nCandidate Raw Dataset:\n{data}"),
|
||||
]
|
||||
|
||||
primary_llm = get_llm(ctx=ctx, name="entity_extractor", is_utils=True).with_structured_output(
|
||||
ExtractionResult
|
||||
)
|
||||
|
||||
try:
|
||||
if use_fallback:
|
||||
fallback_llm = get_llm(
|
||||
ctx=ctx, name="entity_extractor", is_utils=True, use_fallback=True
|
||||
).with_structured_output(ExtractionResult)
|
||||
raw = await with_fallback(
|
||||
main_call=lambda: invoke_llm_with_timeout_message(primary_llm.ainvoke(messages)),
|
||||
fallback_call=lambda: invoke_llm_with_timeout_message(fallback_llm.ainvoke(messages)),
|
||||
)
|
||||
else:
|
||||
raw = await invoke_llm_with_timeout_message(primary_llm.ainvoke(messages))
|
||||
|
||||
if isinstance(raw, ExtractionResult):
|
||||
return raw
|
||||
if isinstance(raw, dict):
|
||||
return ExtractionResult.model_validate(raw)
|
||||
return cast(ExtractionResult, raw)
|
||||
except Exception as exc:
|
||||
logger.error(f"Entity extraction turn failed: {exc}")
|
||||
return ExtractionResult(
|
||||
found=False,
|
||||
output=None,
|
||||
reason=f"LLM extraction error: {str(exc)[:400]}",
|
||||
)
|
||||
Reference in new issue
Block a user