copass-google-agents 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,38 @@
1
+ # Dependencies
2
+ node_modules/
3
+
4
+ # Build output
5
+ dist/
6
+ *.tsbuildinfo
7
+
8
+ # Environment
9
+ .env
10
+ .env.*
11
+
12
+ # IDE
13
+ .vscode/
14
+ .idea/
15
+ *.swp
16
+ *.swo
17
+ *~
18
+
19
+ # OS
20
+ .DS_Store
21
+ Thumbs.db
22
+
23
+ # Test
24
+ coverage/
25
+
26
+ # Lerna
27
+ lerna-debug.log
28
+ .nx/cache
29
+ .nx/workspace-data
30
+
31
+ # Python
32
+ __pycache__/
33
+ *.pyc
34
+ *.pyo
35
+ *.egg-info/
36
+ .venv/
37
+ venv/
38
+ .olane
@@ -0,0 +1,138 @@
1
+ Metadata-Version: 2.4
2
+ Name: copass-google-agents
3
+ Version: 0.1.0
4
+ Summary: Copass agent primitives for Google Vertex AI Agent Engine (ADK)
5
+ Project-URL: Homepage, https://github.com/olane-labs/copass-harness
6
+ Project-URL: Repository, https://github.com/olane-labs/copass-harness.git
7
+ Author: Olane Inc.
8
+ License: MIT
9
+ Keywords: adk,agent-engine,agents,copass,google,knowledge-graph,vertex-ai
10
+ Classifier: License :: OSI Approved :: MIT License
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Programming Language :: Python :: 3.10
13
+ Classifier: Programming Language :: Python :: 3.11
14
+ Classifier: Programming Language :: Python :: 3.12
15
+ Requires-Python: >=3.10
16
+ Requires-Dist: copass-core-agents>=0.1.0
17
+ Requires-Dist: google-cloud-aiplatform[adk,agent-engines]>=1.148.1
18
+ Provides-Extra: dev
19
+ Requires-Dist: mypy>=1.10; extra == 'dev'
20
+ Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
21
+ Requires-Dist: pytest>=8.0; extra == 'dev'
22
+ Requires-Dist: ruff>=0.5; extra == 'dev'
23
+ Description-Content-Type: text/markdown
24
+
25
+ # copass-google-agents
26
+
27
+ Google Vertex AI **Agent Engine** (ADK) backend for Copass. Depends on [`copass-core-agents`](../copass-core-agents), which owns the vendor-neutral primitives (`BaseAgent`, `AgentTool`, `AgentBackend` ABC, events, `AgentScope`, registries, etc.) shared across every provider-specific Copass SDK.
28
+
29
+ This package owns the Google-specific piece — `GoogleAgentBackend` and the `CopassGoogleAgent` convenience subclass — and re-exports the core primitives for one-line dev imports. Either of these works for consumers:
30
+
31
+ ```python
32
+ from copass_google_agents import BaseAgent, CopassGoogleAgent # convenient
33
+ # or
34
+ from copass_core_agents import BaseAgent # explicit boundary
35
+ from copass_google_agents import CopassGoogleAgent
36
+ ```
37
+
38
+ Pairs with Copass's server-side router — both sides import the same code so the agent runtime is a single codepath, whether the agent runs in the dev's process or server-side via Copass's Router endpoint.
39
+
40
+ > **Status: scaffold (v0.1.0).** Constructors, type surface, and public imports are in place. `GoogleAgentBackend.run` / `GoogleAgentBackend.stream` / `deploy_adk_agent` / `adk_event_to_agent_events` currently raise `NotImplementedError`. Implementation lands in a follow-up pass.
41
+
42
+ ## Install
43
+
44
+ ```bash
45
+ pip install copass-google-agents
46
+ ```
47
+
48
+ Requires `google-cloud-aiplatform[agent_engines,adk]>=1.148.1` (which pulls in `google-adk>=1.31`). Uses Application Default Credentials (ADC) — run `gcloud auth application-default login` locally, or set `GOOGLE_APPLICATION_CREDENTIALS` / attach a service account.
49
+
50
+ ## Architecture
51
+
52
+ Agent Engine diverges from Claude Managed Agents in one important way: **ADK agents are pre-deployed resources** (`projects/{p}/locations/{l}/reasoningEngines/{id}`) and their **tools are baked in at deploy time**. You cannot pass tools per-run.
53
+
54
+ To preserve Copass's `AgentToolResolver` runtime-plug model, `copass-google-agents` deploys ADK agents carrying a single `copass_dispatch(tool_name, arguments)` function tool. At run time that proxy calls back into your Copass service, which hosts the real resolver and invokes the right tool for the current user.
55
+
56
+ So:
57
+ - **`GoogleAgentBackend`** is *session-only* — streams queries against a pre-deployed engine.
58
+ - **`deploy_adk_agent`** (ops helper) is the one-time setup that wires the proxy tool into a new ADK agent resource.
59
+ - **Zero client-side tools** is the expected case. `CopassGoogleAgent` defaults to an empty `AgentToolRegistry`.
60
+
61
+ ## Quickstart (planned — not functional in the scaffold)
62
+
63
+ ```python
64
+ import os
65
+ from copass_google_agents import (
66
+ AgentInvocationContext,
67
+ AgentScope,
68
+ CopassGoogleAgent,
69
+ )
70
+
71
+ agent = CopassGoogleAgent(
72
+ identity="support",
73
+ system_prompt="You are a support agent.",
74
+ project=os.environ["GOOGLE_CLOUD_PROJECT"],
75
+ reasoning_engine_id=os.environ["COPASS_REASONING_ENGINE_ID"],
76
+ )
77
+
78
+ ctx = AgentInvocationContext(scope=AgentScope(user_id="u-123"))
79
+ result = await agent.run(
80
+ messages=[{"role": "user", "content": "Hello"}],
81
+ context=ctx,
82
+ )
83
+ print(result.final_text)
84
+ ```
85
+
86
+ ## Streaming (planned)
87
+
88
+ ```python
89
+ from copass_google_agents import (
90
+ AgentFinish,
91
+ AgentTextDelta,
92
+ AgentToolCall,
93
+ AgentToolResult,
94
+ )
95
+
96
+ async for evt in agent.stream(messages, context=ctx):
97
+ match evt:
98
+ case AgentTextDelta(text=chunk):
99
+ print(chunk, end="", flush=True)
100
+ case AgentToolCall(name=name):
101
+ print(f"\n[tool-call] {name}")
102
+ case AgentToolResult(name=name):
103
+ print(f"\n[tool-result] {name}")
104
+ case AgentFinish(stop_reason=reason, session_id=sid):
105
+ print(f"\n[finish] {reason} session={sid}")
106
+ ```
107
+
108
+ ## Multi-turn continuation (planned)
109
+
110
+ Agent Engine sessions hold conversation state. Capture `AgentFinish.session_id` and thread it back on the next turn:
111
+
112
+ ```python
113
+ from copass_google_agents import SESSION_ID_HANDLE
114
+
115
+ ctx2 = AgentInvocationContext(
116
+ scope=AgentScope(user_id="u-123"),
117
+ handles={SESSION_ID_HANDLE: prior_session_id},
118
+ )
119
+ ```
120
+
121
+ ## Deploying an ADK agent (planned)
122
+
123
+ ```python
124
+ from copass_google_agents.deploy import deploy_adk_agent
125
+
126
+ engine = deploy_adk_agent(
127
+ display_name="support-agent",
128
+ project="my-gcp-project",
129
+ system_prompt="You are a support agent...",
130
+ copass_api_url="https://api.copass.id",
131
+ copass_api_key=os.environ["COPASS_API_KEY"],
132
+ )
133
+ print(engine.resource_name) # feed into CopassGoogleAgent(reasoning_engine_id=...)
134
+ ```
135
+
136
+ ## License
137
+
138
+ MIT.
@@ -0,0 +1,114 @@
1
+ # copass-google-agents
2
+
3
+ Google Vertex AI **Agent Engine** (ADK) backend for Copass. Depends on [`copass-core-agents`](../copass-core-agents), which owns the vendor-neutral primitives (`BaseAgent`, `AgentTool`, `AgentBackend` ABC, events, `AgentScope`, registries, etc.) shared across every provider-specific Copass SDK.
4
+
5
+ This package owns the Google-specific piece — `GoogleAgentBackend` and the `CopassGoogleAgent` convenience subclass — and re-exports the core primitives for one-line dev imports. Either of these works for consumers:
6
+
7
+ ```python
8
+ from copass_google_agents import BaseAgent, CopassGoogleAgent # convenient
9
+ # or
10
+ from copass_core_agents import BaseAgent # explicit boundary
11
+ from copass_google_agents import CopassGoogleAgent
12
+ ```
13
+
14
+ Pairs with Copass's server-side router — both sides import the same code so the agent runtime is a single codepath, whether the agent runs in the dev's process or server-side via Copass's Router endpoint.
15
+
16
+ > **Status: scaffold (v0.1.0).** Constructors, type surface, and public imports are in place. `GoogleAgentBackend.run` / `GoogleAgentBackend.stream` / `deploy_adk_agent` / `adk_event_to_agent_events` currently raise `NotImplementedError`. Implementation lands in a follow-up pass.
17
+
18
+ ## Install
19
+
20
+ ```bash
21
+ pip install copass-google-agents
22
+ ```
23
+
24
+ Requires `google-cloud-aiplatform[agent_engines,adk]>=1.148.1` (which pulls in `google-adk>=1.31`). Uses Application Default Credentials (ADC) — run `gcloud auth application-default login` locally, or set `GOOGLE_APPLICATION_CREDENTIALS` / attach a service account.
25
+
26
+ ## Architecture
27
+
28
+ Agent Engine diverges from Claude Managed Agents in one important way: **ADK agents are pre-deployed resources** (`projects/{p}/locations/{l}/reasoningEngines/{id}`) and their **tools are baked in at deploy time**. You cannot pass tools per-run.
29
+
30
+ To preserve Copass's `AgentToolResolver` runtime-plug model, `copass-google-agents` deploys ADK agents carrying a single `copass_dispatch(tool_name, arguments)` function tool. At run time that proxy calls back into your Copass service, which hosts the real resolver and invokes the right tool for the current user.
31
+
32
+ So:
33
+ - **`GoogleAgentBackend`** is *session-only* — streams queries against a pre-deployed engine.
34
+ - **`deploy_adk_agent`** (ops helper) is the one-time setup that wires the proxy tool into a new ADK agent resource.
35
+ - **Zero client-side tools** is the expected case. `CopassGoogleAgent` defaults to an empty `AgentToolRegistry`.
36
+
37
+ ## Quickstart (planned — not functional in the scaffold)
38
+
39
+ ```python
40
+ import os
41
+ from copass_google_agents import (
42
+ AgentInvocationContext,
43
+ AgentScope,
44
+ CopassGoogleAgent,
45
+ )
46
+
47
+ agent = CopassGoogleAgent(
48
+ identity="support",
49
+ system_prompt="You are a support agent.",
50
+ project=os.environ["GOOGLE_CLOUD_PROJECT"],
51
+ reasoning_engine_id=os.environ["COPASS_REASONING_ENGINE_ID"],
52
+ )
53
+
54
+ ctx = AgentInvocationContext(scope=AgentScope(user_id="u-123"))
55
+ result = await agent.run(
56
+ messages=[{"role": "user", "content": "Hello"}],
57
+ context=ctx,
58
+ )
59
+ print(result.final_text)
60
+ ```
61
+
62
+ ## Streaming (planned)
63
+
64
+ ```python
65
+ from copass_google_agents import (
66
+ AgentFinish,
67
+ AgentTextDelta,
68
+ AgentToolCall,
69
+ AgentToolResult,
70
+ )
71
+
72
+ async for evt in agent.stream(messages, context=ctx):
73
+ match evt:
74
+ case AgentTextDelta(text=chunk):
75
+ print(chunk, end="", flush=True)
76
+ case AgentToolCall(name=name):
77
+ print(f"\n[tool-call] {name}")
78
+ case AgentToolResult(name=name):
79
+ print(f"\n[tool-result] {name}")
80
+ case AgentFinish(stop_reason=reason, session_id=sid):
81
+ print(f"\n[finish] {reason} session={sid}")
82
+ ```
83
+
84
+ ## Multi-turn continuation (planned)
85
+
86
+ Agent Engine sessions hold conversation state. Capture `AgentFinish.session_id` and thread it back on the next turn:
87
+
88
+ ```python
89
+ from copass_google_agents import SESSION_ID_HANDLE
90
+
91
+ ctx2 = AgentInvocationContext(
92
+ scope=AgentScope(user_id="u-123"),
93
+ handles={SESSION_ID_HANDLE: prior_session_id},
94
+ )
95
+ ```
96
+
97
+ ## Deploying an ADK agent (planned)
98
+
99
+ ```python
100
+ from copass_google_agents.deploy import deploy_adk_agent
101
+
102
+ engine = deploy_adk_agent(
103
+ display_name="support-agent",
104
+ project="my-gcp-project",
105
+ system_prompt="You are a support agent...",
106
+ copass_api_url="https://api.copass.id",
107
+ copass_api_key=os.environ["COPASS_API_KEY"],
108
+ )
109
+ print(engine.resource_name) # feed into CopassGoogleAgent(reasoning_engine_id=...)
110
+ ```
111
+
112
+ ## License
113
+
114
+ MIT.
@@ -0,0 +1,60 @@
1
+ [build-system]
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "copass-google-agents"
7
+ version = "0.1.0"
8
+ description = "Copass agent primitives for Google Vertex AI Agent Engine (ADK)"
9
+ readme = "README.md"
10
+ license = { text = "MIT" }
11
+ authors = [{ name = "Olane Inc." }]
12
+ requires-python = ">=3.10"
13
+ keywords = [
14
+ "copass",
15
+ "knowledge-graph",
16
+ "google",
17
+ "vertex-ai",
18
+ "agent-engine",
19
+ "adk",
20
+ "agents",
21
+ ]
22
+ classifiers = [
23
+ "License :: OSI Approved :: MIT License",
24
+ "Programming Language :: Python :: 3",
25
+ "Programming Language :: Python :: 3.10",
26
+ "Programming Language :: Python :: 3.11",
27
+ "Programming Language :: Python :: 3.12",
28
+ ]
29
+ dependencies = [
30
+ "google-cloud-aiplatform[agent_engines,adk]>=1.148.1",
31
+ "copass-core-agents>=0.1.0",
32
+ ]
33
+
34
+ [project.optional-dependencies]
35
+ dev = [
36
+ "pytest>=8.0",
37
+ "pytest-asyncio>=0.23",
38
+ "mypy>=1.10",
39
+ "ruff>=0.5",
40
+ ]
41
+
42
+ [project.urls]
43
+ Homepage = "https://github.com/olane-labs/copass-harness"
44
+ Repository = "https://github.com/olane-labs/copass-harness.git"
45
+
46
+ [tool.hatch.build.targets.wheel]
47
+ packages = ["src/copass_google_agents"]
48
+
49
+ [tool.pytest.ini_options]
50
+ asyncio_mode = "auto"
51
+ testpaths = ["tests"]
52
+
53
+ [tool.ruff]
54
+ line-length = 100
55
+ target-version = "py310"
56
+
57
+ [tool.mypy]
58
+ python_version = "3.10"
59
+ strict = true
60
+ packages = ["copass_google_agents"]
@@ -0,0 +1,104 @@
1
+ """Copass agent SDK for Google Vertex AI Agent Engine (ADK).
2
+
3
+ This package owns the Google-specific backend. All provider-neutral
4
+ ABCs (``BaseAgent``, ``AgentTool``, ``AgentBackend``, events, scope,
5
+ registries) live in :mod:`copass_core_agents` and are re-exported here
6
+ for convenience — dev code can import everything it needs from one
7
+ place.
8
+
9
+ Public surface:
10
+
11
+ Google-specific (owned here):
12
+ GoogleAgentBackend
13
+ CopassGoogleAgent — convenience subclass of BaseAgent
14
+ DEFAULT_LOCATION
15
+ DEFAULT_MODEL
16
+ DISPATCH_TOOL_NAME
17
+ SESSION_ID_HANDLE
18
+
19
+ Provider-neutral (re-exported from copass_core_agents):
20
+ BaseAgent, AgentScope, AgentInvocationContext
21
+ AgentTool, AgentToolRegistry, AgentToolResolver
22
+ ToolSpec, ToolCall, ToolConflictPolicy, ToolConflictError
23
+ AgentEvent, AgentTextDelta, AgentToolCall, AgentToolResult,
24
+ AgentFinish
25
+ AgentBackend, AgentRunResult
26
+ register_agent, get_agent_class, list_agents
27
+ register_agent_tool, get_agent_tool, try_get_agent_tool,
28
+ list_agent_tools
29
+ """
30
+
31
+ # Re-export core (vendor-neutral) primitives for one-line imports.
32
+ from copass_core_agents import (
33
+ AgentBackend,
34
+ AgentEvent,
35
+ AgentFinish,
36
+ AgentInvocationContext,
37
+ AgentRunResult,
38
+ AgentScope,
39
+ AgentTextDelta,
40
+ AgentTool,
41
+ AgentToolCall,
42
+ AgentToolRegistry,
43
+ AgentToolResolver,
44
+ AgentToolResult,
45
+ BaseAgent,
46
+ ToolCall,
47
+ ToolConflictError,
48
+ ToolConflictPolicy,
49
+ ToolSpec,
50
+ get_agent_class,
51
+ get_agent_tool,
52
+ list_agent_tools,
53
+ list_agents,
54
+ register_agent,
55
+ register_agent_tool,
56
+ try_get_agent_tool,
57
+ )
58
+
59
+ # Google-specific (owned here).
60
+ from copass_google_agents.backends.google_agent_backend import (
61
+ DEFAULT_LOCATION,
62
+ DISPATCH_TOOL_NAME,
63
+ SESSION_ID_HANDLE,
64
+ GoogleAgentBackend,
65
+ )
66
+ from copass_google_agents.google_agent import DEFAULT_MODEL, CopassGoogleAgent
67
+
68
+ __version__ = "0.1.0"
69
+
70
+ __all__ = [
71
+ "__version__",
72
+ # Google-specific
73
+ "CopassGoogleAgent",
74
+ "DEFAULT_MODEL",
75
+ "GoogleAgentBackend",
76
+ "DEFAULT_LOCATION",
77
+ "DISPATCH_TOOL_NAME",
78
+ "SESSION_ID_HANDLE",
79
+ # Re-exported from copass_core_agents
80
+ "BaseAgent",
81
+ "AgentScope",
82
+ "AgentInvocationContext",
83
+ "AgentTool",
84
+ "AgentToolRegistry",
85
+ "AgentToolResolver",
86
+ "ToolSpec",
87
+ "ToolCall",
88
+ "ToolConflictError",
89
+ "ToolConflictPolicy",
90
+ "AgentEvent",
91
+ "AgentTextDelta",
92
+ "AgentToolCall",
93
+ "AgentToolResult",
94
+ "AgentFinish",
95
+ "AgentBackend",
96
+ "AgentRunResult",
97
+ "register_agent",
98
+ "get_agent_class",
99
+ "list_agents",
100
+ "register_agent_tool",
101
+ "get_agent_tool",
102
+ "try_get_agent_tool",
103
+ "list_agent_tools",
104
+ ]
@@ -0,0 +1,101 @@
1
+ """Module-scope definition of the ``copass_dispatch`` proxy tool.
2
+
3
+ ADK serializes function tools by reference; closures over deploy-time
4
+ variables do not round-trip into Agent Engine's remote runtime.
5
+ This module defines the tool at module scope and reads its
6
+ configuration from environment variables baked into the deployed
7
+ engine (``COPASS_API_URL``, ``COPASS_API_KEY``, ``COPASS_DISPATCH_PATH``).
8
+
9
+ The function's signature and docstring are what ADK exposes to the
10
+ model as the tool schema — keep both pedagogical.
11
+ """
12
+
13
+ from __future__ import annotations
14
+
15
+ import os
16
+ from typing import Any, Dict, Optional
17
+
18
+
19
+ DEFAULT_DISPATCH_PATH = "/api/v1/agents/dispatch"
20
+ """Default path on the Copass service where the proxy POSTs tool
21
+ invocations. Overridable at deploy time via ``COPASS_DISPATCH_PATH``."""
22
+
23
+
24
+ async def copass_dispatch(
25
+ tool_name: str,
26
+ arguments: Dict[str, Any],
27
+ tool_context: Optional[Any] = None,
28
+ ) -> Dict[str, Any]:
29
+ """Route a tool invocation through Copass's server-side resolver.
30
+
31
+ ADK Agent Engine bakes tools at deploy time. To preserve the
32
+ runtime ``AgentToolResolver`` plug model, every deployed Copass
33
+ agent carries exactly this one function tool. The model calls
34
+ ``copass_dispatch`` with the logical tool name and arguments;
35
+ the Copass service receives the call, looks the tool up against
36
+ the current user's resolver, executes it, and returns the result.
37
+
38
+ Args:
39
+ tool_name: The logical name of the tool to invoke (as
40
+ advertised in the agent's system prompt).
41
+ arguments: JSON-serializable arguments for the tool.
42
+ tool_context: ADK-injected context providing ``user_id`` and
43
+ ``session_id`` when available. ADK populates this
44
+ automatically at invocation time.
45
+
46
+ Returns:
47
+ The tool result dict, passed straight from the Copass
48
+ service response body.
49
+ """
50
+ import httpx # deferred import — keeps cold-start lean
51
+
52
+ api_url = os.environ.get("COPASS_API_URL")
53
+ api_key = os.environ.get("COPASS_API_KEY")
54
+ if not api_url or not api_key:
55
+ return {
56
+ "error": (
57
+ "copass_dispatch misconfigured: COPASS_API_URL / "
58
+ "COPASS_API_KEY env vars not set on the deployed agent."
59
+ )
60
+ }
61
+ path = os.environ.get("COPASS_DISPATCH_PATH", DEFAULT_DISPATCH_PATH)
62
+
63
+ user_id = None
64
+ session_id = None
65
+ if tool_context is not None:
66
+ user_id = getattr(tool_context, "user_id", None)
67
+ session_id = getattr(tool_context, "session_id", None)
68
+
69
+ payload = {
70
+ "tool_name": tool_name,
71
+ "arguments": arguments or {},
72
+ "user_id": user_id,
73
+ "session_id": session_id,
74
+ }
75
+ url = f"{api_url.rstrip('/')}{path}"
76
+
77
+ async with httpx.AsyncClient(timeout=60.0) as http:
78
+ resp = await http.post(
79
+ url,
80
+ json=payload,
81
+ headers={
82
+ "Authorization": f"Bearer {api_key}",
83
+ "Content-Type": "application/json",
84
+ },
85
+ )
86
+ try:
87
+ resp.raise_for_status()
88
+ except httpx.HTTPStatusError as err:
89
+ return {
90
+ "error": (
91
+ f"copass_dispatch HTTP {resp.status_code}: {err}"
92
+ ),
93
+ "response_text": resp.text[:1000],
94
+ }
95
+ try:
96
+ return dict(resp.json())
97
+ except ValueError:
98
+ return {"text": resp.text}
99
+
100
+
101
+ __all__ = ["copass_dispatch", "DEFAULT_DISPATCH_PATH"]
@@ -0,0 +1,23 @@
1
+ """Google agent backends.
2
+
3
+ Re-exports the core ``AgentBackend`` / ``AgentRunResult`` ABCs
4
+ (implemented in ``copass-core-agents``) alongside this package's
5
+ Google-specific ``GoogleAgentBackend``.
6
+ """
7
+
8
+ from copass_core_agents.backends import AgentBackend, AgentRunResult
9
+ from copass_google_agents.backends.google_agent_backend import (
10
+ DEFAULT_LOCATION,
11
+ DISPATCH_TOOL_NAME,
12
+ SESSION_ID_HANDLE,
13
+ GoogleAgentBackend,
14
+ )
15
+
16
+ __all__ = [
17
+ "AgentBackend",
18
+ "AgentRunResult",
19
+ "GoogleAgentBackend",
20
+ "DEFAULT_LOCATION",
21
+ "DISPATCH_TOOL_NAME",
22
+ "SESSION_ID_HANDLE",
23
+ ]