GCAP-SPEC-FUNCTION-DESCRIPTOR-0001 implementation. Mirrors connector runtime pattern exactly. FunctionPlugin — trigger_events, handle(), descriptor(), knative_manifest() FunctionRegistry — trigger_index for event-driven routing FunctionRuntime — invoke() + dispatch() with Chronicle lineage governed_function decorator — SDK surface for function authors BillingProcessor — GSAP_CR_RECEIVED → billable event with Chronicle CID EchoFunction — dev/test API: /functions/ catalogue, invoke, dispatch, manifest, health 8 tests passing. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
70 lines
2.3 KiB
Python
70 lines
2.3 KiB
Python
"""governed_function decorator — wraps async functions as FunctionPlugins."""
|
|
from __future__ import annotations
|
|
|
|
import functools
|
|
from typing import Any, Callable, Awaitable
|
|
|
|
from .base import FunctionContext, FunctionPlugin, FunctionResult
|
|
|
|
|
|
def governed_function(
|
|
function_id: str,
|
|
corpus_entry_cid: str,
|
|
capability_mask: int = 1,
|
|
trigger_events: list[str] | None = None,
|
|
accord_template: str = "",
|
|
gsap_required: bool = True,
|
|
chronicle_enabled: bool = True,
|
|
max_duration_seconds: int = 30,
|
|
display_name: str = "",
|
|
description: str = "",
|
|
version: str = "0.1.0",
|
|
registry: Any = None,
|
|
) -> Callable:
|
|
"""Decorator that wraps an async function as a governed FunctionPlugin.
|
|
|
|
Usage::
|
|
|
|
@governed_function(
|
|
function_id="my-func",
|
|
corpus_entry_cid="sha256:abc...",
|
|
)
|
|
async def my_func(event, context):
|
|
return FunctionResult(success=True, data=event)
|
|
"""
|
|
|
|
def decorator(
|
|
fn: Callable[[dict[str, Any], FunctionContext], Awaitable[FunctionResult]],
|
|
) -> FunctionPlugin:
|
|
|
|
class WrappedFunction(FunctionPlugin):
|
|
pass
|
|
|
|
instance = WrappedFunction.__new__(WrappedFunction)
|
|
instance.function_id = function_id
|
|
instance.corpus_entry_cid = corpus_entry_cid
|
|
instance.capability_mask = capability_mask
|
|
instance.trigger_events = trigger_events or []
|
|
instance.accord_template = accord_template
|
|
instance.gsap_required = gsap_required
|
|
instance.chronicle_enabled = chronicle_enabled
|
|
instance.max_duration_seconds = max_duration_seconds
|
|
instance.display_name = display_name or function_id
|
|
instance.description = description
|
|
instance.version = version
|
|
|
|
async def handle(event: dict[str, Any], context: FunctionContext) -> FunctionResult:
|
|
return await fn(event, context)
|
|
|
|
instance.handle = handle # type: ignore[assignment]
|
|
instance.health_check = lambda: True # type: ignore[assignment]
|
|
|
|
# Auto-register if a registry is provided
|
|
if registry is not None:
|
|
registry.register(instance)
|
|
|
|
# Preserve original function metadata
|
|
functools.update_wrapper(instance, fn)
|
|
return instance
|
|
|
|
return decorator
|