Skip to content

Commit 9819dc7

Browse files
committed
Added a skill that performs CRUD operations on points
1 parent c5b494e commit 9819dc7

File tree

5 files changed

+288
-9
lines changed

5 files changed

+288
-9
lines changed

notebooks/scratchpad.ipynb

Lines changed: 80 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,28 +3,99 @@
33
{
44
"cell_type": "code",
55
"execution_count": null,
6-
"id": "eb98ef8f",
6+
"id": "9e70ce57",
77
"metadata": {},
88
"outputs": [],
9+
"source": [
10+
"_CREATE=False\n",
11+
"_READ=False\n",
12+
"_UPDATE=True\n",
13+
"_DELETE=True"
14+
]
15+
},
16+
{
17+
"cell_type": "code",
18+
"execution_count": 22,
19+
"id": "eb98ef8f",
20+
"metadata": {},
21+
"outputs": [
22+
{
23+
"name": "stdout",
24+
"output_type": "stream",
25+
"text": [
26+
"Connecting to deployed solution...\n",
27+
"Connected successfully to \"litouka's notebook test - blank solution(local-build)\" at \"vmp-028b-ymfhwy2m\".\n"
28+
]
29+
}
30+
],
931
"source": [
1032
"from intrinsic.solutions import deployments\n",
1133
"\n",
12-
"solution = deployments.connect_to_selected_solution()"
34+
"solution = deployments.connect_to_selected_solution()\n",
35+
"executive = solution.executive\n",
36+
"skills = solution.skills\n",
37+
"points_crud_skill = skills.com.example.points_crud"
1338
]
1439
},
1540
{
1641
"cell_type": "code",
17-
"execution_count": null,
42+
"execution_count": 23,
1843
"id": "6878fdea",
1944
"metadata": {},
2045
"outputs": [],
2146
"source": [
22-
"executive = solution.executive\n",
23-
"skills = solution.skills\n",
24-
"\n",
25-
"counter_demo = skills.com.example.counter_demo\n",
26-
"counter_demo_1 = counter_demo()\n",
27-
"executive.run(counter_demo_1)"
47+
"if _CREATE:\n",
48+
" create_points = points_crud_skill(create=True)\n",
49+
" executive.run(create_points)"
50+
]
51+
},
52+
{
53+
"cell_type": "code",
54+
"execution_count": 24,
55+
"id": "9527f974",
56+
"metadata": {},
57+
"outputs": [
58+
{
59+
"data": {
60+
"text/html": [
61+
"<span style=\"color: #2c8b22; font-family: monospace; font-weight: bold; padding-left: var(--jp-code-padding);\">Execution successful</span>"
62+
],
63+
"text/plain": [
64+
"<IPython.core.display.HTML object>"
65+
]
66+
},
67+
"metadata": {},
68+
"output_type": "display_data"
69+
}
70+
],
71+
"source": [
72+
"if _READ:\n",
73+
" read_points = points_crud_skill(read=True)\n",
74+
" executive.run(read_points)"
75+
]
76+
},
77+
{
78+
"cell_type": "code",
79+
"execution_count": 25,
80+
"id": "3936df1b",
81+
"metadata": {},
82+
"outputs": [],
83+
"source": [
84+
"if _UPDATE:\n",
85+
" update_point = points_crud_skill(update=True)\n",
86+
" executive.run(update_point)"
87+
]
88+
},
89+
{
90+
"cell_type": "code",
91+
"execution_count": 26,
92+
"id": "9e9bf2ea",
93+
"metadata": {},
94+
"outputs": [],
95+
"source": [
96+
"if _DELETE:\n",
97+
" delete_points = points_crud_skill(delete=True)\n",
98+
" executive.run(delete_points)"
2899
]
29100
}
30101
],

skills/points_crud/BUILD

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
load("@ai_intrinsic_sdks//bazel:skills.bzl", "py_skill", "skill_manifest")
2+
load("@com_github_grpc_grpc//bazel:python_rules.bzl", "py_proto_library")
3+
load("@com_google_protobuf//bazel:proto_library.bzl", "proto_library")
4+
load("@rules_python//python:defs.bzl", "py_library")
5+
6+
proto_library(
7+
name = "points_crud_proto",
8+
srcs = ["points_crud.proto"],
9+
)
10+
11+
py_proto_library(
12+
name = "points_crud_py_pb2",
13+
deps = [":points_crud_proto"],
14+
)
15+
16+
skill_manifest(
17+
name = "points_crud_py_manifest",
18+
src = "points_crud.manifest.textproto",
19+
deps = [":points_crud_proto"],
20+
)
21+
22+
py_library(
23+
name = "points_crud",
24+
srcs = ["points_crud.py"],
25+
deps = [
26+
":points_crud_py_pb2",
27+
"//services/points_storage:points_storage_service_py_pb2",
28+
"//services/points_storage:points_storage_service_py_pb2_grpc",
29+
"@ai_intrinsic_sdks//intrinsic/skills/proto:equipment_py_pb2",
30+
"@ai_intrinsic_sdks//intrinsic/skills/python:proto_utils",
31+
"@ai_intrinsic_sdks//intrinsic/skills/python:skill_interface",
32+
"@ai_intrinsic_sdks//intrinsic/util:decorators",
33+
"@ai_intrinsic_sdks//intrinsic/util/grpc:connection",
34+
"@ai_intrinsic_sdks//intrinsic/util/grpc:interceptor",
35+
"@com_google_absl_py//absl/logging",
36+
"@com_google_protobuf//:protobuf_python",
37+
],
38+
)
39+
40+
py_skill(
41+
name = "points_crud_skill",
42+
manifest = ":points_crud_py_manifest",
43+
deps = [
44+
":points_crud",
45+
":points_crud_py_pb2",
46+
],
47+
)
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# proto-file: https://github.com/intrinsic-ai/sdk/blob/main/intrinsic/skills/proto/skill_manifest.proto
2+
# proto-message: intrinsic_proto.skill.SkillManifest
3+
4+
id {
5+
package: "com.example"
6+
name: "points_crud"
7+
}
8+
display_name: "Store points"
9+
vendor {
10+
display_name: "Intrinsic"
11+
}
12+
documentation {
13+
description: "Stores coordinates of 3d points in key-value storage."
14+
}
15+
options {
16+
supports_cancellation: false
17+
python_config {
18+
skill_module: "skills.points_crud.points_crud"
19+
proto_module: "skills.points_crud.points_crud_pb2"
20+
create_skill: "skills.points_crud.points_crud.PointsCrud"
21+
}
22+
}
23+
dependencies {
24+
required_equipment {
25+
key: "points_storage_service"
26+
value {
27+
capability_names: "points_storage.PointsStorageService"
28+
}
29+
}
30+
}
31+
parameter {
32+
message_full_name: "com.example.PointsCrudParams"
33+
default_value {
34+
type_url: "type.googleapis.com/com.example.PointsCrudParams"
35+
}
36+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
syntax = "proto3";
2+
3+
package com.example;
4+
5+
message PointsCrudParams {
6+
bool create = 1;
7+
bool read = 2;
8+
bool update = 3;
9+
bool delete = 4;
10+
}

skills/points_crud/points_crud.py

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
"""Contains the points_crud skill."""
2+
3+
from absl import logging
4+
import grpc
5+
from intrinsic.skills.python import proto_utils
6+
from intrinsic.skills.python import skill_interface
7+
from intrinsic.util.decorators import overrides
8+
from intrinsic.util.grpc import connection
9+
from intrinsic.util.grpc import interceptor
10+
from services.points_storage import points_storage_service_pb2 as points_storage_proto
11+
from services.points_storage import points_storage_service_pb2_grpc as points_storage_grpc
12+
from skills.points_crud import points_crud_pb2
13+
14+
15+
def make_grpc_stub(resource_handle):
16+
logging.info(f"Address: {resource_handle.connection_info.grpc.address}")
17+
logging.info(
18+
f"Server Instance: {resource_handle.connection_info.grpc.server_instance}"
19+
)
20+
logging.info(f"Header: {resource_handle.connection_info.grpc.header}")
21+
22+
# Create a gRPC channel without using TLS
23+
grpc_info = resource_handle.connection_info.grpc
24+
grpc_channel = grpc.insecure_channel(grpc_info.address)
25+
connection_params = connection.ConnectionParams(
26+
grpc_info.address, grpc_info.server_instance, grpc_info.header
27+
)
28+
29+
intercepted_channel = grpc.intercept_channel(
30+
grpc_channel,
31+
interceptor.HeaderAdderInterceptor(connection_params.headers),
32+
)
33+
return points_storage_grpc.PointsStorageServiceStub(intercepted_channel)
34+
35+
36+
class PointsCrud(skill_interface.Skill):
37+
"""Implementation of the points_crud skill."""
38+
39+
def store_point(self, stub, name: str, x: float, y: float, z: float):
40+
logging.info(f"Storing point ({x}, {y}, {z}) under the name {name}")
41+
request = points_storage_proto.StorePointRequest()
42+
request.name = name
43+
request.point.x = x
44+
request.point.y = y
45+
request.point.z = z
46+
stub.Store(request)
47+
logging.info(f"Point {name} has been stored")
48+
49+
def get_point(self, stub, name: str):
50+
logging.info(f"Fetching point {name}")
51+
request = points_storage_proto.GetPointRequest()
52+
request.name = name
53+
response = stub.Get(request)
54+
pt = response.point
55+
logging.info(f"Got ({pt.x}, {pt.y}, {pt.z})")
56+
return pt
57+
58+
def get_all_points(self, stub):
59+
logging.info("Fetching all points")
60+
request = points_storage_proto.GetAllPointsRequest()
61+
response = stub.GetAll(request)
62+
logging.info(f"Got {len(response.items)} points:")
63+
for item in response.items:
64+
pt = item.point
65+
logging.info(f"- Point {item.name}: ({pt.x}, {pt.y}, {pt.z})")
66+
67+
def delete_point(self, stub, name: str):
68+
logging.info(f"Deleting point {name}")
69+
request = points_storage_proto.DeleteRequest()
70+
request.name = name
71+
stub.Delete(request)
72+
logging.info(f"Point {name} has been deleted")
73+
74+
75+
@overrides(skill_interface.Skill)
76+
def execute(
77+
self,
78+
request: skill_interface.ExecuteRequest[
79+
points_crud_pb2.PointsCrudParams
80+
],
81+
context: skill_interface.ExecuteContext,
82+
) -> None:
83+
params = request.params
84+
logging.info(f"Invoking the skill with create={params.create}, read={params.read}, update={params.update}, delete={params.delete}")
85+
stub = make_grpc_stub(context.resource_handles["points_storage_service"])
86+
87+
if params.create:
88+
logging.info("Creating two points")
89+
self.store_point(stub, "A", 1.0, 2.0, 3.0)
90+
self.store_point(stub, "B", 10.0, 20.0, 30.0)
91+
92+
if params.read:
93+
self.get_point(stub, "A")
94+
self.get_all_points(stub)
95+
96+
if params.update:
97+
logging.info("Moving point A by 10 units along X axis")
98+
pt = self.get_point(stub, "A")
99+
self.store_point(stub, "A", pt.x + 10.0, pt.y, pt.z)
100+
101+
logging.info("Fetching point A to confirm that it has been updated")
102+
self.get_point(stub, "A")
103+
104+
if params.delete:
105+
self.delete_point(stub, "A")
106+
self.delete_point(stub, "B")
107+
108+
logging.info("Fetching all points, expecting an empty list")
109+
self.get_all_points(stub)
110+
logging.info("Done fetching all points")
111+
112+
113+
114+
115+

0 commit comments

Comments
 (0)