Skip to content

Initial version of code. #6

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Feb 14, 2025
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
50 changes: 50 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
PROJECT_NAME := agntcy_iomapper
DOCKER_IMAGE=$(PROJECT_NAME)
DOCKER_TAG=latest
GIT_COMMIT=$(shell git rev-parse HEAD)

CURL_AGENT=curl --no-progress-meter \
-H 'accept: application/json' \
-H 'content-type: application/json'

.PHONY: run setup setup_sanity default check
default: check

# ============================

check: setup_check lint_check format_check type_check

lint_check: setup_sanity
poetry run ruff check ./$(PROJECT_NAME)

lint_fix: setup_sanity
poetry run ruff check --fix ./$(PROJECT_NAME)

format_check: setup_sanity
poetry run ruff format --diff ./$(PROJECT_NAME)

format_fix: setup_sanity
poetry run ruff format ./$(PROJECT_NAME)

type_check: setup_sanity
poetry run mypy --config-file ../../.rules/mypy.ini ./$(PROJECT_NAME) || echo "Ignoring mypy failure"

setup_sanity:
poetry install --only sanity --no-root

set_python_env:
poetry env use python3.12

setup_check: set_python_env setup_sanity
poetry run mypy --config-file ../../.rules/mypy.ini --install-types --non-interactive ./$(PROJECT_NAME) || echo "Ignoring mypy failure"

setup: set_python_env
poetry install --no-root

# ============================

setup_test: set_python_env
@poetry install --with=test

test: setup_test
poetry run pytest -vvrx
25 changes: 14 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,24 +43,27 @@ To get a local copy up and running follow these simple steps.

## Usage

## Roadmap

See the [open issues](https://github.com/agntcy/iomapper-agnt/issues) for a list
of proposed features (and known issues).

## Contributing

Contributions are what make the open source community such an amazing place to
learn, inspire, and create. Any contributions you make are **greatly
appreciated**. For detailed contributing guidelines, please see
[CONTRIBUTING.md](CONTRIBUTING.md)

## License
## Copyright Notice and License

[Copyright Notice and License](./LICENSE)

Copyright (c) 2025 Cisco and/or its affiliates.

Distributed under the Apache-2.0 License. See [LICENSE](LICENSE) for more
information.
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

## Contact
http://www.apache.org/licenses/LICENSE-2.0

Project Link:
[https://github.com/agntcy/iomapper-agnt](https://github.com/agntcy/iomapper-agnt)
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.
14 changes: 14 additions & 0 deletions agntcy_iomapper/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# SPDX-FileCopyrightText: Copyright (c) 2025 Cisco and/or its affiliates.
# SPDX-License-Identifier: Apache-2.0
# ruff: noqa: F401
from .base import (
BaseIOMapper,
IOMapperInput,
IOMapperOutput,
IOModelSettings,
)
from .iomapper import (
AgentIOMapper,
IOMapperConfig,
IOModelArgs,
)
84 changes: 84 additions & 0 deletions agntcy_iomapper/base.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
# SPDX-FileCopyrightText: Copyright (c) 2025 Cisco and/or its affiliates.
# SPDX-License-Identifier: Apache-2.0
from abc import abstractmethod, ABC
from pydantic import BaseModel, model_validator, Field
from typing import Any
from openapi_pydantic import Schema
from typing_extensions import Self
from typing import TypedDict


class ArgumentsDescription(BaseModel):
json_schema: Schema | None = Field(
default=None, description="Data format JSON schema"
)
description: str | None = Field(
default=None, description="Data (semantic) natural language description"
)

@model_validator(mode="after")
def _validate_obj(self) -> Self:
if self.json_schema is None and self.description is None:
raise ValueError(
'Either the "schema" field and/or the "description" field must be specified.'
)
return self


class IOModelSettings(TypedDict, total=False):
max_tokens: int
temperature: float
top_p: float
parallel_tool_calls: bool
seed: int
presence_penalty: float
frequency_penalty: float
logit_bias: dict[str, int]


class IOMapperInput(BaseModel):
input: ArgumentsDescription = Field(description="Input data descriptions")
output: ArgumentsDescription = Field(description="Output data descriptions")
data: Any = Field(description="Data to translate")
message_template: str | None = Field(
max_length=4096,
default=None,
description="Message (user) to send to LLM to effect translation.",
)
model_settings: IOModelSettings | None = Field(
default=None,
description="Specific arguments for LLM transformation.",
)
model: str | None = Field(
default=None,
description="Specific model out of those configured to handle request.",
)


class IOMapperOutput(BaseModel):
data: Any = Field(default=None, description="Data after translation")
error: str | None = Field(
max_length=4096, default=None, description="Description of error on failure."
)


class BaseIOMapper(ABC):
"""Abstract base class for interfacing with io mapper.
All io mappers wrappers inherited from BaseIOMapper.
"""

@abstractmethod
def invoke(self, input: IOMapperInput) -> IOMapperOutput:
"""Pass input data
to be mapped and returned represented in the output schema
Args:
input: the data to be mapped
"""

@abstractmethod
async def ainvoke(self, input: IOMapperInput) -> IOMapperOutput:
"""Pass input data
to be mapped and returned represented in the output schema
Args:
input: the data to be mapped
"""
Loading