Plugin SDKs¶
RoboDev provides SDK helper libraries and build tooling for three languages.
The protobuf definitions in proto/ are the source of truth. Generated stubs
are not checked into the repository — you generate them locally with
make sdk-gen before using the SDKs.
What's in the repository¶
| Language | Directory | What's included |
|---|---|---|
| Go | sdk/go/ |
Helper scaffolding and examples; no generated stubs |
| Python | sdk/python/ |
plugin.py base class helpers; proto stub dirs are empty until you run make sdk-gen |
| TypeScript | sdk/typescript/ |
plugin.ts base class helpers; proto stub dirs are empty until you run make sdk-gen |
Generating stubs¶
Run the following Make target to regenerate all three SDKs from the proto sources:
This invokes buf generate with the appropriate configuration for each
language. You will need buf installed and available on your PATH. Install
it with:
# macOS / Linux
brew install bufbuild/buf/buf
# Or download a release binary from https://github.com/bufbuild/buf/releases
Individual languages can also be generated directly:
buf generate proto/ # Go stubs
buf generate proto/ --template buf.gen.python.yaml # Python stubs
buf generate proto/ --template buf.gen.ts.yaml # TypeScript stubs
Go SDK (sdk/go/)¶
The Go stubs are a module importable by any Go plugin. They provide the
generated protobuf types and gRPC service definitions. Combine them with
the pkg/plugin/ interfaces and hashicorp/go-plugin to build a built-in
or third-party plugin.
import (
v1 "github.com/unitaryai/robodev/proto/v1"
)
func (b *MyBackend) Handshake(
ctx context.Context,
req *v1.HandshakeRequest,
) (*v1.HandshakeResponse, error) {
return &v1.HandshakeResponse{
InterfaceVersion: 1,
PluginName: "my-backend",
PluginVersion: "1.0.0",
}, nil
}
See Writing a Plugin for a complete walkthrough.
Python SDK (sdk/python/)¶
The Python stubs are generated by buf using the protoc-gen-python and
protoc-gen-grpc-python plugins. They provide the message classes and
service stub classes needed to implement a gRPC server.
A minimal ticketing plugin skeleton:
import grpc
from concurrent import futures
from robodev.v1 import ticketing_pb2, ticketing_pb2_grpc, common_pb2
class MyTicketingBackend(ticketing_pb2_grpc.TicketingBackendServicer):
def Handshake(self, request, context):
return common_pb2.HandshakeResponse(
interface_version=1,
plugin_name="my-backend",
plugin_version="1.0.0",
)
def PollReadyTickets(self, request, context):
# Call your issue tracker API here.
return ticketing_pb2.PollReadyTicketsResponse(tickets=[])
def serve():
server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
ticketing_pb2_grpc.add_TicketingBackendServicer_to_server(
MyTicketingBackend(), server
)
server.add_insecure_port("[::]:50051")
server.start()
server.wait_for_termination()
if __name__ == "__main__":
serve()
Refer to the example Jira plugin at
examples/plugins/example-jira-python/ for a complete implementation
including pyproject.toml and a Dockerfile.
TypeScript SDK (sdk/typescript/)¶
The TypeScript stubs are generated by buf using protoc-gen-grpc-web or
protoc-gen-ts. They provide typed message interfaces and service client
stubs compatible with Node.js gRPC.
A minimal notifications plugin skeleton:
import * as grpc from '@grpc/grpc-js';
import {
NotificationChannelService,
INotificationChannelServer,
} from './generated/notifications_grpc_pb';
import {
HandshakeRequest,
HandshakeResponse,
} from './generated/common_pb';
class TeamsNotificationChannel implements INotificationChannelServer {
handshake(
call: grpc.ServerUnaryCall<HandshakeRequest, HandshakeResponse>,
callback: grpc.sendUnaryData<HandshakeResponse>,
): void {
const response = new HandshakeResponse();
response.setInterfaceVersion(1);
response.setPluginName('teams');
response.setPluginVersion('1.0.0');
callback(null, response);
}
// ... implement notify, notifyStart, notifyComplete ...
}
const server = new grpc.Server();
server.addService(NotificationChannelService, new TeamsNotificationChannel());
server.bindAsync('0.0.0.0:50051', grpc.ServerCredentials.createInsecure(), () => {
server.start();
});
Refer to the example Teams plugin at
examples/plugins/example-teams-ts/ for a complete implementation including
package.json, tsconfig.json, and a Dockerfile.
Interface versioning¶
All generated stubs carry the interface_version constant from their
respective proto package. This version must match what the controller expects
(currently 1 for all services). See the
Plugin gRPC API reference for the full
versioning rules.