Semantic Kernel¶
Available · kernel functions and a plugin ·
auto-invocation filter approval · pip install "agent-adapter[semantic-kernel]"
Dependency pin
semantic-kernel 1.4x pins pydantic<2.14: installing the extra downgrades pydantic
(to 2.13.x) and pulls ~430 MB. It is not in all and has its own nox session
(contract-semantic_kernel). Semantic Kernel is in maintenance mode; for new agents
see Microsoft Agent Framework.
Functions¶
Function (agent_adapter.integrations.semantic_kernel) |
Returns |
|---|---|
kernel_function(spec, *, executor=None) |
one KernelFunctionFromMethod (a subclass), one parameter per schema property |
kernel_plugin(registry, *, name="agent_adapter", executor=None) |
a KernelPlugin; the model sees <name>-<tool> |
approval_filter(port, registry, *, plugin="agent_adapter") |
an AUTO_FUNCTION_INVOCATION filter for that plugin's functions (None: any plugin) |
INTEGRATION |
get_integration("semantic_kernel"); bind_approval(port) = the filter, resolving specs from our functions |
Each parameter carries its property schema ($refs inlined) as schema_data. Values
that are not strings come back as JSON text (the model sees str(result)).
Wiring¶
kernel = Kernel()
kernel.add_plugin(kernel_plugin(registry, executor=Executor(registry))) # agent_adapter-<tool>
kernel.add_filter(
FilterTypes.AUTO_FUNCTION_INVOCATION, approval_filter(CallbackApproval(reviewer), registry)
)
# then: a chat service with FunctionChoiceBehavior.Auto() calls the tools through this kernel
Approval¶
sequenceDiagram
participant K as Kernel (function calling)
participant F as approval filter
participant P as ApprovalPort
participant Fn as kernel function
participant Ex as Executor
K->>F: AutoFunctionInvocationContext (agent_adapter-send_invoice, call id)
F->>P: request(tool="send_invoice", arguments, call_id)
alt approved
F->>Fn: next(context) with a one-use token
Fn->>Ex: run_spec(..., ctx.approval = token, if it matches)
else denied / pending
F-->>K: function_result = error text (not called)
end
| Case | What happens |
|---|---|
| Approved | a one-use token for that invocation only, bound to the conversation's run, the call id, <plugin>-<function> and the validated arguments; the executor does not ask again |
| No call id on the function call | denied (the approval could not be bound to it) |
| Denied | the function is not called; its result is {"error": {"kind": "approval-denied", ...}} |
Port raises ApprovalPending |
the result is approval required: <id> |
| Edited arguments | not supported: an edit is treated as a denial (logged at WARNING) |
| A function of another plugin | not gated by the filter: the executor's own port decides |
No filter, or kernel.invoke(...) outside function calling |
the executor's own confirm rule and port decide (no port: denied) |
The filter never sets context.terminate: after a denial the model gets the result and
the conversation goes on.
Calls and errors¶
| Item | Behaviour |
|---|---|
| Call id | the function call content's id → ctx.call_id (auto-invocation only) |
| Run | one run id per chat history (conversation) behind the filter |
ToolArgsInvalid, ToolError, ApprovalDenied, GuardrailBlocked, RunLimitExceeded |
returned as {"error": {"kind", "message"}} |
| Other errors | raised; SK reports An error occurred while invoking the function ... |
CancelledError |
propagates |
Semantic Kernel injects kernel, service, execution_settings and arguments by name,
so tools with such argument names are refused with ToolDefinitionError.